iSpeaker Live iSpeaker Live / Docs
Quality

Test Cases

Every test case a QA tester needs to verify the iSpeaker Live MVP — grouped by module, tagged by type and priority.

On this page

About these test cases

This is the master catalog of test cases for iSpeaker Live MVP 1.0 during the current Testing Phase. Cases are grouped by module and tagged with a type, priority, and module label so testers can build smoke, regression, and exploratory runs from one source of truth.

ℹ️
Test cases here pair with the higher-level test scenarios and the UI/UX QA checklist on the UI/UX guidelines page. Bugs discovered while running these cases should be logged using the format on the bug reporting page.

How to use this catalog

  1. Pick a module section that matches the build under test.
  2. For each case: set up the Preconditions, follow the Steps in order, then verify each Expected result independently.
  3. Mark the case Pass only when every expected result is observed. Any deviation is a Fail and must be logged as a bug with the case ID referenced.
  4. For new bugs, attach screenshots / screen recordings and the device + build number.
  5. Use Test data values when listed. If no values are listed, use realistic data and document what you used in the run notes.
⚠️
Run destructive tests (delete account, refund, withdrawal approval) only against the staging environment. Never against production unless explicitly authorized.

Legend & conventions

Priority

Critical Blocks release if it fails. High Important business or security path. Medium Significant user-facing behavior. Low Cosmetic / minor convenience.

Type

Functional Integration UI/UX Security Performance Accessibility i18n Negative API

ID prefixes

  • TC-AUTH-* auth & roles  ·  TC-PRF-* profile  ·  TC-FEED-* social feed
  • TC-FLW-* follow  ·  TC-CRS-* courses  ·  TC-BK-* books
  • TC-LR-* live rooms  ·  TC-CON-* consultations  ·  TC-PAY-* wallet/payments
  • TC-CART-* cart  ·  TC-CHAT-* chat  ·  TC-GIFT-* gifts  ·  TC-NTF-* notifications
  • TC-ADM-* admin  ·  TC-I18N-* localization  ·  TC-A11Y-* accessibility
  • TC-PERF-* performance  ·  TC-SEC-* security  ·  TC-SET-* / TC-SRCH-* / TC-DASH-* misc.

Authentication & Roles

Registration, login, password recovery, role switching, and session integrity.

TC-AUTH-001 Register new student with valid Saudi phone Functional Priority: Critical Auth
Preconditions
  1. App or web is open at the registration screen.
  2. Email tester01@example.com is not yet registered.
  3. Phone +966500000001 is not yet registered.
Test data
  • Name: Nora Test
  • Email: tester01@example.com
  • Phone: +966500000001
  • Password: Test@1234
  • Language: Arabic
Steps
  1. Open the registration page.
  2. Fill in name, email, phone, and password fields with the test data above.
  3. Select Student as account type (or accept default).
  4. Accept the terms-of-service checkbox.
  5. Tap/click the Register button.
Expected results
  1. Account is created successfully.
  2. A welcome notification is shown in Arabic (default language).
  3. User is redirected to the home feed.
  4. The users table contains a new row with is_verified = 0.
  5. A wallets row with balance 0.00 is auto-created.
  6. A user_profiles row with language = ar is auto-created.
Postconditions
  • Test account exists and is logged in.
  • Bearer token is stored on the client.
TC-AUTH-002 Register with already-used email Negative Priority: High Auth
Preconditions
  1. An account with tester01@example.com already exists.
Steps
  1. Open the registration page.
  2. Enter the same email tester01@example.com.
  3. Fill in the rest of the fields with valid data.
  4. Submit the form.
Expected results
  1. Submission is blocked with a clear validation error.
  2. Error message reads "The email has already been taken." in English, or its Arabic equivalent.
  3. No new row is created in the users table.
  4. HTTP response is 422 Unprocessable Entity with the field name email.
TC-AUTH-003 Login with valid credentials returns Sanctum token Functional Priority: Critical Auth
Preconditions
  1. Valid verified account exists.
Test data
  • email: tester01@example.com
  • password: Test@1234
Steps
  1. Open the login screen.
  2. Enter the email and password.
  3. Tap Login.
Expected results
  1. Response 200 OK is returned.
  2. JSON contains token and user objects.
  3. Token is persisted to secure storage (mobile) or HTTP-only storage (web).
  4. User lands on the feed with their name visible in the topbar.
  5. A new row appears in personal_access_tokens.
