Skip to content

fix(server): repair tool_use integration tests broken in #3637 - #3655

Closed
bokelley wants to merge 1 commit into
mainfrom
bokelley/fix-server-integration-tests
Closed

fix(server): repair tool_use integration tests broken in #3637#3655
bokelley wants to merge 1 commit into
mainfrom
bokelley/fix-server-integration-tests

Conversation

@bokelley

Copy link
Copy Markdown
Contributor

Summary

Fixes three integration-test failures introduced in #3637 (route-level integration tests for the tool_use refactor) that have been breaking the Server integration tests CI job on main. Each had a distinct cause:

  1. property-enhancement-function.test.ts — module-load TypeError. The AdAgentsManager mock used vi.fn().mockImplementation(() => ({...})). The arrow function passed to mockImplementation cannot be called with new, but property-enhancement.ts:18 does new AdAgentsManager() at module scope. Fix: replace with class FakeAdAgentsManager { validateDomain = mocks.validateDomain }.

  2. brand-classifier-route.test.ts + brand-enrichment-route.test.tsSUFFIX used ${process.pid}_${Date.now()}. Underscores are invalid in domain names per RFC 1035, and both enrichBrand and the seed loop in expandHouse validate against ^[a-z0-9.-]+\.[a-z]{2,}$. The route returned {status: 'failed', error: 'Invalid domain format'} — yielding HTTP 500 where the tests expected 200, and seeded=0 where they expected 2. Fix: hyphen separator.

  3. prospect-triage-function.test.ts flakiness (not in the original CI failure list — that run got lucky — but reproducibly fails ~1-2/3 runs locally). triageEmailDomain fired logTriageDecision without awaiting, so the test queried prospect_triage_log before the INSERT landed. logTriageDecision already swallows its own errors internally, so awaiting it is contract-preserving and cannot cause triage to fail. Fix: await the call; remove the now-redundant outer .catch().

Why the production code change is safe

logTriageDecision (lines 247–267 of prospect-triage.ts) wraps its pool.query in try/catch and only logs warnings — awaiting cannot bubble new errors. All 3 callers of triageEmailDomain already await it; no caller depended on early return. The added latency is one synchronous INSERT into prospect_triage_log on a function that already does an Anthropic messages.create (~hundreds of ms), so it's noise.

The deeper signal: the test was correctly asserting on a side effect that the implementation was firing-and-forgetting. The contract should be "function returned" = "audit row exists." Awaiting aligns the implementation with that invariant.

Verification

  • All 4 test files pass locally (9/9 tests).
  • prospect-triage-function.test.ts stable across 3 consecutive runs.
  • Pre-commit (typecheck + unit tests) green.
  • Reviewed by code-reviewer and nodejs-testing-expert agents — both say ship; no blockers.

Out of scope (follow-up)

brand-properties-parse.test.ts:69 and addie-brand-property-tools.test.ts:51 still use ${process.pid}_${Date.now()} underscore-SUFFIX. They pass today because their domains skip the RFC 1035 regex, but they're latent traps. Worth a separate issue to standardize hyphen-SUFFIX across all integration tests (or extract a shared helper). Not in this PR.

🤖 Generated with Claude Code

Three test files added in #3637 (route-level integration tests for the
tool_use refactor) broke the Server integration tests CI job. Each had a
distinct cause:

1. property-enhancement-function.test.ts — the AdAgentsManager mock used
   `vi.fn().mockImplementation(() => ({...}))`. The arrow function passed
   to mockImplementation cannot be called with `new`, but
   property-enhancement.ts does `new AdAgentsManager()` at module scope.
   Failure was a module-load TypeError, killing all tests in the file.
   Fix: use `class FakeAdAgentsManager { ... }` so the mock supports `new`.

2. brand-classifier-route.test.ts and brand-enrichment-route.test.ts —
   SUFFIX used `${process.pid}_${Date.now()}`. Underscores are invalid in
   domain names per RFC 1035, and both `enrichBrand` and the seed loop in
   `expandHouse` validate against `^[a-z0-9.-]+\.[a-z]{2,}$`. The route
   returned {status: 'failed', error: 'Invalid domain format'} — yielding
   HTTP 500 where the tests expected 200, and seeded=0 sub-brands where
   they expected 2. Fix: use a hyphen separator.

3. prospect-triage-function.test.ts (not in the original failure list,
   but flakily fails ~1-2/3 runs locally) — triageEmailDomain fired
   logTriageDecision without awaiting, so the test could query
   prospect_triage_log before the INSERT completed. logTriageDecision
   swallows its own errors, so awaiting it is contract-preserving and
   cannot cause triage to fail. Fix: await the call; removed the
   now-redundant outer .catch().

Verified locally: all 4 test files pass (9/9 tests), prospect-triage
stable across 3 consecutive runs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bokelley

Copy link
Copy Markdown
Contributor Author

Superseded by #3656, which merged ~2 minutes earlier with the same three fixes (hyphen SUFFIX + class mock + prospect-triage flake). Different choice on prospect-triage: #3656 added an awaitTriageLog poll helper in the test rather than changing triageEmailDomain to await its log write. Reasonable trade — preserves caller-visible latency on the fire-and-forget path. Closing this PR.

@bokelley bokelley closed this Apr 30, 2026
@bokelley
bokelley deleted the bokelley/fix-server-integration-tests branch April 30, 2026 11:29
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