Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MOBILE-4339 quiz: Add unanswered questions warning #3928

Merged
merged 1 commit into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions scripts/langindex.json
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,7 @@
"addon.mod_quiz.stateoverdue": "quiz",
"addon.mod_quiz.stateoverduedetails": "quiz",
"addon.mod_quiz.status": "quiz",
"addon.mod_quiz.submission_confirmation_unanswered": "quiz",
"addon.mod_quiz.submitallandfinish": "quiz",
"addon.mod_quiz.summaryofattempt": "quiz",
"addon.mod_quiz.summaryofattempts": "quiz",
Expand Down
1 change: 1 addition & 0 deletions src/addons/mod/quiz/lang.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
"stateoverdue": "Overdue",
"stateoverduedetails": "Must be submitted by {{$a}}",
"status": "Status",
"submission_confirmation_unanswered": "Questions without a response: {{$a}}",
"submitallandfinish": "Submit all and finish",
"summaryofattempt": "Summary of attempt",
"summaryofattempts": "Summary of your previous attempts",
Expand Down
29 changes: 28 additions & 1 deletion src/addons/mod/quiz/pages/player/player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,34 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy, CanLeave {
try {
// Show confirm if the user clicked the finish button and the quiz is in progress.
if (!timeUp && this.attempt.state == AddonModQuizProvider.ATTEMPT_IN_PROGRESS) {
await CoreDomUtils.showConfirm(Translate.instant('addon.mod_quiz.confirmclose'));
let message = Translate.instant('addon.mod_quiz.confirmclose');

const unansweredCount = this.summaryQuestions
.filter(question => AddonModQuiz.isQuestionUnanswered(question))
.length;

if (unansweredCount > 0) {
const warning = Translate.instant(
'addon.mod_quiz.submission_confirmation_unanswered',
{ $a: unansweredCount },
);

message += `
<ion-card class="core-warning-card">
<ion-item>
<ion-label>
${ warning }
</ion-label>
</ion-item>
</ion-card>
`;
}

await CoreDomUtils.showConfirm(
message,
Translate.instant('addon.mod_quiz.submitallandfinish'),
Translate.instant('core.submit'),
);
}

modal = await CoreDomUtils.showModalLoading('core.sending', true);
Expand Down
16 changes: 16 additions & 0 deletions src/addons/mod/quiz/services/quiz.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import { AddonModQuizAttempt } from './quiz-helper';
import { AddonModQuizOffline, AddonModQuizQuestionsWithAnswers } from './quiz-offline';
import { AddonModQuizAutoSyncData, AddonModQuizSyncProvider } from './quiz-sync';
import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site';
import { QUESTION_INVALID_STATE_CLASSES, QUESTION_TODO_STATE_CLASSES } from '@features/question/constants';

const ROOT_CACHE_KEY = 'mmaModQuiz:';

Expand Down Expand Up @@ -1517,6 +1518,21 @@ export class AddonModQuizProvider {
return !!element.querySelector('.mod_quiz-blocked_question_warning');
}

/**
* Check if a question is unanswered.
*
* @param question Question.
* @returns Whether it's unanswered.
*/
isQuestionUnanswered(question: CoreQuestionQuestionParsed): boolean {
if (!question.stateclass) {
return false;
}

return QUESTION_TODO_STATE_CLASSES.some(stateClass => stateClass === question.stateclass)
|| QUESTION_INVALID_STATE_CLASSES.some(stateClass => stateClass === question.stateclass);
}

/**
* Check if a quiz is enabled to be used in offline.
*
Expand Down
218 changes: 218 additions & 0 deletions src/addons/mod/quiz/tests/behat/basic-usage-403.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
@addon_mod_quiz @app @javascript @lms_from4.0 @lms_upto4.3
Feature: Attempt a quiz in app
As a student
In order to demonstrate what I know
I need to be able to attempt quizzes

# These scenarios are duplicated from main because the unanswered questions warning
# is not available before 4.4.
Background:
Given the Moodle site is compatible with this feature
And the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "users" exist:
| username |
| student1 |
| teacher1 |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| teacher1 | C1 | editingteacher |
And the following "activities" exist:
| activity | name | intro | course | idnumber |
| quiz | Quiz 1 | Quiz 1 description | C1 | quiz1 |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
And the following "questions" exist:
| questioncategory | qtype | name | questiontext |
| Test questions | truefalse | TF1 | Text of the first question |
| Test questions | truefalse | TF2 | Text of the second question |
And quiz "Quiz 1" contains the following questions:
| question | page |
| TF1 | 1 |
| TF2 | 2 |
And the following "activities" exist:
| activity | name | intro | course | idnumber |
| quiz | Quiz 2 | Quiz 2 description | C1 | quiz2 |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions 2 |
And the following "questions" exist:
| questioncategory | qtype | name | questiontext |
| Test questions | multichoice | TF3 | Text of the first question |
| Test questions | shortanswer | TF4 | Text of the second question |
| Test questions | numerical | TF5 | Text of the third question |
| Test questions | essay | TF6 | Text of the fourth question |
| Test questions | ddwtos | TF7 | The [[1]] brown [[2]] jumped over the [[3]] dog. |
| Test questions | truefalse | TF8 | Text of the sixth question |
| Test questions | match | TF9 | Text of the seventh question |
| Test questions | description | TF10 | Text of the eighth question |
# TODO test calculated question type.
# The calculatedsimple type is implemented using the calculated type.
# The calculatedmulti type is implemented using the multichoice type.
# The randomsamatch type is implemented using the match type.
And the following "questions" exist:
| questioncategory | qtype | name | template |
| Test questions | gapselect | TF11 | missingchoiceno |
| Test questions | ddimageortext | TF12 | xsection |
| Test questions | ddmarker | TF13 | mkmap |
And quiz "Quiz 2" contains the following questions:
| question | page |
| TF3 | 1 |
| TF4 | 2 |
| TF5 | 3 |
| TF6 | 4 |
| TF7 | 5 |
| TF8 | 6 |
| TF9 | 7 |
| TF10 | 8 |
| TF11 | 9 |
| TF12 | 10 |
| TF13 | 11 |

# TODO rewrite using generators.
And I am on the "Course 1" "core_question > course question bank" page logged in as teacher1
And I add a "Embedded answers (Cloze)" question filling the form with:
| Question name | multianswer |
| Question text | {1:SHORTANSWER:=Berlin} is the capital of Germany. |
| General feedback | The capital of Germany is Berlin. |
And I am on the "quiz2" "Activity" page
And I click on "Questions" "link"
And I click on "Add" "link"
And I click on "from question bank" "link"
And I set the field with xpath "//tr[contains(normalize-space(.), 'multianswer')]//input[@type='checkbox']" to "1"
And I click on "Add selected questions to the quiz" "button"
And I log out

Scenario: View a quiz entry page (attempts, status, etc.)
Given I entered the quiz activity "Quiz 1" on course "Course 1" as "student1" in the app
When I press "Attempt quiz now" in the app
Then I should find "Text of the first question" in the app
But I should not find "Text of the second question" in the app

When I press "Next" in the app
Then I should find "Text of the second question" in the app
But I should not find "Text of the first question" in the app

When I press "Previous" in the app
Then I should find "Text of the first question" in the app
But I should not find "Text of the second question" in the app

When I press "Next" in the app
Then I should find "Text of the second question" in the app
But I should not find "Text of the first question" in the app

When I press "Previous" in the app
Then I should find "Text of the first question" in the app
But I should not find "Text of the second question" in the app

When I press "Next" in the app
And I press "Submit" in the app
Then I should find "Summary of attempt" in the app

When I press "Not yet answered" within "2" "ion-item" in the app
Then I should find "Text of the second question" in the app
But I should not find "Text of the first question" in the app

When I press "Submit" in the app
And I press "Submit all and finish" in the app
Then I should find "Once you submit" in the app

When I press "Cancel" near "Once you submit" in the app
Then I should find "Summary of attempt" in the app

When I press "Submit all and finish" in the app
And I press "Submit" near "Once you submit" in the app
Then I should find "Review" in the app
And I should find "Started on" in the app
And I should find "State" in the app
And I should find "Completed on" in the app
And I should find "Time taken" in the app
And I should find "Marks" in the app
And I should find "Grade" in the app
And I should find "Question 1" in the app
And I should find "Question 2" in the app

Scenario: Attempt a quiz (all question types)
Given I entered the quiz activity "Quiz 2" on course "Course 1" as "student1" in the app
When I press "Attempt quiz now" in the app
And I press "Four" in the app
And I press "Three" in the app
And I set the field "Answer" to "Berlin" in the app
And I press "Next" in the app
And I set the field "Answer" to "testing" in the app
And I press "Next" in the app
And I set the field "Answer" to "5" in the app
And I press "Next" in the app
And I set the field "Answer" to "Testing an essay" in the app
And I press "Next" "ion-button" in the app
And I press "quick" ".drag" in the app
And I click on ".place1.drop" "css"
And I press "fox" ".drag" in the app
And I click on ".place2.drop" "css"
And I press "lazy" ".drag" in the app
And I click on ".place3.drop" "css"
And I press "Next" in the app
And I press "True" in the app
And I press "Next" in the app
And I set the field "frog" to "amphibian" in the app
And I set the field "newt" to "insect" in the app
And I set the field "cat" to "mammal" in the app
And I press "Next" in the app
Then I should find "Text of the eighth question" in the app

When I press "Next" in the app
And I set the field "Blank 1" to "cat" in the app
And I set the field "Blank 2" to "mat" in the app
And I press "Next" in the app
And I press "abyssal" ".drag" in the app
And I click on ".place6.dropzone" "css"
And I press "trench" ".drag" in the app
And I click on ".place3.dropzone" "css"
And I press "Next" in the app
And I press "Railway station" ".marker" in the app
And I click on "img.dropbackground" "css"
And I press "Submit" in the app
Then I should find "Answer saved" in the app
And I should find "Incomplete answer" within "10" "ion-item" in the app
But I should not find "Not yet answered" in the app

When I press "Submit all and finish" in the app
And I press "Submit" in the app
Then I should find "Review" in the app
And I should find "Finished" in the app
And I should find "Not yet graded" in the app

When I press "Correct" within "Question 2" "ion-card" in the app
Then I should find "The correct answer is: Berlin" in the app
And I should find "Mark 1.00 out of 1.00" in the app

Scenario: Submit a quiz & Review a quiz attempt
Given I entered the quiz activity "Quiz 1" on course "Course 1" as "student1" in the app
When I press "Attempt quiz now" in the app
Then I should find "Text of the first question" in the app
And the UI should match the snapshot

When I press "True" in the app
And I press "Next" in the app
And I press "False" in the app
And I press "Submit" in the app
And I press "Submit all and finish" in the app
And I press "Submit" in the app
Then I should find "Review" in the app

When I replace "/.*/" within "page-addon-mod-quiz-review core-loading > ion-card ion-item:nth-child(1) p:nth-child(2)" with "[Started on date]"
And I replace "/.*/" within "page-addon-mod-quiz-review core-loading > ion-card ion-item:nth-child(3) p:nth-child(2)" with "[Completed on date]"
Then the UI should match the snapshot

Given I entered the quiz activity "Quiz 1" on course "Course 1" as "teacher1" in the app
When I press "Information" in the app
And I press "Open in browser" in the app
And I switch to the browser tab opened by the app
And I log in as "teacher1"
And I follow "Attempts: 1"
And I follow "Review attempt"
Then I should see "Finished"
And I should see "1.00/2.00"
6 changes: 3 additions & 3 deletions src/addons/mod/quiz/tests/behat/basic_usage-311.feature
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ Feature: Attempt a quiz in app
Then I should find "Summary of attempt" in the app

When I press "Submit all and finish" in the app
And I press "OK" near "Once you submit" in the app
And I press "Submit" near "Once you submit" in the app
Then I should find "Review" in the app
And I should find "Started on" in the app
And I should find "State" in the app
Expand Down Expand Up @@ -181,7 +181,7 @@ Feature: Attempt a quiz in app
But I should not find "Not yet answered" in the app

When I press "Submit all and finish" in the app
And I press "OK" in the app
And I press "Submit" in the app
Then I should find "Review" in the app
And I should find "Finished" in the app
And I should find "Not yet graded" in the app
Expand All @@ -200,7 +200,7 @@ Feature: Attempt a quiz in app
And I press "False" in the app
And I press "Submit" in the app
And I press "Submit all and finish" in the app
And I press "OK" in the app
And I press "Submit" in the app
Then I should find "Review" in the app

When I replace "/.*/" within "page-addon-mod-quiz-review core-loading > ion-card ion-item:nth-child(1) p:nth-child(2)" with "[Started on date]"
Expand Down
2 changes: 1 addition & 1 deletion src/addons/mod/quiz/tests/behat/basic_usage-39.feature
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ Feature: Attempt a quiz in app
And I should find "Incomplete answer" within "9" "ion-item" in the app

When I press "Submit all and finish" in the app
And I press "OK" in the app
And I press "Submit" in the app
Then I should find "Review" in the app
And I should find "Finished" in the app
And I should find "Not yet graded" in the app
12 changes: 9 additions & 3 deletions src/addons/mod/quiz/tests/behat/basic_usage.feature
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,13 @@ Feature: Attempt a quiz in app
When I press "Submit" in the app
And I press "Submit all and finish" in the app
Then I should find "Once you submit" in the app
And I should find "Questions without a response: 2" in the app

When I press "Cancel" near "Once you submit" in the app
Then I should find "Summary of attempt" in the app

When I press "Submit all and finish" in the app
And I press "OK" near "Once you submit" in the app
And I press "Submit" near "Once you submit" in the app
Then I should find "Review" in the app
And I should find "Started on" in the app
And I should find "State" in the app
Expand Down Expand Up @@ -178,7 +179,9 @@ Feature: Attempt a quiz in app
But I should not find "Not yet answered" in the app

When I press "Submit all and finish" in the app
And I press "OK" in the app
Then I should find "Questions without a response: 1" in the app

When I press "Submit" in the app
Then I should find "Review" in the app
And I should find "Finished" in the app
And I should find "Not yet graded" in the app
Expand All @@ -198,7 +201,10 @@ Feature: Attempt a quiz in app
And I press "False" in the app
And I press "Submit" in the app
And I press "Submit all and finish" in the app
And I press "OK" in the app
Then I should find "Once you submit" in the app
But I should not find "Questions without a response" in the app

When I press "Submit" in the app
Then I should find "Review" in the app

When I replace "/.*/" within "page-addon-mod-quiz-review core-loading > ion-card ion-item:nth-child(1) p:nth-child(2)" with "[Started on date]"
Expand Down
Loading