Skip to content

Add a notice about deleted users#1663

Merged
nygrenh merged 3 commits intomasterfrom
review-fix
Mar 2, 2026
Merged

Add a notice about deleted users#1663
nygrenh merged 3 commits intomasterfrom
review-fix

Conversation

@nygrenh
Copy link
Member

@nygrenh nygrenh commented Feb 27, 2026

Summary by CodeRabbit

  • New Features
    • Adds a visible "user likely deleted" notice and corresponding localized message where missing users are encountered.
  • Bug Fixes
    • Improved handling of deleted or missing user accounts across course, user management, and submission pages to avoid blank fields.
  • Tests
    • Updated system tests to use a centralized logout flow helper for more reliable logout steps.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 27, 2026

📝 Walkthrough

Walkthrough

Introduces a DeletedUserNotice component and changes useUserDetails to return a discriminated union (ok / not-found). Consumers (pages/components) now use extractUserDetail and isUserDetailsNotFound to render user data or the DeletedUserNotice when a user is not found.

Changes

Cohort / File(s) Summary
User Details Hook
services/main-frontend/src/hooks/useUserDetails.ts
Returns UserDetailsResult union (ok
Deleted User Notice
services/main-frontend/src/components/DeletedUserNotice.tsx
New component rendering a localized message and the userId when a user is likely deleted.
Pages & UI Consumers
services/main-frontend/src/app/manage/course-instances/.../CourseInstanceUserInfoBox.tsx, services/main-frontend/src/app/manage/users/[id]/page.tsx, services/main-frontend/src/app/submissions/[id]/page.tsx, services/main-frontend/src/components/UserDisplay/index.tsx
Switched from reading raw query data to using extractUserDetail; conditionally render DeletedUserNotice when isUserDetailsNotFound is true; adjusted item construction and guards accordingly.
Localization
shared-module/packages/common/src/locales/en/main-frontend.json
Added message-user-likely-deleted localization key.
System Tests
system-tests/src/tests/*, system-tests/src/utils/flows/topbar.flow.ts
Replaced direct Topbar.logout usage with logoutViaTopbar(page) flow helper and updated tests to use it.

Sequence Diagram(s)

sequenceDiagram
    participant Component as Page/Component
    participant Hook as useUserDetails
    participant API as Backend
    rect rgba(200,200,255,0.5)
    Component->>Hook: call useUserDetails(userId)
    Hook->>API: GET /users/:userId
    alt 200 OK
        API-->>Hook: 200 + user data
        Hook-->>Component: { kind: "ok", user }
        Component->>Component: extractUserDetail() -> user
        Component->>Component: render user info
    else 404 / RecordNotFound
        API-->>Hook: 404 / error indicating not found
        Hook-->>Component: { kind: "not-found", userId }
        Component->>Component: isUserDetailsNotFound() -> true
        Component->>Component: render DeletedUserNotice(userId)
    end
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

test

Suggested reviewers

  • Redande

Poem

🐰 A nibble, a hop, a missing name,
I sniffed the fields, called out the same.
If user’s gone and records hide,
I’ll post a note with gentle pride.
Hooray for unions, tidy and bright! 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add a notice about deleted users' clearly and accurately summarizes the primary change: introducing a DeletedUserNotice component and integrating it across multiple pages to notify when user details cannot be found.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch review-fix

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
services/main-frontend/src/hooks/useUserDetails.ts (1)

57-68: Consider more robust error detection for RecordNotFound.

The message.includes("RecordNotFound") check is fragile as it depends on the exact error message format from the backend. If the backend error message format changes, this detection could break silently.

Consider also checking for a structured error code if the backend provides one, or documenting this coupling with the backend error format.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@services/main-frontend/src/hooks/useUserDetails.ts` around lines 57 - 68, The
current catch in useUserDetails (handling axiosError: AxiosError<ErrorResponse>)
relies on message.includes("RecordNotFound"), which is brittle; update the
detection in the catch block to first check for a structured error code (e.g.,
axiosError.response?.data?.code === "RecordNotFound" or other backend-provided
code) and only fall back to inspecting the message if the code is absent,
preserving the existing 404 check and returning the same { kind: "not-found",
userId: safeUserId } shape; ensure you reference axiosError, ErrorResponse, and
safeUserId in the changes and handle undefined response/data safely.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@services/main-frontend/src/hooks/useUserDetails.ts`:
- Around line 57-68: The current catch in useUserDetails (handling axiosError:
AxiosError<ErrorResponse>) relies on message.includes("RecordNotFound"), which
is brittle; update the detection in the catch block to first check for a
structured error code (e.g., axiosError.response?.data?.code ===
"RecordNotFound" or other backend-provided code) and only fall back to
inspecting the message if the code is absent, preserving the existing 404 check
and returning the same { kind: "not-found", userId: safeUserId } shape; ensure
you reference axiosError, ErrorResponse, and safeUserId in the changes and
handle undefined response/data safely.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d09d72b and 5388509.

📒 Files selected for processing (7)
  • services/main-frontend/src/app/manage/course-instances/[id]/points/user_id/CourseInstanceUserInfoBox.tsx
  • services/main-frontend/src/app/manage/users/[id]/page.tsx
  • services/main-frontend/src/app/submissions/[id]/page.tsx
  • services/main-frontend/src/components/DeletedUserNotice.tsx
  • services/main-frontend/src/components/UserDisplay/index.tsx
  • services/main-frontend/src/hooks/useUserDetails.ts
  • shared-module/packages/common/src/locales/en/main-frontend.json

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
system-tests/src/tests/add-user-country.spec.ts (2)

71-72: ⚠️ Potential issue | 🟡 Minor

Research consent save should use waitForSuccessNotification.

The "Save" button click is a backend mutation but doesn't wait for confirmation. Compare with user-research-consent.spec.ts lines 40-45 which properly uses waitForSuccessNotification for the same action.

🐛 Proposed fix
     await researchConsentDialog.getByText("I want to participate in the").click()
-    await researchConsentDialog.getByRole("button", { name: "Save" }).click()
+    await waitForSuccessNotification(page, async () => {
+      await researchConsentDialog.getByRole("button", { name: "Save" }).click()
+    })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@system-tests/src/tests/add-user-country.spec.ts` around lines 71 - 72, The
test clicks the research consent Save button without awaiting the backend
mutation result; replace the direct click call with a call that uses the helper
to wait for the success notification (use waitForSuccessNotification) around the
click on researchConsentDialog.getByRole("button", { name: "Save" }) so the test
waits for the backend response (see existing pattern in
user-research-consent.spec.ts where waitForSuccessNotification wraps the save
click).

63-65: ⚠️ Potential issue | 🟡 Minor

Backend mutation should use waitForSuccessNotification.

The "Create an account" click triggers a backend mutation but doesn't use waitForSuccessNotification. This could cause flaky tests if the operation hasn't completed before proceeding. The same action in create-account-and-login.spec.ts properly wraps it with the helper.

As per coding guidelines: "For Playwright system tests, make sure each test that triggers a backend mutation (e.g., clicking a save button) waits for a UI confirmation element that proves the request completed successfully before proceeding. Prefer using waitForSuccessNotification for success toasts."

🐛 Proposed fix
-    await page.getByRole("button", { name: "Create an account" }).click()
-
-    await expect(page.getByText("Success", { exact: true })).toBeVisible()
+    await waitForSuccessNotification(
+      page,
+      async () => {
+        await page.getByRole("button", { name: "Create an account" }).click()
+      },
+      "Success",
+    )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@system-tests/src/tests/add-user-country.spec.ts` around lines 63 - 65,
Replace the direct assertion that checks for the "Success" text after clicking
the "Create an account" button with the standardized helper: call
waitForSuccessNotification(page) after the await page.getByRole("button", {
name: "Create an account" }).click() so the test waits for the backend mutation
to complete; locate the click call in add-user-country.spec.ts and swap the
await expect(page.getByText("Success", { exact: true })).toBeVisible() with
await waitForSuccessNotification(page), and ensure the
waitForSuccessNotification helper is imported where other specs (e.g.,
create-account-and-login.spec.ts) use it.
🧹 Nitpick comments (1)
system-tests/src/tests/user-research-consent.spec.ts (1)

71-72: Inconsistent logout approach within the same file.

Line 48 uses the new logoutViaTopbar(page) helper, but line 72 still uses the direct topbar2.logout(). Consider using the helper here as well for consistency, or if the immediate clickLogin() on line 73 makes the helper's login-link verification redundant, add a brief comment explaining why.

♻️ Suggested refactor for consistency
-    const topbar2 = new Topbar(page)
-    await topbar2.logout()
-    await topbar2.clickLogin()
+    await logoutViaTopbar(page)
+    const topbar2 = new Topbar(page)
+    await topbar2.clickLogin()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@system-tests/src/tests/user-research-consent.spec.ts` around lines 71 - 72,
The logout call is inconsistent: replace the direct Topbar.logout invocation
(topbar2.logout()) with the shared helper logoutViaTopbar(page) to match the
earlier usage, or if you intentionally keep the direct call because the
immediate clickLogin() on the next line makes the helper's login-link
verification redundant, add a one-line comment above topbar2.logout() explaining
that rationale; update references to Topbar/topbar2 accordingly so only one
logout approach (logoutViaTopbar or documented direct logout) is used in this
file.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@system-tests/src/tests/add-user-country.spec.ts`:
- Around line 71-72: The test clicks the research consent Save button without
awaiting the backend mutation result; replace the direct click call with a call
that uses the helper to wait for the success notification (use
waitForSuccessNotification) around the click on
researchConsentDialog.getByRole("button", { name: "Save" }) so the test waits
for the backend response (see existing pattern in user-research-consent.spec.ts
where waitForSuccessNotification wraps the save click).
- Around line 63-65: Replace the direct assertion that checks for the "Success"
text after clicking the "Create an account" button with the standardized helper:
call waitForSuccessNotification(page) after the await page.getByRole("button", {
name: "Create an account" }).click() so the test waits for the backend mutation
to complete; locate the click call in add-user-country.spec.ts and swap the
await expect(page.getByText("Success", { exact: true })).toBeVisible() with
await waitForSuccessNotification(page), and ensure the
waitForSuccessNotification helper is imported where other specs (e.g.,
create-account-and-login.spec.ts) use it.

---

Nitpick comments:
In `@system-tests/src/tests/user-research-consent.spec.ts`:
- Around line 71-72: The logout call is inconsistent: replace the direct
Topbar.logout invocation (topbar2.logout()) with the shared helper
logoutViaTopbar(page) to match the earlier usage, or if you intentionally keep
the direct call because the immediate clickLogin() on the next line makes the
helper's login-link verification redundant, add a one-line comment above
topbar2.logout() explaining that rationale; update references to Topbar/topbar2
accordingly so only one logout approach (logoutViaTopbar or documented direct
logout) is used in this file.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5388509 and e34cba0.

📒 Files selected for processing (3)
  • system-tests/src/tests/add-user-country.spec.ts
  • system-tests/src/tests/create-account-and-login.spec.ts
  • system-tests/src/tests/user-research-consent.spec.ts

@nygrenh nygrenh merged commit 6a40665 into master Mar 2, 2026
16 checks passed
@nygrenh nygrenh deleted the review-fix branch March 2, 2026 10:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant