Skip to content

test: harden silently-passing tests, prune framework-only and duplicate ones#1339

Merged
ascorbic merged 3 commits into
mainfrom
test/fix-silent-skip-tests
Jun 4, 2026
Merged

test: harden silently-passing tests, prune framework-only and duplicate ones#1339
ascorbic merged 3 commits into
mainfrom
test/fix-silent-skip-tests

Conversation

@ascorbic

@ascorbic ascorbic commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator

What does this PR do?

Audit-driven cleanup of low-value and misleading tests. The audit surfaced a long list of suspect tests; this PR acts only on the ones that are genuinely broken or worthless, after verifying each against the code under test. (Many flagged tests turned out to be legitimate, mocks at a network/dependency boundary that still assert real logic, and were left untouched.)

Fixed tests that passed even when the asserted behavior was broken:

  • integration/auth/device-flow.test.ts — the Token Revoke suite used if (!result.success) return; with no preceding expect, so a failed device-code/token exchange returned green. Added expect(...success).toBe(true) before the narrowing guard (matching the rest of the file).
  • integration/wordpress-migration/theme-unit-test.test.ts — ~7 conversions gated all assertions on if (post), silently passing if the fixture lookup missed. Now assert the post exists (fixture verified to contain the blocks) and convert; the embed test (fixture has none) feeds synthetic markup; the content-integrity loop asserts it verified at least one post.
  • e2e/content-crud.spec.ts "publish action changes status" — clicked Publish behind if (isVisible()) and never checked the result. Now publishes unconditionally and asserts the action flips to "Unpublish".
  • e2e/plugins.spec.ts / e2e/wordpress-import.spec.ts "does not show error" — negative-only assertions that passed on a blank page. Anchored each with a positive content assertion.

Made registration-only tests actually exercise behavior:

  • unit/plugins/hooks.test.ts — the "hook sorting" and "content:beforeSave" tests only checked getHookCount. Rewritten to run the pipeline against a real in-memory DB context and assert priority order, dependency ordering, and content transformation/chaining. (The capability-enforcement tests were kept, they verify real registration gating.)

Strengthened accept-only / no-assertion tests:

  • unit/fields/all-fields.test.ts — image/file/portableText "validate structure" tests only asserted valid input did not throw; added reject cases.
  • cloudflare/db/do-dialect.test.ts — the no-op transaction test had no assertion; now asserts the read-only path issues no SQL to the stub.

Removed framework-only / tautological / duplicate tests:

  • Deleted admin/tests/editor/input-rules.test.ts — it built a vanilla TipTap editor from bare StarterKit and tested the framework, not any EmDash code.
  • auth-atproto/tests/auth.test.ts — removed the "descriptor shape invariants" block (asserted that hardcoded constants are non-empty strings).
  • cloudflare/tests/do-config.test.ts — removed passthrough tests redundant with the full-descriptor assertions.
  • SignupPage, MediaDetailPanel, invite-flow, settings-pages — removed/merged exact or same-name duplicate tests.

No production code changed; this is test-only.

Closes #

Type of change

  • Bug fix
  • Feature (requires maintainer-approved Discussion)
  • Refactor (no behavior change)
  • Translation
  • Documentation
  • Performance improvement
  • Tests
  • Chore (dependencies, CI, tooling)

Checklist

  • I have read CONTRIBUTING.md
  • pnpm typecheck passes
  • pnpm lint passes
  • pnpm test passes (or targeted tests for my change) — ran the changed suites (core plugins/fields/auth, auth-atproto, cloudflare, admin SignupPage/MediaDetailPanel); e2e specs use standard Playwright APIs and run in CI
  • pnpm format has been run
  • I have added/updated tests for my changes (if applicable) — this PR is the test change
  • User-visible strings wrapped for translation — n/a, no admin UI strings touched
  • I have added a changeset — n/a, test-only, no published package source changed
  • New features link to an approved Discussion — n/a, not a feature

AI-generated code disclosure

  • This PR includes AI-generated code — model/tool: Claude Opus 4.8 (opencode)

Screenshots / test output

Targeted runs after changes: core plugins dir 592 passed, device-flow + theme-unit-test 51 passed, fields 41 passed, auth-atproto 13 passed, cloudflare do-config/do-dialect 11 passed, admin SignupPage + MediaDetailPanel 25 passed. pnpm lint:quick clean, pnpm typecheck clean across all packages.

…te ones

Audit-driven cleanup of low-value and misleading tests:

- Fix silent-skip tests that passed when the asserted behavior was broken:
  device-flow Token Revoke (missing expect before the success guard),
  theme-unit-test gutenberg conversions (assertions gated on if(post)),
  and two e2e specs (publish status, plugins/wp-import "no error") that
  passed on a blank page.
