e2e(FR-2982): assert inviter email is shown in folder invitation modal#7610
Conversation
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has required the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
There was a problem hiding this comment.
Pull request overview
Extends an existing E2E helper to optionally assert the inviter's email appears in the folder invitation modal, then enables the assertion in the existing vfolder share test. This closes a coverage gap around the modal's "From" field, which currently has no unit, Storybook, or E2E verification.
Changes:
- Add optional
inviterEmailparameter toacceptAllInvitationAndVerifySpecificFolderand assert the modal contains it when provided. - Pass
userInfo.user.emailat the existing call site invfolder-crud.spec.tsso the assertion runs in CI.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| e2e/utils/test-util.ts | Adds optional inviterEmail argument and a toContainText assertion on the invitation modal. |
| e2e/vfolder/vfolder-crud.spec.ts | Passes inviter email (userInfo.user.email) to the helper to enable the new check. |
Coverage Report for react-coverage (./react)
File Coverage
|
||||||||||||||||||||||||||||||||||||||||||||
c89cb25 to
cbe1693
Compare
cbe1693 to
654d33d
Compare
147f8b1 to
25baf00
Compare
654d33d to
ee4142c
Compare
25baf00 to
f849b3a
Compare
ee4142c to
99d6077
Compare
f849b3a to
005aaf8
Compare
99d6077 to
941b668
Compare
005aaf8 to
868c4a8
Compare
…page (#7607) Linked Jira: [FR-2979](https://lablup.atlassian.net/browse/FR-2979) Backend counterpart: [BA-6193](https://lablup.atlassian.net/browse/BA-6193) (merged, SSO empty-email) Backend follow-up: [BA-6228](https://lablup.atlassian.net/browse/BA-6228) (expose `inviter_user_email` as a separate DTO field) <!-- `Resolves #N (FR-2979)` will be added once the Jira→GitHub clone webhook fires. --> ## TL;DR FR-2979 ("Summary page invitation card shows empty `From:`") has **two independent root causes**. This PR fixes the frontend one. The other one is server-side and lives in BA-6193. Both need to land for FR-2979 to be fully resolved end-to-end. | # | Root cause | Where it lives | Status | | --- | --- | --- | --- | | 1 | Both the Summary card and `FolderInvitationResponseModal` read `invitation.inviter` blindly. The legacy backend used to put the inviter email there, but manager v25.6.0 plans to expose it under a separate `inviter_user_email` field. This PR gates the read with the existing `invitation-inviter-email` capability flag and falls back to the legacy `inviter` field for older managers. | Frontend (this PR) | Fixed here | | 2 | Backend persists `User.email = ""` for SSO-created accounts and mirrors it straight into the invitation response, so the sender renders blank regardless of the field name; the accept handler's `if not inviter_email` check also raises on the empty string. | Backend ([BA-6193](https://lablup.atlassian.net/browse/BA-6193)) | Tracked separately | After **this PR alone**: users invited by a manually-created sender on a manager that exposes `inviter_user_email` see the sender's email again. Users whose inviter is an SSO-created account still see blank — unblocked only by BA-6193. ## What this PR does Use the same capability-check pattern that `FolderInvitationResponseModal.tsx` originally followed (added in FR-1101): read `baiClient.supports('invitation-inviter-email')` and choose the field accordingly. Both call sites also fall back to `'-'` to avoid rendering `From: undefined` when neither field has a value. - `react/src/components/FolderInvitationResponseModal.tsx` — add `useSuspendedBackendaiClient` + `hasInviterEmail`, render `(hasInviterEmail ? item.inviter_user_email : item.inviter) || '-'` in the "From" descriptions item. - `react/src/components/SummaryPageItems/SummaryItemInvitation.tsx` — same gating in the card title. ## Known limitation (and the backend follow-up that unblocks it) The current `VFolderInvitationDTO` (`src/ai/backend/common/dto/manager/vfolder/response.py` in `lablup/backend.ai`) only declares the single `inviter` field: ```python class VFolderInvitationDTO(BackendAISchema): inviter: str = Field(description="Inviter email, or username if email is empty") ... ``` The handler collapses both possibilities into that field (`inviter=info.inviter_user_email or info.inviter_username or ""`). So on managers where the capability flag is *true* but the DTO has not yet been expanded with `inviter_user_email`, this PR will render `From: -` for every invitation. Older managers (capability = false) continue to read the legacy `inviter` field and work as before. The backend side needs to add `inviter_user_email` as a separate DTO field for the capability-gated branch to actually show the email. Tracked separately in [BA-6228](https://lablup.atlassian.net/browse/BA-6228) — until that lands, manager ≥ 25.6.0 will render `From: -` for every invitation. Older managers (capability = false) continue to read the legacy `inviter` field and work as before. ## What this PR explicitly does NOT fix — and why the frontend can't The SSO-side problem above is **not** addressable from the client: - The invitation payload contains the empty email itself; there is no other identifying field to fall back to. - The payload has no `is_sso` / `external_id` flag, so the frontend cannot even differentiate SSO rows to apply a special UI. - A cosmetic "Unknown sender" fallback would only mask the symptom while leaving the accept-flow exception in BA-6193 untouched. So the fix has to land where the empty email originates — the backend. See [BA-6193](https://lablup.atlassian.net/browse/BA-6193). ## Verification - `bash scripts/verify.sh` — Relay, Lint, Format PASS. TypeScript surfaces only pre-existing failures in unrelated files; no new errors in the touched files. - Manual: invite a manually-created user from another manually-created user on a manager that exposes `inviter_user_email`; the Summary card and the invitation modal both show the inviter's email. On a manager that only returns `inviter` (current main), both fall back to the legacy field and render correctly. SSO-related rows remain blank, expected until BA-6193 lands. ## Checklist - [x] Documentation — n/a (capability-check pattern already documented by FR-1101's PR) - [x] Minimum required manager version — no change (the existing capability flag covers both old and new managers) - [x] Minimum requirements to check during review — log in as the invitee and confirm the Summary invitation card title and the `FolderInvitationResponseModal` "From:" field both show the inviter's email (or `-` if not available on the current manager) - [ ] Test case(s) — covered by the e2e in #7610 (FR-2982) [FR-2979]: https://lablup.atlassian.net/browse/FR-2979?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ [BA-6193]: https://lablup.atlassian.net/browse/BA-6193?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ [BA-6228]: https://lablup.atlassian.net/browse/BA-6228?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
e2c9281 to
6995ec4
Compare
868c4a8 to
17c6056
Compare
6995ec4 to
3e33168
Compare
|
@yomybaby both of your inline comments are addressed: |
approved by others. and resolved comment.
Merge activity
|
#7610) Resolves #7608 (FR-2982) > Stacked on #7607 — merge that one first. ## Summary - Extend `acceptAllInvitationAndVerifySpecificFolder` (in `e2e/utils/test-util.ts`) with an optional `inviterEmail` parameter. - When the parameter is provided, assert that the open `FolderInvitationResponseModal` contains that email before the Accept loop. This catches regressions in the modal's "From" field — i.e. broken `item.inviter_user_email` plumbing or a broken `invitation-inviter-email` capability check. - Pass `userInfo.user.email` (the inviter set up by `loginAsUser` in `beforeEach`) at the single existing call site in `e2e/vfolder/vfolder-crud.spec.ts` ("User can share vFolder"), so the assertion runs in CI. - No production source changes; e2e-only. ## Why - The "From" field is the only place an invitee sees who shared a folder with them. Today no e2e / unit / Storybook test asserts that field is non-empty or correct. - Existing test already exercises the modal, so the new check is a low-cost extension rather than a new scenario. ## Test plan - [ ] CI: existing `vfolder/vfolder-crud.spec.ts` "User can share vFolder" run passes with the new assertion enabled. - [ ] On a backend with `invitation-inviter-email` capability, the assertion confirms `user@lablup.com` is rendered inside the modal. - [ ] On a backend without that capability, the assertion would fail (the modal falls back to `item.inviter`, a non-email value); intentional — this is the regression we want to surface.
3e33168 to
2931506
Compare

Resolves #7608 (FR-2982)
Summary
acceptAllInvitationAndVerifySpecificFolder(ine2e/utils/test-util.ts) with an optionalinviterEmailparameter.FolderInvitationResponseModalcontains that email before the Accept loop. This catches regressions in the modal's "From" field — i.e. brokenitem.inviter_user_emailplumbing or a brokeninvitation-inviter-emailcapability check.userInfo.user.email(the inviter set up byloginAsUserinbeforeEach) at the single existing call site ine2e/vfolder/vfolder-crud.spec.ts("User can share vFolder"), so the assertion runs in CI.Why
Test plan
vfolder/vfolder-crud.spec.ts"User can share vFolder" run passes with the new assertion enabled.invitation-inviter-emailcapability, the assertion confirmsuser@lablup.comis rendered inside the modal.item.inviter, a non-email value); intentional — this is the regression we want to surface.