TC-AUTH-004 Login with wrong password Negative Priority: High Auth
Steps
  1. Enter a valid email but wrong password.
  2. Submit the form.
Expected results
  1. Login is rejected.
  2. A generic error like "Invalid credentials" is shown (no hint about which field is wrong).
  3. No token is issued.
  4. After 5 consecutive failures the account is temporarily rate-limited.
Notes
Verify that the error does not leak whether the email exists — this is a security requirement.
TC-AUTH-005 Forgot password — request reset link Functional Priority: High Auth
Steps
  1. On the login screen, tap Forgot password?.
  2. Enter a registered email address.
  3. Submit the request.
Expected results
  1. A success toast is shown.
  2. A row is created in password_reset_tokens.
  3. An email is sent to the address with a reset link valid for 60 minutes.
  4. The reset link works only once.
TC-AUTH-006 Logout invalidates the current token Security Priority: High Auth
Preconditions
  1. User is logged in with a valid Sanctum token.
Steps
  1. Open the settings menu.
  2. Tap Logout.
  3. After confirmation, try to call any protected endpoint with the old token (using a test client).
Expected results
  1. The user is returned to the login screen.
  2. The local token is cleared.
  3. The corresponding row in personal_access_tokens is deleted.
  4. Reusing the old token returns 401 Unauthorized.
TC-AUTH-007 Switch role from Student to Speaker Functional Priority: High Auth
Preconditions
  1. User is a Student with no active Speaker role.
Steps
  1. Open the profile menu.
  2. Tap Become a Speaker.
  3. Fill the speaker profile form (headline, expertises, bio).
  4. Submit.
Expected results
  1. A new role assignment is created in model_has_roles.
  2. Speaker dashboard becomes accessible from the profile menu.
  3. The user still has the Student role and can still consume content.
  4. Speaker-only nav items (My Courses, Consultations, Earnings) become visible.
Notes
Admin role is granted only via Filament and cannot be self-assigned.
TC-AUTH-008 Token rotation: stolen token cannot survive password change Security Priority: Critical Auth
Steps
  1. Login on Device A and copy the Sanctum token.
  2. Login on Device B and change the password.
  3. On Device A, attempt to call /api/profile with the old token.
Expected results
  1. Old tokens are invalidated upon password change.
  2. Device A receives 401 and is redirected to login.

Profile

Editing profile data, avatar uploads, speaker fields, and privacy.

TC-PRF-001 Update profile fields and view persistence Functional Priority: High Profile
Preconditions
  1. User is logged in.
Steps
  1. Open Edit profile.
  2. Update bio, headline, location, and timezone.
  3. Toggle Show email off.
  4. Save changes.
  5. Refresh the profile page.
Expected results
  1. Changes are saved without errors.
  2. On refresh, all new values are present.
  3. user_profiles.show_email is 0.
  4. Email is no longer visible on the public profile page.
TC-PRF-002 Upload avatar — accept image, reject non-image Functional Priority: High Profile
Steps
  1. Open Edit profile.
  2. Tap on avatar area and select a JPG ≤ 2 MB.
  3. Save.
  4. Try again with a PDF file.
Expected results
  1. JPG upload succeeds; new avatar is shown across the app within 5 seconds.
  2. PDF upload is rejected with a clear validation message ("Image must be JPG/PNG/WebP, max 2MB").
  3. No partial file ends up in storage.
TC-PRF-003 Add speaker experience and certificate entries Functional Priority: Medium Profile
Preconditions
  1. User has Speaker role.
Steps
  1. Open the Speaker profile editor.
  2. Add one experience entry (title, company, start date, "I currently work here").
  3. Add one certificate entry (title, issuer, issue date, credential URL).
  4. Save.
Expected results
  1. Both entries appear on the public profile in chronological order.
  2. user_experiences and user_certificates rows exist for the user.
  3. Reordering entries (drag/drop) updates the order column.
TC-PRF-004 Private profile hides content from non-followers Functional Priority: High Profile
Steps
  1. User A toggles "Private profile" ON.
  2. User B (not following A) opens A's profile.
Expected results
  1. B sees A's basic info (name, avatar, headline) only.
  2. Posts, followers, and following lists are hidden behind a "Follow to see content" panel.
  3. B can send a follow request.

Social Feed & Reactions

Posts, comments, reactions, sharing, and moderation.

TC-FEED-001 Create a text post and see it on the feed Functional Priority: Critical Feed
Steps
  1. Open the home feed.
  2. Tap the Create post composer.
  3. Type "Hello iSpeaker Live!".
  4. Tap Publish.
Expected results
  1. Post appears at the top of the feed instantly (optimistic UI).
  2. On refresh, the post persists.
  3. A posts row with post_type = "text" is created.
  4. Other followers receive the new post in their feed.
TC-FEED-002 Create a post with an image attachment Functional Priority: High Feed
Steps
  1. Open the composer.
  2. Attach a single JPG ≤ 5 MB.
  3. Add caption "Test image post".
  4. Publish.
Expected results
  1. posts.post_type = "image".
  2. media_urls contains the uploaded image URL.
  3. Image renders with the correct aspect ratio in the feed.
  4. Tapping the image opens a fullscreen viewer.
TC-FEED-003 React, change reaction, then remove reaction on a post Functional Priority: High Feed
Steps
  1. Open any post.
  2. Long-press the reaction button and pick "Love".
  3. Tap again and switch to "Haha".
  4. Tap again to remove the reaction.
Expected results
  1. Reaction count updates correctly each step.
  2. The reactions unique index (user_id, reactable_id, reactable_type) prevents duplicates.
  3. Removing leaves no reaction row for the user on the post.
TC-FEED-004 Comment on a post and receive a notification Integration Priority: High Feed
Preconditions
  1. Post belongs to user A. User B will comment.
Steps
  1. User B opens user A's post.
  2. Adds a comment "Nice post!".
  3. User A opens notifications.
Expected results
  1. comments table has a new row.
  2. posts.comments_count is incremented.
  3. A notifications row for user A is created with type comment.
  4. User A receives a push notification (FCM) and an in-app real-time notification (Reverb).
TC-FEED-005 Report a post for harassment Functional Priority: Medium Feed
Steps
  1. Open any post.
  2. Tap the menu and choose Report.
  3. Pick "Harassment" and add a short description.
  4. Submit.
Expected results
  1. post_reports row is inserted with status pending.
  2. The reporter sees a confirmation toast.
  3. The same user reporting the same post again replaces or merges the report (no duplicates).
  4. The report appears in the Filament admin panel for review.
TC-FEED-006 Share a post with a comment Functional Priority: Medium Feed
Steps
  1. Open a post and tap Share.
  2. Choose Share to feed.
  3. Add comment "Worth a read".
  4. Submit.
Expected results
  1. post_shares row is created.
  2. posts.shares_count is incremented.
  3. The shared item shows on the sharer's profile feed with the comment on top.
TC-FEED-007 Pagination: feed loads next 20 items on scroll Performance Priority: Medium Feed
Preconditions
  1. Feed has at least 80 posts available.
Steps
  1. Open the feed.
  2. Scroll to the bottom three times.
Expected results
  1. Each scroll triggers a paginated request returning 20 items.
  2. No duplicate posts are loaded.
  3. p95 response time ≤ 600 ms on staging.

Follow System

Direct follow, follow requests for private accounts, unfollow.

TC-FLW-001 Follow a public profile directly Functional Priority: High Follow
Steps
  1. User B opens user A's public profile.
  2. Taps Follow.
Expected results
  1. followers row is created (B follows A).
  2. user_profiles.followers_count for A is incremented.
  3. user_profiles.following_count for B is incremented.
  4. A is notified that B started following them.
TC-FLW-002 Request to follow a private profile, then accept Functional Priority: High Follow
Preconditions
  1. User A has private profile.
Steps
  1. User B taps Follow on A's profile.
  2. A opens follow requests and accepts B.
Expected results
  1. After the tap: a row in follow_requests with status = pending.
  2. A receives a notification "B requested to follow you".
  3. On accept: the row's status becomes accepted, a followers row is created, and counters update.
  4. B receives a notification "A accepted your follow request".
TC-FLW-003 Unfollow decrements counters correctly Functional Priority: Medium Follow
Steps
  1. B is following A.
  2. B taps Unfollow.
Expected results
  1. The followers row is deleted.
  2. Both counters decrement by 1.
  3. No notification is sent on unfollow.

Courses & Lessons

Authoring, enrollment, playback, progress, and certification.

TC-CRS-001 Speaker publishes a paid course end-to-end Functional Priority: Critical Courses
Preconditions
  1. User has Speaker role.
