Skip to content

[EPAC-1875]: Add integration tests for POST /api/v1/device/register handler#459

Merged
riddim-developer-bot[bot] merged 2 commits into
mainfrom
symphony/epac-1875-add-integration-tests-for-post-api-v1-device-reg
May 14, 2026
Merged

[EPAC-1875]: Add integration tests for POST /api/v1/device/register handler#459
riddim-developer-bot[bot] merged 2 commits into
mainfrom
symphony/epac-1875-add-integration-tests-for-post-api-v1-device-reg

Conversation

@riddim-developer-bot
Copy link
Copy Markdown
Contributor

Why

The device-register upsert SQL — including the ON CONFLICT DO UPDATE clause and TEXT[] array storage for topic_ids / bill_ids — was only exercised by mocked-repository tests. Schema drift, array serialization bugs, or a removed ON CONFLICT clause would not fail existing tests. This PR adds five DB-backed integration tests that catch those failures at PR time.

What changed

  • backend/device-register/main_integration_test.go (new): five integration tests under //go:build integration, each wrapped in _testdb.WithTx for rollback isolation.
    • TestDeviceRegisterHappyPath_InsertsRow — full payload insert, asserts all fields written.
    • TestDeviceRegisterUpsert_SameTokenUpdates — seeds a row then re-POSTs; asserts exactly one row with updated topic_ids.
    • TestDeviceRegisterMissingToken_Returns400 — empty JSON body; asserts 400 with "token" in error message.
    • TestDeviceRegisterMalformedJSON_Returns400 — non-JSON body; asserts 400 and zero rows written.
    • TestDeviceRegisterEmptyFollows_StoresEmptyArrays — omitted arrays; asserts non-NULL {} stored, not NULL.
  • backend/device-register/go.mod: added epac/_testdb v0.0.0 require + replace directive (mirrors pattern in live-status/go.mod).

Trade-offs not taken

  • Did not use t.Parallel() — the harness shares one migrated schema and sync.Once; parallel tests would race on migrated.Do. Sequential is consistent with all other integration tests in the repo.
  • Did not assert granularity JSONB readback — the AC does not require it and the column defaults to {}. The core correctness (array types, upsert) is what matters here.

Test plan

# Requires Docker
cd backend
docker compose -f docker-compose.test.yml up -d
cd device-register
DATABASE_URL=postgres://epac:epac@localhost:5433/epac_test go test -tags=integration -v ./...
docker compose -f ../docker-compose.test.yml down

CI runs this automatically via the backend-integration-tests workflow.

Verification

  • go build ./... — clean
  • go vet -tags=integration ./... — clean
  • Integration tests require a live Postgres instance (DATABASE_URL); skipped locally without Docker but run in CI.

Resolves EPAC-1875

Reviewer-Boundary: review-only

Five integration tests under //go:build integration verify the real
device_subscriptions upsert SQL — happy path insert, ON CONFLICT update,
missing token 400, malformed JSON 400 with no DB write, and empty
follow-lists stored as non-NULL empty arrays.

Also wires epac/_testdb into go.mod so the harness is available to the
device-register test binary.
@riddim-developer-bot riddim-developer-bot Bot added the autonomous Enrolled in prconverged daemon for automated review and merge label May 14, 2026
@riddim-developer-bot riddim-developer-bot Bot enabled auto-merge (squash) May 14, 2026 23:20
…efore t.Cleanup

The test registered a t.Cleanup(restoreSpeechVectors) callback but also used
defer conn.Close(ctx). Defers fire when the function returns, before t.Cleanup
runs, so restoreSpeechVectors received an already-closed connection ("conn closed").

testdb.Connect already registers its own t.Cleanup to close the connection, so
the defer was redundant and harmful. Removing it restores the correct LIFO
cleanup order: restoreSpeechVectors runs first, conn.Close runs last.

Pre-existing failure on main (4 consecutive failures before EPAC-1875 PR).
@riddim-developer-bot
Copy link
Copy Markdown
Contributor Author

CI fix pushed — commit 4d7ad282

The test-integration job failed on TestSearchSpeechesLegacyFallback in backend/search/ (not in the device-register tests, which all passed: ok epac/device-register 0.740s).

