Conversation
- Add early return in initForProject to avoid redundant sessionStorage reads - Create shared selector functions in view-as-project-permissions.ts: - createViewAsCredentialsQuery: fetches deployment credentials for mocked user - createViewAsProjectQuery: fetches project with mocked user's JWT - computeEffectivePermissions: computes effective permissions based on View As state - Update project layout and TopNavigationBar to use shared selectors - Reduces code duplication in the 3-query chain pattern Co-authored-by: ericokuma <ericokuma@users.noreply.github.com>
Add Playwright tests for the View As functionality: - Admin can access View As menu from project home and dashboard - Admin can select a user to view as - View As state persists across page refresh - View As state persists when navigating within the same project - View As state clears when navigating to a different project - Admin can clear View As state using the chip remove button - Admin can change the viewed user using the chip dropdown Note: The test for effective permissions (e.g., Share button hidden for viewer) is commented out as it requires the viewerPage fixture to be fully set up. Co-authored-by: ericokuma <ericokuma@users.noreply.github.com>
|
Cursor Agent can help with this pull request. Just |
Lint rule vitest/no-commented-out-tests requires using skip/only instead of commenting out tests. Co-authored-by: ericokuma <ericokuma@users.noreply.github.com>
Co-authored-by: ericokuma <ericokuma@users.noreply.github.com>
Co-authored-by: ericokuma <ericokuma@users.noreply.github.com>
ericpgreen2
left a comment
There was a problem hiding this comment.
Issues
1. E2E tests don't validate the core behavior of View As (High)
The test suite tests UI mechanics (popover opens, chip renders, sessionStorage persists) but not the actual purpose of View As — that an admin sees restricted permissions when impersonating a less-privileged user.
The e2e environment only has one user (the admin), so every test selects the admin to "view as" themselves. The comment on line 72 makes this explicit: // Select the first user in the list (the admin user itself). Since the effective permissions are identical to the admin's real permissions, the query chain (GetDeploymentCredentials → GetProjectWithBearerToken → effective permissions) is never exercised in a way that produces observable differences.
The skipped test ("Effective permissions update correctly when viewing as a viewer") is the one that would cover this, but it requires a second user with viewer-level permissions to be provisioned in setup.ts. Without it, the tests give confidence that the UI plumbing works but not that security policy enforcement actually functions through View As.
Consider either:
- Provisioning a viewer user in the e2e setup and enabling the skipped test, or
- Adding a unit/integration test that asserts the effective permissions reflect the mocked user's restrictions (not the admin's) when View As is active.
2. The shared selectors are thin wrappers — consider a compound hook instead (Medium)
view-as-project-permissions.ts extracts three functions, but both consumers (+layout.svelte:138-158, TopNavigationBar.svelte:80-99) still repeat the same multi-step chain: read viewAsUserStore → create credentials query → pipe access token into project query → derive effective permissions. The wrappers move individual steps behind functions without actually reducing the duplication.
Worse, the two consumers compute effective permissions differently — the layout uses computeEffectivePermissions (switches on the whole object), while the navbar uses inline ?? fallback per field (falls through to the admin's permission if a mocked field is undefined).
A single compound hook that encapsulates the entire chain would eliminate both problems:
// Returns the mocked user's project permissions (or undefined when View As is inactive)
export function createViewAsPermissions(org: string, project: string) {
const mockedUserId = get(viewAsUserStore)?.id; // or accept as param
const credentialsQuery = createAdminServiceGetDeploymentCredentials(...);
const projectQuery = createAdminServiceGetProjectWithBearerToken(...);
// return derived store with projectPermissions
}Both consumers would call one thing and get back the mocked permissions, then merge with their actual permissions in a single consistent place.
3. Silent test skip inside "Admin can change the viewed user" (Low)
view-as.spec.ts:247-259: The if (userCount > 1) block means the core assertion (selecting a different user) is silently skipped when only one user exists — which is always the case in the current e2e environment. The test passes without testing its stated purpose. Consider asserting userCount > 1 so CI fails loudly if the fixture is misconfigured, or skip the test with a message.
Minor
test.describe.configure({ mode: "serial" })may not be needed — each test navigates fresh and doesn't depend on prior test state. Parallel mode would be faster in CI.
Developed in collaboration with Claude Code
This PR addresses the follow-up feedback for the "View As" feature (APP-765) by improving code structure, efficiency, and test coverage.
Key Changes:
GetDeploymentCredentials→GetProjectWithBearerToken→ effective permissions query chain into a new shared selector (useViewAsProjectPermissions). This deduplicates logic previously duplicated inProjectLayoutandTopNavigationBar, making the code more maintainable and reducing component complexity.viewerPagefixture setup).initForProject: Implemented an early return ininitForProjectto prevent redundantsessionStoragereads when the project scope has not changed, improving efficiency.Checklist:
Linear Issue: APP-765