Skip to content

Pre/Post test renderer#14389

Open
AlexVelezLl wants to merge 4 commits intolearningequality:release-v0.19.xfrom
AlexVelezLl:assessment-viewer
Open

Pre/Post test renderer#14389
AlexVelezLl wants to merge 4 commits intolearningequality:release-v0.19.xfrom
AlexVelezLl:assessment-viewer

Conversation

@AlexVelezLl
Copy link
Member

Summary

  • Copied the current QuizRenderer to a new PrePostTest renderer component, and modified it to display pre/post tests. (Kept the copy isolated on a different commit, so that relevant changes are more visible to reviewers).
  • Updated useProgressTracking composable to track pre/post test progress.
    • Updated the initContentSession to use a Strategy pattern to make this method more flexible, maintainable, and understandable, since the current implementation was super difficult to read (at least it was to me). Previous unit tests had all these execution paths well covered, so I have good confidence in the refactor.
  • Added the new PrePostTestRenderer as another case of the "CourseContentViewer" component, trying to make it compatible with other renderers.
Grabacion.de.pantalla.2026-03-16.a.la.s.10.13.59.a.m.mov

References

Closes #14134.

Reviewer guidance

  • As Coach, Create/Assign a course to learners.
  • Open the first pre test.
  • As Learner, look at the course unit page. See that pre test is being rendered. Complete it. Check that learners cannot navigate to other resources.
  • As Coach, close the pre test.
  • As Learner, look at the course unit page. See that pre-test is marked as completed, and that learner can navigate to unit resources.
  • Do the same for post-tests.

AI usage

I used Claude to write unit tests for the updated behavior of the useProgressTracking composable

@AlexVelezLl AlexVelezLl requested a review from rtibblesbot March 16, 2026 15:17
@github-actions github-actions bot added APP: Learn Re: Learn App (content, quizzes, lessons, etc.) DEV: frontend SIZE: very large labels Mar 16, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 16, 2026

@AlexVelezLl
Copy link
Member Author

Hey @rtibblesbot, could you take a look, please?

Copy link
Contributor

@rtibblesbot rtibblesbot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean PR that adds pre/post test rendering within the course context. The strategy pattern refactor of initContentSession is a nice improvement. CI passing.

  • blocking: QUIZ strategy validate regression — lessonId no longer checked (test silently passes due to try/catch antipattern)
  • suggestion: Missing force/immediate flags on exam submission in PrePostTestRenderer
  • suggestion: No intermediate progress tracking when saving answers without closing
  • suggestion: PrePostTestRenderer and AnswerHistory use Options API (AGENTS.md requires Composition API for new components)
  • suggestion: postTestItemDescription always reads version_a_item_ids regardless of which version the learner gets
  • praise: Strategy pattern refactor, thorough COURSE_TEST test coverage, good navigation constraint logic

@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly

How was this generated?

Reviewed the pull request diff checking for:

  • Correctness: bugs, edge cases, undocumented behavior, resource leaks, hardcoded values
  • Design: unnecessary complexity, naming, readability, comment accuracy, redundant state
  • Architecture: duplicated concerns, minimal interfaces, composition over inheritance
  • Testing: behavior-based assertions, mocks only at hard boundaries, accurate coverage
  • Completeness: missing dependencies, unupdated usages, i18n, accessibility, security
  • Principles: DRY (same reason to change), SRP, Rule of Three (no premature abstraction)
  • Checked CI status and linked issue acceptance criteria
  • For UI changes: inspected screenshots for layout, visual completeness, and consistency

QUIZ: 'quiz',
NODE: 'node',
COURSE_TEST: 'course_test',
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

praise: The strategy pattern refactor is well-structured — validate, buildData, and isSessionAlreadyStarted are cleanly separated per session type, making the logic much easier to follow than the previous imperative approach. The COURSE_TEST strategy slots in naturally.


