def get_team_submission_by_course_item_team(course_id, item_id, team_id): """ Given a course_id, item_id, and team_id, return team submission for the team assignment Raises: - TeamSubmissionNotFoundError if there is no matching team submission - TeamSubmissionInternalError if there is some other error looking up the team submission. """ model_query_params = dict(course_id=course_id, item_id=item_id, team_id=team_id) query_params_string = "course_id={course_id} item_id={item_id} team_id={team_id}".format(**model_query_params) try: # In the equivalent non-teams api call, we're filtering on student item and then getting first(), # which will get us the most recent active submission due to the sort order of the model. # However, for this model, we have a uniqueness constraint (non-db, as a signal handler) # that means we can only ever have one submission per team per assignment. I don't fully understand # the logic behind the non-teams api, but this shouldn't have to do that filter. team_submission = TeamSubmission.objects.prefetch_related( 'submissions' ).get( **model_query_params ) except TeamSubmission.DoesNotExist as error: logger.error("Team submission for %s not found.", query_params_string) raise TeamSubmissionNotFoundError( f"No team submission matching {query_params_string}" ) from error except Exception as exc: err_msg = ( f"Attempt to get team submission for {query_params_string} " f"caused error: {exc}" ) logger.error(err_msg) raise TeamSubmissionInternalError(err_msg) from exc return team_submission
def test_get_team_submission_uuid_error(self, mock_get_team_sub): mock_get_team_sub.side_effect = TeamSubmissionNotFoundError() self.assertIsNone(self.test_block.get_team_submission_uuid()) mock_get_team_sub.assert_called_with( STUDENT_ITEM_DICT['course_id'], STUDENT_ITEM_DICT['item_id'], self.test_block.team.team_id )
def get_team_submission_student_ids(team_submission_uuid): """ Returns a list of student_ids for a specific team submission. Raises: - TeamSubmissionNotFoundError when no matching student_ids are found, or if team_submission_uuid is falsy - TeamSubmissionInternalError if there is a database error """ if not team_submission_uuid: raise TeamSubmissionNotFoundError() try: student_ids = StudentItem.objects.filter( submission__team_submission__uuid=team_submission_uuid).order_by( 'student_id').distinct().values_list('student_id', flat=True) except DatabaseError as exc: err_msg = "Attempt to get student ids for team submission {team_submission_uuid} caused error: {exc}".format( team_submission_uuid=team_submission_uuid, exc=exc) logger.error(err_msg) raise TeamSubmissionInternalError(err_msg) if not student_ids: raise TeamSubmissionNotFoundError() return list(student_ids)
def get_team_submission_student_ids(team_submission_uuid): """ Returns a list of student_ids for a specific team submission. Raises: - TeamSubmissionNotFoundError when no matching student_ids are found, or if team_submission_uuid is falsy - TeamSubmissionInternalError if there is a database error """ if not team_submission_uuid: raise TeamSubmissionNotFoundError() try: student_ids = TeamSubmission.objects.filter( uuid=team_submission_uuid).values_list( 'submissions__student_item__student_id', flat=True) except DatabaseError as exc: err_msg = ( f"Attempt to get student ids for team submission {team_submission_uuid} " f"caused error: {exc}") logger.error(err_msg) raise TeamSubmissionInternalError(err_msg) from exc if not student_ids: raise TeamSubmissionNotFoundError() return list(student_ids)
def get_team_submission_by_uuid(team_submission_uuid): """ Given a uuid, return the matching team submission. Raises: - TeamSubmissionNotFoundError if there is no matching team submission - TeamSubmissionInternalError if there is some other error looking up the team submission. """ try: return TeamSubmission.objects.prefetch_related('submissions').get(uuid=team_submission_uuid) except TeamSubmission.DoesNotExist as error: logger.error("Team Submission %s not found.", team_submission_uuid) raise TeamSubmissionNotFoundError( f"No team submission matching uuid {team_submission_uuid}" ) from error except Exception as exc: err_msg = ( f"Attempt to get team submission for uuid {team_submission_uuid} " f"caused error: {exc}" ) logger.error(err_msg) raise TeamSubmissionInternalError(err_msg) from exc
def get_team_submission_by_student_item(student_item): """ Return the team submission that has an individual submission tied to the given StudentItem Raises: - TeamSubmissionNotFoundError if there is no matching team submission - TeamSubmissionInternalError if there is some other error looking up the team submission. """ try: return TeamSubmission.objects.prefetch_related('submissions').get( submissions__student_item=student_item) except TeamSubmission.DoesNotExist: logger.error( "Team submission for {} not found.".format(student_item)) raise TeamSubmissionNotFoundError( "No team submission matching {}".format(student_item)) except Exception as exc: err_msg = "Attempt to get team submission for {student_item} caused error: {exc}".format( student_item=student_item, exc=exc) logger.error(err_msg) raise TeamSubmissionInternalError(err_msg)
def test_get_team_submission_uuid_no_team(self, mock_get_team_sub_for_student): mock_get_team_sub_for_student.side_effect = TeamSubmissionNotFoundError( ) self.assertIsNone(self.test_block.get_team_submission_uuid()) mock_get_team_sub_for_student.assert_called_with(STUDENT_ITEM_DICT)