diff --git a/server/assignments/schema/mutations.py b/server/assignments/schema/mutations.py index 0a3951fa..7bb4c23d 100644 --- a/server/assignments/schema/mutations.py +++ b/server/assignments/schema/mutations.py @@ -1,4 +1,5 @@ import graphene +from django.core.exceptions import MultipleObjectsReturned from graphene import relay from graphql_relay import from_global_id from rest_framework.exceptions import PermissionDenied @@ -22,7 +23,13 @@ class UpdateAssignment(relay.ClientIDMutation): def mutate_and_get_payload(cls, root, info, **kwargs): assignment_data = kwargs.get('assignment') assignment = get_object(Assignment, assignment_data.get('id')) - (submission, created) = assignment.submissions.get_or_create(student=info.context.user) + + try: + (submission, _created) = assignment.submissions.get_or_create(student=info.context.user) + except MultipleObjectsReturned: + for submission in assignment.submissions.filter(student=info.context.user): + submission.delete() + submission = assignment.submissions.create(student=info.context.user) submission.text = assignment_data.get('answer', '') submission.document = assignment_data.get('document', '') final = assignment_data.get('final') diff --git a/server/assignments/tests/test_duplicate_student_submissions.py b/server/assignments/tests/test_duplicate_student_submissions.py new file mode 100644 index 00000000..6c8d8667 --- /dev/null +++ b/server/assignments/tests/test_duplicate_student_submissions.py @@ -0,0 +1,60 @@ +from django.test import TestCase, RequestFactory +from graphene.test import Client +from graphql_relay import to_global_id + +from api.schema import schema +from assignments.factories import AssignmentFactory +from assignments.models import StudentSubmission +from users.models import User +from users.services import create_users + +UPDATE_ASSIGNMENT_MUTATION = """ +mutation UpdateAssignment($input: UpdateAssignmentInput!) { + updateAssignment(input: $input) { + updatedAssignment { + id + submission { + id + text + final + } + } + } +} +""" + + +class DuplicateStudentSubmissionsTestCase(TestCase): + def setUp(self): + create_users() + + self.student1 = User.objects.get(username='student1') + self.assignment = AssignmentFactory() + self.assignment_id = to_global_id('AssignmentNode', self.assignment.id) + + # create 2 submissions, can happen if multiple requests arrive simultaneously + StudentSubmission.objects.create(assignment=self.assignment, student=self.student1, text='abc') + StudentSubmission.objects.create(assignment=self.assignment, student=self.student1, text='abcd') + + request = RequestFactory().get('/') + request.user = self.student1 + self.client = Client(schema=schema, context_value=request) + + def test_returns_one_submission(self): + query = UPDATE_ASSIGNMENT_MUTATION + answer = "Abcdefg" + variables = { + "input": { + "assignment": { + "answer": answer, + "document": "", + "final": True, + "id": self.assignment_id + } + } + } + + result = self.client.execute(query, variables=variables) + self.assertIsNone(result.get('errors')) + self.assertEquals( + result.get('data').get('updateAssignment').get('updatedAssignment').get('submission').get('text'), answer) diff --git a/server/core/settings.py b/server/core/settings.py index ddcfd7ee..7ed5597c 100644 --- a/server/core/settings.py +++ b/server/core/settings.py @@ -328,20 +328,14 @@ if not DEBUG and os.environ.get('SENTRY_DSN'): event['user'] = {'id': id} return event + environment = os.environ.get('SENTRY_ENV', 'localhost') + sentry_sdk.init( dsn=os.environ.get('SENTRY_DSN'), integrations=[DjangoIntegration()], send_default_pii=True, - before_send=before_send - ) - -if not DEBUG and os.environ.get('SENTRY_DSN'): - import sentry_sdk - from sentry_sdk.integrations.django import DjangoIntegration - - sentry_sdk.init( - dsn=os.environ.get('SENTRY_DSN'), - integrations=[DjangoIntegration()] + before_send=before_send, + environment=environment ) # LOGGING['handlers'] = { diff --git a/server/notes/tests.py b/server/notes/tests.py deleted file mode 100644 index 7ce503c2..00000000 --- a/server/notes/tests.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.test import TestCase - -# Create your tests here.