wip: Add tests

This commit is contained in:
Christian Cueni 2023-12-07 12:02:23 +01:00
parent c3b2dde902
commit 6317df0cc8
10 changed files with 181 additions and 13 deletions

View File

@ -18,12 +18,9 @@
</span> </span>
{{ $t("feedback.feedbackPageInfo") }} {{ $t("feedback.feedbackPageInfo") }}
</p> </p>
<FeedbackPageVV <FeedbackPageVV v-if="feedbackType === 'vv'" :feedback-data="feedbackData" />
v-if="feedbackData != undefined && feedbackType === 'vv'"
:feedback-data="feedbackData"
/>
<FeedbackPageUK <FeedbackPageUK
v-else-if="feedbackData != undefined && feedbackType === 'uk'" v-else-if="feedbackType === 'uk'"
:feedback-data="feedbackData" :feedback-data="feedbackData"
/> />
</main> </main>
@ -36,7 +33,7 @@ import { useCurrentCourseSession } from "@/composables";
import { itGet } from "@/fetchHelpers"; import { itGet } from "@/fetchHelpers";
import * as log from "loglevel"; import * as log from "loglevel";
import { onMounted, ref } from "vue"; import { onMounted, ref } from "vue";
import type { FeedbackData } from "@/types"; import type { FeedbackData, FeedbackType } from "@/types";
import FeedbackPageVV from "@/pages/cockpit/FeedbackPageVV.vue"; import FeedbackPageVV from "@/pages/cockpit/FeedbackPageVV.vue";
import FeedbackPageUK from "@/pages/cockpit/FeedbackPageUK.vue"; import FeedbackPageUK from "@/pages/cockpit/FeedbackPageUK.vue";
@ -49,7 +46,7 @@ log.debug("FeedbackPage created", props.circleId);
const courseSession = useCurrentCourseSession(); const courseSession = useCurrentCourseSession();
const feedbackData = ref<FeedbackData | undefined>(undefined); const feedbackData = ref<FeedbackData | undefined>(undefined);
const feedbackType = ref<"vv" | undefined>(undefined); const feedbackType = ref<FeedbackType | undefined>(undefined);
onMounted(async () => { onMounted(async () => {
log.debug("FeedbackPage mounted"); log.debug("FeedbackPage mounted");
@ -57,7 +54,10 @@ onMounted(async () => {
`/api/core/feedback/${courseSession.value.id}/${props.circleId}` `/api/core/feedback/${courseSession.value.id}/${props.circleId}`
); );
log.debug("FeedbackPage feedbackData", feedbackData.value); log.debug("FeedbackPage feedbackData", feedbackData.value);
if (["uk", "vv"].includes(feedbackData.value?.feedbackType ?? "")) { if (
feedbackData.value &&
["uk", "vv"].includes(feedbackData.value?.feedbackType ?? "")
) {
feedbackType.value = feedbackData.value.feedbackType; feedbackType.value = feedbackData.value.feedbackType;
} }
}); });

View File

@ -15,7 +15,7 @@ import type { FeedbackData } from "@/types";
import * as log from "loglevel"; import * as log from "loglevel";
import { useTranslation } from "i18next-vue"; import { useTranslation } from "i18next-vue";
const props = defineProps<{ defineProps<{
feedbackData: FeedbackData; feedbackData: FeedbackData;
}>(); }>();

View File

@ -15,7 +15,7 @@ import type { FeedbackData } from "@/types";
import * as log from "loglevel"; import * as log from "loglevel";
import { useTranslation } from "i18next-vue"; import { useTranslation } from "i18next-vue";
const props = defineProps<{ defineProps<{
feedbackData: FeedbackData; feedbackData: FeedbackData;
}>(); }>();

View File

