From 71a80962211c28a2950287817be3f41d44a6894e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Fri, 22 May 2015 16:00:02 +0200 Subject: [PATCH] [Backport] Fix a bug that create non-ouner memberships where the importer user is a member of the importer project. --- taiga/export_import/api.py | 48 +++++++++++++++++--------- taiga/export_import/service.py | 5 ++- tests/integration/test_importer_api.py | 37 +++++++++++++++++--- 3 files changed, 67 insertions(+), 23 deletions(-) diff --git a/taiga/export_import/api.py b/taiga/export_import/api.py index 01947685..48e8592c 100644 --- a/taiga/export_import/api.py +++ b/taiga/export_import/api.py @@ -88,11 +88,38 @@ class ProjectImporterViewSet(mixins.ImportThrottlingPolicyMixin, CreateModelMixi data = request.DATA.copy() data['owner'] = data.get('owner', request.user.email) + # Create Project project_serialized = service.store_project(data) - if project_serialized is None: + if not project_serialized: raise exc.BadRequest(service.get_errors()) + # Create roles + roles_serialized = None + if "roles" in data: + roles_serialized = service.store_roles(project_serialized.object, data) + + if not roles_serialized: + raise exc.BadRequest(_("We needed at least one role")) + + # Create memberships + if "memberships" in data: + service.store_memberships(project_serialized.object, data) + + try: + owner_membership = project_serialized.object.memberships.get(user=project_serialized.object.owner) + owner_membership.is_owner = True + owner_membership.save() + except Membership.DoesNotExist: + Membership.objects.create( + project=project_serialized.object, + email=project_serialized.object.owner.email, + user=project_serialized.object.owner, + role=project_serialized.object.roles.all().first(), + is_owner=True + ) + + # Create project values choicess if "points" in data: service.store_choices(project_serialized.object, data, "points", serializers.PointsExportSerializer) @@ -127,6 +154,7 @@ class ProjectImporterViewSet(mixins.ImportThrottlingPolicyMixin, CreateModelMixi "severities" in data): service.store_default_choices(project_serialized.object, data) + # Created custom attributes if "userstorycustomattributes" in data: service.store_custom_attributes(project_serialized.object, data, "userstorycustomattributes", @@ -142,26 +170,12 @@ class ProjectImporterViewSet(mixins.ImportThrottlingPolicyMixin, CreateModelMixi "issuecustomattributes", serializers.IssueCustomAttributeExportSerializer) - if "roles" in data: - service.store_roles(project_serialized.object, data) - - if "memberships" in data: - service.store_memberships(project_serialized.object, data) - - if project_serialized.object.memberships.filter(user=project_serialized.object.owner).count() == 0: - if project_serialized.object.roles.all().count() > 0: - Membership.objects.create( - project=project_serialized.object, - email=project_serialized.object.owner.email, - user=project_serialized.object.owner, - role=project_serialized.object.roles.all().first(), - is_owner=True - ) - + # Is there any error? errors = service.get_errors() if errors: raise exc.BadRequest(errors) + # Importer process is OK response_data = project_serialized.data response_data['id'] = project_serialized.object.id headers = self.get_success_headers(response_data) diff --git a/taiga/export_import/service.py b/taiga/export_import/service.py index df15684e..32ee9710 100644 --- a/taiga/export_import/service.py +++ b/taiga/export_import/service.py @@ -155,7 +155,10 @@ def store_role(project, role): def store_roles(project, data): results = [] for role in data.get("roles", []): - results.append(store_role(project, role)) + serialized = store_role(project, role) + if serialized: + results.append(serialized) + return results diff --git a/tests/integration/test_importer_api.py b/tests/integration/test_importer_api.py index 67f4407b..94b72561 100644 --- a/tests/integration/test_importer_api.py +++ b/tests/integration/test_importer_api.py @@ -53,17 +53,17 @@ def test_valid_project_import_without_extra_data(client): data = { "name": "Imported project", "description": "Imported project", + "roles": [{"name": "Role"}] } response = client.post(url, json.dumps(data), content_type="application/json") assert response.status_code == 201 response_data = json.loads(response.content.decode("utf-8")) must_empty_children = [ - "issues", "user_stories", "roles", "us_statuses", "wiki_pages", "priorities", + "issues", "user_stories", "us_statuses", "wiki_pages", "priorities", "severities", "milestones", "points", "issue_types", "task_statuses", - "memberships", "issue_statuses", "wiki_links", + "issue_statuses", "wiki_links", ] - assert all(map(lambda x: len(response_data[x]) == 0, must_empty_children)) assert response_data["owner"] == user.email @@ -166,6 +166,22 @@ def test_valid_project_import_with_extra_data(client): assert response_data["owner"] == user.email +def test_invalid_project_import_without_roles(client): + user = f.UserFactory.create() + client.login(user) + + url = reverse("importer-list") + data = { + "name": "Imported project", + "description": "Imported project", + } + + response = client.post(url, json.dumps(data), content_type="application/json") + assert response.status_code == 400 + response_data = json.loads(response.content.decode("utf-8")) + assert len(response_data) == 2 + assert Project.objects.filter(slug="imported-project").count() == 0 + def test_invalid_project_import_with_extra_data(client): user = f.UserFactory.create() client.login(user) @@ -174,7 +190,10 @@ def test_invalid_project_import_with_extra_data(client): data = { "name": "Imported project", "description": "Imported project", - "roles": [{}], + "roles": [{ + "permissions": [], + "name": "Test" + }], "us_statuses": [{}], "severities": [{}], "priorities": [{}], @@ -187,7 +206,7 @@ def test_invalid_project_import_with_extra_data(client): response = client.post(url, json.dumps(data), content_type="application/json") assert response.status_code == 400 response_data = json.loads(response.content.decode("utf-8")) - assert len(response_data) == 8 + assert len(response_data) == 7 assert Project.objects.filter(slug="imported-project").count() == 0 @@ -198,6 +217,10 @@ def test_valid_project_import_with_custom_attributes(client): data = { "name": "Imported project", "description": "Imported project", + "roles": [{ + "permissions": [], + "name": "Test" + }], "userstorycustomattributes": [{ "name": "custom attribute example 1", "description": "short description 1", @@ -234,6 +257,10 @@ def test_invalid_project_import_with_custom_attributes(client): data = { "name": "Imported project", "description": "Imported project", + "roles": [{ + "permissions": [], + "name": "Test" + }], "userstorycustomattributes": [{ }], "taskcustomattributes": [{ }], "issuecustomattributes": [{ }]