Root cause (pre-existing on main — 4 consecutive failures before this PR opened):
TestSearchSpeechesLegacyFallback used defer conn.Close(ctx) which fired when the test function returned, closing the connection before the t.Cleanup(restoreSpeechVectors) callback could run — causing "conn closed". testdb.Connect already owns connection teardown via its own t.Cleanup, making the defer redundant and harmful.

Fix: removed the redundant defer conn.Close(ctx) from TestSearchSpeechesLegacyFallback only (the other search tests don't have t.Cleanup callbacks that use the connection, so their defer pattern is harmless). This restores the correct LIFO cleanup order: restoreSpeechVectors runs first, then conn.Close.

No production code changed. Device-register integration tests are unaffected.

@riddim-developer-bot riddim-developer-bot Bot added agent:working Symphony developer-bot lease (not a CI required check) and removed agent:working Symphony developer-bot lease (not a CI required check) labels May 14, 2026
@riddim-reviewer-bot riddim-reviewer-bot Bot added the agent:working Symphony developer-bot lease (not a CI required check) label May 14, 2026
@riddim-reviewer-bot
Copy link
Copy Markdown

⚠️ Autonomous review liveness watchdog

Symphony expected a reviewer-bot review for the current autonomous PR head within the configured SLA window, but none was found.

Copy link
Copy Markdown

@riddim-reviewer-bot riddim-reviewer-bot Bot left a comment

Choose a reason for hiding this comment

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

ReviewAutonomousPR

  • Verdict: approve
  • Reviewer boundary: review_only
  • Acceptance criteria coverage: covered=5, missing=0, unclear=0

Summary

The patch adds the requested DB-backed integration tests for POST /api/v1/device/register, including upsert and malformed-input behavior, and uses the shared integration harness correctly; overall it satisfies the acceptance criteria and is mergeable.

Actionable findings

  1. risk / follow_up — Malformed-JSON no-write assertion is table-scoped instead of token-scoped (backend/device-register/main_integration_test.go:173)
    • TestDeviceRegisterMalformedJSON_Returns400 asserts COUNT(*) FROM device_subscriptions == 0 after sending invalid JSON. This is broader than necessary and can yield brittle failures if other fixture/test rows are present in the same shared table state. A token-specific absence check is safer and still verifies the contract.
    • Actionability: follow_up

Acceptance criteria coverage

  • covered — TestDeviceRegisterHappyPath_InsertsRow
    • Implemented integration test posts valid payload, expects 200, reads back device_subscriptions, and validates stored token/member/topics/bills.
    • Actionability: none
    • Evidence: backend/device-register/main_integration_test.go
  • covered — TestDeviceRegisterUpsert_SameTokenUpdates
    • Implemented by seeding a row for a token, posting again with the same token, asserting single-row count and updated topic_ids.
    • Actionability: none
    • Evidence: backend/device-register/main_integration_test.go
  • covered — TestDeviceRegisterMissingToken_Returns400
    • Implemented with {} payload and asserts HTTP 400 plus error text containing token.
    • Actionability: none
    • Evidence: backend/device-register/main_integration_test.go
  • covered — TestDeviceRegisterMalformedJSON_Returns400
    • Implemented malformed JSON path and checks for HTTP 400 and no writes, with an assertion that is currently table-wide rather than token-scoped.
    • Actionability: follow_up
    • Evidence: backend/device-register/main_integration_test.go
    • Suggested follow-up: Scope no-write assertion to test token or fixture isolation
  • covered — TestDeviceRegisterEmptyFollows_StoresEmptyArrays
    • Implemented with missing topic_ids/bill_ids, asserts stored arrays are non-nil and length zero.
    • Actionability: none
    • Evidence: backend/device-register/main_integration_test.go

@riddim-developer-bot riddim-developer-bot Bot merged commit ff6903b into main May 14, 2026
32 of 34 checks passed
@riddim-developer-bot riddim-developer-bot Bot deleted the symphony/epac-1875-add-integration-tests-for-post-api-v1-device-reg branch May 14, 2026 23:56
@riddim-reviewer-bot riddim-reviewer-bot Bot removed the agent:working Symphony developer-bot lease (not a CI required check) label May 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autonomous Enrolled in prconverged daemon for automated review and merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants