Skip to content

fix: restore and test typed analytics mock accessors - #395

Merged
Lakes41 merged 2 commits into
Adamantine-guild:mainfrom
Flames4fun:fix/analytics-mock-accessor-tests
Aug 19, 2026
Merged

fix: restore and test typed analytics mock accessors#395
Lakes41 merged 2 commits into
Adamantine-guild:mainfrom
Flames4fun:fix/analytics-mock-accessor-tests

Conversation

@Flames4fun

Copy link
Copy Markdown
Contributor

Description

This PR restores the typed analytics accessor implementation in MockAccessApi and adds focused regression coverage for its public analytics contract.

The analytics section of lib/api/mock.ts contained two consecutive declarations for the same analytics property. The second declaration used any and left the module syntactically invalid, preventing the test compiler from parsing the mock API.

The implementation removes only the duplicate untyped declaration and preserves the existing AnalyticsDataSource contract. It then moves the pre-existing analytics fixture tests into the repository's discoverable test/ directory and adds direct tests for every accessor exposed through MockAccessApi.analytics.

The change intentionally remains small: it does not alter analytics behavior, production API contracts, CI/CD configuration, generated types, application rendering, or the live API implementation.

Linked Issue

Closes #391

Type of Change

  • Bug fix (UI or API integration)
  • New feature / component
  • UI/UX improvement
  • Documentation update
  • Chore / refactor / dependency update
  • Tests only

Changes Made

  • Removed the duplicate public analytics: any declaration that prevented lib/api/mock.ts from parsing.
  • Preserved the typed public analytics: AnalyticsDataSource declaration.
  • Moved lib/api/analytics/mock.test.ts to test/mock-analytics.test.ts, where it is discovered by the existing Node.js test runner configuration.
  • Preserved all 17 existing analytics fixture and invariant tests.
  • Added focused public-contract tests for:
    • getMembershipTrend
    • getRoleDistribution
    • getAccessAttempts
  • Added a public-surface guard that enumerates the three accessors declared by AnalyticsDataSource. If another accessor is exposed later without corresponding test coverage, the suite will fail and require an explicit review.
  • Added explicit resourceAccess coverage through the public getAccessAttempts accessor.
  • Strengthened representative-value assertions:
    • Membership growth contains 30 consecutive daily entries.
    • Growth starts from the documented seed of 80 members.
    • Each newMembers value matches the change in totalMembers.
    • Seeded role counts are validated for member, moderator, and admin.
    • All three seeded resource-access entries are validated.
  • Asserted public response keys and values rather than object or array reference identity.
  • Did not modify CI/CD configuration, package.json, test/tsconfig.json, OpenAPI fixtures, generated API types, or UI components.

Why This Approach

Several approaches were considered during the investigation:

1. Keep the tests under lib/api/analytics/ and change the test runner configuration

This would make the tests discoverable, but it would expand the change into repository-wide test configuration. The established convention is to place executable tests directly under test/, and the issue explicitly requests the repository's existing framework and conventions.

2. Test only MOCK_ANALYTICS_SUMMARY and its internal helper functions

The previous suite already provided strong fixture-level coverage, but those tests could remain green while the public MockAccessApi.analytics accessors returned a different or malformed structure. This would not fully protect the behavior consumed by the application.

3. Render the Next.js analytics page

A rendering test would exercise substantially more code, including authentication state, React Query behavior, and component setup. It would be slower, more brittle, and less precise when diagnosing an accessor regression.

4. Directly test the public mock API while preserving the existing fixture tests

This approach was selected because it provides the strongest issue-specific signal with the smallest production change. It follows the repository's Node.js test conventions, exercises the exact API consumed by the analytics page, and avoids coupling the tests to React or Next.js rendering.

The work is separated into two conventional commits so the parser correction can be reviewed independently from the test relocation and coverage changes:

  • fix: restore typed analytics mock accessor
  • test: cover analytics mock accessors

Acceptance Criteria Verification

Acceptance criterion Evidence
Analytics mock accessors currently exposed by the module have focused tests All three methods declared by AnalyticsDataSource have direct MockAccessApi.analytics tests. An additional surface test enumerates the three exposed method names.
resourceAccess is explicitly covered if exposed through the API getAccessAttempts validates the complete public shape and representative values for all three seeded resources.
Tests assert the public shape rather than implementation-specific object identity Tests validate keys, primitive values, collection contents, and semantic relationships. They do not require returned arrays or objects to retain a specific reference identity.
Tests use the repository's existing test framework and conventions Tests use node:test, node:assert/strict, test/setup-env, and the existing top-level test/ discovery pattern.
No CI/CD configuration is added No CI/CD, workflow, package-script, or test-runner configuration files were changed.

Screenshots / Recordings

Not applicable. This PR does not modify UI behavior or rendering.

Test Evidence

Focused committed suite

node --test test-dist/test/mock-analytics.test.js

tests 21
suites 1
pass 21
fail 0
cancelled 0
skipped 0
todo 0

Static validation

npm run lint -- --file lib/api/mock.ts --file test/mock-analytics.test.ts
No ESLint warnings or errors
npm run check-types
SUCCESS: Frontend API types are in sync with openapi.json.

git diff --check also completed successfully.

Repeated and adversarial simulations

