import datetime import io from django.utils.translation import activate 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.export import export_feedback_with_circle_restriction 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_export_feedback_with_cs_circle_pairs(self): cs_circle_pairs = [ ( self.course_session_be.id, [self.circle_fahrzeug.id, self.circle_reisen.id], ), ( self.course_session_zh.id, [self.circle_reisen.id, self.circle_fahrzeug.id], ), ] export_data = io.BytesIO( export_feedback_with_circle_restriction(cs_circle_pairs, save_as_file=False) ) wb = load_workbook(export_data) 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) def test_french_export(self): activate("fr") wb = self._generate_workbook( [self.course_session_be.id, self.course_session_zh.id] ) header = [ "Opérations", "Date", "Degré de satisfaction au global", "Degré de réalisation des objectifs", "As-tu l’impression de bien maîtriser les sujets qui ont été abordés pendant le cours ?", "Les travaux préparatoires étaient-ils clairs et compréhensibles ?", "Que penses-tu des compétences techniques de la personne chargée du cours et de sa maîtrise du sujet ?", "Les questions et les suggestions des participants ont-elles été prises au sérieux et traitées correctement ?", "Souhaites-tu ajouter quelque chose à l’intention de la personne chargée du cours ?", "Est-ce que tu recommandes ce cours ?", "Qu’est-ce qui t’a particulièrement plu ?", "À ton avis, quels sont les points qui pourraient être améliorés ?", ] self.expected_data_fahrzeug[0] = header self._check_export(wb, self.expected_data_fahrzeug, 3, 12) def test_italian_export(self): activate("it") wb = self._generate_workbook( [self.course_session_be.id, self.course_session_zh.id] ) header = [ "Svolgimenti", "Data", "Soddisfazione complessiva", "Raggiungimento complessivo degli obiettivi", "Come valuti il tuo livello di preparazione sui temi dopo il corso?", "Gli incarichi di preparazione erano chiari e comprensibili?", "Come valuti il livello di preparazione sui temi e le competenze specialistiche dell’istruttore/istruttrice del corso?", "Le domande e i suggerimenti dei/delle partecipanti al corso sono stati accolti e presi sul serio?", "Cos’altro vorresti ancora dire all’istruttore/istruttrice del corso?", "Raccomanderesti il corso?", "Cos’hai apprezzato particolarmente?", "Dove vedi un potenziale di miglioramento?", ] self.expected_data_fahrzeug[0] = header self._check_export(wb, self.expected_data_fahrzeug, 3, 12)