Repository navigation
Commit b309866
test(console): pin the object-storage-sync-refused advisory on every object save and publish door (#30761)
Fixes #30723
Clause-②: no
Metadata-protocol: none
## 维护者速读
- **改了什么**:只加测试。把服务端 `object-storage-sync-refused` 告警(原样复制生产者的形状,`path`
为空串)喂进控制台对象保存/发布的四个入口,钉住管理员一定能看到带服务端 message 与 hint 的警告。
- **为什么改**:卡片预期第二条——控制台本来就通用地渲染
`advisories`,这里核实它在对象保存/发布入口确实生效;此前没有任何测试用这条规则的真实形状(空 `path`)走过这些入口。
- **风险与回滚**:零运行时风险,没有改任何源码、文案、i18n 键或 package.json;回滚即删掉两个测试块。
-
**先看**:`ui/packages/app-shell/src/views/metadata-admin/useMetadataClient.advisorySink.test.tsx`(新
describe:save / publish / publishDraft / publishPackageDrafts
四个入口);`ui/packages/app-shell/src/services/MetadataService.saveAdvisories.test.ts`(新
describe:适配器 `meta.saveItem`,即 Setup 的对象保存)。
- **两分钟验证**:在 `ui/` 下运行 `pnpm exec vitest run
packages/app-shell/src/views/metadata-admin/useMetadataClient.advisorySink.test.tsx
packages/app-shell/src/services/MetadataService.saveAdvisories.test.ts`,预期
2 个文件、13 个测试全绿。
- **需要你做的**:无,席位落地。
## What changes
Tests only. One finding in the exact shape
`objectStorageSyncRefusedNotice` returns
(`packages/metadata-protocol/src/protocol-registry-hydration.ts`, copied
verbatim with a comment naming the file and function; no new
dependency), driven through every console object write door with a real
client over a fake `fetch`:
- `useMetadataClient.advisorySink.test.tsx`, new top-level `describe`
(the real hook, factory, `MetadataClient`, `readSaveAdvisories` and
`emitSaveAdvisories`; only `sonner` and `fetch` stubbed):
- (a) `save('object', …)` in publish mode: resolves, warning titled
"Saved";
- (b) `publish` and `publishDraft`: resolve, warning titled "Published";
- (c) `publishPackageDrafts`, the finding on one `published[]` element:
resolves, warning titled "Published".
- `MetadataService.saveAdvisories.test.ts`, new top-level `describe`:
(d) `MetadataService.saveObject` through the adapter's `meta.saveItem`
interceptor: resolves, event `door: 'save'`, `mode: 'publish'`, warning
titled "Saved".
Each pin asserts the warning tier (never `error`), and that the
description carries `[object-storage-sync-refused] object "NAME" —
MESSAGE` and the `hint`, verbatim.
The check itself (the card's Expected bullet 2): the positions the claim
measured hold on `40a9265ff`. The producer returns all six string keys
with `path: ''`; `readSaveAdvisories` keeps a finding with an
empty-string `path` (it checks `typeof`, not truthiness);
`useMetadataClient` wires `onSaveAdvisory` into every console
`MetadataClient`; `AdapterProvider` subscribes to the adapter's
`meta.saveItem` interceptor; both render through `emitSaveAdvisories`.
No console object-write door was found that does not reach a sink: the
other `MetadataClient` constructions are the adapter's private one (a
view draft save and view resets, not object writes, and drafts are never
advised), `MetadataProvider`'s preview client (reads only), and the two
`plugin-designer` pages (no console consumer). The only response schemas
declaring `advisories` are the save, single-item publish and batch
publish-drafts responses, all covered above.
## Tests
Run on `da4bf8058` (the final head), from `ui/`:
- `pnpm exec vitest run
packages/app-shell/src/views/metadata-admin/useMetadataClient.advisorySink.test.tsx
packages/app-shell/src/services/MetadataService.saveAdvisories.test.ts`:
`Test Files 2 passed (2)`, `Tests 13 passed (13)`.
- `pnpm --filter @object-ui/app-shell run type-check` (both `tsc
--noEmit` and `tsc -p tsconfig.test.json`, which compiles the tests):
exit 0.
- `eslint` on the two files: exit 0.
### Ablations (each restored; `git diff HEAD` empty after each, blob
equal to HEAD)
Done through `scripts/ablation-replace.mjs`, which proved each mutation
landed on disk. The `@object-ui/data-objectstack` import resolves to
`src` through the `ui/vitest.config.mts` alias, so no rebuild was
needed.
| Ablation | Result |
|:--|:--|
| A1: `readSaveAdvisories` also requires a non-empty `path` (length
greater than zero) | exactly the 5 new pins red, all 8 existing pins
green (5 failed / 8 passed). The existing gate-finding fixtures carry a
non-empty `path`, so only this shape can catch it |
| A2: the console sink call `emitSaveAdvisories(…)` in
`useMetadataClient` cut | the 4 new `MetadataClient` pins red, plus the
2 existing SAVE/PUBLISH connection pins (6 failed / 7 passed) |
| A3: the adapter interceptor's emit cut (its condition made never true)
| the new `saveItem` pin red, plus the 3 existing `MetadataService`
advisory pins (4 failed / 9 passed) |
The first attempt at A1 was a no-op: its anchor was a substring of its
replacement, so the tool refused to run (anchor count 1 to 1) and
restored the file. It was re-run with an anchor that does not overlap;
the table above shows that second run.
## Acceptance notes
- Out of scope, observed (from the claim; not changed here): the frame
reads "the authoring check raised N advisory finding(s)", but this
finding comes from the storage sync, not the authoring gate. That is
wording, not behaviour.
- The producer copy is a fixture. If the server's wording changes, the
pins still pass (they compare the fixture's own strings), so they guard
the console channel and not the server text. That matches the renderer
contract: server prose is rendered verbatim and never pinned by the
console.
- The batch door reaches the console once #30693 lands server-side. The
client half is pinned here already.
## Verification
<details><summary>Derived gates: 26 of 26 run, all exit 0 (reconciled
with --ran)</summary>
`node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack`, then `--ran` with each exit code recorded:
`Run reconciliation — 26 derived, 26 run, 0 NOT-MEASURED, 0 UNRUN`, `a
DERIVED zero — all 26 recorded an exit code and none of them is 3`.
These include `check:test-source-alias`,
`check:cross-package-test-inputs`, `check:nul-bytes`,
`check:type-check-coverage`, `check:type-check-debt`,
`check:undeclared-dep-imports`, `check:published-files`,
`check-sdui-manifest` (and `--self-test`), `check-comment-mask-corpus`
and `pnpm --dir ui exec vitest run scripts/`, each exit 0.
</details>
<details><summary>Not run locally (left to CI)</summary>
The whole `@object-ui/app-shell` suite (`Test UI`) and the repo-wide
lint are left to CI. Locally I ran the two changed files plus the
package type-check, which compiles the tests. `skip-changeset`: the diff
touches only `*.test.ts(x)`, which no package's `files[]` ships.
</details>
---
_Generated by [Claude
Code](https://claude.ai/code/session_01L6bhgWn6zhNa4LL7VB1rtL)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent adf6ee0 commit b309866
2 files changed
Lines changed: 147 additions & 0 deletions
File tree
- ui/packages/app-shell/src
- services
- views/metadata-admin
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
167 | 167 | | |
168 | 168 | | |
169 | 169 | | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
183 | 183 | | |
184 | 184 | | |
185 | 185 | | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
0 commit comments