- Rewrite plugins/hooks.test.ts sorting/beforeSave tests to actually
  execute the pipeline and assert ordering, dependency order, and content
  chaining instead of only checking getHookCount.
- Strengthen field structural validators (image/file/portableText) and the
  preview DO no-op transaction test with real reject/assert cases.
- Delete input-rules.test.ts (tested vanilla TipTap, not EmDash) and remove
  tautological/duplicate tests (auth-atproto descriptor invariants,
  do-config passthrough dupes, SignupPage/MediaDetailPanel/invite-flow/
  settings-pages duplicates).
Copilot AI review requested due to automatic review settings June 4, 2026 10:42
@changeset-bot

changeset-bot Bot commented Jun 4, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: f7b7479

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 4, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
emdash-playground f7b7479 Jun 04 2026, 11:04 AM

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 4, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
emdash-demo-cache f7b7479 Jun 04 2026, 11:04 AM

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 4, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
docs f7b7479 Jun 04 2026, 11:04 AM

@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Scope check

This PR changes 651 lines across 18 files. Large PRs are harder to review and more likely to be closed without review.

If this scope is intentional, no action needed. A maintainer will review it. If not, please consider splitting this into smaller PRs.

See CONTRIBUTING.md for contribution guidelines.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Cleans up and hardens the test suite by removing low-signal/tautological tests and tightening assertions in unit/integration/e2e coverage. In addition, it updates the Cloudflare astro dev SSR Vite pre-bundling list (with a changeset) to prevent re-optimize/reload cascades on first authenticated/admin/MCP requests.

Changes:

  • Harden multiple tests that previously could pass without exercising the intended behavior (adds positive anchors and reject/assertion guards).
  • Remove/merge framework-only or duplicate tests across admin, auth-atproto, and Cloudflare packages.
  • Expand Cloudflare SSR optimizeDeps.include to pre-bundle late-discovered auth/MCP/admin deps and add a patch changeset documenting the fix.

Reviewed changes

Copilot reviewed 17 out of 18 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/core/tests/unit/plugins/hooks.test.ts Reworks hook pipeline tests to execute real hook behavior using an in-memory SQLite/Kysely context.
packages/core/tests/unit/fields/all-fields.test.ts Adds negative/reject cases so schemas are required to throw on invalid inputs.
packages/core/tests/integration/wordpress-migration/theme-unit-test.test.ts Replaces conditional assertions with explicit fixture precondition assertions and adds a loop guard to prevent silently asserting nothing.
packages/core/tests/integration/auth/device-flow.test.ts Adds explicit success === true expectations before narrowing guards in revoke tests.
packages/core/src/astro/integration/vite-config.ts Adds additional Cloudflare SSR optimizeDeps.include entries to prevent dev-time re-optimize cascades for auth/MCP/admin-only imports.
packages/cloudflare/tests/do-config.test.ts Removes redundant passthrough tests.
packages/cloudflare/tests/db/do-dialect.test.ts Adds an assertion ensuring preview transaction methods don’t issue SQL (read-only behavior).
packages/auth-atproto/tests/auth.test.ts Removes tautological “descriptor invariants” tests that only assert constant shapes.
packages/admin/tests/editor/input-rules.test.ts Deletes framework-only TipTap tests that don’t validate EmDash behavior.
packages/admin/tests/components/SignupPage.test.tsx Prunes duplicate step-advance tests while keeping behavioral assertions.
packages/admin/tests/components/MediaDetailPanel.test.tsx Prunes duplicate caption-visibility coverage while keeping behavior checks.
e2e/tests/wordpress-import.spec.ts Anchors “no crash” checks with a positive heading assertion to avoid blank-page false positives.
e2e/tests/settings-pages.spec.ts Removes a duplicate “pipeline section” e2e test by folding checks into the primary test.
e2e/tests/plugins.spec.ts Anchors the regression guard with a positive “plugin count/content rendered” assertion.
e2e/tests/invite-flow.spec.ts Strengthens invite error assertions by checking the “Back to login” link is present.
e2e/tests/content-crud.spec.ts Makes publish action unconditional and asserts the UI flips to “Unpublish”.
demos/cloudflare/emdash-env.d.ts Updates generated demo collection typings (adds page template; expands featured_image shape).
.changeset/fix-cf-dev-optimize-cascade.md Adds a patch changeset describing the Cloudflare dev optimizeDeps fix.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +61 to +72
// A real in-memory DB is needed for the context factory so hooks can
// actually execute (getContext throws without one).
let db: Kysely<DbSchema>;

beforeEach(() => {
const sqliteDb = new Database(":memory:");
db = new Kysely<DbSchema>({ dialect: new SqliteDialect({ database: sqliteDb }) });
});

afterEach(async () => {
await db.destroy();
});
Comment on lines 192 to 193
// Find a post in the "Classic" category
const classicPost = wxrData.posts.find((p) => p.categories.includes("classic"));
Comment on lines +398 to 405
// Auth deps imported only on auth/login/callback routes, so
// the initial page scan misses them. Pre-bundle to avoid a
// re-optimize + reload cascade on first authenticated request.
"emdash > @oslojs/crypto/hmac",
"emdash > @oslojs/crypto/subtle",
"emdash > @oslojs/crypto/rsa",
"emdash > arctic",
// MCP SDK — server/index.js statically imports ajv (CJS-only).
@pkg-pr-new

pkg-pr-new Bot commented Jun 4, 2026

Copy link
Copy Markdown

Open in StackBlitz

@emdash-cms/admin

npm i https://pkg.pr.new/@emdash-cms/admin@1339

@emdash-cms/auth

npm i https://pkg.pr.new/@emdash-cms/auth@1339

@emdash-cms/auth-atproto

npm i https://pkg.pr.new/@emdash-cms/auth-atproto@1339

@emdash-cms/blocks

npm i https://pkg.pr.new/@emdash-cms/blocks@1339

@emdash-cms/cloudflare

npm i https://pkg.pr.new/@emdash-cms/cloudflare@1339

@emdash-cms/contentful-to-portable-text

npm i https://pkg.pr.new/@emdash-cms/contentful-to-portable-text@1339

emdash

npm i https://pkg.pr.new/emdash@1339

create-emdash

npm i https://pkg.pr.new/create-emdash@1339

@emdash-cms/gutenberg-to-portable-text

npm i https://pkg.pr.new/@emdash-cms/gutenberg-to-portable-text@1339

@emdash-cms/plugin-cli

npm i https://pkg.pr.new/@emdash-cms/plugin-cli@1339

@emdash-cms/plugin-types

npm i https://pkg.pr.new/@emdash-cms/plugin-types@1339

@emdash-cms/registry-client

npm i https://pkg.pr.new/@emdash-cms/registry-client@1339

@emdash-cms/registry-lexicons

npm i https://pkg.pr.new/@emdash-cms/registry-lexicons@1339

@emdash-cms/sandbox-workerd

npm i https://pkg.pr.new/@emdash-cms/sandbox-workerd@1339

@emdash-cms/x402

npm i https://pkg.pr.new/@emdash-cms/x402@1339

@emdash-cms/plugin-ai-moderation

npm i https://pkg.pr.new/@emdash-cms/plugin-ai-moderation@1339

@emdash-cms/plugin-atproto

npm i https://pkg.pr.new/@emdash-cms/plugin-atproto@1339

@emdash-cms/plugin-audit-log

npm i https://pkg.pr.new/@emdash-cms/plugin-audit-log@1339

@emdash-cms/plugin-color

npm i https://pkg.pr.new/@emdash-cms/plugin-color@1339

@emdash-cms/plugin-embeds

npm i https://pkg.pr.new/@emdash-cms/plugin-embeds@1339

@emdash-cms/plugin-field-kit

npm i https://pkg.pr.new/@emdash-cms/plugin-field-kit@1339

@emdash-cms/plugin-forms

npm i https://pkg.pr.new/@emdash-cms/plugin-forms@1339

@emdash-cms/plugin-webhook-notifier

npm i https://pkg.pr.new/@emdash-cms/plugin-webhook-notifier@1339

commit: f7b7479

@github-actions github-actions Bot added review/awaiting-author Reviewed; waiting on the author to respond and removed review/needs-review No maintainer or bot review yet labels Jun 4, 2026

@emdashbot emdashbot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The test-hardening work is genuinely good. The device-flow narrowing guards, the theme-unit-test if (post) removals, the unconditional e2e publish flow with Unpublish verification, the synthetic embed test, the hooks rewrite against a real in-memory DB context, and the deletion of framework-only TipTap tests are all real improvements that make the test suite more trustworthy.

However, this PR is not test-only despite its own description, title, and changeset checkbox saying otherwise. It smuggles in three non-test changes:

  1. packages/core/src/astro/integration/vite-config.ts — adds optimizeDeps.include entries for Cloudflare dev SSR.
  2. demos/cloudflare/emdash-env.d.ts — manually edits generated type declarations.
  3. .changeset/fix-cf-dev-optimize-cascade.md — a changeset for the above production change.

This violates AGENTS.md scope discipline ("No drive-by refactors… in unrelated files") and is materially misleading to reviewers — the PR description causes reviewers to skip the production diff thinking there is none.

The emdash-env.d.ts file in particular has a header that says "Generated by EmDash on dev server start / Do not edit manually", yet it was hand-edited. If the new fields are needed, the generator should be updated, not the output.

