Skip to content

Commit

Permalink
Add clone analysis mutation
Browse files Browse the repository at this point in the history
  • Loading branch information
sudan45 committed Dec 18, 2024
1 parent eeb0e1a commit 879c0dd
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 1 deletion.
17 changes: 17 additions & 0 deletions apps/analysis/mutation.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
AnalysisType,
)
from .serializers import (
AnalysisCloneGqlSerializer,
AnalysisPillarGqlSerializer,
DiscardedEntryGqlSerializer,
AnalysisTopicModelSerializer,
Expand Down Expand Up @@ -113,6 +114,11 @@
serializer_class=AnalysisGqlSerializer,
)

AnalysisCloneInputType = generate_input_type_for_serializer(
'AnalysisCloneInputType',
serializer_class=AnalysisCloneGqlSerializer
)


class RequiredPermissionMixin():
permissions = [
Expand Down Expand Up @@ -314,6 +320,14 @@ class Arguments:
result = graphene.Field(AnalysisPillarType)


class AnalysisClone(AnalysisMutationMixin, PsGrapheneMutation):
class Arguments:
data = AnalysisCloneInputType(required=True)
model = Analysis
serializer_class = AnalysisCloneGqlSerializer
result = graphene.Field(AnalysisType)


class Mutation():
# Analysis Pillar
analysis_pillar_update = UpdateAnalysisPillar.Field()
Expand All @@ -339,3 +353,6 @@ class Mutation():
analysis_create = CreateAnalysis.Field()
analysis_update = UpdateAnalysis.Field()
analysis_delete = DeleteAnalysis.Field()

# AnalysisClone
analysis_clone = AnalysisClone.Field()
31 changes: 30 additions & 1 deletion apps/analysis/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,36 @@ def update(self, instance, validated_data):
return super().update(instance, validated_data)


AnalysisCloneGqlSerializer = AnalysisCloneInputSerializer
class AnalysisCloneGqlSerializer(serializers.Serializer):
analysis_id = IntegerIDField()
title = serializers.CharField(required=True, write_only=True)
start_date = serializers.DateField(write_only=True, required=False, allow_null=True)
end_date = serializers.DateField(required=True, write_only=True)

def validate(self, data):
start_date = data.get('start_date')
end_date = data.get('end_date')
if start_date and start_date > end_date:
raise serializers.ValidationError(
{'end_date': 'End date must occur after start date'}
)
return data

def validate_analysis_id(self, analysis_id):
analysis = Analysis.objects.filter(
project=self.context['request'].active_project,
pk=analysis_id
).first()
if analysis is None:
raise serializers.ValidationError("Analysis does not exists")
return analysis

def create(self, validated_data):
title = validated_data['title']
end_date = validated_data['end_date']
# NOTE validated_data['analysis_id'] is an object of analysis
validated_data['analysis_id'].clone_analysis(title, end_date)
return validated_data


class AnalysisTopicModelSerializer(UserResourceSerializer, serializers.ModelSerializer):
Expand Down
84 changes: 84 additions & 0 deletions apps/analysis/tests/test_mutations.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@
AnalysisPillarFactory,
AnalysisReportFactory,
AnalysisReportUploadFactory,
AnalyticalStatementFactory,
DiscardedEntryFactory,
)

from analysis.models import (
DiscardedEntry,
TopicModel,
TopicModelCluster,
AutomaticSummary,
Expand Down Expand Up @@ -1732,3 +1735,84 @@ def _query_check(**kwargs):
self.assertEqual(analysis_pillar_resp_data['title'], self.update_minput['analysisPillarUpdate']['title'])
self.assertEqual(analysis_pillar_resp_data['id'], str(self.update_minput['analysisPillarID']))
self.assertEqual(analysis_pillar_resp_data['analysisId'], str(self.analysis.id))


class TestCloneAnalysisMutationSchema(GraphQLTestCase):
ANALYSIS_CLONE_MUTATION = '''
mutation AnalysisClone($projectId: ID!, $data: AnalysisCloneInputType!) {
project(id: $projectId) {
analysisClone(data: $data) {
ok
errors
result {
id
title
endDate
}
__typename
}
__typename
}
}
'''

def setUp(self):
super().setUp()
self.project = ProjectFactory.create()
self.member_user = UserFactory.create()
self.non_member_user = UserFactory.create()
self.readonly_member_user = UserFactory.create()
self.project.add_member(self.readonly_member_user, role=self.project_role_reader_non_confidential)
af = AnalysisFrameworkFactory.create()
project = ProjectFactory.create(analysis_framework=af)
lead = LeadFactory.create(project=project)
self.project.add_member(self.member_user, role=self.project_role_member)
entry = EntryFactory.create(project=project, lead=lead)
EntryFactory.create(project=project, lead=lead)
self.analysis = AnalysisFactory.create(
project=project,
team_lead=self.member_user,
end_date=datetime.date(2022, 4, 1),

)
pillar = AnalysisPillarFactory.create(analysis=self.analysis, title='title1', assignee=self.member_user)
AnalyticalStatementFactory.create(
analysis_pillar=pillar,
statement='Hello from here',
client_id='1',
)
DiscardedEntryFactory.create(
entry=entry,
analysis_pillar=pillar,
tag=DiscardedEntry.TagType.REDUNDANT
)

def test_clone_analysis(self):
def _query_check(**kwargs):
return self.query_check(
self.ANALYSIS_CLONE_MUTATION,
variables=self.minput,
**kwargs
)
self.minput = dict(
data=dict(
analysisId=self.analysis.id,
title='cloned_title',
endDate="2022-04-01",
),
projectId=self.project.id,
)
# without login
_query_check(assert_for_error=True)

# With login (non-member)
self.force_login(self.non_member_user)
_query_check(assert_for_error=True)

# member user (read-only)
self.force_login(self.readonly_member_user)
_query_check(assert_for_error=True)

# member user
self.force_login(self.member_user)
_query_check(assert_for_error=False)
14 changes: 14 additions & 0 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,19 @@ type AnalysisAutomaticSummaryType {
status: AutomaticSummaryStatusEnum!
}

type AnalysisClone {
errors: [GenericScalar!]
ok: Boolean
result: AnalysisType
}

input AnalysisCloneInputType {
analysisId: ID!
title: String!
startDate: Date
endDate: Date!
}

input AnalysisFrameworkCloneInputType {
afId: ID!
title: String!
Expand Down Expand Up @@ -5521,6 +5534,7 @@ type ProjectMutationType {
analysisCreate(data: AnalysisInputType!): CreateAnalysis
analysisUpdate(data: AnalysisInputType!, id: ID!): UpdateAnalysis
analysisDelete(id: ID!): DeleteAnalysis
analysisClone(data: AnalysisCloneInputType!): AnalysisClone
exportCreate(data: ExportCreateInputType!): CreateUserExport
exportUpdate(data: ExportUpdateInputType!, id: ID!): UpdateUserExport
exportCancel(id: ID!): CancelUserExport
Expand Down

0 comments on commit 879c0dd

Please sign in to comment.