Skip to content

Comments

321 consolidate duplicated generatemocktoken helper into shared teststory utility#336

Open
nguyenduy wants to merge 81 commits intomainfrom
321-consolidate-duplicated-generatemocktoken-helper-into-shared-teststory-utility
Open

321 consolidate duplicated generatemocktoken helper into shared teststory utility#336
nguyenduy wants to merge 81 commits intomainfrom
321-consolidate-duplicated-generatemocktoken-helper-into-shared-teststory-utility

Conversation

@nguyenduy
Copy link
Contributor

@nguyenduy nguyenduy commented Jan 8, 2026

Summary by Sourcery

Extract shared Storybook authentication and environment mocking into reusable utilities and standardize their usage across UI stories.

Enhancements:

  • Introduce shared Storybook auth wrappers and environment/storage mocks to centralize test configuration.
  • Refine App container stories with richer mocked GraphQL data for listings, account setup, and admin state, improving story realism.
  • Update Storybook stories to rely on common decorators and utilities instead of in-file mocks, reducing duplication and tightening consistency across app, layout, and admin stories.

Tests:

  • Adjust numerous Storybook stories to use new shared auth and Apollo decorators while preserving existing behavior and interaction tests.

…where unnecessary

- Changed play functions in various Storybook stories from async to synchronous where applicable.
- Updated imports for MockAuthWrapper to a new file for better organization.
- Removed unused MockAuthWrapper and MockUnauthWrapper implementations from storybook-decorators.tsx for it mixes exporting constants and components
@nguyenduy nguyenduy requested a review from a team January 8, 2026 21:55
@nguyenduy nguyenduy linked an issue Jan 8, 2026 that may be closed by this pull request
4 tasks
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Jan 8, 2026

Reviewer's Guide

Refactors Storybook test infrastructure by centralizing mock auth wrappers and environment/storage setup into shared utilities, adds reusable GraphQL mock builders for App stories, and updates many Storybook stories to use the new shared decorators and helpers while making minor consistency/typing tweaks to play functions and props.

Sequence diagram for AppContainer story with centralized GraphQL mocks

sequenceDiagram
    participant SB as StorybookRunner
    participant ST as AppContainerStory
    participant WMAC as withMockApolloClient
    participant AP as ApolloProvider
    participant AC as ApolloClient(MockLink)
    participant C as AppContainer

    SB->>ST: Load AuthenticatedCompletedOnboarding story
    ST->>WMAC: Apply decorator with mocks
    WMAC->>AP: Wrap Story with ApolloProvider
    AP->>AC: Initialize client with mocks

    SB->>C: Render AppContainer inside providers

    C->>AC: Query AppContainerCurrentUserDocument
    AC-->>C: Mock response from buildCurrentUserMock

    C->>AC: Query ListingsPageContainerGetListingsDocument
    AC-->>C: Mock response from buildListingsMock

    C->>AC: Query UseUserIsAdminDocument
    AC-->>C: Mock response from buildUseUserIsAdminMock

    C-->>SB: Render UI for authenticated user with listings
Loading

Class diagram for shared Storybook test utilities and helpers

classDiagram
    class StorybookDecorators {
        +withAuthDecorator(storyFn) JSXElement
        +withMockApolloClient(storyFn, mocks) JSXElement
        +withMockRouter(initialPath) Decorator
    }

    class StorybookMockAuthWrappers {
        +MockAuthWrapper~FC~
        +MockUnauthWrapper~FC~
    }

    class AppContainerStoriesHelpers {
        +buildCurrentUserMock(id, hasCompletedOnboarding) ApolloMock
        +buildListingsMock(listings) ApolloMock
        +buildUseUserIsAdminMock(isAdmin) ApolloMock
    }

    class ApolloMock {
        +request QueryRequest
        +result QueryResult
    }

    class QueryRequest {
        +query DocumentNode
        +variables any
    }

    class QueryResult {
        +data any
    }

    StorybookDecorators --> StorybookMockAuthWrappers : uses
    StorybookDecorators --> ApolloMock : configures
    AppContainerStoriesHelpers --> ApolloMock : builds
Loading

File-Level Changes

