Skip to content

Arch unit test additions #290

Open
jasonmorais wants to merge 6 commits into
mainfrom
jason/arch-unit-additions
Open

Arch unit test additions #290
jasonmorais wants to merge 6 commits into
mainfrom
jason/arch-unit-additions

Conversation

@jasonmorais

@jasonmorais jasonmorais commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Summary by Sourcery

Introduce reusable architecture fitness tests for Cellix API, UI, and Serenity-based verification suites and wire them into key apps and verification packages, while improving worktree-aware test environment behavior and timeouts.

New Features:

  • Add TypeScript-based architecture checkers and Vitest suites for Cellix API composition, UI app composition, and Serenity/Cucumber suite conventions, with public entrypoints under dedicated subpaths.
  • Add portable architecture stub fixtures and contract tests to verify that the new architecture rules both accept valid setups and reject incomplete ones.
  • Expose new archunit test helpers from the @cellix/archunit-tests package and document their usage and scope in updated README and manifest files.
  • Introduce Serenity convention tests into OCom verification acceptance and E2E packages, and UI/app composition tests into API and UI portal projects via new Vitest arch configs and scripts.

Bug Fixes:

  • Make the E2E test environment honor worktree-specific Azurite, Mongo, and mock-auth host settings so spawned services target the correct ports and hosts.
  • Increase Serenity boot-time handling by adding a dedicated cold-boot timeout and wiring it into Cucumber lifecycle hooks to avoid premature scenario timeouts in slow environments.

Enhancements:

  • Refine staff acceptance step definitions by introducing dedicated Serenity tasks and questions for opening the staff landing route and querying the target route, clarifying responsibilities.
  • Tidy several existing tests and TypeScript configs, including excluding architecture stub fixtures from the archunit package build and compressing some test expectations for readability.

Build:

  • Export new API, UI app, and Serenity subpath entrypoints from the @cellix/archunit-tests package and update its package.json exports and TypeScript config accordingly.
  • Add vitest.arch.config.ts wiring for architecture tests and register test:arch scripts plus required devDependencies (archunit-tests and config-vitest) across API, UI, and verification packages.
  • Update pnpm workspace dependency overrides for brace-expansion versions to consolidated, newer ranges.

Documentation:

  • Extend the @cellix/archunit-tests README and add a package manifest document describing the new architecture checkers, public API shape, and consumption patterns for downstream packages.

Tests:

  • Add contract and stub-rejection tests that exercise the new API composition, UI app composition, and Serenity suite convention checkers against both valid fixtures and intentionally incomplete stubs.
  • Introduce package-local architecture test suites in API, UI, and verification projects that consume the new archunit helpers to enforce composition and Serenity conventions as part of their test runs.

Chores:

  • Adjust root README formatting and perform minor code style cleanups in mock OAuth seedwork tests and related files.

@sourcery-ai

sourcery-ai Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Introduces reusable ArchUnit-style architecture fitness tests for Cellix APIs, UI apps, and Serenity suites, wires them into API/UI/verification packages via Vitest arch configs and test files, and hardens worktree-aware test infrastructure (timeouts, env wiring) and Serenity step abstractions while tightening TS/build setup and dependency overrides.

Sequence diagram for new Serenity staff landing route handling

sequenceDiagram
  actor StaffUser
  participant StaffLandingSteps
  participant SerenityActor as Actor
  participant SerenityNotes as notes

  StaffUser->>StaffLandingSteps: When enters staff operations workspace
  StaffLandingSteps->>SerenityActor: attemptsTo(OpenStaffLanding(route))
  SerenityActor->>SerenityNotes: set('targetRoute', route)

  StaffUser->>StaffLandingSteps: Then should be directed to expectedRoute
  StaffLandingSteps->>SerenityActor: answer(StaffTargetRoute())
  SerenityActor->>SerenityNotes: get('targetRoute')
  SerenityActor-->>StaffLandingSteps: targetRoute
  StaffLandingSteps-->>StaffUser: compare targetRoute with expectedRoute
Loading

File-Level Changes

Change Details Files
Add reusable API, UI app, and Serenity architecture checkers plus Vitest helpers in @cellix/archunit-tests, including TypeScript source analyzers and contract tests.
  • Implement TypeScript AST utilities to inspect imports, calls, JSX, and callbacks for architecture checks.
  • Add API composition checker ensuring Cellix.initializeInfrastructureServices → setContext → initializeApplicationServices → registerAzureFunction* → startUp order and lifecycle behavior, with helper to register Vitest suites.
  • Add UI app composition checker validating root element guarding, React StrictMode, required providers, and React Router routing, with Vitest suite helper.
  • Add Serenity suite convention checker enforcing managed world/lifecycle, context loader, Screenplay delegation, and managed infrastructure (servers/UI portals), with Vitest suite helper.
  • Create contract tests and stub-rejection tests that exercise success and failure paths for API/UI/Serenity checkers using temporary fixtures and bundled stub projects.
  • Exclude architecture stub fixtures from normal TS compilation and document the new modules and conventions in README and manifest.
packages/cellix/archunit-tests/src/checks/typescript-source.ts
packages/cellix/archunit-tests/src/checks/api-composition.ts
packages/cellix/archunit-tests/src/checks/ui-app-composition.ts
packages/cellix/archunit-tests/src/checks/serenity-suite-conventions.ts
packages/cellix/archunit-tests/src/test-suites/api-composition.ts
packages/cellix/archunit-tests/src/test-suites/ui-app-composition.ts
packages/cellix/archunit-tests/src/test-suites/serenity-suite-conventions.ts
packages/cellix/archunit-tests/src/api.ts
packages/cellix/archunit-tests/src/ui-app.ts
packages/cellix/archunit-tests/src/serenity.ts
packages/cellix/archunit-tests/src/application-composition.contract.test.ts
packages/cellix/archunit-tests/src/serenity.contract.test.ts
packages/cellix/archunit-tests/src/stub-rejection.contract.test.ts
packages/cellix/archunit-tests/src/fixtures/architecture-stubs/**
packages/cellix/archunit-tests/tsconfig.json
packages/cellix/archunit-tests/readme.md
packages/cellix/archunit-tests/manifest.md
packages/cellix/archunit-tests/package.json
packages/cellix/archunit-tests/src/index.ts
Wire new architecture test suites into API, UI, acceptance, and e2e projects via Vitest arch configs and minimal per-project test entrypoints.
  • Add vitest.arch.config.ts files in API/UI/verification packages using shared @cellix/config-vitest archConfig.
  • Add test:arch scripts and Vitest/dev-dependency wiring in package.json for API, UI apps, acceptance, and e2e packages.
  • Create small archunit test files per project that call describeApiCompositionTests, describeUiAppCompositionTests, or describeSerenitySuiteConventionTests with project-specific roots and provider lists.
apps/api/src/archunit-tests/api-composition.test.ts
apps/api/package.json
apps/ui-community/src/archunit-tests/ui-app-composition.test.ts
apps/ui-community/vitest.arch.config.ts
apps/ui-community/package.json
apps/ui-staff/src/archunit-tests/ui-app-composition.test.ts
apps/ui-staff/vitest.arch.config.ts
apps/ui-staff/package.json
packages/ocom-verification/acceptance-api/src/archunit-tests/serenity-conventions.test.ts
packages/ocom-verification/acceptance-api/vitest.arch.config.ts
packages/ocom-verification/acceptance-api/package.json
packages/ocom-verification/acceptance-ui/src/archunit-tests/serenity-conventions.test.ts
packages/ocom-verification/acceptance-ui/vitest.arch.config.ts
packages/ocom-verification/acceptance-ui/package.json
packages/ocom-verification/e2e-tests/src/archunit-tests/serenity-conventions.test.ts
packages/ocom-verification/e2e-tests/vitest.arch.config.ts
packages/ocom-verification/e2e-tests/package.json
Refine Serenity acceptance step definitions by introducing Screenplay tasks/questions and sharing staff landing route state via typed notes abstractions instead of direct notes manipulation in steps.
  • Introduce StaffApiNotes interface under contexts/staff/notes and a StaffTargetRoute Question that reads the target route from notes.
  • Introduce OpenStaffLanding Interaction that sets the target route in notes via an Actor.
  • Update staff-landing.steps.ts to use OpenStaffLanding tasks in When steps and StaffTargetRoute Question in Then steps, removing inline notes usage and local notes interface.
packages/ocom-verification/acceptance-api/src/contexts/staff/notes/staff-notes.ts
packages/ocom-verification/acceptance-api/src/contexts/staff/tasks/open-staff-landing.ts
packages/ocom-verification/acceptance-api/src/contexts/staff/questions/staff-target-route.ts
packages/ocom-verification/acceptance-api/src/contexts/staff/step-definitions/staff-landing.steps.ts
Make e2e test environment and Serenity lifecycle more robust in worktree mode by retargeting service env vars and adding a dedicated cold-boot timeout.
  • Extend e2e test environment loader to call applyWorktreeServiceEnv when WORKTREE_NAME is set, rewriting Azurite connection string ports, AzureWebJobsStorage, Mongo connection string, and mock-auth OIDC endpoint/issuer hosts to worktree-specific values using shared port helpers.
  • Update Serenity Cucumber lifecycle hook registration to pass a new boot timeout (from getTimeout('boot')) for the first Before hook, in addition to per-scenario timeouts.
  • Expose a new boot timeout in defaultVerificationTimeouts with documentation about cold-start behavior.
packages/ocom-verification/e2e-tests/src/shared/environment/test-environment.ts
packages/ocom-verification/e2e-tests/src/cucumber-lifecycle-hooks.ts
packages/cellix/serenity-framework/src/settings/timeout-settings.ts
Tighten build, TypeScript, and dependency setup for archunit tests and cleanup minor test formatting.
  • Exclude architecture stub fixtures from @cellix/archunit-tests main TS compilation to keep them as explicit negative fixtures only.
  • Add new subpath exports (api, ui-app, serenity) from @cellix/archunit-tests and re-export from the main index for consumers.
  • Consolidate pnpm brace-expansion overrides to major-range keys and bump to newer patch/minor versions.
  • Reformat a few test files for single-line writeUsers/writeEnv calls and condensed warnSpy expectation without behavior change.
  • Add a small whitespace tweak in the root readme and touch .snyk/turbo/lock/mock-oidc fixtures as part of dependency/infra updates (no behavioral logic added).
packages/cellix/archunit-tests/tsconfig.json
packages/cellix/archunit-tests/package.json
packages/cellix/archunit-tests/src/index.ts
pnpm-workspace.yaml
packages/cellix/server-oauth2-mock-seedwork/tests/file-user-store.test.ts
packages/cellix/server-oauth2-mock-seedwork/tests/portal-discovery.test.ts
readme.md
.snyk
packages/ocom/service-queue-storage/turbo.json
pnpm-lock.yaml
apps/ui-community/mock-oidc.users.json
apps/ui-staff/mock-oidc.users.json

Possibly linked issues

  • #Integrate ArchUnitTS with Vitest for workspace package architectural fitness testing: PR implements Vitest-integrated ArchUnitTS-style architecture suites, adds initial tests and configs across packages, fulfilling the issue.

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

@jasonmorais jasonmorais marked this pull request as ready for review July 1, 2026 19:10
@jasonmorais jasonmorais requested a review from a team July 1, 2026 19:10
@jasonmorais jasonmorais requested a review from a team as a code owner July 1, 2026 19:10

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

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 new architecture checkers (checkApiComposition, checkUiAppComposition, checkSerenitySuiteConventions) rely heavily on brittle string/regex matching; consider pushing some of these checks through a TypeScript/AST-based helper or more tolerant patterns so minor formatting/import changes in consumer code don’t cause spurious violations.
  • In checkSerenitySuiteConventions, the per-context and per-step-file checks are performed sequentially with multiple await calls; if these suites will scan many contexts/files, consider batching the file reads (e.g., with Promise.all) to keep the architecture test runtime reasonable.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new architecture checkers (`checkApiComposition`, `checkUiAppComposition`, `checkSerenitySuiteConventions`) rely heavily on brittle string/regex matching; consider pushing some of these checks through a TypeScript/AST-based helper or more tolerant patterns so minor formatting/import changes in consumer code don’t cause spurious violations.
- In `checkSerenitySuiteConventions`, the per-context and per-step-file checks are performed sequentially with multiple `await` calls; if these suites will scan many contexts/files, consider batching the file reads (e.g., with `Promise.all`) to keep the architecture test runtime reasonable.

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.

@jasonmorais

Copy link
Copy Markdown
Contributor Author

@sourcery-ai review

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

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 Serenity suite convention checker relies on literal string matches like registerLifecycleHooks() in world.ts, which seems at odds with your own contract tests where lifecycle hooks are defined in cucumber-lifecycle-hooks.ts; consider tightening this to check for the lifecycle import/usage in the lifecycle file rather than enforcing a call in world.ts.
  • The UI app composition checks enforce a specific if/throw root guard via AST (containsIfThrow), which may be too rigid for apps that guard the mount point differently (e.g., assertions or helper functions); you might want to broaden this check to validate presence of a null-check and error handling without requiring an exact if + throw shape.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The Serenity suite convention checker relies on literal string matches like `registerLifecycleHooks()` in `world.ts`, which seems at odds with your own contract tests where lifecycle hooks are defined in `cucumber-lifecycle-hooks.ts`; consider tightening this to check for the lifecycle import/usage in the lifecycle file rather than enforcing a call in `world.ts`.
- The UI app composition checks enforce a specific `if`/`throw` root guard via AST (`containsIfThrow`), which may be too rigid for apps that guard the mount point differently (e.g., assertions or helper functions); you might want to broaden this check to validate presence of a null-check and error handling without requiring an exact `if` + `throw` shape.

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.

1 participant