Skip to content

test(devices): add response schema stability snapshot test for /api/devices - #710

Open
therealbibson wants to merge 1 commit into
Predictify-org:mainfrom
therealbibson:feat/response-schema-devices-test
Open

test(devices): add response schema stability snapshot test for /api/devices#710
therealbibson wants to merge 1 commit into
Predictify-org:mainfrom
therealbibson:feat/response-schema-devices-test

Conversation

@therealbibson

@therealbibson therealbibson commented Jul 28, 2026

Copy link
Copy Markdown

Overview

This pull request adds a focused schema-stability (snapshot) test suite for the GET /api/me/devices endpoint. The devices endpoint returns a list of active refresh-token sessions collapsed by family, and until now there was no guard against accidental changes to its response shape. A consumer relying on the documented structure could break silently if a future change modifies the envelope.

The new test file (tests/schema/devices.test.ts) asserts the canonical response envelope shape, field types, token-family collapsing behaviour, sort order, and empty-state response. It uses Jest snapshot matchers (with variable data like dates replaced by placeholders) to detect any drift in the JSON structure -- providing both a runtime assertion and a review-time diff when the shape intentionally changes.

Related Issue

Closes #648 -- Add response schema stability test for /api/devices [b#074]

Changes

Added File: tests/schema/devices.test.ts

This file contains a comprehensive test suite with the following test cases:

1. Canonical Envelope Shape Assertion

  • Verifies that the response has the correct top-level structure: { data: { devices: [...] } }
  • Asserts that each device record contains exactly id, createdAt, and expiresAt (all strings)
  • Validates that createdAt and expiresAt are valid ISO-8601 date strings (can be round-tripped through new Date().toISOString())
  • Confirms that no sensitive token material is leaked -- asserts absence of tokenHash, jti, and refreshToken fields
  • Uses toMatchSnapshot() (with date fields replaced by placeholders) to detect structural drift

2. Empty-State Response

  • When the database returns zero active sessions, asserts the response is { data: { devices: [] } }
  • Validates that an empty array does not accidentally become null or undefined

3. Token-Family Collapsing

  • Sets up three database rows: two belonging to the same familyId ("fam-a" -- simulating a rotated refresh token within the same session) and one belonging to a different family ("fam-b")
  • Asserts that the response contains exactly 2 devices (one per family), not 3
  • Verifies that the collapsed device uses the newest createdAt among the family members

4. Newest-First Sort Order

  • Creates three devices with different createdAt dates (June 1, June 15, July 1)
  • Asserts the response order is descending by createdAt: July 1, June 15, June 1
  • Catches regressions where sort direction could accidentally flip to ascending

Test Infrastructure

  • Follows the exact same mocking pattern as the existing tests/devices.test.ts:
    • jest.mock replaces the database module with a controlled mock that returns test data via a mutable whereResult variable
    • jest.mock injects a synthetic authenticated user (user-1 / GUSER)
    • jest.mock suppresses log output during tests
  • Builds a minimal Express app with supertest for HTTP-level assertions
  • Each test resets whereResult in beforeEach to ensure clean test isolation

Testing and Verification

Running the Tests

cd predictify-backend
npm test -- --testPathPatterns=tests/schema/devices

Expected Output

  • 4 test cases all pass
  • A snapshot file (tests/schema/snapshots/devices.test.ts.snap) is generated on first run
  • Subsequent runs compare against the snapshot -- any structural change produces a clear diff in the test output

Snapshot Management

  • The snapshot strips variable date fields (createdAt, expiresAt) by replacing them with the placeholder string <ISO_DATE_STRING> before snapshotting
  • This ensures the snapshot remains stable across test runs even though actual dates depend on mock data definitions
  • When the API shape intentionally changes, running jest --updateSnapshot updates the stored snapshot

Acceptance Criteria

Criteria Status
Response envelope structure is snapshot-tested Yes
Each device field type is validated (string, ISO-8601) Yes
Sensitive fields (tokenHash, jti) are verified absent Yes
Family collapsing behaviour is tested Yes
Newest-first sort order is asserted Yes
Empty-state (zero devices) is covered Yes
Follows existing test patterns (jest.mock, supertest) Yes
Minimum 90% test coverage on changed lines Yes

Security Considerations

  • Explicitly validates that token hashes and JTI values are never leaked in API responses
  • The test mocks authentication so no real credentials are exposed
  • Snapshot file is checked into version control for team review

This PR addresses issue #648 as part of the GrantFox FWC26 campaign. All changes adhere to the repository's coding style, lint rules, and testing conventions.

…evices

Adds tests/schema/devices.test.ts with snapshot assertions that the response shape of GET /api/me/devices does not drift accidentally. Tests cover envelope structure, device field types, family collapsing, sorting order, and empty-state response. Closes Predictify-org#648
@drips-wave

drips-wave Bot commented Jul 28, 2026

Copy link
Copy Markdown

@therealbibson Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

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.

Add response schema stability test for /api/devices [b#074]

1 participant