Skip to content

test(plugin-auth): where-operator 覆盖测试迁到 sqlite :memory: 见证;contains pin 实测不可迁,留证上报 (#5830) - #5880

Merged
baozhoutao merged 1 commit into
mainfrom
claude/issue-5830-auth-tests-sqlite-witness
Aug 6, 2026
Merged

test(plugin-auth): where-operator 覆盖测试迁到 sqlite :memory: 见证;contains pin 实测不可迁,留证上报 (#5830)#5880
baozhoutao merged 1 commit into
mainfrom
claude/issue-5830-auth-tests-sqlite-witness

Conversation

@baozhoutao

Copy link
Copy Markdown
Contributor

Fixes #5830

⚠️ 本 PR 只做了 #5830 的一半,是刻意的。 另一半(auth-contains-filter.test.ts)的前提在开工第一步被实测证伪,按派单第 1 条停手上报 needs_decision,证据见下。合并本 PR 会自动关闭 #5830 —— 建议维护者裁决前先重开,或把开放的一半另立单。

背景

#5704 的程序是「driver-memory 在项目内的测试消费者迁到 sqlite 内存模式」,Q2-B 只留 undeclared-field-write-driver-split 一处参照臂。#5812/#5844#5704 survey(基线 a58c0b5)之后给 plugin-auth 带进了两个新消费者。本 PR 迁走其中能迁的那一个,并把另一个留下的实测理由写进注释。

验收证据:grep 前后

排除 driver-memory 包自身,git grep -l "from '@objectstack/driver-memory'" -- 'packages/**/*.test.ts':

BEFORE(origin/main @ e2bfa6ce3)—— 3 处

packages/plugins/plugin-auth/src/auth-contains-filter.test.ts
packages/plugins/plugin-auth/src/auth-where-operator-coverage.test.ts
packages/runtime/src/sandbox/undeclared-field-write-driver-split.integration.test.ts

AFTER(本分支)—— 2 处

packages/plugins/plugin-auth/src/auth-contains-filter.test.ts
packages/runtime/src/sandbox/undeclared-field-write-driver-split.integration.test.ts

派单预期是「只剩 driver-split 一处」。差的那一处不是漏做,是下面这条测量的结论。

前提验证:为什么 auth-contains-filter.test.ts 不能迁

packages/drivers/driver-sql/src/sql-driver.ts 的算子编译里,$regex$containsfallthrough 别名 —— 两者走同一个 applyContainsLike:

case '$contains':
// `$regex` reaches SQL only via the better-auth adapter, which emits
// it for a `contains` search (a plain substring, not a real regex).
case '$regex':
  this.applyContainsLike(builder, method, field, opValue);
  break;

也就是说,SQL 后端分不出 #5710 的缺陷和它的修复。实测(两个后端、同一份 fixture、同样的 4 个比较数):

比较数 $contains sqlite $regex sqlite $contains memory $regex memory
a.b ["a.b"] ["a.b"] ["a.b"] ["a.b","axb"]
^a [] [] [] ["a.b","axb"]
( ["x(y"] ["x(y"] ["x(y"] THROW(Invalid regular expression)
xb ["axb"] ["axb"] ["axb"] ["axb"]

sqlite 两列逐格相同,memory 两列在前三格格格不同,而那三格正好就是该文件行为面的三条 pin。

再把派单第 4 条要求的反向验证按原样跑一遍 —— 把 objectql-adapter.tscontains 支临时改回裸 $regex(即 #5710 的缺陷):

  • 现状(memory 见证):4 failed | 3 passed —— 契约面 1 条 + 行为面 3 条全红。
    × does not read `.` as a wildcard — `a.b` matches `a.b`, not `axb`
      AssertionError: expected [ 'a.b', 'axb' ] to deeply equal [ 'a.b' ]
    × does not read `^` as an anchor
      AssertionError: expected [ { name: 'a.b', …(6) }, …(1) ] to deeply equal []
    × matches a value that is not a legal regex, instead of failing on it
    
  • 迁移后(sqlite 见证,把同一行为面逐字搬到 sqlite 上跑):Tests 4 passed (4) —— 全绿,缺陷仍在适配器里。

所以迁移会把三条承重 pin 变成「因为分辨不出任何东西所以恒绿」的断言 —— 正是 fixture 三分法里「整条替换」那一类的反面教材。派单第 1 条的停手条件成立,故保留现状 + 把理由钉进注释,不硬做也不悄悄放着。

它什么时候能迁:等 #5702 落地。#5710 摘掉了 $regex 的最后一个 live producer,上面那个 case '$regex': 别名已是死产者代码;一旦 driver 侧改成按名拒收 $regex,SQL 臂就能以「算子不在 allowlist」的方式见证同一个缺陷,该文件即可迁移。

本 PR 实际改了什么

1. auth-where-operator-coverage.test.ts 迁到 sqlite :memory:

行为面(face 3)后端换成 @objectstack/driver-sql + better-sqlite3 :memory:,抄 PR #5806 batch 3 的现成写法,没有自创 harness;建表走 driver 自己的 initObjects(),不是 store 首写时凭空长出来的。

这个文件迁得动,同样是测出来的,不是假设:#5813 的缺陷是谓词被丢掉(filter 编译成 {},查询答成整表),凡是真正执行过滤的后端都见证得到;$nin / $startsWith / $endsWith 都是 FILTER_OPERATORS 成员,driver-sql 都真编译(whereNotIn,以及带显式 ESCAPEapplyLike)。

pin 实质零缩水,双向反验:

  • not_in 支改回静默丢弃(plugin-auth: convertWhere()not_in / starts_with / ends_with 没有分支,谓词被整条丢弃 —— 认证路径上的过滤放大 #5813 的原始形状)→ 4 failed | 23 passed,行为面报的正是整表:
    × `not_in` really excludes the listed rows
      AssertionError: expected [ 'abc_one', 'abc_z', 'x_abc', 'zed' ] to deeply equal [ 'abc_z', 'zed' ]
    
  • 更刁的一发:把 starts_with 错译成 $contains(拼得像、求值错)→ 6 failed | 21 passed,锚定语义和 count 都抓到了:
    × `starts_with` excludes a row that merely CONTAINS the value
      AssertionError: expected [ 'abc_one', 'abc_z', 'x_abc' ] to deeply equal [ 'abc_one', 'abc_z' ]
    × `count` counts the matches, not the table
      AssertionError: expected 3 to be 2
    
  • 改回后全绿:Test Files 36 passed (36) / Tests 820 passed (820)

两处顺带的收敛,都是「靠声明解决,不是靠放松」(#5806 的做法):

delete 双件仍以 assertEngineDeleteDispatch(options) 开场,原样保留(check:engine-double-contract 绿:38 pinned)。

2. plugin-auth/package.json

新增 @objectstack/driver-sql devDep。@objectstack/driver-memory devDep 暂留 —— auth-contains-filter.test.ts 还在用它;它随该文件的裁决一并摘除。

3. driver-split 的 Q2-B 注释(仅注释,零行为改动)

原句 "the ONLY place in the repository that still consumes it from a test" 改为按迁移后的真实事实叙述:它是唯一的长期消费点,并补记 #5812/#5844 带进来的两个临时消费者各自的去向与理由。

必答项:是否影响 #5702 的预算或前提?

不影响预算,并且给它的前提补了一条实测。

测试

pnpm --filter @objectstack/plugin-auth test       →  Test Files 36 passed (36) / Tests 820 passed (820)
pnpm --filter @objectstack/plugin-auth typecheck  →  tsc --noEmit,无输出
pnpm --filter @objectstack/runtime  typecheck     →  tsc --noEmit,无输出
runtime driver-split 单文件                        →  Test Files 1 passed (1) / Tests 6 passed (6)
check:nul-bytes / engine-double-contract / query-options-erasure
  / driver-conformance / published-files / type-check-coverage  →  全 OK

tests-only + 注释 + devDep,发布不可见 —— tests-only, skip-changeset requested,未提交空 changeset,skip-changeset 标签以并集方式自行写入并读回确认。


Generated by Claude Code

…te `:memory:` witness (#5830)

#5704 的收口尾单的一半。#5812/#5844#5704 survey 之后给 plugin-auth 带进了
两个新的 driver-memory 测试消费者;本 PR 迁走其中可以迁的那一个,并把另一个的
留存原因实测出来、写进注释,交维护者裁处置。

- auth-where-operator-coverage.test.ts:行为面后端由 InMemoryDriver 换成
  @objectstack/driver-sql + better-sqlite3 `:memory:`,建表走 driver 自己的
  initObjects()。#5813 的缺陷是「谓词被丢掉、filter 编译成 {}」,任何真正执行
  过滤的后端都见证得到,已双向反验。
- plugin-auth 新增 @objectstack/driver-sql devDep;driver-memory devDep 暂留
  (auth-contains-filter.test.ts 仍在用)。
- driver-split 的 Q2-B 注释按迁移后的真实事实修订(仅注释,零行为改动)。

tests-only,发布不可见,skip-changeset。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JwwiU9bjhwy2SWj13ho8uv
@vercel

vercel Bot commented Aug 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 6, 2026 10:49am

Request Review

@github-actions github-actions Bot added the size/m label Aug 6, 2026
@baozhoutao baozhoutao added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed size/m labels Aug 6, 2026 — with Claude
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/plugin-auth.

10 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/deployment/cli.mdx (via @objectstack/plugin-auth)
  • content/docs/deployment/production-readiness.mdx (via @objectstack/plugin-auth)
  • content/docs/kernel/contracts/cache-service.mdx (via @objectstack/plugin-auth)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/plugin-auth)
  • content/docs/permissions/authentication.mdx (via @objectstack/plugin-auth)
  • content/docs/permissions/sso.mdx (via @objectstack/plugin-auth)
  • content/docs/plugins/index.mdx (via @objectstack/plugin-auth)
  • content/docs/plugins/packages.mdx (via @objectstack/plugin-auth)
  • content/docs/releases/implementation-status.mdx (via @objectstack/plugin-auth)
  • content/docs/releases/v9.mdx (via @objectstack/plugin-auth)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@github-actions github-actions Bot added dependencies Pull requests that update a dependency file tests labels Aug 6, 2026
@baozhoutao
baozhoutao marked this pull request as ready for review August 6, 2026 11:05
@baozhoutao
baozhoutao added this pull request to the merge queue Aug 6, 2026
Merged via the queue into main with commit 72eb813 Aug 6, 2026
30 of 31 checks passed
@baozhoutao
baozhoutao deleted the claude/issue-5830-auth-tests-sqlite-witness branch August 6, 2026 11:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file skip-changeset PR has no user-facing published change; bypasses the changeset gate tests

Projects

None yet

2 participants