def on_grading_process_finished(course): evaluations = course.evaluations.all() if all(evaluation.state == 'reviewed' for evaluation in evaluations): for evaluation in evaluations: assert evaluation.grading_process_is_finished for evaluation in evaluations: evaluation.publish() evaluation.save() EmailTemplate.send_participant_publish_notifications(evaluations) EmailTemplate.send_contributor_publish_notifications(evaluations)
def test_send_contributor_publish_notifications(): responsible1 = baker.make(UserProfile) responsible2 = baker.make(UserProfile) # use is_single_result to get can_publish_average_grade to become true evaluation1 = baker.make(Evaluation, course__responsibles=[responsible1], is_single_result=True) evaluation2 = baker.make(Evaluation, course__responsibles=[responsible2]) editor1 = baker.make(UserProfile) contributor1 = baker.make(UserProfile) contributor2 = baker.make(UserProfile) editor2 = baker.make(UserProfile) contributor_both = baker.make(UserProfile) # Contributions for evaluation1 make_contributor(responsible1, evaluation1) make_contributor(contributor1, evaluation1) make_contributor(contributor_both, evaluation1) make_editor(editor1, evaluation1) # Contributions for evaluation2 make_editor(editor2, evaluation2) contributor_both_contribution = make_contributor(contributor_both, evaluation2) contributor2_contribution = make_contributor(contributor2, evaluation2) baker.make(TextAnswer, contribution=contributor_both_contribution) baker.make(TextAnswer, contribution=contributor2_contribution) expected_calls = [ # these 4 are included since they are contributors for evaluation1 which can publish the average grade call(responsible1, {}, {"user": responsible1, "evaluations": {evaluation1}}, use_cc=True), call(editor1, {}, {"user": editor1, "evaluations": {evaluation1}}, use_cc=True), call(contributor1, {}, {"user": contributor1, "evaluations": {evaluation1}}, use_cc=True), call( contributor_both, {}, {"user": contributor_both, "evaluations": {evaluation1, evaluation2}}, use_cc=True ), # contributor2 has textanswers, so they are notified call(contributor2, {}, {"user": contributor2, "evaluations": {evaluation2}}, use_cc=True), ] with patch("evap.evaluation.models.EmailTemplate.send_to_user") as send_to_user_mock: EmailTemplate.send_contributor_publish_notifications({evaluation1, evaluation2}) # Assert that all expected publish notifications are sent to contributors. send_to_user_mock.assert_has_calls(expected_calls, any_order=True) # if general textanswers for an evaluation exist, all responsibles should also be notified baker.make(TextAnswer, contribution=evaluation2.general_contribution) expected_calls.append(call(responsible2, {}, {"user": responsible2, "evaluations": {evaluation2}}, use_cc=True)) with patch("evap.evaluation.models.EmailTemplate.send_to_user") as send_to_user_mock: EmailTemplate.send_contributor_publish_notifications({evaluation1, evaluation2}) send_to_user_mock.assert_has_calls(expected_calls, any_order=True)
def upload_grades(request, semester_id, course_id): semester = get_object_or_404(Semester, id=semester_id) if semester.grade_documents_are_deleted: raise PermissionDenied course = get_object_or_404(Course, id=course_id, semester=semester) final_grades = request.GET.get( 'final') == 'true' # if parameter is not given, assume midterm grades grade_document = GradeDocument(course=course) if final_grades: grade_document.type = GradeDocument.Type.FINAL_GRADES grade_document.description_en = settings.DEFAULT_FINAL_GRADES_DESCRIPTION_EN grade_document.description_de = settings.DEFAULT_FINAL_GRADES_DESCRIPTION_DE else: grade_document.type = GradeDocument.Type.MIDTERM_GRADES grade_document.description_en = settings.DEFAULT_MIDTERM_GRADES_DESCRIPTION_EN grade_document.description_de = settings.DEFAULT_MIDTERM_GRADES_DESCRIPTION_DE form = GradeDocumentForm(request.POST or None, request.FILES or None, instance=grade_document) if form.is_valid(): form.save(modifying_user=request.user) evaluations = course.evaluations.all() if final_grades and all(evaluation.state == 'reviewed' for evaluation in evaluations): for evaluation in evaluations: evaluation.publish() evaluation.save() EmailTemplate.send_participant_publish_notifications(evaluations) EmailTemplate.send_contributor_publish_notifications(evaluations) messages.success(request, _("Successfully uploaded grades.")) return redirect('grades:course_view', semester.id, course.id) template_data = dict( semester=semester, course=course, form=form, final_grades=final_grades, show_automated_publishing_info=final_grades, ) return render(request, "grades_upload_form.html", template_data)
def toggle_no_grades(request): course_id = request.POST.get("course_id") course = get_object_or_404(Course, id=course_id) if course.semester.grade_documents_are_deleted: raise PermissionDenied course.gets_no_grade_documents = not course.gets_no_grade_documents course.save() evaluations = course.evaluations.all() if course.gets_no_grade_documents and all(evaluation.state == 'reviewed' for evaluation in evaluations): for evaluation in evaluations: evaluation.publish() evaluation.save() EmailTemplate.send_participant_publish_notifications(evaluations) EmailTemplate.send_contributor_publish_notifications(evaluations) return HttpResponse() # 200 OK