diff --git a/server/vbv_lernwelt/assignment/tests/test_assignment_completions_export.py b/server/vbv_lernwelt/assignment/tests/test_assignment_completions_export.py index ee21e875..da3abb1a 100644 --- a/server/vbv_lernwelt/assignment/tests/test_assignment_completions_export.py +++ b/server/vbv_lernwelt/assignment/tests/test_assignment_completions_export.py @@ -14,10 +14,10 @@ from vbv_lernwelt.course_session.models import ( CourseSessionAssignment, CourseSessionEdoniqTest, ) -from vbv_lernwelt.course_session.tests.test_attendance_export import ExportBaseTextCase +from vbv_lernwelt.course_session.tests.test_attendance_export import ExportBaseTestCase -class AssignmentCompletionExportTestCase(ExportBaseTextCase): +class AssignmentCompletionExportTestCase(ExportBaseTestCase): def setUp(self): create_default_users() self.course = create_test_course(include_vv=False, with_sessions=True) diff --git a/server/vbv_lernwelt/course_session/tests/test_attendance_export.py b/server/vbv_lernwelt/course_session/tests/test_attendance_export.py index 9966818c..242febc3 100644 --- a/server/vbv_lernwelt/course_session/tests/test_attendance_export.py +++ b/server/vbv_lernwelt/course_session/tests/test_attendance_export.py @@ -11,7 +11,7 @@ from vbv_lernwelt.course.models import CourseSession from vbv_lernwelt.course_session.services.export_attendance import export_attendance -class ExportBaseTextCase(TestCase): +class ExportBaseTestCase(TestCase): def _check_export(self, wb, expected_data, max_row, max_col): for row in wb.active.iter_rows(max_col=max_col, max_row=max_row): for cell in row: @@ -20,7 +20,7 @@ class ExportBaseTextCase(TestCase): ) -class AttendanceExportTestCase(ExportBaseTextCase): +class AttendanceExportTestCase(ExportBaseTestCase): def setUp(self): create_default_users() create_test_course(include_vv=False, with_sessions=True) diff --git a/server/vbv_lernwelt/feedback/tests/test_feedback_export.py b/server/vbv_lernwelt/feedback/tests/test_feedback_export.py new file mode 100644 index 00000000..8857c292 --- /dev/null +++ b/server/vbv_lernwelt/feedback/tests/test_feedback_export.py @@ -0,0 +1,178 @@ +import datetime +import io + +from openpyxl import load_workbook + +from vbv_lernwelt.core.constants import TEST_STUDENT1_USER_ID, TEST_STUDENT2_USER_ID +from vbv_lernwelt.core.create_default_users import create_default_users +from vbv_lernwelt.core.models import User +from vbv_lernwelt.course.creators.test_course import create_test_course +from vbv_lernwelt.course.models import CourseSession +from vbv_lernwelt.course_session.tests.test_attendance_export import ExportBaseTestCase +from vbv_lernwelt.feedback.factories import FeedbackResponseFactory +from vbv_lernwelt.feedback.models import FeedbackResponse +from vbv_lernwelt.feedback.services import export_feedback +from vbv_lernwelt.learnpath.models import Circle + + +class FeedbackExportTestCase(ExportBaseTestCase): + def setUp(self): + super().setUp() + + create_default_users() + create_test_course(include_vv=True, with_sessions=True) + + self.course_session_be = CourseSession.objects.get(title="Test Bern 2022 a") + self.course_session_zh = CourseSession.objects.get(title="Test Zürich 2022 a") + + self.circle_fahrzeug = Circle.objects.get( + slug="test-lehrgang-lp-circle-fahrzeug" + ) + self.circle_reisen = Circle.objects.get(slug="test-lehrgang-lp-circle-reisen") + + self.test_student1 = User.objects.get(id=TEST_STUDENT1_USER_ID) + self.test_student2 = User.objects.get(id=TEST_STUDENT2_USER_ID) + + self.course_sessions = [ + self.course_session_be, + self.course_session_be, + self.course_session_zh, + ] + self.feedback_data = { + "satisfaction": [1, 4, 2], + "goal_attainment": [2, 4, 3], + "proficiency": [20, 60, 80], + "preparation_task_clarity": [True, False, True], + "instructor_competence": [1, 2, 3], + "instructor_respect": [40, 80, 100], + "instructor_open_feedback": ["super", "ok", "naja"], + "would_recommend": [False, True, False], + "course_positive_feedback": ["Bla", "Katze", "Hund"], + "course_negative_feedback": ["Maus", "Hase", "Fuchs"], + } + + self.users = [self.test_student1, self.test_student2, self.test_student2] + self.circles = [self.circle_fahrzeug, self.circle_fahrzeug, self.circle_reisen] + + for i in range(3): + FeedbackResponseFactory( + circle=self.circles[i], + course_session=self.course_sessions[i], + data={ + "satisfaction": self.feedback_data["satisfaction"][i], + "goal_attainment": self.feedback_data["goal_attainment"][i], + "proficiency": self.feedback_data["proficiency"][i], + "preparation_task_clarity": self.feedback_data[ + "preparation_task_clarity" + ][i], + "instructor_competence": self.feedback_data[ + "instructor_competence" + ][i], + "instructor_open_feedback": self.feedback_data[ + "instructor_open_feedback" + ][i], + "would_recommend": self.feedback_data["would_recommend"][i], + "instructor_respect": self.feedback_data["instructor_respect"][i], + "course_positive_feedback": self.feedback_data[ + "course_positive_feedback" + ][i], + "course_negative_feedback": self.feedback_data[ + "course_negative_feedback" + ][i], + "feedback_type": "uk", + }, + feedback_user=self.users[i], + submitted=True, + ) + + ( + self.expected_data_fahrzeug, + self.expected_data_reisen, + ) = self._generate_expected_data() + + def _generate_expected_data(self): + feedback_data = [] + + for i in range(3): + feedback_data.append( + [ + self.course_sessions[i].title, + datetime.datetime.now().strftime("%d.%m.%Y"), + self.feedback_data["satisfaction"][i], + self.feedback_data["goal_attainment"][i], + self.feedback_data["proficiency"][i], + self.feedback_data["preparation_task_clarity"][i], + self.feedback_data["instructor_competence"][i], + self.feedback_data["instructor_respect"][i], + self.feedback_data["instructor_open_feedback"][i], + self.feedback_data["would_recommend"][i], + self.feedback_data["course_positive_feedback"][i], + self.feedback_data["course_negative_feedback"][i], + ] + ) + + expected_data_fahrzeug = [ + self._make_header(), + feedback_data[0], + feedback_data[1], + ] + + expected_data_reisen = [ + self._make_header(), + feedback_data[2], + ] + + return expected_data_fahrzeug, expected_data_reisen + + def _generate_workbook(self, course_session_ids): + export_data = io.BytesIO( + export_feedback(course_session_ids, save_as_file=False) + ) + return load_workbook(export_data) + + def _make_header(self): + return [ + "Durchführung", + "Datum", + "Zufriedenheit insgesamt", + "Zielerreichung insgesamt", + "Wie beurteilst du deine Sicherheit bezüglichen den Themen nach dem Kurs?", + "Waren die Vorbereitungsaufträge klar und verständlich?", + "Wie beurteilst du die Themensicherheit und Fachkompetenz des Kursleiters/der Kursleiterin?", + "Wurden Fragen und Anregungen der Kursteilnehmenden ernst genommen und aufgegriffen?", + "Was möchtest du dem Kursleiter/der Kursleiterin sonst noch sagen?", + "Würdest du den Kurs weiterempfehlen?", + "Was hat dir besonders gut gefallen?", + "Wo siehst du Verbesserungspotential?", + ] + + def test_export_feedback(self): + wb = self._generate_workbook( + [self.course_session_be.id, self.course_session_zh.id] + ) + self.assertEqual(len(wb.sheetnames), 2) + self.assertEqual(wb.sheetnames[0], "Fahrzeug") + self.assertEqual(wb.sheetnames[1], "Reisen") + + self._check_export(wb, self.expected_data_fahrzeug, 3, 12) + + wb.active = wb["Reisen"] + self._check_export(wb, self.expected_data_reisen, 2, 12) + + def test_does_not_include_unsubmitted_feedback(self): + feedback = FeedbackResponse.objects.get( + circle=self.circle_reisen, + course_session=self.course_session_zh, + feedback_user=self.test_student2, + ) + + feedback.submitted = False + feedback.save() + + wb = self._generate_workbook( + [self.course_session_be.id, self.course_session_zh.id] + ) + self.assertEqual(len(wb.sheetnames), 1) + self.assertEqual(wb.sheetnames[0], "Fahrzeug") + + self._check_export(wb, self.expected_data_fahrzeug, 3, 12)