|
35 | 35 | * - CONTROL: a package-less row minted beside a package's row before the fix |
36 | 36 | * stays as it is, and a server-stated rewrite of that row (the |
37 | 37 | * stored-metadata migration passes `packageId: null`) still writes it; |
38 | | - * - an item a code package ships, with no stored row: the package-less save |
39 | | - * writes the package-unbound overlay and the read serves it, as before; with |
40 | | - * an overlay row already bound to the code package, it writes that row; |
| 38 | + * - [#28576, ADR-0146 D11] an item a code package ships: the package-less save |
| 39 | + * is refused naming the base's pair and the migration ceremony, with no |
| 40 | + * stored row or with an overlay row bound to the code package, and writes |
| 41 | + * nothing; |
41 | 42 | * - the draft path: a package-less draft save still inherits the package |
42 | 43 | * (its own suite, `sys-metadata-repository.draft-package-inherit.test.ts`, |
43 | 44 | * holds the rest). |
@@ -419,37 +420,41 @@ describe('CONTROL: what the resolution leaves alone', () => { |
419 | 420 | }); |
420 | 421 | }); |
421 | 422 |
|
422 | | -describe('an item a CODE package ships', () => { |
423 | | - it('with no stored row: the package-less save writes the package-unbound overlay, and the read serves it', async () => { |
| 423 | +describe('an item a CODE package ships: the package-less write is closed (ADR-0146 D11)', () => { |
| 424 | + const PAIR = `${CODE_PACKAGE}.custom`; |
| 425 | + const closed = (e: unknown) => { |
| 426 | + expect(resolveThrownHttpError(e)).toMatchObject({ status: 403, code: 'NOT_OVERRIDABLE' }); |
| 427 | + expect(String((e as Error).message)).toContain(`'${PAIR}'`); |
| 428 | + expect(String((e as Error).message)).toContain('os migrate packageless-overlays'); |
| 429 | + }; |
| 430 | + |
| 431 | + it('with no stored row: the package-less save is refused naming the pair, and nothing is written', async () => { |
424 | 432 | const name = 'showcase_task_grid'; |
425 | 433 | const { protocol, rows } = makeProtocol([packagedView(name)]); |
426 | 434 |
|
427 | | - const saved = await protocol.saveMetaItem({ type: 'view', name, item: viewBody(name, 'Overlaid') }); |
| 435 | + const refused = await protocol.saveMetaItem({ type: 'view', name, item: viewBody(name, 'Overlaid') }).then(() => undefined, (e) => e); |
428 | 436 |
|
429 | | - expect(saved.message).toBe( |
430 | | - `Saved customization overlay (env-wide, state=active) — type=view, name=${name} [seq=${saved.seq}]`, |
431 | | - ); |
432 | | - expect(rows('view', name).map((r) => r.package_id ?? null)).toEqual([null]); |
433 | | - expect((await protocol.getMetaItem({ type: 'view', name })).item.label).toBe('Overlaid'); |
| 437 | + closed(refused); |
| 438 | + expect(rows('view', name)).toEqual([]); |
| 439 | + expect((await protocol.getMetaItem({ type: 'view', name })).item.label).not.toBe('Overlaid'); |
434 | 440 | }); |
435 | 441 |
|
436 | | - it('with an overlay row bound to the code package: the package-less save writes that row', async () => { |
| 442 | + it('with an overlay row bound to the code package: the package-less save is refused, and that row is untouched', async () => { |
437 | 443 | const name = 'showcase_task_grid'; |
438 | 444 | // [#26708] The code package ships the object its view binds: a save |
439 | 445 | // naming the (installed) package is judged against its closure. |
440 | 446 | const { protocol, rows } = makeProtocol([ |
441 | 447 | packagedView(name), |
442 | 448 | { type: 'object', item: { name: 'task', _packageId: CODE_PACKAGE, fields: { name: { type: 'text' } } } }, |
443 | 449 | ]); |
444 | | - // The overlay a save naming the package writes (ADR-0005: an overlay of |
445 | | - // a code-shipped item names the package it customizes). |
| 450 | + // A save naming the package names a package: not the write D11 closes. |
446 | 451 | await protocol.saveMetaItem({ type: 'view', name, item: viewBody(name, 'Named'), packageId: CODE_PACKAGE }); |
447 | 452 |
|
448 | | - const saved = await protocol.saveMetaItem({ type: 'view', name, item: viewBody(name, 'Unnamed') }); |
| 453 | + const refused = await protocol.saveMetaItem({ type: 'view', name, item: viewBody(name, 'Unnamed') }).then(() => undefined, (e) => e); |
449 | 454 |
|
450 | | - expect(saved.message).toContain(`package=${CODE_PACKAGE}`); |
| 455 | + closed(refused); |
451 | 456 | expect(rows('view', name).map((r) => r.package_id ?? null)).toEqual([CODE_PACKAGE]); |
452 | | - expect((await protocol.getMetaItem({ type: 'view', name })).item.label).toBe('Unnamed'); |
| 457 | + expect((await protocol.getMetaItem({ type: 'view', name })).item.label).toBe('Named'); |
453 | 458 | }); |
454 | 459 | }); |
455 | 460 |
|
|
0 commit comments