def _make_team_submission(cls, attempt_number=1, course_id=COURSE_ID, item_id=ITEM_1_ID, team_id=TEAM_1_ID, status=None, create_submissions=False): """ Convenience method to create test TeamSubmissions with some default values """ model_args = { 'attempt_number': attempt_number, 'course_id': course_id, 'item_id': item_id, 'team_id': team_id, } if status: model_args['status'] = status team_submission = TeamSubmissionFactory.create(**model_args) if create_submissions: for student_id in cls.student_ids: student_item = cls._get_or_create_student_item( student_id, course_id=course_id, item_id=item_id) SubmissionFactory.create(student_item=student_item, team_submission=team_submission, answer='Foo') return team_submission
def test_one_course_multiple_users_one_submission_per(self): submission = SubmissionFactory.create( answer=self.create_answer(100, 100, 100, 200)) self.create_another_submission(submission, same_course=True) self.create_another_submission(submission, same_course=True) self.assert_command_output( {submission.student_item.course_id: (3, 1500, 500)})
def test_create_submission_for_team_existing_individual_submission(self): """ Test for calling create_submission_for_team when a user somehow already has an existing active submission for the item. This can happen if a user was on a team that submitted and then is reassigned to a team that didn't have a submission and is submitting. Expected outcome: submission is created because the previous submission was not team based """ user_3_item = self._get_or_create_student_item(self.anonymous_user_id_map[self.user_3]) SubmissionFactory.create(student_item=user_3_item) team_submission_data = self._call_create_submission_for_team_with_default_args() self.assertEqual(team_submission_data['attempt_number'], 1) submission_student_ids = [sub.student_item.student_id for sub in Submission.objects.select_related( 'student_item' ).filter(uuid__in=team_submission_data['submission_uuids']).all()] self.assertIn(user_3_item.student_id, submission_student_ids)
def test_one_course_one_learner(self): submission = SubmissionFactory.create(answer=self.create_answer(100, 100, 100)) self.create_another_submission(submission, same_user=True, same_course=True) self.create_another_submission(submission, same_user=True, same_course=True) self.assert_command_output( {submission.student_item.course_id: (1, 900, 900)} )
def fakeit(): conference = ConferenceFactory() USERS_NUMBER = random.randint(10, 50) SUBMISSION_NUMBER = int(USERS_NUMBER * 0.4) users = UserFactory.create_batch(USERS_NUMBER) submissions = SubmissionFactory.create_batch(SUBMISSION_NUMBER, conference=conference) counts_votes = {} for submission in submissions: counts_votes[submission.pk] = 0 for user in users: i_vote_only = random.randint(0, len(submissions)) submission_to_vote = random.sample(submissions, k=i_vote_only) for submission in submission_to_vote: # make more realistic: skip some voting... if bool(random.getrandbits(1)): continue value = get_random_vote() VoteFactory(user=user, value=value, submission=submission) counts_votes[submission.pk] += value return conference, counts_votes
def test_one_entry(self, filesizes): submission = SubmissionFactory.create(answer=self.create_answer( *filesizes)) total_filesize = sum(filesizes) self.assert_command_output({ submission.student_item.course_id: (1, total_filesize, total_filesize) })
def _make_individual_submission( cls, student_id, course_id=COURSE_ID, item_id=ITEM_1_ID, team_submission=None, ): """ Convenience method to create test Submissions with some default values """ student_item = cls._get_or_create_student_item(student_id, course_id=course_id, item_id=item_id) return SubmissionFactory.create(student_item=student_item, team_submission=team_submission, answer='Foo')
def test_create_submission_for_team_existing_individual_submission(self): """ Test for calling create_submission_for_team when a user somehow already has an existing active submission for the item. For normal Submissions, if a submission exists and we create another one, the second will increment the first's attempt_number. However, for team submissions, we currently pass the attempt_number from team_api.create_submission to api.create_submission, so all created individual submissions will have the same attempt_number """ user_3_item = self._get_or_create_student_item( self.anonymous_user_id_map[self.user_3]) SubmissionFactory.create(student_item=user_3_item) team_submission_data = self._call_create_submission_for_team_with_default_args( ) self.assertEqual(team_submission_data['attempt_number'], 1) submissions = Submission.objects.select_related('student_item').filter( uuid__in=team_submission_data['submission_uuids']).all() for submission in submissions: self.assertEqual(submission.attempt_number, 1)
def test_multiple_courses_one_user(self): submission_1 = SubmissionFactory.create(answer=self.create_answer(100, 100, 100)) submission_2 = self.create_another_submission(submission_1, same_user=True) submission_3 = self.create_another_submission(submission_1, same_user=True) submission_4 = self.create_another_submission(submission_1, same_user=True) self.assert_command_output( { submission_1.student_item.course_id: (1, 300, 300), submission_2.student_item.course_id: (1, 300, 300), submission_3.student_item.course_id: (1, 300, 300), submission_4.student_item.course_id: (1, 300, 300), } )
def test_entire_course_out_of_range(self, exclude_course): course_1_submission = SubmissionFactory.create( created_at=dt.datetime(2020, 1, 3), answer=self.create_answer(100, 100, 100) ) self.create_another_submission( course_1_submission, same_course=True, ) self.create_another_submission( course_1_submission, same_course=True, ) if exclude_course: created_at = dt.datetime(2019, 12, 1) else: created_at = dt.datetime(2020, 1, 3) course_2_submission = SubmissionFactory.create( created_at=created_at, answer=self.create_answer(500, 200) ) self.create_another_submission( course_2_submission, same_course=True, ) expected_output = { course_1_submission.student_item.course_id: (3, 900, 300) } if not exclude_course: expected_output[course_2_submission.student_item.course_id] = (2, 1400, 700) self.assert_command_output( expected_output, max_date=self.max_date, min_date=self.min_date, )
def test_submission_excluded_same_course_different_user( self, exclude_submission, expected_users, expected_bytes): submission_1 = SubmissionFactory.create( created_at=dt.datetime(2020, 1, 3), answer=self.create_answer(100, 100, 100)) self.create_another_submission(submission_1, same_course=True, time_delta=self.td_day) self.create_another_submission( submission_1, same_course=True, time_delta=self.td_month if exclude_submission else self.td_day) self.assert_command_output( { submission_1.student_item.course_id: (expected_users, expected_bytes, 300) }, max_date=self.max_date, min_date=self.min_date, )
def setUpTestData(cls): cls.course_id = 'test-course-id' cls.item_id = 'test-item-id' cls.answer = { 'something': 'b', 'something_else': 7000, 'some_other_thing': ['one_thing', 'two_thing'] } cls.student_items = [ StudentItemFactory.create(course_id=cls.course_id, item_id=cls.item_id) for _ in range(5) ] cls.submissions = [ SubmissionFactory.create(student_item=cls.student_items[i], answer=cls.answer) for i in range(5) ] cls.team_submission = TeamSubmissionFactory.create( course_id=cls.course_id, item_id=cls.item_id) cls.team_submission.submissions.set(cls.submissions) super().setUpTestData()
def create_another_submission( self, submission, answer=None, same_user=False, same_course=False, time_delta=None, ): """ Creates a new Submission, copying certain fields from the 'base' """ kwargs = {} if same_user: kwargs['student_id'] = submission.student_item.student_id if same_course: kwargs['course_id'] = submission.student_item.course_id student_item = StudentItemFactory.create(**kwargs) created_at = submission.created_at new_submission = SubmissionFactory.create( student_item=student_item, answer=answer if answer else submission.answer, created_at=created_at if time_delta is None else created_at + time_delta) return new_submission
def test_many_courses(self): """ Five courses, each course has 5000 total bytes First course has one user, fifth course has five users """ # 'makes' ten courses first_submissions = [ SubmissionFactory.create(answer=self.create_answer(500, 300, 200)) for _ in range(5) ] for additional_users, base_submission in enumerate(first_submissions): for _ in range(4): self.create_another_submission(base_submission, same_course=True, same_user=additional_users > 0) additional_users -= 1 expected_output = { submission.student_item.course_id: (5 - i, 5000, round(5000 / (5 - i))) for i, submission in enumerate(first_submissions) } self.assert_command_output(expected_output)
def test_empty_submission_only(self): SubmissionFactory.create(answer=self.create_answer()) self.assert_command_output({})
def test_one_empty_submission(self): SubmissionFactory.create(answer=self.create_answer()) submission_2 = SubmissionFactory.create( answer=self.create_answer(100, 200)) self.assert_command_output( {submission_2.student_item.course_id: (1, 300, 300)})
def _submit_tutorial(client, conference, **kwargs): talk = SubmissionFactory.create(type=SubmissionType.objects.get_or_create( name="tutorial")[0]) languages = [language.code for language in conference.languages.all()] defaults = { "title": talk.title, "abstract": talk.abstract, "elevator_pitch": talk.elevator_pitch, "notes": talk.notes, "languages": languages, "conference": conference.code, "topic": conference.topics.first().id, "type": talk.type.id, "duration": conference.durations.first().id, "audience_level": conference.audience_levels.first().id, "tags": [tag.name for tag in talk.tags.all()], "speaker_level": talk.speaker_level, "previous_talk_video": talk.previous_talk_video, } variables = {**defaults, **kwargs} return ( client.query( """mutation( $conference: ID!, $topic: ID!, $title: String!, $abstract: String!, $languages: [ID!]!, $type: ID!, $duration: ID!, $audience_level: ID!, $tags: [ID!], $speaker_level: String!, $elevator_pitch: String, $notes: String, $previous_talk_video: String ) { sendSubmission(input: { title: $title, abstract: $abstract, languages: $languages, conference: $conference, topic: $topic, type: $type, duration: $duration, audienceLevel: $audience_level, tags: $tags, notes: $notes, elevatorPitch: $elevator_pitch, speakerLevel: $speaker_level, previousTalkVideo: $previous_talk_video }) { __typename ... on Submission { id title abstract elevatorPitch audienceLevel { name } languages { code name } notes tags { name } } ... on SendSubmissionErrors { validationConference: conference validationTopic: topic validationTitle: title validationAbstract: abstract validationLanguages: languages validationType: type validationDuration: duration validationAudienceLevel: audienceLevel validationTags: tags validationPreviousTalkVideo: previousTalkVideo validationPreviousSpeakerLevel: speakerLevel nonFieldErrors } } }""", variables=variables, ), variables, )