diff --git a/README.rst b/README.rst index eb52a8e..e8466d6 100644 --- a/README.rst +++ b/README.rst @@ -397,4 +397,5 @@ You can run tests by doing so. In the project directory: $ export PYTHONPATH=main $ python -m unittest discover test # or even - $ python setup.py test + $ poetry install + $ poetry run pytest \ No newline at end of file diff --git a/cloudfoundry_client/v3/apps.py b/cloudfoundry_client/v3/apps.py index 4382ea2..5ec8486 100644 --- a/cloudfoundry_client/v3/apps.py +++ b/cloudfoundry_client/v3/apps.py @@ -1,7 +1,7 @@ from typing import TYPE_CHECKING, Optional -from cloudfoundry_client.common_objects import JsonObject -from cloudfoundry_client.v3.entities import EntityManager +from cloudfoundry_client.common_objects import JsonObject, Pagination +from cloudfoundry_client.v3.entities import EntityManager, Entity if TYPE_CHECKING: from cloudfoundry_client.client import CloudFoundryClient @@ -27,3 +27,11 @@ def get_routes(self, application_guid: str) -> JsonObject: def get_manifest(self, application_guid: str) -> str: return self.client.get(url="%s%s/%s/manifest" % (self.target_endpoint, self.entity_uri, application_guid)).text + + def list_revisions(self, application_guid: str, **kwargs) -> Pagination[Entity]: + uri: str = "%s/%s/revisions" % (self.entity_uri, application_guid) + return super(AppManager, self)._list(requested_path=uri, **kwargs) + + def list_deployed_revisions(self, application_guid: str, **kwargs) -> Pagination[Entity]: + uri: str = "%s/%s/revisions/deployed" % (self.entity_uri, application_guid) + return super(AppManager, self)._list(requested_path=uri, **kwargs) diff --git a/tests/fixtures/v3/apps/GET_{id}_deployed_revisions_response.json b/tests/fixtures/v3/apps/GET_{id}_deployed_revisions_response.json new file mode 100644 index 0000000..920f448 --- /dev/null +++ b/tests/fixtures/v3/apps/GET_{id}_deployed_revisions_response.json @@ -0,0 +1,62 @@ +{ + "pagination": { + "total_results": 1, + "total_pages": 1, + "first": { + "href": "https://api.example.org/v3/apps/1cb006ee-fb05-47e1-b541-c34179ddc446/revisions?page=1&per_page=50" + }, + "last": { + "href": "https://api.example.org/v3/apps/1cb006ee-fb05-47e1-b541-c34179ddc446/revisions?page=1&per_page=50" + }, + "next": null, + "previous": null + }, + "resources": [ + { + "guid": "885735b5-aea4-4cf5-8e44-961af0e41920", + "version": 1, + "droplet": { + "guid": "585bc3c1-3743-497d-88b0-403ad6b56d16" + }, + "processes": { + "web": { + "command": "bundle exec rackup" + } + }, + "sidecars": [ + { + "name": "auth-sidecar", + "command": "bundle exec sidecar", + "process_types": ["web"], + "memory_in_mb": 300 + } + ], + "description": "Initial revision.", + "deployable": true, + "relationships": { + "app": { + "data": { + "guid": "1cb006ee-fb05-47e1-b541-c34179ddc446" + } + } + }, + "created_at": "2017-02-01T01:33:58Z", + "updated_at": "2017-02-01T01:33:58Z", + "metadata": { + "labels": {}, + "annotations": {} + }, + "links": { + "self": { + "href": "https://api.example.org/v3/revisions/885735b5-aea4-4cf5-8e44-961af0e41920" + }, + "app": { + "href": "https://api.example.org/v3/apps/1cb006ee-fb05-47e1-b541-c34179ddc446" + }, + "environment_variables": { + "href": "https://api.example.org/v3/revisions/885735b5-aea4-4cf5-8e44-961af0e41920/environment_variables" + } + } + } + ] +} \ No newline at end of file diff --git a/tests/fixtures/v3/apps/GET_{id}_revisions_response.json b/tests/fixtures/v3/apps/GET_{id}_revisions_response.json new file mode 100644 index 0000000..920f448 --- /dev/null +++ b/tests/fixtures/v3/apps/GET_{id}_revisions_response.json @@ -0,0 +1,62 @@ +{ + "pagination": { + "total_results": 1, + "total_pages": 1, + "first": { + "href": "https://api.example.org/v3/apps/1cb006ee-fb05-47e1-b541-c34179ddc446/revisions?page=1&per_page=50" + }, + "last": { + "href": "https://api.example.org/v3/apps/1cb006ee-fb05-47e1-b541-c34179ddc446/revisions?page=1&per_page=50" + }, + "next": null, + "previous": null + }, + "resources": [ + { + "guid": "885735b5-aea4-4cf5-8e44-961af0e41920", + "version": 1, + "droplet": { + "guid": "585bc3c1-3743-497d-88b0-403ad6b56d16" + }, + "processes": { + "web": { + "command": "bundle exec rackup" + } + }, + "sidecars": [ + { + "name": "auth-sidecar", + "command": "bundle exec sidecar", + "process_types": ["web"], + "memory_in_mb": 300 + } + ], + "description": "Initial revision.", + "deployable": true, + "relationships": { + "app": { + "data": { + "guid": "1cb006ee-fb05-47e1-b541-c34179ddc446" + } + } + }, + "created_at": "2017-02-01T01:33:58Z", + "updated_at": "2017-02-01T01:33:58Z", + "metadata": { + "labels": {}, + "annotations": {} + }, + "links": { + "self": { + "href": "https://api.example.org/v3/revisions/885735b5-aea4-4cf5-8e44-961af0e41920" + }, + "app": { + "href": "https://api.example.org/v3/apps/1cb006ee-fb05-47e1-b541-c34179ddc446" + }, + "environment_variables": { + "href": "https://api.example.org/v3/revisions/885735b5-aea4-4cf5-8e44-961af0e41920/environment_variables" + } + } + } + ] +} \ No newline at end of file diff --git a/tests/v3/test_apps.py b/tests/v3/test_apps.py index 8aeb0cf..5c9ed9d 100644 --- a/tests/v3/test_apps.py +++ b/tests/v3/test_apps.py @@ -4,7 +4,7 @@ from typing import Optional, List, Union from abstract_test_case import AbstractTestCase -from cloudfoundry_client.common_objects import JsonObject +from cloudfoundry_client.common_objects import JsonObject, Pagination from cloudfoundry_client.v3.entities import Entity @@ -160,3 +160,32 @@ def test_get_manifest(self): self.assertIsInstance(application_route, dict) self.assertEqual(application_route.get("route"), "my-app.example.com") self.assertEqual(application_route.get("protocol"), "http1") + + def test_list_revisions(self): + self.client.get.return_value = self.mock_response( + "/v3/apps/app_guid/revisions", HTTPStatus.OK, {"Content-Type": "application/json"}, "v3", "apps", + "GET_{id}_revisions_response.json" + ) + revisions_response: Pagination[Entity] = self.client.v3.apps.list_revisions("app_guid") + revisions: list[dict] = [revision for revision in revisions_response] + self.assertIsInstance(revisions, list) + self.assertEqual(len(revisions), 1) + revision: dict = revisions[0] + self.assertIsInstance(revision, dict) + self.assertEqual(revision.get("guid"), "885735b5-aea4-4cf5-8e44-961af0e41920") + self.assertEqual(revision.get("description"), "Initial revision.") + self.assertEqual(revision.get("deployable"), True) + + def test_list_deployed_revisions(self): + self.client.get.return_value = self.mock_response( + "/v3/apps/app_guid/revisions/deployed", HTTPStatus.OK, {"Content-Type": "application/json"}, "v3", "apps", + "GET_{id}_deployed_revisions_response.json" + ) + revisions_response: Pagination[Entity] = self.client.v3.apps.list_deployed_revisions("app_guid") + revisions: list[dict] = [revision for revision in revisions_response] + self.assertIsInstance(revisions, list) + self.assertEqual(len(revisions), 1) + revision: dict = revisions[0] + self.assertIsInstance(revision, dict) + self.assertEqual(revision.get("created_at"), "2017-02-01T01:33:58Z") + self.assertEqual(revision.get("version"), 1)