Steps
  1. Open Create course.
  2. Fill title, subtitle, description, language=AR, level=Beginner, price=99.00.
  3. Add one section ("Module 1").
  4. Add one lesson (title, upload an MP4, set order=1).
  5. Add a course thumbnail.
  6. Save as draft.
  7. Use the preview, then click Publish.
Expected results
  1. courses.status moves from draft to published.
  2. Course appears in the public courses listing.
  3. total_lessons and total_duration_minutes reflect the added lesson.
TC-CRS-002 Cannot publish a course with zero lessons Negative Priority: High Courses
Steps
  1. Create a draft course without any lessons.
  2. Click Publish.
Expected results
  1. Publish is blocked.
  2. A clear error explains "Course must contain at least one section with one lesson."
  3. status remains draft.
TC-CRS-003 Student enrolls in a free course Functional Priority: Critical Courses
Preconditions
  1. A published free course exists.
Steps
  1. Open the course detail page.
  2. Tap Enroll for free.
Expected results
  1. Enrollment is immediate; the user lands on the course player.
  2. enrollments row with price_paid = 0 and status = active.
  3. courses.students_count is incremented.
  4. No transactions row is created.
TC-CRS-004 Student purchases a paid course via wallet Integration Priority: Critical Courses
Preconditions
  1. Course price is 99 SAR. Student wallet balance is ≥ 99 SAR.
Steps
  1. Open the paid course.
  2. Tap Buy now and choose Pay from wallet.
  3. Confirm.
Expected results
  1. A transactions debit row of 99 is created for the student.
  2. A transactions credit row of (99 minus platform fee) is created for the speaker (after release period if applicable).
  3. Student wallet balance decreases by 99; speaker pending_balance increases.
  4. enrollments row is created.
  5. invoices row is created with a unique invoice number and a downloadable PDF URL.
TC-CRS-005 Lesson progress is tracked and resumes Functional Priority: High Courses
Preconditions
  1. User is enrolled in a course with a 10-minute video lesson.
Steps
  1. Open the lesson and play until 3:30.
  2. Close the app.
  3. Re-open the course and re-open the same lesson.
Expected results
  1. lesson_progress.watched_duration_seconds ≈ 210.
  2. Video resumes from the saved timestamp ± 2 seconds.
  3. Lesson is marked complete once the user reaches ≥ 95% of duration.
TC-CRS-006 Certificate is issued upon 100% completion Functional Priority: High Courses
Preconditions
  1. User is 99% through a course.
Steps
  1. Complete the final lesson.
Expected results
  1. enrollments.status becomes completed.
  2. A certificates row is created with a unique certificate_number and verification URL.
  3. User receives a notification and an email.
  4. Visiting the verification URL displays the certificate page.
TC-CRS-007 Add and retrieve lesson notes Functional Priority: Low Courses
Steps
  1. Inside a video lesson at 1:24, open the Notes tab.
  2. Add a note "Important formula".
  3. Save.
  4. Close and re-open the lesson.
Expected results
  1. lesson_notes row stored with timestamp_seconds ≈ 84.
  2. On reopen, the note is listed in the Notes tab.

Books & Reader

Publishing, previews, annotations, progress tracking, DRM-like protections.

TC-BK-001 Speaker uploads a PDF book and publishes it Functional Priority: High Books
Preconditions
  1. User has Speaker role.
Steps
  1. Open Publish a book.
  2. Fill title, author, description, price, category.
  3. Upload a PDF (≤ 50 MB).
  4. Set "preview pages" to 5.
  5. Disable printing, disable copying.
  6. Publish.
Expected results
  1. books.status becomes published.
  2. page_count is auto-detected from the PDF.
  3. Book appears in the books listing.
  4. On the public reader page, only the first 5 pages are accessible before purchase.
TC-BK-002 Reader uses preview pages and is prompted to buy Functional Priority: High Books
Steps
  1. Open a paid book detail page as a guest student.
  2. Tap Read preview.
  3. Scroll past page 5.
Expected results
  1. Pages 1-5 render correctly.
  2. Page 6 onwards is blurred with a "Buy to continue reading" overlay.
TC-BK-003 Annotations save and persist (highlight, note, bookmark) Functional Priority: Medium Books
Preconditions
  1. User has purchased the book.
Steps
  1. Open page 12, highlight a sentence and pick yellow.
  2. Add a note on page 14.
  3. Bookmark page 18.
  4. Close the reader.
  5. Re-open the book.
