> ## Documentation Index
> Fetch the complete documentation index at: https://docs.junojourney.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Quizzes

> Assessments with scoring, retries, time limits, and AI-assisted validation.

export const RelatedPages = ({pages = []}) => {
  if (pages.length === 0) return null;
  return <>
      <br />
      <strong>Related articles</strong>
      <CardGroup cols={2}>
        {pages.map(page => <Card title={page.title} href={page.href} key={page.href} />)}
      </CardGroup>
    </>;
};

export const VideoWalkthrough = ({src, alt, caption}) => {
  return <Frame caption={caption}>
      <img src={src} alt={alt || caption || "Walkthrough"} />
    </Frame>;
};

export const RoleBadge = ({roles = []}) => {
  const colorMap = {
    Admin: "yellow",
    Manager: "blue",
    Learner: "green",
    "Co-editor": "purple"
  };
  return <>
      {roles.map(role => <span key={role}><Badge color={colorMap[role] || "gray"} size="sm" shape="pill">{role}</Badge>{" "}</span>)}
    </>;
};

## What is a quiz?

A Quiz is a standalone assessment in Juno. Quizzes can exist on their own or be embedded inside a Course or Journey. They support multiple question types, configurable scoring, time limits, and retry policies.

***

## Question types

### Graded automatically

| Type                | How it works                       |
| ------------------- | ---------------------------------- |
| **Multiple choice** | Select one or more correct answers |
| **True / False**    | Binary choice                      |
| **Rating**          | Scale-based response               |

### Requires manual or AI validation

| Type                 | How it works                       |
| -------------------- | ---------------------------------- |
| **Open text**        | Free-form written response         |
| **Free text**        | Short text input                   |
| **File upload**      | Learner uploads a document or file |
| **Recording**        | Audio or video recording           |
| **Todo / Checklist** | Task completion checklist          |

### Other

| Type          | How it works              |
| ------------- | ------------------------- |
| **Signature** | Digital signature capture |

***

## Quiz settings

<RoleBadge roles={["Admin"]} />

The settings panel has **3 tabs** for quizzes: General, Quiz Behavior, and Permission & Control.

### General tab

Same as courses: title, description, tags, difficulty level, language.

### Quiz Behavior tab

**Attempts limit:**

* Number of times a learner can attempt the quiz
* Range: 1–5
* Default: 3
* Quiz locks when limit is reached

**Time limit (minutes):**

* Time allowed per attempt
* Default: 60 minutes
* Can be disabled for unlimited time

**Passing grade:**

* Minimum percentage to pass (1–100)
* Default: 80%

<Warning>
  Once a passing grade is set, it cannot be removed. Only the value can be changed.
</Warning>

**Shuffle answers for Multiple Choice Questions:**

* Randomizes the **answer options** within each multiple choice question (not the question order)
* Only visible if enabled by your admin

**Grade reveal** — controls when learners see their results:

| Option                                      | When results are shown                                               |
| ------------------------------------------- | -------------------------------------------------------------------- |
| **Show results immediately when available** | Auto-graded questions: immediately. Open questions: after validation |
| **Let me choose when to send results**      | You manually release results to all participants at once             |

**Due dates** (if enabled):

* Same as courses: None, Specific date, or Relative date
* With notification toggles

### Permission & Control tab

Same as courses: co-editors, audience, validators, validation mode (Manual/Auto/Recommend), privacy settings, access restriction.

***

## Time limit behavior

When a quiz has a time limit, a **countdown timer** appears in the unit's top bar from the moment the learner opens the first question.

### How the countdown works

| Behavior                | Detail                                                                                                                                                     |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Starts**              | The first time the learner opens the quiz consumption view — `startedAt` is captured server-side                                                           |
| **End time**            | `startedAt + time limit` — fixed on the server, not recomputed by the browser                                                                              |
| **Closing the tab**     | The countdown **keeps running** — there is no pause. Re-opening shows the real remaining time                                                              |
| **Refresh / reconnect** | Frontend re-fetches `timeLeft` from the server, so the displayed value is always authoritative                                                             |
| **Multiple devices**    | The same attempt across devices shares the same `startedAt` — the timer is the same everywhere                                                             |
| **When timer hits 0**   | The quiz **auto-submits** with whatever answers exist. If the learner closed the tab earlier, the next time anyone opens the quiz it finalizes immediately |

<Warning>
  Closing the browser or going idle does **not** stop the time-limit countdown. A learner who opens a 30-minute quiz, leaves it for 35 minutes, and comes back will see a submitted attempt with their then-current answers.
</Warning>

### Time limit vs. Time Spent

