Skip to main content

OAuth2 Admin Console - Test Cases

Admin backend-path: /admin/ | Framework: Vue 3 + TailwindCSS | Playwright E2E

Module 1: Login / Authentication

1.1 Admin Login Page (/admin/login)

IDTest CaseStepsExpected ResultPriority
A-LOGIN-001Valid admin credentialsEnter valid admin username/password, click Sign inRedirect to Dashboard (/admin/)P0
A-LOGIN-002Empty usernameLeave username blank, click Sign inForm does not submit (HTML5 required)P1
A-LOGIN-003Empty passwordLeave password blank, click Sign inForm does not submit (HTML5 required)P1
A-LOGIN-004Both fields emptyClick Sign in with empty fieldsForm does not submitP1
A-LOGIN-005Wrong passwordEnter valid username + wrong passwordRed error banner displayed, stays on login pageP0
A-LOGIN-006Non-existent userEnter unregistered username + any passwordError message shownP0
A-LOGIN-007Non-admin userEnter credentials of user without admin roleError message: requires admin roleP0
A-LOGIN-008SQL injection in usernameEnter ' OR 1=1 -- as usernameError message, no data leakP0
A-LOGIN-009XSS in usernameEnter <script>alert('xss')</script>Input rendered as text, no script executionP0
A-LOGIN-010Whitespace-only usernameEnter spaces only, click Sign inForm does not submitP1
A-LOGIN-011Loading stateSubmit valid credentialsButton shows "Signing in...", disabled during requestP2
A-LOGIN-012Browser back after loginLogin successfully, press browser BackRedirect to Dashboard (auth guard active)P1
A-LOGIN-013Direct access to protected pageNavigate to /admin/users without authRedirect to /admin/loginP0
A-LOGIN-014Session persistenceLogin, close tab, reopen /admin/Session restored, Dashboard shownP1
A-LOGIN-015Concurrent login attemptsRapidly click Sign in multiple timesOnly one request sent (button disabled)P2

1.2 Logout

IDTest CaseStepsExpected ResultPriority
A-LOGOUT-001Normal logoutClick "Sign out" in sidebarSession cleared, redirect to login pageP0
A-LOGOUT-002Access after logoutLogout, navigate to /admin/usersRedirect to login pageP0
A-LOGOUT-003Browser back after logoutLogout, press browser BackRedirect to login (no cached page)P1

Module 2: Dashboard (/admin/)

IDTest CaseStepsExpected ResultPriority
A-DASH-001Stats display on loadNavigate to Dashboard4 stat cards shown: Total Users, Applications, Active Tokens, Failures TodayP0
A-DASH-002System health indicatorsView DashboardSystem Status (green/red dot), Database status, Redis status displayedP0
A-DASH-003Quick action linksClick each Quick Action cardNavigates to correct page (Applications/Users/Roles/Scopes)P1
A-DASH-004Loading stateObserve page during API callStats show "—" while loading, then updateP2
A-DASH-005API failure handlingSimulate /health/ready failureRed error banner shown, System Status shows "Unhealthy"P0
A-DASH-006Stats API failureSimulate /api/admin/dashboard/stats failureError banner displayed with descriptive messageP0
A-DASH-007Failures today = 0When no failures todayNumber displayed in normal text color (not red)P2
A-DASH-008Failures today > 0When failures existNumber displayed in red colorP2

Module 3: Applications (/admin/applications)

3.1 Application List

IDTest CaseStepsExpected ResultPriority
A-APP-001List loads successfullyNavigate to Applications pageTable shows client_id, name, type, grant_types, created_atP0
A-APP-002Empty listWhen no clients existTable shows "No clients found" or empty stateP1
A-APP-003Navigate to detailClick a client rowNavigates to /admin/applications/:idP0
A-APP-004Delete clientClick Delete on a client, confirm dialogClient removed from list, success messageP0
A-APP-005Delete client cancelClick Delete, cancel confirm dialogClient remains in listP1
A-APP-006Reset secret from listClick Reset Secret, confirmSecret modal shows new secretP0

3.2 Create Application