Recommendation: split the vite-config.ts change and its changeset into a separate bug-fix PR. Revert the manual edit of emdash-env.d.ts and regenerate it properly (or move it to its own PR). The test changes can then land cleanly.

(The technical correctness of each new optimizeDeps.include entry is unverified without a build, since the sandbox does not have node_modules installed.)

Comment on lines 397 to +399
"emdash > @emdash-cms/auth > @oslojs/webauthn",
// Auth deps imported only on auth/login/callback routes, so
// the initial page scan misses them. Pre-bundle to avoid a

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[needs fixing] This PR is explicitly described as test-only with no production code changes, yet it adds production build-configuration entries to the Cloudflare SSR optimizeDeps.include list. This violates AGENTS.md scope discipline ("No drive-by refactors, no bulk lint/type cleanups, no 'while I'm here' edits in unrelated files"). The vite-config.ts change and its changeset should be split into a separate bug-fix PR so reviewers can evaluate it on its own merits.

Comment thread demos/cloudflare/emdash-env.d.ts Outdated
ascorbic added 2 commits June 4, 2026 11:56
…lector, drop stray demos types

- hooks.test.ts: close the better-sqlite3 handle in afterEach (matches repo pattern)
- theme-unit-test: select a classic-category post with no wp: block markers so
  the classic-HTML fallback path is genuinely exercised
- revert an unrelated regenerated demos/cloudflare/emdash-env.d.ts that was
  swept in accidentally; merged latest main so the already-merged #1336
  vite-config/changeset no longer show in this PR's diff
@github-actions github-actions Bot added review/needs-rereview Author pushed changes since the last review and removed review/awaiting-author Reviewed; waiting on the author to respond labels Jun 4, 2026
@ascorbic ascorbic added the bot:review Trigger an emdashbot code review on this PR label Jun 4, 2026
@ascorbic

ascorbic commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks @copilot — addressed all three:

  1. sqlite handle not closed (hooks.test.ts) — fixed; afterEach now keeps a reference to the better-sqlite3 instance and calls sqliteDb.close() after db.destroy(), matching the pattern in exclusive-hooks.test.ts/email-pipeline.test.ts.
  2. classic-editor selector (theme-unit-test.ts) — fixed; the test now selects a classic-category post that also contains no <!-- wp: markers, so it genuinely exercises the classic-HTML fallback path instead of passing on whatever is in the category.
  3. vite-config / changeset in a "test-only" PR — good catch, but this was a stale-merge-base artifact, not an intended change. That work is the already-merged fix(core): pre-bundle auth/MCP/admin deps to stop CF dev optimize cascade #1336; my branch's copies were byte-identical to main, so they only appeared because the branch was cut before fix(core): pre-bundle auth/MCP/admin deps to stop CF dev optimize cascade #1336 landed. I've merged latest main (they now drop out of the diff) and reverted an unrelated regenerated demos/cloudflare/emdash-env.d.ts that got swept in. The PR is now genuinely test-only, so the description/checklist stand.

@emdashbot emdashbot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Prior review issue resolved: the non-test production changes (vite-config.ts, emdash-env.d.ts, and the changeset) have been dropped from the diff, and the PR is now genuinely test-only.

The test-hardening work is solid and the right thing to do:

  • The device-flow expect(...success).toBe(true) guards fix silently-passing narrowing blocks (matching the rest of the file).
  • The theme-unit-test removals of if (post) skips and toBeGreaterThanOrEqual(0) tautologies are real improvements; the synthetic embed markup and the tightened classic-editor selector both genuinely exercise the converter instead of skating by.
  • The e2e publish flow now asserts the status flip to "Unpublish", and the negative-only "does not show error" tests are anchored with positive content assertions so a blank page can't pass.
  • The hooks rewrite runs against a real in-memory DB context and verifies priority ordering, dependency ordering, and content chaining — previously it only checked registration counts.
  • Deleting the framework-only TipTap input-rules tests, duplicate SignupPage/MediaDetailPanel/settings-pages/invite-flow tests, and tautological descriptor-shape invariants is good cleanup.

I checked all 15 changed files against call sites, sibling implementations, and repo conventions. No logic bugs, regressions, or AGENTS.md violations remain. Good to land.

@github-actions github-actions Bot added review/approved Approved; no new commits since and removed review/needs-rereview Author pushed changes since the last review labels Jun 4, 2026
@ascorbic ascorbic merged commit 3adc603 into main Jun 4, 2026
47 of 48 checks passed
@ascorbic ascorbic deleted the test/fix-silent-skip-tests branch June 4, 2026 12:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/admin area/cloudflare area/core bot:review Trigger an emdashbot code review on this PR review/approved Approved; no new commits since size/XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants