|
49 | 49 | * crossing the wall, a tenancy-disabled object, and `preserveAudit`, whose |
50 | 50 | * update-only exemption never reaches `organization_id`. A system context |
51 | 51 | * never met the strip. |
52 | | - * - The `update`-mode `validate()` preview runs no middleware, so it is |
53 | | - * wall-blind: it still reports the drop of an admitted re-point. |
| 52 | + * - The `update`-mode `validate()` preview runs no middleware, so it was |
| 53 | + * wall-blind: it reported the drop of an admitted re-point and admitted a |
| 54 | + * refused one. It now reads the wall's own per-row verdict (#25062), and |
| 55 | + * answers a re-point as its write does. |
54 | 56 | */ |
55 | 57 |
|
56 | 58 | import { describe, it, expect, afterEach, vi } from 'vitest'; |
@@ -578,17 +580,29 @@ describe('[#24822] where no wall judges the column, the update strip takes the r |
578 | 580 | }); |
579 | 581 | }); |
580 | 582 |
|
581 | | -describe('[#24822] the `update`-mode validate() preview is wall-blind (it runs no middleware)', () => { |
582 | | - it('it still reports an admitted re-point as dropped, while the write stores it; and a refused one as dropped, while the write refuses it', async () => { |
| 583 | +describe('[#24822][#25062] the `update`-mode validate() preview answers a re-point as its write does', () => { |
| 584 | + it('an admitted re-point is reported as no drop, and the write stores it; a refused one is refused by both, with the write\'s code and message', async () => { |
583 | 585 | const b = await boot('group'); |
584 | 586 |
|
585 | 587 | const admitted = await b.engine.validate(INJECTED, { id: 'r1', organization_id: SISTER_ORG }, { mode: 'update', context: GROUP_CTX as never }); |
586 | 588 | const refused = await b.engine.validate(INJECTED, { id: 'r1', organization_id: FOREIGN_ORG }, { mode: 'update', context: GROUP_CTX as never }); |
587 | 589 |
|
588 | | - expect(admitted.results[0]?.droppedFields).toEqual(READONLY_DROP(INJECTED)); |
589 | | - expect(refused.results[0]?.droppedFields).toEqual(READONLY_DROP(INJECTED)); |
| 590 | + expect(admitted.valid).toBe(true); |
| 591 | + expect(admitted.results[0]?.droppedFields).toBeUndefined(); |
| 592 | + expect(refused.valid).toBe(false); |
| 593 | + expect(refused.results[0]?.droppedFields).toBeUndefined(); |
| 594 | + const refusal = refused.results[0]?.errors[0]; |
| 595 | + expect(refusal?.field).toBe('organization_id'); |
| 596 | + expect(refusal?.code).toBe('PERMISSION_DENIED'); |
| 597 | + |
| 598 | + const refusedWrite = await repoint(b, INJECTED, FOREIGN_ORG, GROUP_CTX, 'id'); |
| 599 | + expectWallRefusal(refusedWrite.outcome, INJECTED); |
| 600 | + expect(refusal?.message).toBe(refusedWrite.outcome.message); |
| 601 | + expect(await b.table(INJECTED)).toEqual(SEEDED(INJECTED)); |
| 602 | + |
590 | 603 | const write = await repoint(b, INJECTED, SISTER_ORG, GROUP_CTX, 'id'); |
591 | 604 | expect(write.outcome.ok, write.outcome.message).toBe(true); |
| 605 | + expect(write.dropped).toEqual([]); |
592 | 606 | expect(await b.table(INJECTED)).toEqual(SEEDED(INJECTED, SISTER_ORG)); |
593 | 607 | }); |
594 | 608 | }); |
0 commit comments