IDTest CaseStepsExpected ResultPriority
A-APP-CR-001Create CONFIDENTIAL clientFill name, type=CONFIDENTIAL, redirect URIs, select grant types, submitClient created, secret modal shown with new secretP0
A-APP-CR-002Create with empty nameLeave name empty, submitForm validation prevents submission or API error shownP0
A-APP-CR-003No grant type selectedDeselect all grant types, submitError: "Please select at least one grant type"P0
A-APP-CR-004Multiple grant typesSelect authorization_code + refresh_token + client_credentialsClient created with comma-separated grant typesP1
A-APP-CR-005Duplicate client nameCreate two clients with same nameSecond creation succeeds (name is not unique key) or proper errorP1
A-APP-CR-006Very long redirect URIEnter redirect URI > 2048 charsEither succeeds or server returns validation error gracefullyP2
A-APP-CR-007Invalid redirect URI formatEnter not-a-url as redirect URIValidation error shownP1
A-APP-CR-008Device code grant typeSelect urn:ietf:params:oauth:grant-type:device_codeClient created with device_code grantP1
A-APP-CR-009Close modal without submitOpen create modal, click CancelModal closes, no API callP1
A-APP-CR-010Loading state during createSubmit create formButton shows "Creating...", disabledP2

3.3 Application Detail (/admin/applications/:id)

IDTest CaseStepsExpected ResultPriority
A-APP-DT-001Info tab loadsOpen application detailClient name, redirect URIs, grant types displayed in editable formP0
A-APP-DT-002Save name changeEdit client name, click SaveSuccess message, name updatedP0
A-APP-DT-003Save with no changesClick Save without modifying anythingMessage: "No changes to save"P1
A-APP-DT-004Edit redirect URIsChange redirect URIs (multi-line), saveURIs saved as comma-separated, displayed correctly on reloadP0
A-APP-DT-005Invalid application IDNavigate to /admin/applications/non-existent-idError message displayedP1
A-APP-DT-006Scopes tabSwitch to Scopes tabAvailable scopes shown with checkboxes, current scopes checkedP0
A-APP-DT-007Save scopesCheck/uncheck scopes, click SaveScopes updated, success messageP0
A-APP-DT-008Reset secretClick Reset Secret, confirmNew secret shown in modalP0
A-APP-DT-009Copy to clipboardClick copy button for secretSecret copied, "Copied to clipboard" messageP2
A-APP-DT-010Credentials tabSwitch to Credentials tabClient ID displayed, reset secret option availableP1

Module 4: Users (/admin/users)

4.1 User List

IDTest CaseStepsExpected ResultPriority
A-USR-001List loadsNavigate to Users pageTable with Username, Email, Verified, MFA, Actions columnsP0
A-USR-002Verified badgeUser has email_verified=trueGreen "Verified" badge shownP1
A-USR-003Unverified badgeUser has email_verified=falseYellow "Pending" badge shownP1
A-USR-004MFA enabledUser has mfa_enabled=trueGreen "Enabled" badgeP1
A-USR-005MFA disabledUser has mfa_enabled=falseGray "Off" badgeP1
A-USR-006Navigate to user detailClick "Details" linkNavigates to /admin/users/:idP0
A-USR-007API errorSimulate GET /api/admin/users failureError banner displayedP0

4.2 Role Assignment (List Page Modal)

IDTest CaseStepsExpected ResultPriority
A-USR-RL-001Assign single roleClick "Assign Roles", enter "admin", saveRoles updated, modal closesP0
A-USR-RL-002Assign multiple rolesEnter "admin, user" (comma-separated)Both roles assignedP0
A-USR-RL-003Empty role inputClick save with empty role inputNo API call (button disabled or input validation)P1
A-USR-RL-004Whitespace rolesEnter ", , admin, "Only "admin" assigned (trimmed, filtered)P1
A-USR-RL-005Non-existent roleEnter "superadmin"API error or graceful handlingP1
A-USR-RL-006Cancel role assignmentOpen modal, click CancelModal closes, no changesP1
A-USR-RL-007Loading stateSubmit role assignmentButton shows "Saving...", disabledP2

4.3 User Detail (/admin/users/:id)