These are two **separate** measurements — see [How "Time Spent" is measured](/admin/training-analytics#how-time-spent-is-measured) for the full breakdown.

| Metric                            | Pauses when learner is idle?            | Capped at 60 min?                    | Source                         |
| --------------------------------- | --------------------------------------- | ------------------------------------ | ------------------------------ |
| **Time limit countdown**          | ✗ No — wall-clock from first open       | ✗ No                                 | Server-anchored on `startedAt` |
| **Time Spent** (analytics column) | ✓ Yes — pauses after 10 min of no input | ✓ Yes (per continuous section visit) | Client heartbeat every 20s     |

Two things follow:

1. **Time Spent on a quiz attempt can be much lower than the time limit** if the learner was idle.
2. **Time Spent caps at \~60 min for a single continuous attempt**. A 90-minute quiz with full engagement throughout will still report Time Spent ≈ 60 min — because the whole quiz is one section and the cap is per-section. The quiz submission is unaffected; only the analytics column stops accumulating.

The tracking mechanism itself is **identical to courses** — the same per-section heartbeat hook runs for every unit type. The only reason a quiz behaves differently in practice is that a quiz is usually a **single continuous section**, while a course is split across many.

### Submitting before time runs out

The learner can submit at any point via the **Submit** button. A confirmation dialog shows:

* How many questions remain unanswered
* How much time is left on the countdown

<InternalNote>
  Implementation:

  * Frontend countdown: [`QuizTimeLeftCountDown`](https://github.com/anthropics/monorepo/blob/release/apps/front/src/features/Unit/components/QuizTimeLeftCountDown.tsx) → `CountdownV3` with `onFinish={submitQuiz}`.
  * Hook: [`useQuizTimeLeft`](https://github.com/anthropics/monorepo/blob/release/apps/front/src/features/Unit/hooks/useQuizTimeLeft.ts) — `useJunoQuery` wrapper around `UserUnitV2.getQuizTimeLeft(unitId, userId)`. Single fetch on mount + standard React Query refetch triggers (window focus, etc.) — **no polling** (`refetchInterval` is not set). The visible countdown is driven locally by `CountdownV3`. Backend route mounted at `GET /users/:userId/units/:unitId/quiz-time-left` (the `users` router mounts `usersUnitsV2` under `/:userId/units/:unitId`).
  * Auto-submit guard: [`UnitSecondaryBarSections.tsx:109-121`](https://github.com/anthropics/monorepo/blob/release/apps/front/src/features/Unit/components/UnitSecondaryBarSections.tsx) — fires `submitQuiz()` when `quizTimeLeft.timeLeft === 0` and no submission is in flight.
  * Backend source of truth: [`UserQuizService.getQuizTimeLeft`](https://github.com/anthropics/monorepo/blob/release/apps/api/src/api/services/UserUnit/UserQuizService.ts) — `endTime = userUnit.startedAt + unit.duration * 60 * 1000`, returns `max(0, endTime - Date.now())`.
  * "Stale tab" finalization: [`useNavigateToUnit.ts:68-73`](https://github.com/anthropics/monorepo/blob/release/apps/front/src/core/units/hooks/useNavigateToUnit.ts) computes `quizTimeExceeded` so the learner lands on the Summary tab even if the auto-submit effect never ran.
</InternalNote>

***

## Standalone vs. embedded

| Mode                 | Description                                                                      |
| -------------------- | -------------------------------------------------------------------------------- |
| **Standalone**       | Quiz exists as its own item in the catalog. Can be assigned directly to learners |
| **Inside a Journey** | Quiz is a step in a Journey sequence                                             |

***

## Taking a quiz (learner view)

When you open a quiz, you'll see:

* **Passing grade** required (or "No passing grade")
* **Attempts remaining** (or "Unlimited attempts")
* **Time limit** (or "Unlimited time")
* **Number of questions**

After submitting:

* Auto-graded questions are scored immediately
* Open questions wait for validation
* You'll see your score once results are released (based on grade reveal setting)
* If you didn't pass and have retries left, you can attempt again

When the quiz is a step inside a [Journey](/learning/learning-paths), the step button shows **Pending review** while a validator is still reviewing your open answers — see [Step button states](/learning/learning-paths#step-button-states).

<Note>
  If you've reached the maximum number of attempts and didn't pass, contact your admin — they can [add an attempt](/admin/training-analytics-actions#add-attempt) or [reset your progress](/admin/training-analytics-actions#reset-progress) from the analytics view.
</Note>

### When an admin reopens a quiz

Admins can reopen a quiz attempt for a learner from the analytics view. When this happens, the learner's answers are unlocked for editing while their per-question grades are preserved — so the analytics view continues to show which questions were answered correctly before the reopen. The quiz's overall completion is cleared and the learner can re-submit.

<RelatedPages
  pages={[
{ href: "/learning/courses", title: "Courses" },
{ href: "/learning/units-and-courses", title: "Content Types Overview" },
{ href: "/learning/learning-paths", title: "Journeys" },
{ href: "/admin/training-analytics", title: "Training Analytics" },
]}
/>