Expected results
  1. Three book_annotations rows exist with correct annotation_type.
  2. Annotations render on re-open.
  3. Bookmarks list shows page 18.
TC-BK-004 Reading progress restores correctly Functional Priority: Medium Books
Steps
  1. Open the book and read to page 23.
  2. Close the app.
  3. Re-open the book from the library.
Expected results
  1. book_reading_progress.current_page is 23.
  2. Reader opens at page 23.
  3. reading_time_minutes increases on each session.
TC-BK-005 Print and copy actions are blocked when disabled Security Priority: High Books
Preconditions
  1. Book has allow_printing = 0 and allow_copying = 0.
Steps
  1. On web, try CTRL/CMD+P.
  2. Try selecting text and copying.
Expected results
  1. Print dialog is suppressed or shows a "Printing disabled" page.
  2. Text selection is disabled; copy returns empty clipboard.
Notes
Note: client-side protections only — combine with watermarks for legal deterrence.

Live Rooms

Scheduling, registration, Jitsi sessions, in-room chat, lifecycle.

TC-LR-001 Speaker schedules a free room for next week Functional Priority: High Live Rooms
Preconditions
  1. User has Speaker role.
Steps
  1. Open Create live room.
  2. Set title, description, category.
  3. Pick start date = next Monday, end date = next Monday.
  4. Pick start time = 19:00, end time = 20:00.
  5. Duration type = day, access type = free.
  6. Save.
Expected results
  1. live_rooms row created with status = scheduled.
  2. Room appears on the speaker dashboard and on the public upcoming rooms list.
  3. Joining is blocked before 5 minutes before start_time.
TC-LR-002 Student registers for a paid room Integration Priority: Critical Live Rooms
Preconditions
  1. Paid room with price 50 SAR. Student wallet has ≥ 50 SAR.
Steps
  1. Open the room detail page.
  2. Tap Register and pay from wallet.
Expected results
  1. live_room_registrations row with status = registered and price_paid = 50.
  2. Transaction is recorded.
  3. participants_count increments.
TC-LR-003 Speaker starts the room and Jitsi room ID is generated Integration Priority: Critical Live Rooms
Preconditions
  1. Scheduled room exists; speaker is the owner.
Steps
  1. Within 5 minutes of start_time, speaker opens the room and taps Start session.
Expected results
  1. current_jitsi_room_id is populated.
  2. status becomes active.
  3. Jitsi iframe (web) or native module (mobile) connects to the new room ID.
  4. Registered students see a "Join now" call-to-action on their dashboards.
TC-LR-004 In-room chat messages broadcast via Reverb Integration Priority: High Live Rooms
Preconditions
  1. Room is active with at least 2 participants.
Steps
  1. User A types "hello" in the room chat and presses send.
  2. Observe user B's screen.
Expected results
  1. live_room_messages row created.
  2. User B sees "hello" within 1 second via the Reverb channel.
  3. Pinning a message updates is_pinned and re-broadcasts.
TC-LR-005 Ending a session moves room to completed Functional Priority: High Live Rooms
Steps
  1. Speaker taps End session.
Expected results
  1. status becomes completed.
  2. Participants are disconnected gracefully.
  3. total_sessions increments.

Consultations

Availability, bookings, payments, completion, and reviews.

TC-CON-001 Speaker defines weekly availability Functional Priority: High Consultations
Preconditions
  1. User has Speaker role.
Steps
  1. Open Consultation availability.
  2. Add a Monday slot 17:00-19:00, 60-minute sessions, 100 SAR per session.
  3. Save.
Expected results
  1. consultation_availabilities row exists.
  2. Student booking calendar shows two slots on Monday: 17:00 and 18:00.
TC-CON-002 Student books a session and pays Integration Priority: Critical Consultations
Steps
  1. Open the speaker's profile and tap Book consultation.
  2. Pick the 17:00 slot on next Monday.
  3. Pay from wallet.
Expected results
  1. consultation_bookings row with status = scheduled.
  2. The slot is no longer offered to other students for that timestamp.
  3. A confirmation notification is sent to both parties.
TC-CON-003 No-show: speaker marks session and refund policy applies Functional Priority: Medium Consultations
Preconditions
  1. Booking is past its scheduled time and never started.
Steps
  1. Speaker opens the booking and marks it No-show (student).