@ -63,7 +63,7 @@ interface Props {
openKeys?: string[]; openKeys?: string[];
} }
const props = withDefaults(defineProps<Props>(), { withDefaults(defineProps<Props>(), {
orderedQuestions: () => [], orderedQuestions: () => [],
ratingKeys: () => [], ratingKeys: () => [],
verticalChartKeys: () => [], verticalChartKeys: () => [],

View File

@ -179,7 +179,11 @@ onMounted(async () => {
<p v-if="stepNo === 0" class="mt-10" data-cy="introduction"> <p v-if="stepNo === 0" class="mt-10" data-cy="introduction">
{{ introduction }} {{ introduction }}
</p> </p>
<p v-if="stepNo > 0 && stepNo + 1 < numSteps" class="pb-2"> <p
v-if="stepNo > 0 && stepNo + 1 < numSteps"
class="pb-2"
:data-cy="`question-${stepNo}`"
>
{{ localStepLabels[stepNo] }} {{ localStepLabels[stepNo] }}
</p> </p>
<div v-for="(question, index) in questionData" :key="index"> <div v-for="(question, index) in questionData" :key="index">

View File

@ -74,7 +74,7 @@ describe("dashboardSupervisor.cy.js", () => {
describe("feedback summary box", () => { describe("feedback summary box", () => {
it("contains correct numbers", () => { it("contains correct numbers", () => {
getDashboardStatistics("feedback.average").should("have.text", "3.3"); getDashboardStatistics("feedback.average").should("have.text", "3.3");
getDashboardStatistics("feedback.count").should("have.text", "3"); getDashboardStatistics("feedback.count").should("have.text", "6");
}); });
it("contains correct details link", () => { it("contains correct details link", () => {
clickOnDetailsLink("feedback"); clickOnDetailsLink("feedback");

View File

@ -30,6 +30,10 @@ describe("feedbackStudent.cy.js", () => {
// fill feedback form // fill feedback form
// step 1 // step 1
cy.url().should("include", "step=1"); cy.url().should("include", "step=1");
cy.get('[data-cy="question-1"]').should(
"contain",
"Zufriedenheit insgesamt"
);
cy.get('[data-cy="next-step"]').should("be.disabled"); cy.get('[data-cy="next-step"]').should("be.disabled");
cy.get('[data-cy="radio-4"]').click(); cy.get('[data-cy="radio-4"]').click();
cy.wait(200); cy.wait(200);
@ -38,6 +42,10 @@ describe("feedbackStudent.cy.js", () => {
// step 2 // step 2
cy.url().should("include", "step=2"); cy.url().should("include", "step=2");
cy.get('[data-cy="question-2"]').should(
"contain",
"Zielerreichung insgesamt"
);
cy.get('[data-cy="next-step"]').should("be.disabled"); cy.get('[data-cy="next-step"]').should("be.disabled");
// the system should store after every step -> check stored data // the system should store after every step -> check stored data
cy.loadFeedbackResponse("feedback_user_id", TEST_STUDENT1_USER_ID).then( cy.loadFeedbackResponse("feedback_user_id", TEST_STUDENT1_USER_ID).then(
@ -54,6 +62,10 @@ describe("feedbackStudent.cy.js", () => {
// step 3 // step 3
cy.url().should("include", "step=3"); cy.url().should("include", "step=3");
cy.get('[data-cy="question-3"]').should(
"contain",
"Wie beurteilst du deine Sicherheit bezüglichen den Themen nach dem Kurs?"
);
cy.get('[data-cy="next-step"]').should("be.disabled"); cy.get('[data-cy="next-step"]').should("be.disabled");
cy.get('[data-cy="radio-80"]').click(); cy.get('[data-cy="radio-80"]').click();
cy.wait(200); cy.wait(200);
@ -62,6 +74,10 @@ describe("feedbackStudent.cy.js", () => {
// step 4 // step 4
cy.url().should("include", "step=4"); cy.url().should("include", "step=4");
cy.get('[data-cy="question-4"]').should(
"contain",
"Waren die Vorbereitungsaufträge klar und verständlich?"
);
cy.get('[data-cy="next-step"]').should("be.disabled"); cy.get('[data-cy="next-step"]').should("be.disabled");
cy.get('[data-cy="radio-false"]').click(); cy.get('[data-cy="radio-false"]').click();
cy.wait(200); cy.wait(200);
@ -70,6 +86,10 @@ describe("feedbackStudent.cy.js", () => {
// step 5 // step 5
cy.url().should("include", "step=5"); cy.url().should("include", "step=5");
cy.get('[data-cy="question-5"]').should(
"contain",
"Wie beurteilst du die Themensicherheit und Fachkompetenz des Kursleiters/der Kursleiterin?"
);
cy.get('[data-cy="next-step"]').should("be.disabled"); cy.get('[data-cy="next-step"]').should("be.disabled");
cy.get('[data-cy="radio-2"]').click(); cy.get('[data-cy="radio-2"]').click();
cy.wait(200); cy.wait(200);
@ -78,6 +98,10 @@ describe("feedbackStudent.cy.js", () => {
// step 6 // step 6
cy.url().should("include", "step=6"); cy.url().should("include", "step=6");
cy.get('[data-cy="question-6"]').should(
"contain",
"Wurden Fragen und Anregungen der Kursteilnehmenden ernst genommen und aufgegriffen?"
);
cy.get('[data-cy="next-step"]').should("be.disabled"); cy.get('[data-cy="next-step"]').should("be.disabled");
cy.get('[data-cy="radio-1"]').click(); cy.get('[data-cy="radio-1"]').click();
cy.wait(200); cy.wait(200);
@ -86,6 +110,10 @@ describe("feedbackStudent.cy.js", () => {
// step 7 // step 7
cy.url().should("include", "step=7"); cy.url().should("include", "step=7");
cy.get('[data-cy="question-7"]').should(
"contain",
"Was möchtest du dem Kursleiter/der Kursleiterin sonst noch sagen?"
);
cy.get('[data-cy="next-step"]').should("be.disabled"); cy.get('[data-cy="next-step"]').should("be.disabled");
cy.get('[data-cy="it-textarea-instructor_open_feedback"]').type( cy.get('[data-cy="it-textarea-instructor_open_feedback"]').type(
"Der Kursleiter ist eigentlich ganz nett." "Der Kursleiter ist eigentlich ganz nett."
@ -96,6 +124,10 @@ describe("feedbackStudent.cy.js", () => {
// step 8 // step 8
cy.url().should("include", "step=8"); cy.url().should("include", "step=8");
cy.get('[data-cy="question-8"]').should(
"contain",
"Würdest du den Kurs weiterempfehlen?"
);
cy.get('[data-cy="next-step"]').should("be.disabled"); cy.get('[data-cy="next-step"]').should("be.disabled");
cy.get('[data-cy="radio-true"]').click(); cy.get('[data-cy="radio-true"]').click();
cy.wait(200); cy.wait(200);
@ -104,6 +136,11 @@ describe("feedbackStudent.cy.js", () => {
// step 9 // step 9
cy.url().should("include", "step=9"); cy.url().should("include", "step=9");
cy.get('[data-cy="question-9"]').should(
"contain",
"Was hat dir besonders gut gefallen?"
);
cy.get('[data-cy="next-step"]').should("be.disabled"); cy.get('[data-cy="next-step"]').should("be.disabled");
cy.get('[data-cy="it-textarea-course_positive_feedback"]').type( cy.get('[data-cy="it-textarea-course_positive_feedback"]').type(
"Ich bin zufrieden mit den meisten Dingen." "Ich bin zufrieden mit den meisten Dingen."
@ -114,6 +151,10 @@ describe("feedbackStudent.cy.js", () => {
// step 10 // step 10
cy.url().should("include", "step=10"); cy.url().should("include", "step=10");
cy.get('[data-cy="question-10"]').should(
"contain",
"Wo siehst du Verbesserungspotential?"
);
cy.get('[data-cy="next-step"]').should("be.disabled"); cy.get('[data-cy="next-step"]').should("be.disabled");
cy.get('[data-cy="it-textarea-course_negative_feedback"]').type( cy.get('[data-cy="it-textarea-course_negative_feedback"]').type(
"Ich bin unzufrieden mit einigen Sachen." "Ich bin unzufrieden mit einigen Sachen."
@ -189,6 +230,10 @@ describe("feedbackStudent.cy.js", () => {
// fill feedback form // fill feedback form
// step 1 // step 1
cy.url().should("include", "step=1"); cy.url().should("include", "step=1");
cy.get('[data-cy="question-1"]').should(
"contain",
"Zufriedenheit insgesamt"
);
cy.get('[data-cy="next-step"]').should("be.disabled"); cy.get('[data-cy="next-step"]').should("be.disabled");
cy.get('[data-cy="radio-4"]').click(); cy.get('[data-cy="radio-4"]').click();
cy.wait(200); cy.wait(200);
@ -197,6 +242,10 @@ describe("feedbackStudent.cy.js", () => {
// step 2 // step 2
cy.url().should("include", "step=2"); cy.url().should("include", "step=2");
cy.get('[data-cy="question-2"]').should(
"contain",
"Zielerreichung insgesamt"
);
cy.get('[data-cy="next-step"]').should("be.disabled"); cy.get('[data-cy="next-step"]').should("be.disabled");
// the system should store after every step -> check stored data // the system should store after every step -> check stored data
cy.loadFeedbackResponse("feedback_user_id", TEST_STUDENT1_USER_ID).then( cy.loadFeedbackResponse("feedback_user_id", TEST_STUDENT1_USER_ID).then(
@ -213,6 +262,10 @@ describe("feedbackStudent.cy.js", () => {
// step 3 // step 3
cy.url().should("include", "step=3"); cy.url().should("include", "step=3");
cy.get('[data-cy="question-3"]').should(
"contain",
"Wie beurteilst du deine Sicherheit bezüglichen den Themen nach dem Circle?"
);
cy.get('[data-cy="next-step"]').should("be.disabled"); cy.get('[data-cy="next-step"]').should("be.disabled");
cy.get('[data-cy="radio-80"]').click(); cy.get('[data-cy="radio-80"]').click();
cy.wait(200); cy.wait(200);
@ -221,6 +274,10 @@ describe("feedbackStudent.cy.js", () => {
// step 4 // step 4
cy.url().should("include", "step=4"); cy.url().should("include", "step=4");
cy.get('[data-cy="question-4"]').should(
"contain",
"Waren die Praxisaufträge klar und verständlich?"
);
cy.get('[data-cy="next-step"]').should("be.disabled"); cy.get('[data-cy="next-step"]').should("be.disabled");
cy.get('[data-cy="radio-false"]').click(); cy.get('[data-cy="radio-false"]').click();
cy.wait(200); cy.wait(200);
@ -229,6 +286,10 @@ describe("feedbackStudent.cy.js", () => {
// step 5 // step 5
cy.url().should("include", "step=5"); cy.url().should("include", "step=5");
cy.get('[data-cy="question-5"]').should(
"contain",
"Würdest du den Circle weiterempfehlen?"
);
cy.get('[data-cy="next-step"]').should("be.disabled"); cy.get('[data-cy="next-step"]').should("be.disabled");
cy.get('[data-cy="radio-false"]').click(); cy.get('[data-cy="radio-false"]').click();
cy.wait(200); cy.wait(200);
@ -237,6 +298,11 @@ describe("feedbackStudent.cy.js", () => {
// step 6 // step 6
cy.url().should("include", "step=6"); cy.url().should("include", "step=6");
cy.get('[data-cy="question-6"]').should(
"contain",
"Was hat dir besonders gut gefallen?"
);
cy.get('[data-cy="next-step"]').should("be.disabled"); cy.get('[data-cy="next-step"]').should("be.disabled");
cy.get('[data-cy="it-textarea-course_positive_feedback"]').type( cy.get('[data-cy="it-textarea-course_positive_feedback"]').type(
"Der Circle ist eigentlich ganz nett." "Der Circle ist eigentlich ganz nett."
@ -247,6 +313,10 @@ describe("feedbackStudent.cy.js", () => {
// step 7 // step 7
cy.url().should("include", "step=7"); cy.url().should("include", "step=7");
cy.get('[data-cy="question-7"]').should(
"contain",
"Wo siehst du Verbesserungspotential?"
);
cy.get('[data-cy="next-step"]').should("be.disabled"); cy.get('[data-cy="next-step"]').should("be.disabled");
cy.get('[data-cy="it-textarea-course_negative_feedback"]').type( cy.get('[data-cy="it-textarea-course_negative_feedback"]').type(
"Ich bin unzufrieden mit einigen Sachen." "Ich bin unzufrieden mit einigen Sachen."

View File

@ -34,6 +34,7 @@ class FeedbackResponseFactory(DjangoModelFactory):
"Das Beispiel mit der Katze fand ich sehr gut veranschaulicht!", "Das Beispiel mit der Katze fand ich sehr gut veranschaulicht!",
] ]
), ),
"feedback_type": FuzzyChoice(["uk", "vv"]),
} }
) )

View File

@ -114,6 +114,7 @@ class FeedbackRestApiTestCase(FeedbackBaseTestCase):
"course_negative_feedback": self.feedback_data[ "course_negative_feedback": self.feedback_data[
"course_negative_feedback" "course_negative_feedback"
][i], ][i],
"feedback_type": "uk",
}, },
feedback_user=self.feedback_users[i], feedback_user=self.feedback_users[i],
submitted=True, submitted=True,
@ -129,6 +130,7 @@ class FeedbackRestApiTestCase(FeedbackBaseTestCase):
expected = { expected = {
"amount": 3, "amount": 3,
"questions": self.feedback_data, "questions": self.feedback_data,
"feedbackType": "uk",
} }
print(response.data) print(response.data)

View File

@ -0,0 +1,91 @@
import json
from graphene_django.utils.testing import GraphQLTestCase
from vbv_lernwelt.core.create_default_users import create_default_users
from vbv_lernwelt.core.models import User
from vbv_lernwelt.course.consts import COURSE_TEST_ID
from vbv_lernwelt.course.creators.test_course import create_test_course
from vbv_lernwelt.course.models import CourseSession
from vbv_lernwelt.feedback.models import FeedbackResponse
from vbv_lernwelt.learnpath.models import LearningContentFeedbackUK
class FeedbackMutationTestCase(GraphQLTestCase):
GRAPHQL_URL = "/server/graphql/"
def setUp(self):
create_default_users()
create_test_course(include_vv=False, with_sessions=True)
self.course_session = CourseSession.objects.get(title="Test Bern 2022 a")
self.learning_content_feedback_page = LearningContentFeedbackUK.objects.get(
slug="test-lehrgang-lp-circle-fahrzeug-lc-feedback"
)
self.student = User.objects.get(username="test-student1@example.com")
self.client.force_login(self.student)
def test_creates_response(self):
data = {
"course_negative_feedback": "schlecht",
"course_positive_feedback": "gut",
"feedback_type": "uk",
"goal_attainment": 3,
"preparation_task_clarity": False,
"proficiency": 100,
"satisfaction": 3,
"would_recommend": False,
"instructor_competence": None,
"instructor_respect": None,
"instructor_open_feedback": None,
}
response = self.query(
f"""
mutation {{
send_feedback(
course_session_id: "{COURSE_TEST_ID}"
learning_content_page_id: "{self.learning_content_feedback_page.id}"
learning_content_type: "learnpath.LearningContentFeedbackUK"
data: {{
course_negative_feedback: "{data['course_negative_feedback']}",
course_positive_feedback: "{data['course_positive_feedback']}",
feedback_type: null,
goal_attainment: {data['goal_attainment']},
preparation_task_clarity: {str(data['preparation_task_clarity']).lower()},
proficiency: {data['proficiency']},
satisfaction: {data['satisfaction']},
would_recommend: {str(data['would_recommend']).lower()},
instructor_competence: null,
instructor_respect: null,
instructor_open_feedback: null,
}},
submitted: false
) {{
feedback_response {{
id
data
submitted
__typename
}}
errors {{
field
messages
__typename
}}
__typename
}}
}}
"""
)
content = json.loads(response.content)
self.assertResponseNoErrors(response)
self.assertDictEqual(
content["data"]["send_feedback"]["feedback_response"]["data"], data
)
feedback = FeedbackResponse.objects.first()
self.assertEqual(feedback.data, data)
self.assertEqual(feedback.submitted, False)
self.assertEqual(feedback.feedback_user, self.student)