Change Details Files
Centralize mock auth wrappers into a dedicated shared utility and update stories to use it.
  • Extract MockAuthWrapper and MockUnauthWrapper into a new test-utils/storybook-mock-auth-wrappers module using createMockAuth/createMockUser and AuthContext.Provider
  • Remove auth wrappers from storybook-decorators and re-import them from the new shared mock-auth-wrappers module where needed
  • Update stories across layouts, shared components, and hooks to import MockAuthWrapper/MockUnauthWrapper from the new module instead of storybook-decorators
apps/ui-sharethrift/src/test-utils/storybook-mock-auth-wrappers.tsx
apps/ui-sharethrift/src/test-utils/storybook-decorators.tsx
apps/ui-sharethrift/src/components/layouts/home/components/create-listing/hooks/use-create-listing-navigation.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/stories/section-layout.stories.tsx
apps/ui-sharethrift/src/components/layouts/signup/section-layout.stories.tsx
apps/ui-sharethrift/src/components/layouts/signup/section-layout.stories.tsx
apps/ui-sharethrift/src/components/layouts/signup/section-layout.stories.tsx
apps/ui-sharethrift/src/components/shared/stories/auth-redirect-user.stories.tsx
apps/ui-sharethrift/src/components/shared/stories/login-selection.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/components/view-listing/listing-information/listing-information.container.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/stories/section-layout.stories.tsx
apps/ui-sharethrift/src/components/layouts/signup/section-layout.stories.tsx
apps/ui-sharethrift/src/components/shared/stories/require-auth-admin.stories.tsx
apps/ui-sharethrift/src/components/layouts/signup/section-layout.stories.tsx
apps/ui-sharethrift/src/components/layouts/signup/section-layout.stories.tsx
Create a shared auth/environment Storybook decorator and reuse it in App and Apollo connection stories instead of duplicating mock env and storage setup.
  • Add mockEnv and mockStorage objects and attach them to globalThis.sessionStorage, globalThis.localStorage, and import.meta.env in storybook-decorators
  • Introduce withAuthDecorator that wraps stories with MockedProvider and AuthProvider configured with mockEnv and mockStorage
  • Refactor ApolloConnection and App stories to import and use withAuthDecorator instead of defining their own mock env/storage and AuthProvider/MockedProvider setup
apps/ui-sharethrift/src/test-utils/storybook-decorators.tsx
apps/ui-sharethrift/src/components/shared/apollo-connection.stories.tsx
apps/ui-sharethrift/src/App.stories.tsx
Enhance App container stories with reusable GraphQL mocks for listings, current user, account plans, and admin checks.
  • Add mockListings data and helper builders buildListingsMock, buildUseUserIsAdminMock, and buildCurrentUserMock for constructing Apollo mocks
  • Update AuthenticatedCompletedOnboarding, AuthenticatedNotCompletedOnboarding, and Unauthenticated stories to use the new helpers and provide richer mocks for listings, account type, account plans, and admin status
  • Adjust imports to include the needed generated GraphQL documents and to use the new MockUnauthWrapper module
apps/ui-sharethrift/src/App.container.stories.tsx
Normalize Storybook play function signatures and minor typings/props adjustments across many stories for consistency.
  • Remove unnecessary async keywords where not needed and standardize spacing in play function declarations (e.g., play: ({ canvasElement }) => and play: async ({ canvasElement }) =>)
  • Tweak argument types for play functions where explicit typing is used (e.g., { canvasElement: HTMLElement }) without changing behavior
  • Make small prop/handler adjustments for type-safety or clarity, such as adding button type, ignoring unused parameters, and loosening callback signatures where appropriate
