Skip to content

test(client): add vitest coverage for Loop SDK#3

Merged
mattdecrevel merged 2 commits into
mainfrom
claude/loop-client-tests
May 28, 2026
Merged

test(client): add vitest coverage for Loop SDK#3
mattdecrevel merged 2 commits into
mainfrom
claude/loop-client-tests

Conversation

@mattdecrevel

Copy link
Copy Markdown
Owner

What

Adds the first vitest test suite for the @mattdecrevel/loop client package. 42 tests across 4 files, ~340ms local runtime.

Test files

  • packages/client/test/typed-helpers.test.ts — every typed helper (signup, subscription, feedback, cron, booking, contact, infra, error, generic, raw, raw notify). Verifies URL, bearer auth header, content-type, and the exact request body Loop receives. Includes parametrized cases for each subscription.kind (new, cancel, payment_failed, addon) and each feedback.category (bug, question, feature, general), and both cron.ok branches.
  • packages/client/test/optional-fields.test.tsLoopExtras (severity, category override, links, footerNote, digest, idempotencyKey, actions) flow onto the envelope, not the payload. Includes a @ts-expect-error guard that extras can't override the locked type field.
  • packages/client/test/fail-open.test.ts — confirms the SDK never throws into caller code: network rejection, HTTP 500, HTTP 401, and AbortController-driven timeout all resolve with undefined and log via console.error. The timeout test asserts the call returns well before the simulated slow response.
  • packages/client/test/tuples.test.ts — as-const tuples (LOOP_CATEGORIES, LOOP_SEVERITIES, LOOP_ACTIONS, LOOP_EVENT_TYPES, LOOP_EVENT_STATUSES) match the canonical Loop taxonomy as hardcoded sets (intentional guardrail — taxonomy drift requires touching this file). Adds compile-time satisfies checks so derived types stay aligned with tuple values.
  • packages/client/test/helpers.tsinstallFetchMock + bodyOf / urlOf / headerOf accessors so each test file stays declarative.

CI

New .github/workflows/test-client.yml runs on PRs touching packages/client/** (and pushes to main). Uses pnpm + Node 22, calls pnpm --filter @mattdecrevel/loop test.

Local test output

 RUN  v3.2.4 /Users/mattdecrevel/Development/loop/packages/client

 ✓ test/tuples.test.ts (6 tests) 3ms
 ✓ test/optional-fields.test.ts (6 tests) 15ms
 ✓ test/typed-helpers.test.ts (25 tests) 21ms
 ✓ test/fail-open.test.ts (5 tests) 70ms

 Test Files  4 passed (4)
      Tests  42 passed (42)
   Duration  343ms

Notes

  • No msw or heavy mocking lib — vi.spyOn(globalThis, 'fetch') is enough.
  • Vitest consumes the raw TS source directly (client has no build step).
  • Did not update packages/client/README.md — the SDK shape doc already lives there and the user noted no update was required.

🤖 Generated with Claude Code

mattdecrevel and others added 2 commits May 28, 2026 12:43
The README's 'Status & roadmap' section was claiming Phase 3 items
were deferred when they're all shipping in production:

- Digest aggregation cron (/api/cron/digest, every 6h in vercel.json)
- Idempotency enforcement (partial unique index + lib/ingest.ts lookup)
- Read API (/api/read, Bearer-authed via LOOP_READ_KEY)
- To-Do / Remind buttons (action handlers + reminders cron every 5min)

Rewrites Status to list everything actually shipping (including the
0.4.0 client + tuple exports) and trims Open list to the genuinely
open items: client/service tests, uptime monitoring, agent-seo reroute,
and a DB backup restore drill.

Also adds a note in 'Sending events' pointing at the new 0.4.0
LOOP_CATEGORIES / LOOP_SEVERITIES / LOOP_ACTIONS / LOOP_EVENT_TYPES /
LOOP_EVENT_STATUSES tuple exports for admin dropdowns.

No CLAUDE.md in this repo, so nothing to sweep there.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds vitest test suite for the @mattdecrevel/loop client package covering
the full public surface:

- typed helpers (signup, subscription, feedback, cron, booking, contact,
  infra, error, generic, raw) — assert URL, bearer auth, content-type,
  and exact request body for each
- optional LoopExtras flow-through (severity, category override, links,
  footerNote, digest, idempotencyKey, actions) and verification that
  extras spread onto the envelope rather than the payload
- fail-open behavior: helpers resolve (never throw) on network errors,
  HTTP 500/4xx responses, and AbortController-driven timeouts; all paths
  log to console.error
- as-const tuples (LOOP_CATEGORIES, LOOP_SEVERITIES, LOOP_ACTIONS,
  LOOP_EVENT_TYPES, LOOP_EVENT_STATUSES) — runtime values match the
  canonical Loop taxonomy and derived types align at compile time

Wires CI via a new test-client.yml workflow that runs on PRs touching
packages/client/**. No build step needed — vitest consumes the raw TS
source directly since the client ships as-is.

42 tests, 4 files, ~340ms locally.

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

vercel Bot commented May 28, 2026

Copy link
Copy Markdown

Deployment failed with the following error:

Hobby accounts are limited to daily cron jobs. This cron expression (*/5 * * * *) would run more than once per day. Upgrade to the Pro plan to unlock all Cron Jobs features on Vercel.

Learn More: https://vercel.link/3Fpeeb1

@mattdecrevel mattdecrevel merged commit 70c7c7f into main May 28, 2026
1 of 2 checks passed
@mattdecrevel mattdecrevel deleted the claude/loop-client-tests branch May 28, 2026 17:52
mattdecrevel added a commit that referenced this pull request May 28, 2026
…ipped

Three items from the open list landed in the last hour:

- Client tests: PR #3 (42 vitest tests covering typed helpers, fail-open,
  AbortController timeout, LoopExtras flow-through, tuple alignment)
- agent-seo SEO digest reroute: discovered already shipping in
  mattdecrevel.com (lib/seo/agent/adapters/base.ts) — the engine's
  notifySlack ignores its own payload and routes via notifyLoop() as a
  seo_report event
- Uptime monitoring: PR #342 on mattdecrevel.com adds a 5-min cron at
  /api/cron/loop-uptime with both a Loop infra event AND a fallback
  Slack webhook (so a Loop outage doesn't kill its own alert path)

Open list is now down to service tests + DB backup drill.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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