🔔 Changes saved by another team member are available.
What is UAT and why does it matter?
UAT (User Acceptance Testing) is the final check before the system goes live. It means real staff and learners use the actual platform — not a demo — and confirm that every feature works the way it should. If something is wrong, we catch it here, not after launch.
This document is the single reference point for the entire 5-day testing session. It tells everyone who tests what, what to look for, how to log problems, and when we need to be done. Non-technical stakeholders can read the Test Scripts and Feature Matrix tabs without needing any system knowledge. Technical staff will find the setup requirements in the Technical Setup tab.
The 10 areas being tested
1 · Programme setup
→
2 · Registration & apply
→
3 · Documents
→
4 · Review & score
5 · Shortlist & award
→
6 · Waitlist
→
7 · Contract & sign
→
8 · Deadline reminders
9 · POPIA data rights
→
10 · Audit trail
Sign-off criteria
The system may go live when all three conditions are met:
1. Zero blocker bugs outstanding. A blocker is any defect that causes wrong data to be saved, a notification not to fire, a document to be lost, or a security gap. Blockers must be fixed and re-tested before go-live.
2. All testers have completed their Feature Matrix. Every role's checklist must be 100% completed, or explicitly marked "N/A" with a reason logged in the bug log.
3. Written sign-off from JTG staff. Tshidi or Gomolemo confirms in writing (email is sufficient) that they have reviewed the bug log triage and are satisfied the system is ready.
What happens after UAT
The bug log is triaged into three buckets: blockers, functional gaps, and polish. Blockers get fixed immediately. Functional gaps are negotiated against the go-live timeline. Polish items are deferred to a post-launch iteration. The system does not need to be perfect to go live — it needs to be trustworthy.
Team assignments
Six people cover four system roles. Only Tshidi's admin account is pre-seeded by the developer. Everyone else self-registers on Day 1 morning, verifies their email, and then Tshidi assigns their system role from the Admin → Users panel before testing begins.
Bursary programme staff
TK
Tshidi
super_admin & verification_officer · pre-seeded
GM
Gomolemo
programme_admin · self-registers Day 1
Interns
VA
Vanessa
learner (eligible) · self-registers Day 1
RO
Rorisang
learner (ineligible) + bug log owner · self-registers Day 1
TS
Tshidiso
reviewer + sponsor · self-registers Day 1
BO
Bonolo
verification_officer + admin support · self-registers Day 1
Registration and role assignment flow
On Day 1 morning, everyone except Tshidi follows the same three steps:
Step 1 — Self-register. Go to the UAT URL, click Register, fill in name, email address, and a password, and submit. Use your real email address so you can receive the verification link and all notification emails during testing.
Step 2 — Verify your email. Check your inbox for the verification email. Click the link. Your account becomes active.
Step 3 — Wait for role assignment. After all five people have registered, Tshidi logs into the Admin panel → Users and assigns each person their system role. Once assigned, log out and log back in — you will now land on the correct portal (learner / reviewer / sponsor / admin).
Tshidi runs role assignment for all five team members before any other testing begins. This is the first thing on Day 1 afternoon and takes approximately 10 minutes.
Why two learners?
The waitlist promotion flow requires one learner to accept an award offer and another to be waiting on the waitlist. Without two separate learner accounts this cannot be tested. Vanessa accepts; Rorisang is on the waitlist and gets promoted. To separately test the decline path, Vanessa will also decline a second award offer — this is what triggers Rorisang's waitlist promotion rather than running an artisan command manually.
Rorisang's institution profile will be set by Gomolemo before the testing session starts — her institution or year of study will fall just outside the eligibility criteria for the UAT programme. This confirms the system correctly blocks ineligible applicants.
Account details
Person
Role assigned by admin
How account is created
Email used
Tshidi
super_admin
Pre-seeded by developer
tshidi@uat.jtg (or real email)
Gomolemo
programme_admin
Self-registers on Day 1
Real email address
Vanessa
learner
Self-registers on Day 1
Real email address
Rorisang
learner
Self-registers on Day 1
Real email address
Tshidiso
reviewersponsor
Self-registers on Day 1
Real email address
Bonolo
verif. officeradmin support
Self-registers on Day 1
Real email address
Because real email addresses are used, all notification emails will land in real inboxes — not just Mailtrap. Confirm with the developer that Mailtrap is only used for the queue/delivery testing steps, and that the UAT mail config sends real emails for the self-registration flow.
Bug log owner
Rorisang is assigned as bug log owner for the session. She is responsible for ensuring every issue — including ones flagged verbally by other testers — is logged in this document before end of each testing day. Her own testing workload is lighter than Vanessa's, which creates the capacity for this role. She does not need to fix anything, only record it clearly and completely.
Scripts are written in plain language. Each step tells the tester exactly what to do and what they should see if the system is working correctly. If what they see differs from the expected result, that is a bug — log it in the Bug Log tab with the step reference number.
Gomolemo, Vanessa, Rorisang, Tshidiso, and Bonolo — Day 1 morning. Tshidi skips this (her account is pre-seeded).
Complete all steps below before Tshidi assigns your role. You will not have full portal access until role assignment is done.
Step R1 — Self-register your account
1
Go to the UAT URL (shared by Tshidi). Click "Register" or "Create account".
✓ Registration form loads with fields for name, email address, and password.
2
Enter your real full name, your real email address, and a password. Submit the form.
✓ You see a message like "Please check your email to verify your account." You are NOT taken to any portal yet.
⚠ If you land immediately on a dashboard with no email verification step, log this as a Blocker: "Email verification not triggered on registration."
Step R2 — Verify your email address
1
Open your inbox. Look for a "Verify your email" or "Confirm your account" message from the system.
✓ Email arrives within 2 minutes containing a verification link.
⚠ If no email after 5 minutes, check spam. If still missing, log as Blocker: "Verification email not delivered."
2
Click the verification link in the email.
✓ Browser confirms "Email verified." Account is now active, but you have no role yet.
3
Log in with your email and password.
✓ You can log in. You see a limited or blank dashboard. No full portal features yet — this is expected until Tshidi assigns your role.
Step R3 — Confirm role access after assignment
Wait for Tshidi to confirm in the group chat that all roles have been assigned, then continue.
1
Log out, then log back in (or refresh).
✓ You land on the correct portal: learner (Vanessa, Rorisang), reviewer (Tshidiso), sponsor (Bonolo), admin (Gomolemo).
⚠ Still seeing the default page? Your role has not been assigned yet. Message Tshidi before logging this as a bug.
2
Manually type a URL for a portal that is not yours (e.g. type /admin/dashboard while you are a learner).
✓ Access denied — redirected to your own portal or shown a 403 error.
⚠ If you can access another role's portal, log immediately as a Blocker: "Role access control not enforced."
TK/GM
Tshidi & Gomolemo — Admin portal
Tshidi oversees Steps 0 and 8 (super_admin — oversight & sign-off). Gomolemo runs Steps 1–7 (programme_admin). Bonolo runs Step 2 as verification_officer in a separate incognito tab and provides technical support to Gomolemo throughout.
Step 1 — Programme, form, rubric, and rule setup (Gomolemo)
1
Log in as Gomolemo. Go to Admin → Programmes → Create new programme. Enter name "JTG UAT Bursary 2025", set the deadline 3 days from today, fund amount R15,000. Under eligibility, set institution to match Vanessa's pre-seeded institution only.
✓ Programme saves and appears in the programme list.
2
Click "Form Builder" on the new programme. Add 3 fields: a text field ("Motivation letter"), a file upload ("Supporting document"), and a dropdown ("Year of study"). Save, then click "Publish Form".
✓ Fields save correctly in preview. Status changes to "Published".
Navigate to Auto-assignment rules. Add a rule to assign Tshidiso as reviewer when an application is moved to "approved_for_review". Save and confirm it is active.
✓ Rule appears in the list and is toggled on.
7
Go to Admin → Contract Templates → Create. Build a template with merge fields for learner name, award amount, and programme name. Save and preview it.
✓ Template saved. Preview shows merge fields as readable placeholders, not raw code.
Step 1b — Universal programme setup (Gomolemo)
1
Create a second programme: "JTG UAT Open Bursary 2025". Set this one to universal mode — no eligibility restrictions. Publish its form.
✓ Programme saves in universal mode. Both Vanessa and Rorisang can see it in their listings (Rorisang cannot see the restricted programme but should see this one).
2
Confirm Rorisang can see the universal programme in her listing even though she is excluded from the restricted one.
✓ Rorisang sees "JTG UAT Open Bursary 2025" in her programme list. She does not see "JTG UAT Bursary 2025". This confirms restricted and universal modes filter correctly.
Step 2 — Document verification (Bonolo in incognito as verification_officer)
Wait until Vanessa has uploaded her documents (Vanessa Script Step 3) before starting this step.
1
Open a new incognito window. Log in as Tshidi's verification_officer account. Go to the verification dashboard.
✓ Applications with pending documents are listed.
2
Open Vanessa's application. Verify both her ID document and transcript by clicking "Verify" on each.
✓ Both documents show as "Verified". Application status automatically moves to "under_review".
3
Test the rejection path: find Rorisang's ID document and reject it with a reason (e.g. "File is unreadable").
✓ Rejection reason is saved and visible. Rorisang's application remains in pending document state.
Step 3 — Move to review and confirm auto-assignment (Gomolemo)
Run this after Bonolo has verified Vanessa's documents (Step 2 above).
1
Go to Admin → Applications. Find Vanessa's application. Change its status to "approved_for_review".
✓ Status updates. Tshidiso appears as the assigned reviewer (auto-assignment rule fired).
2
Check Mailtrap (or Tshidiso's in-app notifications) for a reviewer assignment email.
✓ ReviewerAssigned email visible in Mailtrap addressed to Tshidiso.
3
After Tshidiso declares a conflict (his Step 3), go to Admin → COI. Find the flagged declaration and reassign to a backup reviewer.
✓ Reassignment recorded. Original reviewer is marked as recused on that application.
Step 3b — Manual reviewer assignment test (Gomolemo)
1
Create a second test application (or use an existing one that has no auto-rule match). Go to Admin → Applications and manually assign a reviewer using the direct assign control — without relying on the auto-assignment rule.
✓ Reviewer is assigned manually. The assignment is visible on the application detail. A reviewer alert notification fires to the assigned reviewer.
Step 4 — Shortlisting and awards (Gomolemo)
Run after Tshidiso has submitted and locked his scores.
1
Go to Admin → Shortlist for the UAT programme. Confirm applications are ranked by weighted score and Vanessa's application appears with a score.
✓ Ranked list displayed with weighted scores visible per application.
3
Select both Vanessa and Rorisang's test applications. Click "Bulk Shortlist".
✓ Both move to "shortlisted". Two StatusChanged emails appear in Mailtrap — one per learner. This was a previously fixed bug — confirm both emails arrive.
4
Create an award for Vanessa. Set offer amount to R15,000 and expiry date 5 days from today. Generate the offer letter.
✓ Offer letter PDF generated and stored. AwardOffered email fires to Vanessa.
5
Add Rorisang to the waitlist (Admin → Waitlist). Confirm she is at position 1.
✓ Rorisang shows as waitlisted at position 1.
Step 5 — Waitlist promotion (Gomolemo)
Trigger this either by having Vanessa decline a second award offer, or by running: php artisan awards:process-expired to expire it manually.
1
Check the waitlist panel. Confirm Rorisang has been automatically promoted.
✓ Rorisang's status changes. WaitlistPromoted email visible in Mailtrap. Waitlist panel shows her as promoted.
Step 6 — Deadline reminders (Gomolemo, with developer)
1
Ask the developer to set the programme deadline to tomorrow. Run: php artisan reminders:deadline --dry-run
✓ Output lists the correct applications without sending any emails.
2
Run the same command without --dry-run. Then run it again.
✓ Emails appear in Mailtrap on first run. Second run sends no duplicates (idempotency confirmed).
Step 7 — POPIA data subject requests (Gomolemo)
Wait until Vanessa and Rorisang have each submitted their DSR from their own portals.
1
Go to Admin → Data Subject Requests. Find Vanessa's access request. Acknowledge it.
✓ Status moves to "acknowledged". Vanessa receives a status update notification.
2
Download the data export for Vanessa's request. Open the JSON file and confirm it contains her real data.
Find Rorisang's erasure request. Execute the erasure. Only on the UAT database.
✓ Rorisang's account is anonymised. Erasure report PDF written to storage. Her name no longer visible anywhere in the system.
Step 7b — Retention policy framework (Gomolemo)
1
Go to Admin → POPIA / Data Settings. Confirm there is a retention policy configuration area — this is where the system defines how long different data types are retained before automatic deletion or anonymisation.
✓ Retention policy settings are visible. You can see or configure retention periods for application data, personal profiles, and financial records.
2
Check whether the policy settings show the current configured retention period and any upcoming scheduled deletions.
✓ Retention settings display correctly without errors. Changes to the configuration save successfully.
Step 8 — Audit log and user management (Tshidi — super_admin)
1
Go to Admin → Audit Logs. Filter by today's date. Spot-check: find the bulk shortlist entry, the erasure executed entry, and a reviewer assignment entry.
✓ All three entries present with correct user names and timestamps.
2
Go to Admin → Contracts. Search for Vanessa's contract by her name.
✓ Contract appears in search results. The signed version is downloadable. Version history is visible (showing at minimum the generated version and the signed version with timestamp).
3
Go to Admin → Contracts. Search for Vanessa by name.
✓ Her signed contract appears in results. Version history shows generated → signed with timestamps. Contract is downloadable.
X
Go to Admin → Users. Toggle a user account inactive, then reactivate it. Run a password reset.
✓ Toggle works. Password reset email appears in Mailtrap.
VA
Vanessa — Eligible learner
Completes the full learner journey: register → apply → upload → accept award → sign contract → DSR.
Complete Pre-session Steps R1–R3 first. This script continues after role assignment.
Step 1 — Complete your learner profile
1
Go to the UAT URL. Click "Register". Enter your name, email (vanessa@uat.jtg), and a password. Submit.
✓ Registration succeeds. You land on the learner dashboard.
2
Go to My Profile → Edit. Complete the personal section (name, ID number, phone, address). Then fill in the academic section (institution — Gomolemo will tell you which one to use — year of study, field of study, student number). Then fill in the financial section (household income, number of dependants, other bursaries). Save.
✓ All three sections (personal, academic, financial) save correctly and display on your profile summary.
3
Find the POPIA consent section on the profile page. Tick the checkbox and save.
✓ Consent is recorded. You are now able to apply for bursaries.
Step 2 — Apply for the bursary
1
Go to Programmes. Confirm the "JTG UAT Bursary 2025" programme is visible.
✓ Programme appears in your list.
2
Click "Apply". Fill in the Motivation field and year of study dropdown. Do NOT submit yet — click "Save as Draft".
✓ Application saved as draft. Visible in My Applications with status "draft".
3
Return to the draft, finish filling it in, and click "Submit".
✓ Application submitted. Status changes to "submitted". A confirmation email arrives in your inbox (or Mailtrap).
Step 3 — Upload documents
1
Go to Documents. Upload a sample PDF as your ID Document. Upload a second sample PDF as your Academic Transcript. Upload a third sample PDF as your Proof of Income (this is the financial document on the programme checklist).
✓ Both documents listed with status "Pending verification".
2
Wait for Tshidi to verify your documents (Admin Step 2). Refresh the page.
✓ Documents show "Verified". Your application tracker shows status has moved to "Under review".
Step 4 — Track your application
1
Go to My Applications → click your application → click "Track Application".
✓ Timeline shows all status changes with dates.
2
Open the notifications panel (bell icon or Notifications menu). Check that status change notifications appear and can be marked as read.
✓ At least one notification visible. Clicking it marks it as read.
Step 5a — Accept Award 1
Wait for Gomolemo to create your award (Admin Step 4). You will receive an email notification when the offer is ready.
1
Go to My Awards. Confirm a pending offer for R15,000 is visible with an expiry date.
✓ Award offer visible with the correct amount.
2
Download the offer letter PDF. Check that it shows your name and the correct amount — not placeholder text.
✓ PDF downloads. Contains your real name and R15,000 — no merge field placeholders visible.
3
Click "Accept award" and confirm the prompt.
✓ Award status changes to "accepted". A contract ready email arrives. Your Contracts section now has a new contract.
Step 5b — Decline Award 2 (triggers Rorisang's waitlist promotion)
Wait for Gomolemo to create Award 2 — used to test the decline path and trigger the waitlist.
1
Go to My Awards. Confirm a second pending offer is visible alongside your accepted Award 1.
✓ Second award offer visible.
2
Click 'Decline award' on the second offer and confirm the prompt.
✓ Status changes to 'declined'. Rorisang should shortly receive a WaitlistPromoted email — confirming the decline triggered her promotion.
3
Confirm the declined award is labelled 'Declined' and you cannot reverse it.
✓ Declined label is permanent. No un-decline option available.
Step 6 — Sign your contract
1
Go to My Contracts. Open the contract. Confirm your name and award details are correctly populated.
✓ Contract displays correctly with real data.
2
Click "Sign contract" and confirm.
✓ Contract marked as signed. Timestamp and IP address recorded (Gomolemo can verify this in the admin application detail view).
3
Download the signed contract PDF.
✓ PDF downloads successfully.
Step 6b — Confirm contract in repository
1
Go to My Contracts. Check that your signed contract is listed and shows a "Signed" status with the timestamp from when you signed it.
✓ Contract listed with signed status, date, and time.
2
Check whether a version history or activity log is visible on the contract (showing: generated → signed).
✓ At minimum, the signed version is clearly distinct and the signature timestamp is permanently recorded.
Step 7 — Submit a data access request (POPIA)
1
Go to Privacy / Data Rights in the learner menu. Click "Request my data".
✓ Request submitted. You receive a reference number or on-screen confirmation.
2
After Gomolemo acknowledges it (Admin Step 7), refresh your DSR page.
✓ Status shows "acknowledged". You have received a notification.
RO
Rorisang — Ineligible learner + bug log owner
Tests the eligibility block, universal mode visibility, waitlist promotion, and decline path. Also owns the shared bug log for the entire session.
As bug log owner, keep the Bug Log tab open in a separate browser tab throughout the entire session. Any issue flagged verbally by another tester must be logged before end of day — not only your own findings.
Complete Pre-session Steps R1–R3 first. This script picks up from where role assignment ends.
Step 1 — Confirm eligibility block and universal programme visibility
1
Register a new account at the UAT URL using rorisang@uat.jtg. Complete your profile with the institution details Gomolemo gives you (these are intentionally set outside the eligibility criteria).
✓ Registration and profile save successfully.
2
Go to Programmes. Check whether "JTG UAT Bursary 2025" is visible in your list.
✓ The programme should NOT be visible, OR if it is visible, attempting to apply must show a clear eligibility block message.
⚠ If the programme is visible AND lets you submit an application without any restriction message, log this immediately as a Blocker: "Eligibility filter not enforced — ineligible learner can apply for restricted programme."
Step 2 — Upload documents (for waitlist test)
Gomolemo will manually add a test application entry for you to set up the waitlist scenario. Follow her instruction on when to do this step.
1
Upload sample PDFs (ID and transcript) to the Documents section.
✓ Documents upload and appear as "Pending verification".
Step 3 — Waitlist placement and promotion
1
After Gomolemo places you on the waitlist (Admin Step 4), go to My Applications and check the status.
✓ Application shows as "waitlisted". Your waitlist position is visible.
2
After the promotion is triggered (Admin Step 5), refresh your applications page.
✓ Status changes. You receive a WaitlistPromoted notification email.
Step 3b — Decline your award offer
After being promoted from the waitlist, you will receive an award offer. This step tests that the decline path works for a waitlisted learner who was promoted.
1
Go to My Awards after your waitlist promotion. You should have a pending award offer.
✓ Award offer visible with amount and expiry date.
2
Click 'Decline award' and confirm.
✓ Status changes to 'declined'. The admin can see this in the awards panel. Note: this step is for coverage only — decline, then proceed to the erasure step.
Step 4 — Submit an erasure request (POPIA)
1
Go to Privacy / Data Rights. Submit an erasure ("right to be forgotten") request.
✓ Request submitted with a reference number.
2
After Gomolemo executes the erasure (Admin Step 7, Day 4), attempt to log in again.
✓ Login fails — the account has been anonymised. This confirms the erasure completed correctly.
TS
Tshidiso — Reviewer & sponsor
Holds two roles. As reviewer: COI declaration, weighted scoring, committee recommendation (clean + conflict paths). As sponsor: tests the sponsor portal in a second browser session after completing the reviewer steps.
Complete Pre-session Steps R1–R3 first. Run Steps 1–4 as reviewer, then Steps S1–S3 as sponsor in a second browser session (or via role switcher if multi-role is supported).
Step 1 — Log in and check dashboard
1
Log in as tshidiso@uat.jtg. You should land on the reviewer dashboard.
✓ Dashboard shows applications assigned to you. A COI declaration prompt or banner is visible.
2
Confirm Vanessa's application appears in your assigned queue with the programme name and assigned date.
✓ Application listed correctly.
Step 2 — Declare no conflict and score (clean path)
1
Click on Vanessa's application. A COI declaration screen appears. Select "I have no conflict of interest" and submit.
✓ COI recorded. You are taken directly to the scoring screen.
2
Score each rubric criterion (0–100): give scores for Academic merit, Financial need, and Motivation. Click "Submit scores".
✓ Scores saved. Weighted total is calculated and displayed correctly.
3
Try to change a score after submitting.
✓ Score fields are read-only. A "Scores locked" indicator is visible. Editing is not possible.
Step 3 — Declare a conflict (conflict path)
Ask Gomolemo to create a second test application for this step before proceeding.
1
Open the second assigned application. On the COI screen, select "I have a conflict of interest" and provide a brief reason. Submit.
✓ You are redirected to a "You have been recused" page. You cannot score this application.
2
Confirm the recused application is no longer in your active scoring queue.
✓ Application removed from your queue. Gomolemo (admin) will see it flagged for reassignment.
Step 4 — Committee recommendation
1
Go to the Committee section in the reviewer portal. Find Vanessa's application.
✓ Committee view shows the application with scores and a recommendation input.
2
Submit a committee recommendation (e.g. "Recommend for award — strong academic record").
✓ Recommendation saved and visible on the application detail view.
Step S1 — Switch to sponsor portal and review the dashboard
Run this after completing all reviewer steps above. If the system supports multiple roles per user, use the role switcher or navigate to the sponsor portal URL directly. If your account only supports one active role, ask Tshidi to set up a second account or configure a role-switch before Day 1.
1
Navigate to the sponsor portal (via role switcher, direct URL, or second account). You should land on the sponsor dashboard.
✓ Dashboard shows programmes you are linked to with application counts and status summaries.
2
Confirm "JTG UAT Bursary 2025" appears with at least 2 applications listed.
✓ Programme visible with correct application counts.
Step S2 — Review applications and awards as sponsor
1
Click into an application. Confirm you can see submitted form responses and document status. Confirm you cannot see restricted data — learner financial information or reviewer scoring notes — outside the sponsor's permitted view.
✓ Appropriate data visible. No access to restricted sections.
⚠ If learner financial data or reviewer notes are visible to you as a sponsor, log immediately as a Blocker: "Sponsor can see restricted data — [specify exactly what is visible]."
2
Go to the Awards section. Confirm you can see awards issued under your programme with their statuses (offered, accepted, declined).
✓ Awards listed with correct statuses.
Step S3 — Access control check
1
While in the sponsor portal, manually type the admin portal URL in your address bar (e.g. /admin/dashboard). Also try /learner/applications and /reviewer/dashboard.
✓ All three deny access. You are redirected to the sponsor portal or shown a 403 error.
⚠ If you can access any portal other than sponsor, log immediately as a Blocker: "Role access control not enforced — specify which URL granted access."
BO
Bonolo — Verification officer & admin support
Two roles: runs document verification in an incognito window (Steps V1–V2) and provides technical admin support to Gomolemo throughout the session. The sponsor portal has moved to Tshidiso.
Complete Pre-session Steps R1–R3 first. You need two browser contexts on Day 2: your main window for admin support, and an incognito window for verification. Confirm your verification_officer credentials with the developer before Day 1 morning.
Run after Vanessa has uploaded all three documents (Vanessa Step 3). Open a separate incognito window for this — do not use your main browser session.
1
Open a new incognito browser window. Log in using your verification_officer credentials (separate from your main Bonolo account — provided by Tshidi or the developer).
✓ You land on the verification dashboard. Pending document submissions are listed.
2
Open Vanessa's application. Review and verify all three documents: ID Document, Academic Transcript, and Proof of Income. Click "Verify" on each after checking it opens and is readable.
✓ All three change to "Verified". Vanessa's application status automatically moves to "under_review" once all three are verified.
3
Test the rejection path: open Rorisang's application and reject one of her documents with a specific reason (e.g. "File is unreadable — please re-upload a clear scan").
✓ Rejection reason saved and visible. Rorisang's application stays in pending document state.
4
Confirm the verification queue reflects the correct state: Vanessa's row gone from the pending queue, Rorisang's row still present.
✓ Verification queue up to date after both actions.
Step V2 — Admin technical support for Gomolemo
This is an ongoing role throughout the session, not discrete steps. Sit alongside Gomolemo (or be on a call) while she works through her admin script and help investigate anything unexpected.
1
When Gomolemo encounters an error or unexpected behaviour, open browser developer tools (F12 or Ctrl+Shift+I). Check the Console tab for red error messages and the Network tab for failed requests shown in red. Copy the full error text into the bug log.
✓ Error details captured. This is the single most useful thing you can give the developer when something breaks.
2
After Gomolemo saves anything important (a programme, form, rubric, or contract template), verify it persists: ask her to refresh the page, then navigate away and back, then log out and back in.
✓ Data intact after all three checks. If data disappears at any point, log as a Blocker with the exact field and form name.
3
After Gomolemo creates award offers and Vanessa accepts, cross-check: confirm the contract appears correctly in both the admin contracts view and Vanessa's My Contracts view with the same data.
✓ Data consistent across both views. Any discrepancy is a Blocker.
4
If a feature described in the test script does not appear in the UI, check whether it is under a different menu or requires a prior configuration step before logging it as a bug. Note everywhere you looked.
✓ Either the feature is found (note the correct location) or confirmed missing (log as Functional Gap with navigation trail).
Each tester ticks off features as they confirm them working during the session. The progress summary updates automatically. If a feature could not be tested, mark it "N/A" and log the reason in the Bug Log.
Feature
Tested by
Result
Create a new programme with deadline and eligibility rules
Gomolemo
Form builder — add, edit, and publish form fields
Gomolemo
Form preview renders correctly before publishing
Gomolemo
Scoring rubric saved with weighted criteria summing to 100%
Gomolemo
Auto-assignment rule fires reviewer on status change
Gomolemo
Document verification — verify a document
Tshidi
Document verification — reject a document with reason
Tshidi
Application moves to under_review automatically after all docs verified
Tshidi
Bulk shortlist fires StatusChanged email to each learner (both emails arrive)
Gomolemo
Award created with offer letter generated as downloadable PDF
Gomolemo
AwardOffered email fires to learner
Gomolemo
Waitlist panel — add learner and confirm position 1
Gomolemo
Waitlist auto-promotion triggers and WaitlistPromoted email fires
Gomolemo
COI conflict: admin successfully reassigns recused reviewer
Gomolemo
Contract template saved with merge fields, preview works
Gomolemo
Deadline reminder sends correct emails, no duplicates on re-run
Gomolemo
DSR access request acknowledged, data export JSON downloaded with real data
Gomolemo
DSR erasure: account anonymised, erasure report written to storage
Gomolemo
Audit log shows all UAT actions with correct user and timestamp
Tshidi
User management: toggle active/inactive and password reset work
Tshidi
Self-registration creates account without immediate portal access
Tshidi
Email verification link sent on registration; activates account when clicked
Tshidi
Role assignment via Admin → Users grants correct portal access per role
Tshidi
Conditional logic on form field: dependent field shows/hides based on selection
Gomolemo
Document checklist per programme — required document types configured and enforced on upload
Gomolemo
Manual reviewer assignment (no auto-rule) works and fires reviewer alert
Gomolemo
Notifications configurable per programme — event-level toggles save correctly
Gomolemo
Bulk status movement: multiple applications transitioned in one action
Gomolemo
POPIA retention policy framework visible and configurable in admin settings
Gomolemo
Contract repository searchable by applicant name
Tshidi
Contract version history shows generated → signed with timestamps
Tshidi
Universal programme mode: visible to all learners regardless of eligibility filter
Gomolemo
Feature
Result
Self-registration with email and password succeeds
Learner profile — all fields save and display correctly
POPIA consent captured on profile page
Eligible programme visible in the programme listing
Save application as draft and successfully resume it
Submit application and receive ApplicationSubmitted email
Upload ID document and transcript — both appear as pending
Application status tracker shows correct timeline of events
In-app notifications appear and can be marked as read
Award offer visible with correct amount and expiry date
Offer letter PDF downloads with real merged data (no placeholder text)
Accept award — status updates, ContractReady email fires
Contract displays with correctly merged content (real name, amount)
Sign contract — timestamp and IP address recorded
Download signed contract PDF successfully
Submit data access (DSR) request with reference number returned
DSR status update notification received when admin acknowledges
Email verification email received; link activates account; login works post-verification
All three profile sections save: personal (ID, address), academic (institution, course), and financial (income, dependants)
Financial document (Proof of Income) uploads and appears in programme's required document checklist
Conditional logic form field: Supervisor name field shows when Postgraduate selected, hidden otherwise
Award decline path: click Decline on Award 2, status updates to 'declined', cannot be reversed
Signed contract in My Contracts shows timestamp and version history (generated → signed)
Feature
Result
Registration completes successfully
Ineligible programme correctly hidden or application correctly blocked
Document upload succeeds
Waitlist placement visible with position number shown
WaitlistPromoted email received after promotion is triggered
Erasure request submitted with reference number
Account inaccessible (login fails) after erasure is executed
Email verification email received; link activates account
Universal programme visible in listing; restricted programme correctly hidden
Award offer received after waitlist promotion
Decline promoted award — status updates to 'declined', cannot be reversed
Feature
Result
Reviewer dashboard loads with assigned applications visible
COI declaration banner visible on dashboard
No-conflict declaration allows access to scoring screen
Rubric scoring inputs work and weighted total is calculated correctly
Scores locked after submission — editing not possible
Conflict declaration recuses reviewer from the application
Recused application removed from active scoring queue
Committee recommendation saved and visible on application
Email verification email received; link activates account; reviewer portal accessible after role assignment
Sponsor dashboard shows linked programme with application counts
Application detail visible as sponsor — no restricted data (financial info, reviewer notes) visible
Awards section shows issued awards with correct statuses
Sponsor cannot access admin, learner, or reviewer portal pages
Bonolo — Verification officer & admin support
Feature
Result
Email verification email received; link activates account; portals accessible after role assignment
Verification dashboard loads with pending document submissions listed
Verify document — status updates to "Verified", no errors
Reject document with specific reason — text saved and visible to learner
All three documents verified → application automatically moves to "under_review"
Verification queue updates correctly after actions (verified items removed from pending)
Browser console checked during Gomolemo admin session — no unhandled red errors on key save actions
Data persistence confirmed: saved admin data remains after page refresh, navigate away, and re-login
Contract data consistent between admin contracts view and Vanessa's My Contracts view
Owned by Rorisang. Every issue found must be logged here before end of each testing day. The log will be triaged on Day 4 into blockers (fix before go-live), functional gaps (negotiate), and polish (defer).
Total bugs
0
Blockers
0
Functional gaps
0
Polish
0
#
Day
Tester
Portal
Step ref
What happened
Expected behaviour
Severity
Screenshot
1
Severity definitions
🔴 BlockerWrong data saved; data loss; notification not firing; security issue (e.g. learner sees another learner's data); document upload fails silently; erasure does not anonymise; contract not generated on acceptance. Must be fixed before go-live.
🟡 Functional gapFeature works but behaves differently than staff expected. Usually a workflow or UX issue rather than a code error. Examples: a filter behaves unexpectedly, a confirmation step is missing, a label is confusing. Negotiate against the timeline.
⚪ PolishCosmetic: spelling errors, font sizes, colour mismatches, spacing, wording that does not cause incorrect behaviour. Defer to a post-launch iteration — this list will never end otherwise.
The session runs over 5 business days. Day 1 is admin-only setup. Learner and reviewer testing runs in parallel on Days 2 and 3. Day 4 is for completing any outstanding items and the group triage meeting. Day 5 is blocker re-testing and written sign-off.
Sessions are 1–3 hours each — not full days. Confirm exact times with Tshidi or Gomolemo based on everyone's availability before the week begins.
Day 1
Environment setup, self-registration, role assignment & programme configuration
Monday
Morning
Developer confirms: migrations clean, storage linked, Mailtrap connected, seeders run, all accounts created and distributed.
Developer only — completed before 9am
Morning (~45 min)
Gomolemo, Vanessa, Rorisang, Tshidiso, and Bonolo self-register at the UAT URL, verify their email addresses, and confirm accounts are active. Pre-session Steps R1–R3.
All testers except Tshidi
Late morning (~30 min)
Tshidi runs Admin Step 0: assigns roles to all five registered accounts. Each person logs out and back in and confirms correct portal access in the group chat.
Tshidi (others on standby)
Afternoon (~2.5h)
Gomolemo runs Admin Script Steps 1 (programme, form builder, rubric, auto-assignment, contract template). Tshidi verifies super_admin access and audit log.
Tshidi + Gomolemo (afternoon only, after role assignment)
End-of-day checkpoint: All six people have working portal access. Both programmes (restricted and universal) are configured and confirmed. Do not proceed to Day 2 until all team members confirm access in the group chat.
Day 2
Registration, application, document verification, and reviewer assignment
Tuesday
Morning (~1.5h)
Vanessa and Rorisang run their registration and application scripts. Rorisang tests the eligibility block. Vanessa submits and uploads documents.
Vanessa + Rorisang
Midday
Tshidi (incognito as verification_officer) verifies Vanessa's documents and rejects one of Rorisang's. Gomolemo moves application to approved_for_review and confirms auto-assignment fires.
Tshidi + Gomolemo
Afternoon (~1h)
Tshidiso logs in and runs the reviewer script: COI clean path, scoring, locked scores, conflict path, committee recommendation.
Tshidiso
Rorisang logs all Day 2 bugs before 5pm.
Day 3
Shortlisting, awards, waitlist, contract signing, and sponsor portal
Wednesday
Morning (~1.5h)
Gomolemo runs shortlisting, bulk shortlist, creates award for Vanessa, places Rorisang on waitlist. Confirms both StatusChanged emails and AwardOffered email in Mailtrap.
Gomolemo
Midday (~1h)
Vanessa accepts award, downloads and checks offer letter PDF, signs contract, downloads signed contract.
If blockers are already piling up, flag this to Tshidi today — Wednesday is the last realistic point to add a buffer day before the Friday sign-off deadline.
Day 4
POPIA requests, deadline reminders, audit log, and bug triage
Thursday
Morning (~1h)
Vanessa and Rorisang submit DSR requests. Gomolemo acknowledges and processes them. Rorisang's erasure executed on UAT database. Deadline reminder command tested with developer.
Gomolemo + Vanessa + Rorisang + Developer
Midday (~30 min)
Tshidi reviews the full audit log and confirms all UAT actions appear with correct users and timestamps. Runs user management tests.
Tshidi
Afternoon (~1.5h)
Bug triage meeting. Tshidi, Gomolemo, and developer review every logged item together. Each item confirmed as Blocker, Functional Gap, or Polish. Blockers assigned to developer for Day 5 fix.
Tshidi + Gomolemo + Developer
All Feature Matrix checklists must be fully completed by end of Day 4. Outstanding unchecked items must be discussed in the triage meeting.
Day 5
Blocker re-testing and formal sign-off
Friday
Morning
Developer deploys fixes for all Day 4 blockers. Gomolemo and/or Tshidi re-run only the affected steps to confirm fixes — no need to re-run the entire script.
Developer + Gomolemo + Tshidi
Afternoon
Formal sign-off. Tshidi or Gomolemo reviews the final bug log (blockers resolved, gaps documented, polish deferred) and sends written sign-off. System is cleared for go-live.
Tshidi or Gomolemo
If the Day 4 triage surfaces more than 3 blockers, alert the developer on Wednesday afternoon so a timeline adjustment can be made before it becomes a last-minute crisis.
This section is for the developer or system administrator setting up the UAT environment. Non-technical stakeholders do not need to read this — but it is included so that all prerequisites are visible to everyone and no setup step can be quietly skipped.
Prerequisites — all must be green before Day 1 afternoon
Prerequisite
How to verify
All 6 new migrations run clean against a fresh database in the correct order
php artisan migrate --fresh
Scheduler cron is active on the UAT server
* * * * * php artisan schedule:run
Mail is routed to Mailtrap — not real addresses
Send a test email and confirm it appears in Mailtrap
Storage symlink created
php artisan storage:link
File permissions on storage/app/public allow web writes
Upload a test PDF and confirm URL is accessible in browser
Database seeded with realistic test data (learner profiles, sponsor link, contract template)
php artisan db:seed
Queue driver decision made and confirmed working: either QUEUE_CONNECTION=sync in .env, or queue:work running persistently
Submit test application and confirm email arrives immediately in Mailtrap
UAT environment is NOT the production database
Confirm DB_DATABASE in .env points to the UAT schema
All 6 tester accounts pre-created with correct roles assigned
Log in as each account and confirm correct portal redirect
Rorisang's learner profile institution set outside eligibility criteria for the UAT programme
Log in as Rorisang and confirm the programme is not visible or apply is blocked
Tshidi can see all self-registered accounts in Admin → Users and assign roles after Day 1 morning registration
Tshidi confirms all five names appear in users list after they register
Bonolo has a verification_officer account or the developer has confirmed how she accesses the verification dashboard (separate account or role assignment)
Bonolo logs in with verification credentials in incognito and lands on verification dashboard before Day 2
Tshidiso's account supports both reviewer and sponsor roles, or a second sponsor account is set up for him
Tshidiso confirms he can access both portals before Day 2 testing begins
Commands reference
Command
When to run during UAT
php artisan migrate --fresh --seed
Before Day 1. Resets the UAT database to a clean seeded state.
php artisan storage:link
Once, before Day 1. Required for document and offer letter file serving.
php artisan queue:work
Run persistently if using database queue driver. Alternatively set QUEUE_CONNECTION=sync.
php artisan awards:process-expired
Day 3 — manually expires a pending award to trigger waitlist promotion.
php artisan reminders:deadline --dry-run
Day 4 — preview which applications would receive reminders without sending.
php artisan reminders:deadline
Day 4 — send actual reminders. Run twice to confirm no duplicate sends.
Known behaviours that are not bugs
Email delivery timing. If QUEUE_CONNECTION=sync, emails arrive in Mailtrap instantly. If using the database queue driver without queue:work running, emails queue but are not delivered. Decide before Day 1 and brief testers so they know what to expect.
Eligibility filter hides programmes entirely. Ineligible learners (Rorisang) will not see the restricted programme in the listing at all — the system does not show it with a "you are ineligible" message, it simply does not appear. This is by design. Brief Rorisang before the session so she knows what to expect and does not incorrectly log an absence as a bug.
Session timeout on long forms. Learners who fill in a long application and step away may return to a logged-out session. The system will prompt them to log in again. The draft should be preserved. This is expected behaviour — testers will likely report it anyway, so flag it in the known-issues briefing before the session starts.
POPIA erasure is irreversible. DataAnonymisation::anonymise() soft-deletes the user account and permanently wipes all PII fields. There is no undo. Only execute the erasure step on the UAT database. Confirm DB_DATABASE in .env is not pointing at production before Rorisang's erasure step on Day 4.