Expected results
  1. status updates to no_show.
  2. Refund rule defined by admin is applied (full / partial / none).
  3. Both parties are notified.
TC-CON-004 Rating is submitted only by participants and only once Functional Priority: Medium Consultations
Steps
  1. Booking is in completed state.
  2. Student submits a 5-star review.
  3. Student tries to submit a second review.
Expected results
  1. First review is saved in consultation_ratings.
  2. Second attempt is blocked with "You have already reviewed this session".
  3. A user not in the booking cannot submit a review at all.

Wallet & Payments

Top-ups, purchases, withdrawals, refunds, VAT/invoicing.

TC-PAY-001 Top up wallet via PayPal (sandbox) Integration Priority: Critical Wallet
Preconditions
  1. PayPal sandbox is configured and accessible.
Steps
  1. Open Wallet and tap Top up.
  2. Choose 100 SAR.
  3. Complete payment in PayPal sandbox.
  4. Return to the app.
Expected results
  1. A pending transactions row is created when initiated.
  2. On webhook confirmation, the row's status moves to completed.
  3. wallets.balance increases by 100.
  4. Invoice is generated with 15% VAT line.
TC-PAY-002 Failed PayPal callback leaves the transaction pending and not credited Negative Priority: Critical Wallet
Steps
  1. Initiate a top-up.
  2. Cancel the PayPal flow before approval.
Expected results
  1. transactions.status remains pending (or moves to failed).
  2. Wallet balance is unchanged.
  3. Pending transaction expires after the configured TTL.
TC-PAY-003 Speaker requests a withdrawal Functional Priority: High Wallet
Preconditions
  1. Speaker wallet has settled balance ≥ minimum threshold.
Steps
  1. Open Wallet and tap Withdraw.
  2. Choose method, enter amount, submit.
Expected results
  1. A debit transactions row is created with status = pending.
  2. pending_balance increases; balance decreases.
  3. Admin sees the request in Filament and can approve/reject.
TC-PAY-004 Concurrent purchases do not overspend Security Priority: Critical Wallet
Preconditions
  1. Wallet balance = 100 SAR. Two pending items in cart, 60 SAR each.
Steps
  1. From two devices simultaneously, attempt to purchase each item via wallet.
Expected results
  1. Only one purchase succeeds; the other returns an "Insufficient funds" error.
  2. Final balance is ≥ 0 (never negative).
  3. Transaction rows reflect the correct outcome.
Notes
Verify Laravel uses a row lock / atomic update on wallets table during debit.
TC-PAY-005 VAT line is correct on invoices Functional Priority: High Wallet
Steps
  1. Make a 100 SAR purchase.
  2. Open the generated invoice.
Expected results
  1. Subtotal = 100, VAT = 15, Total = 115 (or per the configured rate).
  2. Invoice PDF renders the same numbers as the transaction record.

Cart & Marketplace

Cart contents, unique items, multi-item checkout.

TC-CART-001 Add a course to cart Functional Priority: High Cart
Steps
  1. Open any paid course.
  2. Tap Add to cart.
Expected results
  1. cart_items row with cartable_type = Course is created.
  2. Cart icon badge increases by 1.
  3. Adding the same item twice does not duplicate (unique index).
TC-CART-002 Checkout multiple items in one transaction Integration Priority: High Cart
Preconditions
  1. Cart has 1 course (50) and 1 book (30). Wallet has ≥ 80 + VAT.
Steps
  1. Open cart and tap Checkout.
  2. Pay from wallet.
Expected results
  1. Both items become enrollment / purchase rows.
  2. Cart is empty after success.
  3. Single invoice consolidates both items.

Chat & Messaging

1:1 conversations, media, replies, read receipts.

TC-CHAT-001 Open a conversation and send a text message Integration Priority: High Chat
Steps
  1. Open user B's profile and tap Message.
  2. Type "hello" and send.
Expected results
  1. A conversations row is created (or existing one is reused).
  2. A messages row is created.
  3. User B sees the message in real time via Reverb.
  4. Unread badge updates on B's side.
TC-CHAT-002 Send media (image), reply to a message Functional Priority: Medium Chat
Steps
  1. In an existing conversation, attach an image.
  2. Send.
  3. Long-press the sent message and choose Reply.
  4. Type a reply and send.
Expected results
  1. First message has type = image and a media_urls entry.
  2. Second message has reply_to_id set.
  3. Reply renders the quoted parent message.