IDTest CaseStepsExpected ResultPriority
A-USR-DT-001Info tab loadsOpen user detailUsername, email, email_verified shown in editable formP0
A-USR-DT-002Edit emailChange email, saveEmail updated, success messageP0
A-USR-DT-003Toggle email verifiedToggle verified checkbox, saveVerification status updatedP0
A-USR-DT-004No changes saveClick Save without changes"No changes" messageP1
A-USR-DT-005Roles tabSwitch to Roles tabAvailable roles as checkboxes, current roles selectedP0
A-USR-DT-006Save rolesCheck/uncheck roles, saveRoles updated, success messageP0
A-USR-DT-007Disable userClick "Disable User", confirm dialogUser disabled, status updatedP0
A-USR-DT-008Enable userClick "Enable User"User enabled, status updatedP0
A-USR-DT-009Security tabSwitch to Security tabLock status, login attempts, locked_until shownP1
A-USR-DT-010Locked user indicatorView locked user"Locked" status with remaining time shownP1
A-USR-DT-011Non-existent userNavigate to /admin/users/999999Error message displayedP1
A-USR-DT-012Concurrent role editTwo admins edit same user's roles simultaneouslyLast write wins or conflict errorP2

Module 5: Roles (/admin/roles)

IDTest CaseStepsExpected ResultPriority
A-ROLE-001List rolesNavigate to Roles pageTable with Name, Description, Users count, ActionsP0
A-ROLE-002Built-in role indicatorsView admin/user roles"built-in" badge shownP1
A-ROLE-003Built-in roles cannot be deletedView actions for built-in rolesNo "Delete" button shownP0
A-ROLE-004Create roleClick Create, enter name + description, submitRole created, appears in tableP0
A-ROLE-005Create role empty nameSubmit with empty nameButton disabled (form validation)P0
A-ROLE-006Create duplicate role nameCreate role with existing nameAPI error shown: role already existsP0
A-ROLE-007Edit role descriptionClick Edit, change description, saveDescription updatedP0
A-ROLE-008Delete custom roleClick Delete on custom role, confirmRole deleted, removed from tableP0
A-ROLE-009Delete role cancelClick Delete, cancel confirm dialogRole remainsP1
A-ROLE-010Role with assigned usersDelete a role that has users assignedConfirm dialog appears; after deletion, users lose that roleP1
A-ROLE-011Empty role listWhen no custom roles existOnly built-in roles shown (admin, user)P2
A-ROLE-012XSS in role nameEnter <script>alert(1)</script> as nameName rendered as text, no script executionP0
A-ROLE-013Very long role nameEnter name > 100 charsEither succeeds or proper validation errorP2

Module 6: Scopes (/admin/scopes)

IDTest CaseStepsExpected ResultPriority
A-SCP-001List scopesNavigate to Scopes pageTable with Name, Description, Mapped Role, Default, Admin-only, ActionsP0
A-SCP-002Built-in scope indicatorsView openid/profile/email/admin"built-in" badge or non-deletableP1
A-SCP-003Create scopeFill name, description, mapped_role, toggle is_default/requires_admin_role, submitScope created, appears in tableP0
A-SCP-004Create scope empty nameSubmit with empty nameButton disabled or validation errorP0
A-SCP-005Create duplicate scopeCreate scope with existing nameAPI error: scope already existsP0
A-SCP-006Edit scopeClick Edit, change description/mapped_role/toggles, saveScope updatedP0
A-SCP-007Toggle is_defaultSet is_default=true for a scopeScope marked as defaultP1
A-SCP-008Toggle requires_admin_roleSet requires_admin_role=trueScope marked as admin-onlyP1
A-SCP-009Delete scopeClick Delete on custom scope, confirmScope deletedP0
A-SCP-010Delete built-in scopeTry to delete openid/adminDelete button not shown or errorP0
A-SCP-011XSS in scope nameEnter <img onerror=alert(1) src=x> as nameRendered as textP0

Module 7: Tokens (/admin/tokens)

