diff --git a/apps/analysis/mutation.py b/apps/analysis/mutation.py index 4e34220516..008785d341 100644 --- a/apps/analysis/mutation.py +++ b/apps/analysis/mutation.py @@ -4,7 +4,6 @@ generate_input_type_for_serializer, PsGrapheneMutation, PsDeleteMutation, - PsBulkGrapheneMutation, ) from deep.permissions import ProjectPermissions as PP @@ -278,7 +277,13 @@ class Arguments: result = graphene.Field(AnalysisReportUploadType) -class CreateAnalysis(RequiredPermissionMixin, PsGrapheneMutation): +class AnalysisMutationMixin(RequiredPermissionMixin): + @classmethod + def filter_queryset(cls, qs, info): + return qs.filter(project=info.context.active_project) + + +class CreateAnalysis(AnalysisMutationMixin, PsGrapheneMutation): class Arguments: data = AnalysisInputType(required=True) model = Analysis @@ -286,7 +291,7 @@ class Arguments: result = graphene.Field(AnalysisType) -class UpdateAnalysis(RequiredPermissionMixin, PsGrapheneMutation): +class UpdateAnalysis(AnalysisMutationMixin, PsGrapheneMutation): class Arguments: data = AnalysisInputType(required=True) id = graphene.ID(required=True) @@ -295,28 +300,13 @@ class Arguments: result = graphene.Field(AnalysisType) -class DeleteAnalysis(RequiredPermissionMixin, PsDeleteMutation): +class DeleteAnalysis(AnalysisMutationMixin, PsDeleteMutation): class Arguments: id = graphene.ID(required=True) model = Analysis result = graphene.Field(AnalysisType) -class BulkAnalysisInputType(AnalysisInputType): - id = graphene.ID() - - -class BulkAnalysis(RequiredPermissionMixin, PsBulkGrapheneMutation): - class Arguments: - items = graphene.List(graphene.NonNull(BulkAnalysisInputType)) - delete_ids = graphene.List(graphene.NonNull(graphene.ID)) - - result = graphene.List(AnalysisType) - deleted_result = graphene.List(graphene.NonNull(AnalysisType)) - model = Analysis - serializer_class = AnalysisGqlSerializer - - class Mutation(): # Analysis Pillar analysis_pillar_update = UpdateAnalysisPillar.Field() @@ -341,4 +331,3 @@ class Mutation(): analysis_create = CreateAnalysis.Field() analysis_update = UpdateAnalysis.Field() analysis_delete = DeleteAnalysis.Field() - analysis_bulk = BulkAnalysis.Field() diff --git a/apps/analysis/tests/test_mutations.py b/apps/analysis/tests/test_mutations.py index 5e00373901..21390d8efc 100644 --- a/apps/analysis/tests/test_mutations.py +++ b/apps/analysis/tests/test_mutations.py @@ -1326,3 +1326,176 @@ def _query_check(_id, **kwargs): else: self.force_login(user) assert _query_public_snapshot_check(snapshot_slug)['data']['publicAnalysisReportSnapshot'] is not None + + +class TestAnalysisMutationSchema(GraphQLTestCase): + CREATE_MUTATION = ''' + mutation MyMutation($analysisData: AnalysisInputType!, $projectId: ID!) { + project(id: $projectId) { + analysisCreate( + data: $analysisData + ) { + errors + ok + result { + id + endDate + title + teamLead { + id + } + } + } + } + } + ''' + UPDATE_MUTATION = ''' + mutation MyMutation($analysisUpdate: AnalysisInputType!, $analysisID: ID!, $projectId: ID!) { + project(id: $projectId) { + analysisUpdate(data: $analysisUpdate, id: $analysisID) { + errors + ok + result { + id + endDate + title + teamLead { + id + } + } + } + } + } + ''' + DELETE_MUTATION = ''' + mutation MyMutation($projectId: ID!, $deleteId: ID!) { + project(id: $projectId) { + analysisDelete(id: $deleteId) { + errors + result { + id + title + } + } + } + } + ''' + + def setUp(self): + super().setUp() + self.af = AnalysisFrameworkFactory.create() + self.project_with_af = ProjectFactory.create(analysis_framework=self.af) + self.project_without_af = ProjectFactory.create() + # Users with different roles + self.non_member_user = UserFactory.create() + self.readonly_member_user = UserFactory.create() + self.member_user = UserFactory.create() + self.project_with_af.add_member(self.readonly_member_user, role=self.project_role_reader_non_confidential) + self.project_with_af.add_member(self.member_user, role=self.project_role_member) + + def test_create_analysis_without_pillar(self): + minput = dict( + analysisData=dict( + title='Test Analysis', teamLead=self.member_user.id, endDate='2020-01-01' + ), + projectId=self.project_with_af.id, + ) + # -- Without login + self.query_check(self.CREATE_MUTATION, variables=minput, assert_for_error=True) + + # -- With login (non-member) + self.force_login(self.non_member_user) + self.query_check(self.CREATE_MUTATION, variables=minput, assert_for_error=True) + + # --- member user (read-only) + self.force_login(self.readonly_member_user) + self.query_check(self.CREATE_MUTATION, variables=minput, assert_for_error=True) + + # --- member user + self.force_login(self.member_user) + content = self.query_check(self.CREATE_MUTATION, variables=minput) + + self.assertEqual( + content['data']['project']['analysisCreate']['result']['title'], + minput['analysisData']['title'] + ) + self.assertEqual( + content['data']['project']['analysisCreate']['result']['teamLead']['id'], + str(self.member_user.id) + ) + self.assertEqual( + content['data']['project']['analysisCreate']['result']['endDate'], + str(minput['analysisData']['endDate']) + ) + + def test_create_analysis_without_analysis_framework(self): + minput = dict( + analysisData=dict( + title='Test Analysis', teamLead=self.member_user.id, endDate='2020-01-01' + ), + projectId=self.project_without_af.id, + ) + + self.force_login(self.non_member_user) + self.query_check(self.CREATE_MUTATION, variables=minput, assert_for_error=True) + + def test_create_and_update_analysis(self): + minput = dict( + analysisData=dict( + title='Test Analysis', teamLead=self.member_user.id, endDate='2020-01-01' + ), + projectId=self.project_with_af.id, + ) + + self.force_login(self.member_user) + content = self.query_check(self.CREATE_MUTATION, variables=minput) + self.assertIsNotNone(content['data']['project']['analysisCreate']['result']['id']) + + update_minput = dict( + analysisUpdate=dict( + title='Updated Analysis', + teamLead=self.member_user.id, + endDate='2022-01-01', + ), + analysisID=content['data']['project']['analysisCreate']['result']['id'], + projectId=self.project_with_af.id, + ) + content = self.query_check(self.UPDATE_MUTATION, variables=update_minput) + self.assertEqual( + content['data']['project']['analysisUpdate']['result']['title'], + update_minput['analysisUpdate']['title'] + ) + self.assertEqual( + content['data']['project']['analysisUpdate']['result']['teamLead']['id'], + str(self.member_user.id) + ) + self.assertEqual( + content['data']['project']['analysisUpdate']['result']['endDate'], + str(update_minput['analysisUpdate']['endDate']) + ) + + def test_create_and_delete_analysis(self): + minput = dict( + analysisData=dict( + title='Test Analysis', teamLead=self.member_user.id, endDate='2020-01-01' + ), + projectId=self.project_with_af.id, + ) + + self.force_login(self.member_user) + content = self.query_check(self.CREATE_MUTATION, variables=minput) + self.assertIsNotNone(content['data']['project']['analysisCreate']['result']['id']) + + delete_minput = dict( + projectId=self.project_with_af.id, + deleteId=content['data']['project']['analysisCreate']['result']['id'], + ) + content = self.query_check(self.DELETE_MUTATION, variables=delete_minput) + self.assertEqual( + content['data']['project']['analysisDelete']['result']['title'], + minput['analysisData']['title'] + ) + self.assertEqual( + content['data']['project']['analysisDelete']['result']['id'], + delete_minput['deleteId'] + ) diff --git a/schema.graphql b/schema.graphql index baec0af657..e8e8d5340a 100644 --- a/schema.graphql +++ b/schema.graphql @@ -3280,12 +3280,6 @@ enum AutomaticSummaryStatusEnum { SEND_FAILED } -type BulkAnalysis { - errors: [[GenericScalar!]] - result: [AnalysisType] - deletedResult: [AnalysisType!] -} - input BulkAnalysisFrameworkMembershipInputType { id: ID member: ID! @@ -3293,16 +3287,6 @@ input BulkAnalysisFrameworkMembershipInputType { clientId: String } -input BulkAnalysisInputType { - id: ID - title: String! - teamLead: ID! - startDate: Date - endDate: Date! - clonedFrom: ID - analysisPillar: [AnalysisPillarGqlInputType!] -} - type BulkEntry { errors: [[GenericScalar!]] result: [EntryType] @@ -5474,7 +5458,6 @@ type ProjectMutationType { analysisCreate(data: AnalysisInputType!): CreateAnalysis analysisUpdate(data: AnalysisInputType!, id: ID!): UpdateAnalysis analysisDelete(id: ID!): DeleteAnalysis - analysisBulk(deleteIds: [ID!], items: [BulkAnalysisInputType!]): BulkAnalysis exportCreate(data: ExportCreateInputType!): CreateUserExport exportUpdate(data: ExportUpdateInputType!, id: ID!): UpdateUserExport exportCancel(id: ID!): CancelUserExport