TC-CHAT-003 Mark messages read updates last_read_at Functional Priority: Medium Chat
Steps
  1. B opens the conversation with A.
Expected results
  1. conversations.user_*_last_read_at updates for B.
  2. A sees double-tick read indicator.

Gifts

Sending paid gifts on posts and rooms; wallet effects.

TC-GIFT-001 Send a gift on a post Integration Priority: Medium Gifts
Preconditions
  1. Sender wallet has enough balance.
Steps
  1. Open a post.
  2. Tap the gift icon, pick a gift, set quantity = 2.
  3. Confirm.
Expected results
  1. gift_transactions row is created with quantity = 2.
  2. Sender wallet decreases by 2 × gift.price.
  3. Receiver wallet pending_balance increases by the platform-defined share.
  4. A gift animation plays on the post.

Notifications

In-app real-time and push (FCM) notifications and deep linking.

TC-NTF-001 Receive in-app notification in real time Integration Priority: High Notifications
Steps
  1. User A comments on user B's post.
  2. Observe user B's notification panel.
Expected results
  1. Bell icon shows a red dot within 1 second.
  2. Tapping the bell shows the notification at the top.
  3. A notifications row exists with the correct type and actor_id.
TC-NTF-002 Mark all notifications as read Functional Priority: Low Notifications
Steps
  1. Open the notifications panel.
  2. Tap Mark all as read.
Expected results
  1. All read_at columns for unread rows are set.
  2. Bell badge clears.
TC-NTF-003 Push notification opens the right deep-link Integration Priority: Medium Notifications
Preconditions
  1. FCM token is registered on the device.
Steps
  1. Trigger a push (e.g., new follower).
  2. Tap the notification when the app is in background.
