Skip to content

Commit 201bee9

Browse files
authored
feat(apps): Add support for the apps revisions endpoints (#254)
* fix(networking): Update entities _get_url_filtered function fix(networking): Update _append_encoded_parameter function to append the parameters with the %s=%s format, in order to be compliant with the Policy Server API interface * feat(apps): Add function for the /v3/apps/:guid/manifest endpoint * test: Add test for the v3 apps get_manifest function * test: Fix formatting of statements in test_get_manifest function * feat(apps): Update calls to _list * test(apps): Add unit tests for revisions and deployed revisions endpoints docs: Update README.rst * chore: Fix linting issues * fix: Rename from get to list revisions
1 parent 62b39ce commit 201bee9

File tree

5 files changed

+166
-4
lines changed

5 files changed

+166
-4
lines changed

README.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,4 +397,5 @@ You can run tests by doing so. In the project directory:
397397
$ export PYTHONPATH=main
398398
$ python -m unittest discover test
399399
# or even
400-
$ python setup.py test
400+
$ poetry install
401+
$ poetry run pytest

cloudfoundry_client/v3/apps.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from typing import TYPE_CHECKING, Optional
22

3-
from cloudfoundry_client.common_objects import JsonObject
4-
from cloudfoundry_client.v3.entities import EntityManager
3+
from cloudfoundry_client.common_objects import JsonObject, Pagination
4+
from cloudfoundry_client.v3.entities import EntityManager, Entity
55

66
if TYPE_CHECKING:
77
from cloudfoundry_client.client import CloudFoundryClient
@@ -27,3 +27,11 @@ def get_routes(self, application_guid: str) -> JsonObject:
2727

2828
def get_manifest(self, application_guid: str) -> str:
2929
return self.client.get(url="%s%s/%s/manifest" % (self.target_endpoint, self.entity_uri, application_guid)).text
30+
31+
def list_revisions(self, application_guid: str, **kwargs) -> Pagination[Entity]:
32+
uri: str = "%s/%s/revisions" % (self.entity_uri, application_guid)
33+
return super(AppManager, self)._list(requested_path=uri, **kwargs)
34+
35+
def list_deployed_revisions(self, application_guid: str, **kwargs) -> Pagination[Entity]:
36+
uri: str = "%s/%s/revisions/deployed" % (self.entity_uri, application_guid)
37+
return super(AppManager, self)._list(requested_path=uri, **kwargs)
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
{
2+
"pagination": {
3+
"total_results": 1,
4+
"total_pages": 1,
5+
"first": {
6+
"href": "https://api.example.org/v3/apps/1cb006ee-fb05-47e1-b541-c34179ddc446/revisions?page=1&per_page=50"
7+
},
8+
"last": {
9+
"href": "https://api.example.org/v3/apps/1cb006ee-fb05-47e1-b541-c34179ddc446/revisions?page=1&per_page=50"
10+
},
11+
"next": null,
12+
"previous": null
13+
},
14+
"resources": [
15+
{
16+
"guid": "885735b5-aea4-4cf5-8e44-961af0e41920",
17+
"version": 1,
18+
"droplet": {
19+
"guid": "585bc3c1-3743-497d-88b0-403ad6b56d16"
20+
},
21+
"processes": {
22+
"web": {
23+
"command": "bundle exec rackup"
24+
}
25+
},
26+
"sidecars": [
27+
{
28+
"name": "auth-sidecar",
29+
"command": "bundle exec sidecar",
30+
"process_types": ["web"],
31+
"memory_in_mb": 300
32+
}
33+
],
34+
"description": "Initial revision.",
35+
"deployable": true,
36+
"relationships": {
37+
"app": {
38+
"data": {
39+
"guid": "1cb006ee-fb05-47e1-b541-c34179ddc446"
40+
}
41+
}
42+
},
43+
"created_at": "2017-02-01T01:33:58Z",
44+
"updated_at": "2017-02-01T01:33:58Z",
45+
"metadata": {
46+
"labels": {},
47+
"annotations": {}
48+
},
49+
"links": {
50+
"self": {
51+
"href": "https://api.example.org/v3/revisions/885735b5-aea4-4cf5-8e44-961af0e41920"
52+
},
53+
"app": {
54+
"href": "https://api.example.org/v3/apps/1cb006ee-fb05-47e1-b541-c34179ddc446"
55+
},
56+
"environment_variables": {
57+
"href": "https://api.example.org/v3/revisions/885735b5-aea4-4cf5-8e44-961af0e41920/environment_variables"
58+
}
59+
}
60+
}
61+
]
62+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
{
2+
"pagination": {
3+
"total_results": 1,
4+
"total_pages": 1,
5+
"first": {
6+
"href": "https://api.example.org/v3/apps/1cb006ee-fb05-47e1-b541-c34179ddc446/revisions?page=1&per_page=50"
7+
},
8+
"last": {
9+
"href": "https://api.example.org/v3/apps/1cb006ee-fb05-47e1-b541-c34179ddc446/revisions?page=1&per_page=50"
10+
},
11+
"next": null,
12+
"previous": null
13+
},
14+
"resources": [
15+
{
16+
"guid": "885735b5-aea4-4cf5-8e44-961af0e41920",
17+
"version": 1,
18+
"droplet": {
19+
"guid": "585bc3c1-3743-497d-88b0-403ad6b56d16"
20+
},
21+
"processes": {
22+
"web": {
23+
"command": "bundle exec rackup"
24+
}
25+
},
26+
"sidecars": [
27+
{
28+
"name": "auth-sidecar",
29+
"command": "bundle exec sidecar",
30+
"process_types": ["web"],
31+
"memory_in_mb": 300
32+
}
33+
],
34+
"description": "Initial revision.",
35+
"deployable": true,
36+
"relationships": {
37+
"app": {
38+
"data": {
39+
"guid": "1cb006ee-fb05-47e1-b541-c34179ddc446"
40+
}
41+
}
42+
},
43+
"created_at": "2017-02-01T01:33:58Z",
44+
"updated_at": "2017-02-01T01:33:58Z",
45+
"metadata": {
46+
"labels": {},
47+
"annotations": {}
48+
},
49+
"links": {
50+
"self": {
51+
"href": "https://api.example.org/v3/revisions/885735b5-aea4-4cf5-8e44-961af0e41920"
52+
},
53+
"app": {
54+
"href": "https://api.example.org/v3/apps/1cb006ee-fb05-47e1-b541-c34179ddc446"
55+
},
56+
"environment_variables": {
57+
"href": "https://api.example.org/v3/revisions/885735b5-aea4-4cf5-8e44-961af0e41920/environment_variables"
58+
}
59+
}
60+
}
61+
]
62+
}

tests/v3/test_apps.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from typing import Optional, List, Union
55

66
from abstract_test_case import AbstractTestCase
7-
from cloudfoundry_client.common_objects import JsonObject
7+
from cloudfoundry_client.common_objects import JsonObject, Pagination
88
from cloudfoundry_client.v3.entities import Entity
99

1010

@@ -160,3 +160,32 @@ def test_get_manifest(self):
160160
self.assertIsInstance(application_route, dict)
161161
self.assertEqual(application_route.get("route"), "my-app.example.com")
162162
self.assertEqual(application_route.get("protocol"), "http1")
163+
164+
def test_list_revisions(self):
165+
self.client.get.return_value = self.mock_response(
166+
"/v3/apps/app_guid/revisions", HTTPStatus.OK, {"Content-Type": "application/json"}, "v3", "apps",
167+
"GET_{id}_revisions_response.json"
168+
)
169+
revisions_response: Pagination[Entity] = self.client.v3.apps.list_revisions("app_guid")
170+
revisions: list[dict] = [revision for revision in revisions_response]
171+
self.assertIsInstance(revisions, list)
172+
self.assertEqual(len(revisions), 1)
173+
revision: dict = revisions[0]
174+
self.assertIsInstance(revision, dict)
175+
self.assertEqual(revision.get("guid"), "885735b5-aea4-4cf5-8e44-961af0e41920")
176+
self.assertEqual(revision.get("description"), "Initial revision.")
177+
self.assertEqual(revision.get("deployable"), True)
178+
179+
def test_list_deployed_revisions(self):
180+
self.client.get.return_value = self.mock_response(
181+
"/v3/apps/app_guid/revisions/deployed", HTTPStatus.OK, {"Content-Type": "application/json"}, "v3", "apps",
182+
"GET_{id}_deployed_revisions_response.json"
183+
)
184+
revisions_response: Pagination[Entity] = self.client.v3.apps.list_deployed_revisions("app_guid")
185+
revisions: list[dict] = [revision for revision in revisions_response]
186+
self.assertIsInstance(revisions, list)
187+
self.assertEqual(len(revisions), 1)
188+
revision: dict = revisions[0]
189+
self.assertIsInstance(revision, dict)
190+
self.assertEqual(revision.get("created_at"), "2017-02-01T01:33:58Z")
191+
self.assertEqual(revision.get("version"), 1)

0 commit comments

Comments
 (0)