IDTest CaseStepsExpected ResultPriority
A-TOK-001List tokensNavigate to Tokens pageTable with token_prefix, client_id, user_id, scope, created_at, expires_atP0
A-TOK-002Filter by client_idEnter client_id filter, click ApplyOnly tokens for that client shownP0
A-TOK-003Filter by user_idEnter user_id filter, click ApplyOnly tokens for that user shownP0
A-TOK-004Clear filtersClick "Clear Filters"Filters reset, all tokens shownP1
A-TOK-005Revoke single tokenClick Revoke on a token, confirm dialogToken revoked, removed from listP0
A-TOK-006Revoke by clientClick bulk action "Revoke by Client", confirmAll tokens for that client revokedP0
A-TOK-007Revoke by userClick "Revoke by User" (requires user_id filter), confirmAll tokens for that user revokedP0
A-TOK-008Revoke by user without filterClick "Revoke by User" without user_id filterNo action (guard: if (!userIdFilter.value) return)P1
A-TOK-009PaginationWhen tokens > per_page (50)Page navigation works, page parameter sent in APIP1
A-TOK-010Empty token listWhen no tokens existTable shows empty stateP2
A-TOK-011Confirm cancelClick Revoke, cancel confirm dialogToken not revokedP1
A-TOK-012Timestamp formattingVerify created_at/expires_at displayFormatted as locale string, not raw ISOP2

Module 8: Audit Logs (/admin/logs)

IDTest CaseStepsExpected ResultPriority
A-LOG-001List loadsNavigate to Audit Logs pageTable with timestamp, action, user, detailsP0
A-LOG-002Empty logsWhen no audit logs existEmpty state displayedP1
A-LOG-003PaginationWhen logs > per_pagePagination controls workP1
A-LOG-004Filter by action typeFilter by specific actionFiltered results shownP1
A-LOG-005Timestamp orderingView multiple logsSorted by timestamp descending (newest first)P1

Module 9: Settings (/admin/settings)

IDTest CaseStepsExpected ResultPriority
A-SET-001Page loadsNavigate to Settings pageCurrent settings displayed in editable formP0
A-SET-002Save settingsModify setting value, click SaveSuccess message, settings updatedP0
A-SET-003Invalid setting valueEnter invalid valueValidation error shownP1
A-SET-004No changes saveClick Save without changes"No changes" or settings re-fetchedP2

Module 10: Navigation & Layout

IDTest CaseStepsExpected ResultPriority
A-NAV-001Sidebar navigationClick each nav itemCorrect page loads, active item highlightedP0
A-NAV-002Active state on detail pagesNavigate to /admin/applications/:id"Applications" nav item highlightedP1
A-NAV-003Top bar titleNavigate between pagesTop bar shows current page nameP2
A-NAV-004User info in sidebarAfter loginUsername initial avatar, name, email shownP2
A-NAV-005Responsive layoutResize to mobile widthSidebar collapses or becomes hamburger menuP1

Module 11: Cross-Cutting Concerns

11.1 Error Handling

IDTest CaseStepsExpected ResultPriority
A-ERR-001Network errorDisable network during API callError banner with user-friendly messageP0
A-ERR-002401 UnauthorizedLet session expire, make API callRedirect to login pageP0
A-ERR-003403 ForbiddenAdmin-only operation by non-adminError message, no data exposedP0
A-ERR-004500 Server errorTrigger server errorError banner, no crashP0
A-ERR-005Success message auto-dismissPerform successful actionSuccess message disappears after 3 secondsP2
A-ERR-006Error message auto-dismissTrigger error messageError message disappears after 5 secondsP2

11.2 Security

IDTest CaseStepsExpected ResultPriority
A-SEC-001CSRF protection (CORS same-origin)Submit forms / send API requestsBearer-token architecture: auth token is NOT in a cookie, so classic CSRF does not apply. Protection is enforced by backend CORS with strict exact-match Origin allowlist (no wildcards) — main.cc origin check. Cross-origin requests from non-allowlisted origins are rejectedP0
A-SEC-002Token storageAfter loginAuth token not in URL or localStorage in plaintextP0
A-SEC-003Route guard bypassManually enter /admin/users URL without authRedirected to loginP0
A-SEC-004Client secret displayView/create client secretSecret shown only once, not persisted in page stateP0

11.3 Performance

IDTest CaseStepsExpected ResultPriority
A-PERF-001Large user listLoad 1000+ usersPage renders without freezing, pagination workingP1
A-PERF-002Dashboard concurrent requestsLoad DashboardTwo API calls fire in parallel (Promise.all)P2
A-PERF-003Lazy-loaded routesNavigate to each pageOnly required component loaded (code splitting)P2