Expected results
  1. App opens at the relevant screen (e.g., the new follower's profile).
  2. Deep link includes the correct entity ID.

Admin Panel

Filament admin authentication, moderation actions, settings.

TC-ADM-001 Admin logs in to Filament panel Functional Priority: High Admin
Preconditions
  1. Admin account exists in users with the admin role assigned.
Steps
  1. Visit /admin.
  2. Enter admin credentials.
Expected results
  1. Login succeeds; Filament dashboard renders.
  2. Non-admin users are redirected away from the panel.
TC-ADM-002 Admin reviews a reported post Functional Priority: High Admin
Steps
  1. Open Post reports.
  2. Open a pending report.
  3. Choose Resolve - hide post.
Expected results
  1. Report status becomes resolved.
  2. Post is soft-deleted or hidden depending on action.
  3. Reporter and post author both receive a notification.
TC-ADM-003 Admin updates platform settings Functional Priority: Medium Admin
Steps
  1. Open Settings.
  2. Change VAT rate from 15 to 16.
  3. Save.
Expected results
  1. settings row is updated.
  2. New invoices use the new rate.
  3. Existing invoices remain unchanged.

Localization (Arabic / English)

Language switching, RTL flips, locale-aware formatting, translation coverage.

TC-I18N-001 Switch UI language from Arabic to English i18n Priority: High Localization
Steps
  1. Open settings and switch language to English.
Expected results
  1. All labels switch to English on the next render.
  2. user_profiles.language updates to en.
  3. Layout direction switches from RTL to LTR.
  4. Date/time formats follow the new locale.
TC-I18N-002 RTL layout flips icons, padding, and arrows UI/UX Priority: High Localization
Steps
  1. In Arabic mode, navigate the home, profile, and chat screens.
  2. Inspect arrows, badges, and progress bars.
Expected results
  1. Back arrows point right.
  2. Drawer slides from the right.
  3. Progress bars fill from right to left.
  4. No clipped text or misplaced icons.
TC-I18N-003 Numbers and currency render correctly per locale i18n Priority: Medium Localization
Steps
  1. Compare 1,234.50 SAR display in EN vs AR.
Expected results
  1. Arabic uses Arabic-Indic digits if configured, otherwise Western digits.
  2. Currency symbol/code position matches the locale (SAR vs ر.س).
TC-I18N-004 No untranslated keys leak to the UI i18n Priority: Medium Localization
Steps
  1. Walk through all main screens in both languages.
Expected results
  1. No raw keys like auth.failed or {{count}} are visible.
  2. All placeholders are correctly interpolated.

Accessibility

Keyboard navigation, screen reader support, color contrast.

TC-A11Y-001 Tab order on key forms is logical Accessibility Priority: High Accessibility
Steps
  1. On the login and registration forms, use TAB to move through fields.
Expected results
  1. Focus visits fields in visual order.
  2. Submit button is reachable with TAB.
  3. Focus ring is visible on every focusable element.
TC-A11Y-002 Screen reader announces form errors Accessibility Priority: High Accessibility
Preconditions
  1. VoiceOver / TalkBack / NVDA is active.
Steps
  1. Submit the login form with empty fields.
Expected results
  1. Each error is announced via aria-live region.
  2. Error text is associated with its field via aria-describedby.
TC-A11Y-003 Color contrast meets WCAG AA Accessibility Priority: Medium Accessibility
Steps
  1. Use a contrast checker on primary buttons, body text, and error text in light and dark themes.
Expected results
  1. Body text vs background ≥ 4.5:1.
  2. Large text and UI elements ≥ 3:1.

Performance

Startup time, scroll smoothness, API latency under load.

TC-PERF-001 Cold start of mobile app under 3 seconds Performance Priority: High Performance
Steps
  1. Force-close the app, then re-launch.
  2. Measure time to interactive home feed.
Expected results
  1. Time to interactive ≤ 3 s on mid-range device with 4G.
TC-PERF-002 Feed scroll FPS remains > 50 Performance Priority: Medium Performance
Steps
  1. Scroll the home feed rapidly for 30 seconds.
Expected results
  1. Average FPS > 50 with no perceptible jank.
  2. No memory leaks after the test (heap stable).
TC-PERF-003 API p95 latency under 600 ms Performance Priority: High Performance
Steps
  1. Run k6/JMeter against staging with 50 concurrent users for 5 minutes on key endpoints.
Expected results
  1. p95 latency ≤ 600 ms on read endpoints.
  2. Error rate < 1%.

Security

Authorization, XSS, rate limiting, signed media URLs.

TC-SEC-001 IDOR — cannot edit another user's post Security Priority: Critical Security
Steps
  1. User A creates post P.
  2. User B (different account) calls PUT /api/posts/{P.id}.
Expected results
  1. Response is 403 Forbidden.
  2. Post P is unchanged.
TC-SEC-002 XSS — script tags in post content are escaped Security Priority: High Security
Steps
  1. Create a post with content <script>alert(1)</script>.
Expected results
  1. The post renders the literal text; no alert fires.
  2. Stored content is sanitized.
TC-SEC-003 Rate limiting on login endpoint Security Priority: High Security
Steps
  1. Hit the login endpoint 20 times in one minute with wrong credentials.
Expected results
  1. After the threshold, responses are 429 Too Many Requests for the remaining attempts.
TC-SEC-004 Private media uses signed URLs Security Priority: High Security
Steps
  1. Open a course video as an enrolled user.
  2. Copy the video URL and open it in an incognito window.
Expected results
  1. Signed URL works within its TTL.
  2. Same URL after expiry returns 403.

Settings, Search & Dashboard

Preferences persistence, global search, dashboard accuracy.

TC-SET-001 Update notification preferences Functional Priority: Low Settings
Steps
  1. Open Settings → Notifications.
  2. Toggle "Email — comments" off.
  3. Save and have another user comment on your post.
Expected results
  1. Setting is persisted.
  2. No email is sent for comments.
  3. In-app notification still appears.
TC-SRCH-001 Search across users, courses, books Functional Priority: Medium Search
Steps
  1. In the search bar, type "Nora".
Expected results
  1. Results are grouped (Users / Courses / Books / Rooms).
  2. Tapping a result navigates to the right page.
  3. Empty queries do not trigger a request.
TC-DASH-001 Speaker dashboard shows correct earnings Functional Priority: Medium Dashboard
Steps
  1. Open the Speaker dashboard.
Expected results
  1. Total students, total revenue, and pending balance match the database aggregates.
  2. Charts render without errors.

Exit checklist for the Testing Phase

Before sign-off, the following must be true:
  • 100% of Critical test cases pass on the target release build.
  • ≥ 95% of High test cases pass. Each failing High has a documented workaround or a deferred-to-1.1 decision.
  • No open Severity-1 or Severity-2 bugs.
  • Bilingual smoke pass (AR & EN) executed on web, Android, and iOS.
  • Performance budgets met on staging (see TC-PERF-*).
  • Sign-off recorded by Product, QA Lead, and Tech Lead.