The focused suite and accessors were additionally exercised through the following local audit scenarios:

  • 40 isolated executions of the final focused suite:
    • 840 tests executed
    • 0 failures
  • Five timezone configurations:
    • UTC
    • America/Los_Angeles
    • America/Bogota
    • Asia/Kathmandu
    • Pacific/Kiritimati
    • 105 tests executed
    • 0 failures
  • 18 date-boundary and randomness simulations covering:
    • Leap-year boundaries
    • New-year boundaries
    • End-of-year boundaries
    • Math.random() = 0
    • Math.random() = 0.999999
    • Multiple extreme timezones
  • 100 concurrent batches:
    • 300 concurrent accessor calls validated
  • Detached invocation of all three accessor functions.
  • Role-distribution verification across:
    • guildpass-demo
    • builders-collective
    • design-guild
    • guildpass-hub
    • An unknown community ID exercising the documented fallback
  • Selected mutation testing:
    • Uncovered extra accessor
    • Structurally valid but flat membership growth
    • Incorrect role counts
    • Incorrect value for a secondary resource
    • All four selected mutants were detected by the final suite

These simulations were used as an adversarial local audit. They are not added as expensive repeated CI tests.

Repository-wide test limitation

The repository's current npm test command is:

tsc -p test/tsconfig.json --skipLibCheck && node --test test-dist/test/*.test.js

The TypeScript phase reports 76 existing diagnostics and exits before the Node.js runner starts. The diagnostics include unrelated existing issues in:

  • SIWE context consumers
  • CommunityState persistence compatibility
  • Existing invalid_state API error codes
  • Query key assertions
  • Wallet session nullability
  • test/admin-guard.test.tsx
  • Duplicated declarations in test/pending-actions.test.ts

A fresh partial verification was therefore performed with:

npx.cmd tsc -p test/tsconfig.json --skipLibCheck --noEmitOnError false
node --test test-dist/test/mock-analytics.test.js

The first command still reports the existing repository diagnostics but emits an updated focused test artifact. The second command passes all 21 analytics tests.

This PR does not claim that the repository-wide npm test or npm run typecheck commands are green.

Mock/live coverage

  • Tested directly against MockAccessApi
  • Tested against live guildpass-core -- not applicable; no live API behavior was changed

Out-of-Scope Findings

The adversarial audit identified several existing concerns. They were intentionally not modified because they would change runtime behavior or broaden this focused test-coverage PR.

AbortSignal behavior

The mock analytics accessors accept an AbortSignal, but currently ignore it. Calling an accessor with an already-aborted signal still resolves normally.

Changing this would require defining cancellation semantics for the mock API and adding corresponding error-handling behavior. That should be handled as a separate contract-level change.

Shared mutable response references

getMembershipTrend and getAccessAttempts return arrays backed by shared fixture references. A consumer can mutate a returned object and affect subsequent calls.

Defensive cloning or immutable fixtures would reduce this risk, but either approach changes existing mock behavior and should be reviewed separately. The tests in this PR deliberately avoid asserting this reference identity.

Analytics contract and documentation drift

MockAccessApi.getAnalyticsSummary() exists as a concrete public class method but is not declared on the composed AccessApi contract.

The current application consumes api.analytics.getMembershipTrend, getRoleDistribution, and getAccessAttempts, while parts of docs/architecture.md describe a different client-computed analytics flow.

The corresponding LiveAccessApi.analytics property also remains typed as any.

Reconciling the legacy summary method, live API typing, consumers, and architecture documentation would be valuable, but it is larger than the focused mock-test issue.

Existing repository validation failures

npm run typecheck currently stops at an unrelated unclosed <Card> element in app/[communitySlug]/admin/settings/page.tsx.

The full lint command also reports unrelated existing errors in billing, admin, developer, policy-dialog, admin-module, settings, and wallet files.

These files were not changed by this PR.

Existing dependency advisories

The local dependency installation reported 31 advisories in the existing dependency graph:

  • 21 moderate
  • 9 high
  • 1 critical

It also reported an existing security warning for the installed Next.js version.

No dependency manifests or lockfiles were changed because dependency remediation is unrelated to this issue and may require coordinated breaking upgrades.

Checklist

  • I have read CONTRIBUTING.md
  • This PR is linked to issue Introduce focused tests for analytics mock API accessors #391
  • npm run typecheck passes -- blocked by pre-existing repository errors described above
  • npm run lint passes globally -- focused lint passes; global lint is blocked by pre-existing errors
  • npm run check-types passes
  • Focused analytics tests pass in mock mode
  • No inline styles were introduced
  • No secrets or API keys are included
  • No environment variables were added
  • No CI/CD configuration was changed
  • No generated API types or OpenAPI fixtures were edited
  • Existing analytics fixture tests were preserved
  • Accessibility review is not applicable because no UI or interactive elements changed
  • Loading, empty, and error-state UI review is not applicable because no feature UI changed

Additional Notes

The branch was created from an updated upstream/main with no commit divergence before the implementation began.

The PR is intentionally limited to restoring the typed mock accessor and protecting its current public response contract. The broader findings above are documented for maintainers rather than silently bundled into this change.

Remove the duplicate untyped declaration that prevented the mock API from parsing while preserving the AnalyticsDataSource contract.
Move the existing analytics fixture suite into the discovered test directory and add focused public-contract coverage for membership trends, role distribution, and resource access.
@Lakes41
Lakes41 merged commit a52c54b into Adamantine-guild:main Aug 19, 2026
1 check passed
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.

Introduce focused tests for analytics mock API accessors

2 participants