apps/ui-sharethrift/src/components/layouts/home/components/create-listing/create-listing.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/components/view-listing/listing-information/listing-information.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/my-listings/stories/all-listings-table.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/account/admin-dashboard/components/admin-listings-table/admin-listings-table.view-listing.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/components/view-listing/listing-information/listing-information.container.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/my-listings/components/requests-table.container.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/my-listings/stories/all-listings-card.stories.tsx
apps/ui-sharethrift/src/components/layouts/signup/components/profile-setup.container.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/account/admin-dashboard/components/admin-users-table/admin-users-table.container.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/components/create-listing/hooks/use-file-limit.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/components/view-listing/sharer-information/sharer-information.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/account/admin-dashboard/components/admin-listings-table/admin-listings-table.container.stories.tsx
apps/ui-sharethrift/src/components/layouts/signup/components/account-setup.container.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/components/create-listing/hooks/use-create-listing-navigation.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/messages/stories/ConversationBoxContainer.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/account/admin-dashboard/components/admin-listings-table/admin-listings-table.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/account/admin-dashboard/components/admin-users-table/stories/admin-users-card.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/account/settings/pages/settings-view.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/my-reservations/stories/reservation-actions.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/account/admin-dashboard/components/admin-listings-table/stories/admin-listings-table.status-tag.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/account/admin-dashboard/components/admin-listings-table/stories/admin-listings-table.title-filter.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/account/profile/components/profile-view.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/components/view-listing/view-listing.container.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/my-reservations/components/reservations-view-history.container.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/my-reservations/stories/reservation-state-utils.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/stories/HeroSection.stories.tsx
apps/ui-sharethrift/src/components/layouts/signup/components/select-account-type.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/account/admin-dashboard/components/admin-users-table/admin-users-table.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/account/settings/components/settings-view.container.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/my-listings/stories/requests-status-helpers.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/my-reservations/components/reservations-view-active.container.stories.tsx
apps/ui-sharethrift/src/components/layouts/signup/section-layout.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/account/admin-dashboard/components/admin-users-table/admin-users.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/account/admin-dashboard/pages/admin-dashboard-main.container.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/account/settings/pages/Settings.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/components/category-filter.container.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/components/hero-section.container.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/components/listings-page.container.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/messages/pages/Conversation.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/my-listings/components/all-listings-table.container.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/my-listings/pages/edit-listing.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/my-listings/pages/my-listings.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/my-listings/stories/my-listings-dashboard.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/my-reservations/stories/reservations-table.stories.tsx
apps/ui-sharethrift/src/components/layouts/home/stories/section-layout.stories.tsx
apps/ui-sharethrift/src/components/layouts/signup/components/select-account-type.container.stories.tsx
apps/ui-sharethrift/src/components/layouts/signup/stories/section-layout.stories.tsx

Assessment against linked issues

Issue Objective Addressed Explanation
#321 Create a shared generateMockToken helper in a test/story utilities location (e.g., apps/ui-sharethrift/src/test-utils/mockToken.ts) with the specified implementation. The diff does not add any new file or export named generateMockToken, nor does it create a mockToken.ts (or equivalent) helper in a shared test-utils location.
#321 Update all story files that previously defined a local generateMockToken to import and use the shared helper instead, removing local implementations. None of the modified story files show removal of a local generateMockToken function or an added import for generateMockToken from a shared utility. The changes focus on auth wrappers, Apollo mocks, and play function signatures.
#321 Eliminate duplicated generateMockToken implementations across the codebase so that no local copies remain. Because no shared generateMockToken helper is introduced and no local generateMockToken implementations are removed or changed, duplicated implementations (if present) are not addressed by this PR.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • The Storybook env/storage mocking in storybook-decorators.tsx now mutates globalThis.sessionStorage, globalThis.localStorage, and import.meta.env at module load; consider moving these side effects into a dedicated Storybook setup (e.g., preview file) or behind a guard so simply importing the decorators in non-Storybook code doesn’t unexpectedly alter global state.
  • The mockStorage implementation is used both as window.localStorage/sessionStorage and as a userStore for AuthProvider, mixing sync (DOM Storage) and async (oidc userStore) style APIs; it may be worth clearly separating these concerns or adding comments to avoid accidental reuse of this object in a context that expects only one of the interfaces.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The Storybook env/storage mocking in `storybook-decorators.tsx` now mutates `globalThis.sessionStorage`, `globalThis.localStorage`, and `import.meta.env` at module load; consider moving these side effects into a dedicated Storybook setup (e.g., preview file) or behind a guard so simply importing the decorators in non-Storybook code doesn’t unexpectedly alter global state.
- The `mockStorage` implementation is used both as `window.localStorage`/`sessionStorage` and as a `userStore` for `AuthProvider`, mixing sync (DOM Storage) and async (oidc userStore) style APIs; it may be worth clearly separating these concerns or adding comments to avoid accidental reuse of this object in a context that expects only one of the interfaces.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Consolidate duplicated generateMockToken helper into shared test/story utility

2 participants