Certificates - QA Test Plan
Overview
Section titled “Overview”The Certificates app enables instructors to design certificate templates using HTML/CSS, issue certificates to students with unique verification codes, and manage the lifecycle of issued certificates. Routes are under /business/apps/certificates/.
Dynamic Variables
Section titled “Dynamic Variables”{{student_name}}— Full name of the student{{course_name}}— Name of the course{{completion_date}}— Date of completion{{certificate_code}}— Unique certificate code{{instructor_name}}— Instructor full name
Template Statuses
Section titled “Template Statuses”active— Template can be used to issue certificatesinactive— Template is in draft / deactivated state
Certificate Statuses
Section titled “Certificate Statuses”active— Certificate is valid and verifiablerevoked— Certificate has been revokedexpired— Certificate has expired
1. Dashboard / Landing Page
Section titled “1. Dashboard / Landing Page”| ID | Description | Preconditions | Steps | Expected Result | Priority |
|---|---|---|---|---|---|
| CT-001 | Dashboard loads with stats | User is logged in as instructor | Navigate to /business/apps/certificates | Page shows Templates count and Issued count stat cards | P0 |
| CT-002 | Nav cards link correctly | User is logged in | View dashboard | ”Templates” and “Issued Certificates” nav cards are visible and link to correct routes | P0 |
| CT-003 | Recent templates display | Templates exist | View dashboard | Up to 5 templates shown with title, description, and status badge | P1 |
| CT-004 | Template status badges render correctly | Templates with active/inactive status exist | View dashboard | Active templates show default badge; inactive show destructive badge | P1 |
| CT-005 | Empty state when no templates | No templates exist | View dashboard | ”No templates yet” message shown | P1 |
| CT-006 | Template links navigate to detail | Templates exist | Click on a template row | Navigates to /business/apps/certificates/templates/{id} | P0 |
2. Template List Page
Section titled “2. Template List Page”| ID | Description | Preconditions | Steps | Expected Result | Priority |
|---|---|---|---|---|---|
| CT-010 | Template list page loads | User is logged in | Navigate to /business/apps/certificates/templates | Header with back arrow, title, and “New Template” button; list of templates | P0 |
| CT-011 | Create template via dialog | User is logged in | 1. Click “New Template” 2. Enter title and optional description 3. Click “Create Template” | Template is created; user is redirected to template detail page with ?new=1 param | P0 |
| CT-012 | Create template - title required | User is logged in | Open dialog, leave title empty, submit | Validation error on title field | P0 |
| CT-013 | Delete template with confirmation | Template exists, no issued certs | 1. Click trash icon on a template 2. Confirm in dialog | Template is deleted; toast success; list refreshes | P0 |
| CT-014 | Delete template with issued certs | Template has issued certificates | Click trash icon, confirm deletion | Template is deactivated instead of deleted (per UI warning) | P1 |
| CT-015 | Cancel delete dialog | Delete confirmation shown | Click “Cancel” in delete dialog | Dialog closes; template remains | P2 |
| CT-016 | Empty state shows CTA | No templates exist | View templates page | ”No templates yet” message with “Create Template” button | P1 |
3. Template Detail / Editor
Section titled “3. Template Detail / Editor”| ID | Description | Preconditions | Steps | Expected Result | Priority |
|---|---|---|---|---|---|
| CT-020 | Template detail page loads | Template exists, user is owner | Navigate to /business/apps/certificates/templates/{id} | Page shows title, status badge, edit form with title, description, orientation, background image, body HTML, and CSS fields | P0 |
| CT-021 | New template toast on creation | Redirected with ?new=1 | Navigate to template detail with ?new=1 | Success toast “Template created!” appears on mount | P1 |
| CT-022 | Update template details | Template exists | Edit title, description, and body HTML; click “Save Template” | Template is updated; success toast appears | P0 |
| CT-023 | Set orientation to landscape | Template exists | Select “Landscape” in orientation dropdown | Orientation field updates; preview iframe uses landscape height (360px) | P1 |
| CT-024 | Set orientation to portrait | Template exists | Select “Portrait” in orientation dropdown | Orientation field updates; preview iframe uses portrait height (500px) | P1 |
| CT-025 | Edit Body HTML field | Template exists | Enter valid HTML in Body HTML textarea | Content is saved; HTML accepts template variable placeholders | P0 |
| CT-026 | Edit Custom CSS field | Template exists | Enter CSS styles in CSS textarea | CSS is applied in preview; saved on update | P1 |
| CT-027 | Available variables are listed | Template detail page loaded | Scroll to variables section | All 5 variables displayed with descriptions: student_name, course_name, completion_date, certificate_code, instructor_name | P0 |
4. Template Preview
Section titled “4. Template Preview”| ID | Description | Preconditions | Steps | Expected Result | Priority |
|---|---|---|---|---|---|
| CT-030 | Toggle preview on | Template has body HTML | Click “Preview” button | Form is hidden; preview iframe renders with placeholder data (Jane Doe, Sample Course, etc.) | P0 |
| CT-031 | Toggle preview off | Preview is visible | Click “Hide Preview” button | Preview is hidden; edit form is shown again | P0 |
| CT-032 | Preview replaces variables with sample data | Template body contains variables | Open preview | {{student_name}} replaced with “Jane Doe”, {{course_name}} with “Sample Course”, {{completion_date}} with current date, {{certificate_code}} with “CERT-PREVIEW-001”, {{instructor_name}} with “John Smith” | P0 |
| CT-033 | Preview applies custom CSS | Template has CSS | Open preview | CSS is injected into iframe <style> tag and applied to content | P1 |
| CT-034 | Empty body shows placeholder message | Body HTML is empty | Open preview | ”Add HTML content to see a preview” message displayed instead of iframe | P1 |
| CT-035 | Preview iframe is sandboxed | Preview is open | Inspect iframe element | Iframe has sandbox="allow-same-origin" attribute | P2 |
5. Template Status Management
Section titled “5. Template Status Management”| ID | Description | Preconditions | Steps | Expected Result | Priority |
|---|---|---|---|---|---|
| CT-040 | Activate inactive template | Template status is inactive | Click “Activate” button | Template status changes to active; toast success; page refreshes | P0 |
| CT-041 | Deactivate active template | Template status is active | Click “Set to Draft” button | Template status changes to inactive; toast success; page refreshes | P0 |
| CT-042 | Delete template from detail page | Template exists | Click trash icon, confirm in dialog | Template is deleted; user redirected to templates list | P0 |
| CT-043 | Delete with issued certs warning | Template has issued certs | View delete confirmation dialog | Warning text mentions deactivation if certificates have been issued | P1 |
| CT-044 | Activation shows loading state | User clicks Activate | Observe button during action | Button shows spinner and is disabled during the request | P2 |
6. Certificate Issuance
Section titled “6. Certificate Issuance”| ID | Description | Preconditions | Steps | Expected Result | Priority |
|---|---|---|---|---|---|
| CT-050 | Issue certificate via dialog | Template is active | 1. Click “Issue” button 2. Enter valid user ID 3. Click “Issue” | Certificate is issued; success toast; issued list refreshes | P0 |
| CT-051 | Issue certificate - user ID required | Issue dialog is open | Leave user ID empty, click “Issue” | Issue button is disabled when user ID is empty | P0 |
| CT-052 | Issued certificates table displays | Certificates have been issued | View template detail page | Table shows Student name, certificate Code (linked to verify route), Issued date, and Status badge | P0 |
| CT-053 | Certificate code links to verify page | Certificate is issued | Click certificate code link | Navigates to /verify/{certificate_code} | P1 |
| CT-054 | Issue failure shows error toast | Server error during issuance | Attempt to issue (simulated failure) | Error toast “Failed to issue certificate” appears | P1 |
7. Issued Certificates Management
Section titled “7. Issued Certificates Management”| ID | Description | Preconditions | Steps | Expected Result | Priority |
|---|---|---|---|---|---|
| CT-060 | Issued certificates page loads | User is instructor with issued certs | Navigate to /business/apps/certificates/issued | Table displays all issued certificates with Student (avatar + name), Code, Issued date, and Status columns | P0 |
| CT-061 | Revoke active certificate | Certificate status is active | 1. Click revoke (ban) icon 2. Confirm in dialog | Certificate status changes to revoked; toast success; table refreshes | P0 |
| CT-062 | Revoke button hidden for non-active | Certificate status is revoked or expired | View row | No revoke button is shown for that certificate | P1 |
| CT-063 | Cancel revoke dialog | Revoke confirmation shown | Click “Cancel” | Dialog closes; certificate status unchanged | P2 |
| CT-064 | Empty state when no issued certs | No certificates issued | View issued page | ”No certificates have been issued yet” message with icon | P1 |
| CT-065 | Student avatar renders when available | Certificate user has avatar_url | View issued table | Student column shows avatar image next to name | P2 |
8. Authorization & Error Handling
Section titled “8. Authorization & Error Handling”| ID | Description | Preconditions | Steps | Expected Result | Priority |
|---|---|---|---|---|---|
| CT-070 | Unauthenticated user gets 401 | User is not logged in | Navigate to templates or issued page | 401 error thrown | P0 |
| CT-071 | Non-owner cannot view template detail | Logged in as different instructor | Navigate to another instructor’s template | 403 error thrown | P0 |
| CT-072 | Non-existent template returns 404 | Invalid template ID | Navigate to /business/apps/certificates/templates/nonexistent | 404 “Template not found” error | P1 |