if (close) {
data.progress = 1;
this.submitting = true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: When close is true, this doesn't pass force: true or immediate: true to updateContentSession, unlike QuizRenderer (line 340-343). The immediate flag is likely set automatically because progress = 1 triggers the completion path in updateContentSession. However, force: true is a safety net that ensures the update is sent even if no thresholds are met (e.g., if the session was somehow already at progress 1). Consider adding both flags to match QuizRenderer behavior:

if (close) {
  data.progress = 1;
  data.force = true;
  data.immediate = true;
  this.submitting = true;
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I matched the behavior we have on ExamPage, which I think is the most similar behavior here. But I think it doesn't hurt if we add these additional flags.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think adding this update doesn't hurt and might save some data along the way!

this.submitting = true;
}

return this.updateContentSession(data).then(() => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: When close is false, QuizRenderer tracks intermediate progress (lines 347-354) so the quiz shows as "in progress" in the UI. This component sends no progress at all when saving a non-closing answer. Was this intentional for pre/post tests? If intermediate progress isn't needed, a brief comment explaining why would help future readers understand the divergence from QuizRenderer.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have implemented this the same way ExamPage does, but not completely sure about this, @rtibbles what do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not really needed no - we do this for the QuizRenderer for the UI so that the visual indicator to the user changes, but as we don't have that for coach assigned exams or pre/post tests in the same way, it's less of a concern.

I think, again, we can revisit this when we have one component to rule them all!

let _uid = 0;

export default {
name: 'PrePostTestRenderer',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: AGENTS.md says "New components must use setup(). Do not use Options API (data(), computed:, methods:)." This component and AnswerHistory.vue use the Options API. The PR description explains this was an intentional copy from QuizRenderer for diff visibility, which is a reasonable trade-off for reviewability — but it might be worth migrating to Composition API before merge or as a fast follow, to avoid accumulating tech debt.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may do this later when we unify all these components

return completedLabel$();
}
const numQuestions = get(
props.unitTree,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: This always reads version_a_item_ids.length for the question count. If versions A and B can have different numbers of items, this could show the wrong total for learners assigned version B. If they're always the same length, a comment noting that assumption would help.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In theory these should always have the same length, right @rtibbles?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, if they're not something has gone wrong!

};

const onResourceFinished = () => {
if (activeTest.value) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

praise: Good handling of the active test case in onResourceFinished — cleanly prevents the resume position from being updated when the learner submits a pre/post test, which is the right behavior since test lifecycle is coach-controlled.

await initContentSession({
courseTest: { unitId: 'test_unit', testType: 'pre' },
node,
courseSessionId: 'test_course_session',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

praise: Thorough test coverage for the COURSE_TEST strategy — validation, happy path, session deduplication, repeat behavior, and different unit/test type transitions are all covered.

Copy link
Contributor

@rtibblesbot rtibblesbot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delta review of the pre/post test renderer PR.

Prior findings

Finding Status
QUIZ strategy lessonId validation regression RESOLVEDlessonId added to QUIZ validate check
Missing force/immediate flags on submission RESOLVED — both flags now included
No intermediate progress tracking ACKNOWLEDGED — matches ExamPage behavior, deferred to maintainer
Options API usage ACKNOWLEDGED — planned for later unification
version_a_item_ids assumption ACKNOWLEDGED — awaiting maintainer confirmation

All prior blocking/suggestion findings are resolved or acknowledged.

CI still in progress. One new suggestion below.


@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly

How was this generated?

Compared the current PR state against findings from a prior review:

  • Retrieved prior bot reviews deterministically via the GitHub API
  • Classified each prior finding as RESOLVED, UNADDRESSED, ACKNOWLEDGED, or CONTESTED
  • Only raised NEW findings for newly introduced code
  • Reviewed the pull request diff checking for correctness, design, architecture, testing, completeness, and adherence to DRY/SRP principles
  • Checked CI status and linked issue acceptance criteria

);
},
},
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

praise: The strategy pattern refactor is well-executed — each strategy cleanly encapsulates its own validation, data building, and session identity logic. The COURSE_TEST strategy slots in naturally alongside QUIZ and NODE without increasing complexity in the main initContentSession flow.

Copy link
Member

@rtibbles rtibbles left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have not manually tested yet - just one thing stood out, I'd have to double check the specs (and/or it might be an i18n decision later) but I think just putting a separate submit string in the translator object that we can tweak later would be helpful.

};

// Each strategy encapsulates one session type's rules
const SESSION_STRATEGIES = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What a splendid application of the Rule of Three!

v-if="submitModalOpen"
:title="isSurvey ? $tr('submitSurvey') : $tr('submitExam')"
:submitText="isSurvey ? $tr('submitSurvey') : $tr('submitExam')"
:title="$tr('submitExam')"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may want to add a new string for "submit test" instead of "quiz" - can put it in the dedicated translator.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this was the same strings the specs showed, but definitely "submit test" sounds better. Is it okay just having a "submit test" string? Or should we differentiate "submit pre-test", "submit post-test"?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes - it feels like for consistency with the other strings, saying "test" makes more sense than quiz - and then people can tell us later whether we need to say "pretest" and "posttest" separably.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

@AlexVelezLl AlexVelezLl force-pushed the assessment-viewer branch 2 times, most recently from 614a405 to b680aba Compare March 16, 2026 20:49
@github-actions github-actions bot added DEV: dev-ops Continuous integration & deployment DEV: backend Python, databases, networking, filesystem... APP: Coach Re: Coach App (lessons, quizzes, groups, reports, etc.) labels Mar 16, 2026
@AlexVelezLl AlexVelezLl changed the base branch from develop to release-v0.19.x March 16, 2026 20:56
Copy link
Contributor

@rtibblesbot rtibblesbot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delta review — all prior blocking/suggestion findings are resolved or acknowledged.

Prior findings

Finding Status
QUIZ strategy lessonId validation regression RESOLVEDlessonId added to QUIZ validate check
Missing force/immediate flags on submission RESOLVED — both flags now included
No intermediate progress tracking ACKNOWLEDGED — matches ExamPage behavior, deferred to unification
Options API usage ACKNOWLEDGED — planned for later unification
version_a_item_ids assumption ACKNOWLEDGED — confirmed by maintainer

CI passing. No new blocking issues.

  • nitpick: Typo in variable name (see inline)
  • praise: Strategy pattern refactor, thorough COURSE_TEST test coverage, good submitTestAction string update per maintainer feedback

@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly

How was this generated?

Compared the current PR state against findings from a prior review:

  • Retrieved prior bot reviews deterministically via the GitHub API
  • Classified each prior finding as RESOLVED, UNADDRESSED, ACKNOWLEDGED, or CONTESTED
  • Only raised NEW findings for newly introduced code
  • Reviewed the pull request diff checking for correctness, design, architecture, testing, completeness, and adherence to DRY/SRP principles
  • Checked CI status and linked issue acceptance criteria

return [];
}
const preposttestVersion = this.masteryCriterion.version;
const preposttestAssesments = get(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: Typo: preposttestAssesmentspreposttestAssessments (missing an s).

});
}

const SessionStrategyType = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

praise: The strategy pattern refactor here is a clean improvement — each session type's validation, data-building, and deduplication logic is now co-located and independently testable. The thorough COURSE_TEST test coverage gives good confidence in the new path.

@pcenov pcenov self-requested a review March 18, 2026 16:00
Copy link
Member

@pcenov pcenov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @AlexVelezLl - I confirm that everything is implemented as specified by you in the reviewer guidance. Will be further testing this once the other pieces of the puzzle are put together! 👍

@rtibbles
Copy link
Member

Flagging that we'll hold off on merge here until after today's off-cycle patch release.

@rtibbles rtibbles self-assigned this Mar 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

APP: Coach Re: Coach App (lessons, quizzes, groups, reports, etc.) APP: Learn Re: Learn App (content, quizzes, lessons, etc.) DEV: backend Python, databases, networking, filesystem... DEV: dev-ops Continuous integration & deployment DEV: frontend SIZE: very large

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Pre/post test assessment viewer within course context

4 participants