From 4c9a611f99a51fa8cc6eae14396c47d2073b19e9 Mon Sep 17 00:00:00 2001 From: Nikita Konovalov Date: Wed, 14 Jan 2015 12:31:55 +0300 Subject: [PATCH] Project Groups and Projects support Added Managers and Object classes. Change-Id: I9d2d3b27832701a34aaa5198c7e15183be607cf2 --- .../tests/v1/test_project_groups.py | 85 +++++++++++++++++++ storyboardclient/tests/v1/test_projects.py | 55 ++++++++++++ storyboardclient/v1/client.py | 4 + storyboardclient/v1/project_groups.py | 63 ++++++++++++++ storyboardclient/v1/projects.py | 27 ++++++ 5 files changed, 234 insertions(+) create mode 100644 storyboardclient/tests/v1/test_project_groups.py create mode 100644 storyboardclient/tests/v1/test_projects.py create mode 100644 storyboardclient/v1/project_groups.py create mode 100644 storyboardclient/v1/projects.py diff --git a/storyboardclient/tests/v1/test_project_groups.py b/storyboardclient/tests/v1/test_project_groups.py new file mode 100644 index 0000000..18d3432 --- /dev/null +++ b/storyboardclient/tests/v1/test_project_groups.py @@ -0,0 +1,85 @@ +# Copyright (c) 2015 Mirantis Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import mock + +from storyboardclient.tests import base as test_base +from storyboardclient.v1 import project_groups +from storyboardclient.v1 import projects + + +class ProjectGroupsTestCase(test_base.TestCase): + + @mock.patch("storyboardclient.v1.project_groups.ProjectGroupsManager." + "_list") + def test_project_groups_list(self, mock_private_list): + mock_private_list.return_value = [ + project_groups.ProjectGroup(mock.MagicMock(), + info={"name": "test_pg"}), + project_groups.ProjectGroup(mock.MagicMock(), + info={"name": "test_pg_2"})] + + project_groups_list = project_groups.ProjectGroupsManager( + mock.MagicMock()).list() + + self.assertEqual(2, len(project_groups_list)) + + @mock.patch("storyboardclient.v1.project_groups.ProjectGroupsManager." + "_post") + def test_project_groups_create(self, mock_private_post): + project_groups.ProjectGroupsManager(mock.MagicMock()).create( + name="test_pg") + + mock_private_post.assert_called_once_with("/project_groups", + {"name": "test_pg"}) + + @mock.patch("storyboardclient.v1.project_groups.ProjectGroupsManager." + "_put") + def test_project_groups_update(self, mock_private_put): + project_groups.ProjectGroupsManager(mock.MagicMock()).update( + id="pg_id", + name="test_pg_updated") + + mock_private_put.assert_called_once_with( + "/project_groups/pg_id", + {"name": "test_pg_updated"}) + + @mock.patch("storyboardclient.v1.project_groups.ProjectsNestedManager." + "_put") + def test_project_groups_add_project(self, mock_private_put): + test_project_group = project_groups.ProjectGroup( + mock.MagicMock(), + info={"id": "test_pg_id"}) + + test_project = projects.Project(mock.MagicMock(), + info={"id": "test_project_id"}) + test_project_group.projects.add(test_project) + + mock_private_put.assert_called_once_with( + "/project_groups/test_pg_id/projects/test_project_id") + + @mock.patch("storyboardclient.v1.project_groups.ProjectsNestedManager." + "_delete") + def test_project_groups_remove_project(self, mock_private_delete): + test_project_group = project_groups.ProjectGroup( + mock.MagicMock(), + info={"id": "test_pg_id"}) + + test_project = projects.Project(mock.MagicMock(), + info={"id": "test_project_id"}) + test_project_group.projects.remove(test_project) + + mock_private_delete.assert_called_once_with( + "/project_groups/test_pg_id/projects/test_project_id") \ No newline at end of file diff --git a/storyboardclient/tests/v1/test_projects.py b/storyboardclient/tests/v1/test_projects.py new file mode 100644 index 0000000..f9047f3 --- /dev/null +++ b/storyboardclient/tests/v1/test_projects.py @@ -0,0 +1,55 @@ +# Copyright (c) 2015 Mirantis Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import mock + +from storyboardclient.tests import base as test_base +from storyboardclient.v1 import projects + + +class ProjectsTestCase(test_base.TestCase): + + @mock.patch("storyboardclient.v1.projects.ProjectsManager._list") + def test_projects_list(self, mock_private_list): + mock_private_list.return_value = [ + projects.Project(mock.MagicMock(), + info={"name": "test_project"}), + projects.Project(mock.MagicMock(), + info={"name": "test_project_2"})] + + teams_list = projects.ProjectsManager(mock.MagicMock()).list() + + self.assertEqual(2, len(teams_list)) + + @mock.patch("storyboardclient.v1.projects.ProjectsManager._post") + def test_projects_create(self, mock_private_post): + projects.ProjectsManager(mock.MagicMock()).create( + name="test_project", + description="test_description") + + mock_private_post.assert_called_once_with( + "/projects", + {"name": "test_project", + "description": "test_description"}) + + @mock.patch("storyboardclient.v1.projects.ProjectsManager._put") + def test_projects_update(self, mock_private_put): + projects.ProjectsManager(mock.MagicMock()).update( + id="project_id", + name="test_project_updated") + + mock_private_put.assert_called_once_with( + "/projects/project_id", + {"name": "test_project_updated"}) diff --git a/storyboardclient/v1/client.py b/storyboardclient/v1/client.py index 1d5616c..1390a05 100644 --- a/storyboardclient/v1/client.py +++ b/storyboardclient/v1/client.py @@ -14,6 +14,8 @@ # limitations under the License. from storyboardclient import base +from storyboardclient.v1 import project_groups +from storyboardclient.v1 import projects from storyboardclient.v1 import teams from storyboardclient.v1 import users @@ -43,4 +45,6 @@ class Client(base.BaseClient): access_token=access_token) self.teams = teams.TeamsManager(self) + self.projects = projects.ProjectsManager(self) + self.project_groups = project_groups.ProjectGroupsManager(self) self.users = users.UsersManager(self) diff --git a/storyboardclient/v1/project_groups.py b/storyboardclient/v1/project_groups.py new file mode 100644 index 0000000..b921aea --- /dev/null +++ b/storyboardclient/v1/project_groups.py @@ -0,0 +1,63 @@ +# Copyright (c) 2015 Mirantis Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from storyboardclient import base +from storyboardclient.v1 import projects + + +class ProjectsNestedManager(base.BaseNestedManager): + parent_url_key = "project_groups" + url_key = "projects" + resource_class = projects.Project + + def add(self, project): + """Add a Project to the Project Group. + + :param project: can be a Project instance or id + :return: the result of Project Group update operation + """ + + if isinstance(project, projects.Project): + project_id = project.id + else: + project_id = project + + self.put(id=project_id) + + def remove(self, project): + """Remove a Project from a Project Group. + + :param project: can be a Project instance or id + :return: the result of Project Group update operation + """ + + if isinstance(project, projects.Project): + project_id = project.id + else: + project_id = project + + self.delete(id=project_id) + + +class ProjectGroup(base.BaseObject): + name = None + title = None + + projects = ProjectsNestedManager + + +class ProjectGroupsManager(base.BaseManager): + url_key = "project_groups" + resource_class = ProjectGroup diff --git a/storyboardclient/v1/projects.py b/storyboardclient/v1/projects.py new file mode 100644 index 0000000..4ada8af --- /dev/null +++ b/storyboardclient/v1/projects.py @@ -0,0 +1,27 @@ +# Copyright (c) 2015 Mirantis Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from storyboardclient import base + + +class Project(base.BaseObject): + name = None + description = None + is_active = None + + +class ProjectsManager(base.BaseManager): + url_key = "projects" + resource_class = Project \ No newline at end of file