Skip to content

Commit c29e83c

Browse files
committed
test(dogfood): pin the reason #25591's verdict gives a staff share on a real showcase_project record (#25602)
The showcase D3/D4 proof's contrast granted on `showcase_project` to a record id that names no row and expected the pre-#25549 object-only reason. Since #25591 the D7 verdict on a public object reads whether the recipient is an external member of the record's organization, so that grant now fails for an unresolvable organization instead, and main's Dogfood Regression Gate (1/3) is red. The contrast now grants on a real project to a staff member of its organization (both preconditions asserted) and pins the ruled reason: "... and the recipient is not one". Claude-Session: https://claude.ai/code/session_014rFBGqoBLiroi35e82xEa7 Co-authored-by: Claude <noreply@anthropic.com>
1 parent a57643d commit c29e83c

1 file changed

Lines changed: 37 additions & 15 deletions

File tree

‎packages/qa/dogfood/test/showcase-d3-d4-capabilities.dogfood.test.ts‎

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@
88
// [#9237] The compound rule moved from `showcase_project` to
99
// `showcase_contact`, and the D3 proof got its missing half with it. On
1010
// `showcase_project` (OWD `public_read_write`) sharing has nothing to
11-
// widen, so every grant the rule reconciled was REFUSED
12-
// (`SHARING_NOT_ENABLED`, ADR-0111 D7) — this file could assert the
13-
// criteria compiled and matched, and never that anything was ENFORCED,
14-
// while its own header claimed both. `showcase_contact` is OWD `private`,
15-
// so the grant lands and the enforcement half is now measured rather than
16-
// implied.
11+
// widen for the organization's staff, so every grant the rule reconciled
12+
// was REFUSED (`SHARING_NOT_ENABLED`, ADR-0111 D7; since #25549 a share
13+
// there is consulted for an `external` member alone) — this file could
14+
// assert the criteria compiled and matched, and never that anything was
15+
// ENFORCED, while its own header claimed both. `showcase_contact` is OWD
16+
// `private`, so the grant lands and the enforcement half is now measured
17+
// rather than implied.
1718
// • ADR-0058 D4 — an RLS `check` clause validates the write POST-IMAGE: a
1819
// contributor cannot reassign an invoice they own to a different owner.
1920
//
@@ -53,6 +54,8 @@ describe('showcase: D3 compound sharing (#1887) + D4 RLS check', () => {
5354
let ql: any;
5455
let token: string;
5556
let invId: string;
57+
let pjId: string;
58+
let memberId: string;
5659

5760
beforeAll(async () => {
5861
stack = await bootShowcase({
@@ -77,6 +80,11 @@ describe('showcase: D3 compound sharing (#1887) + D4 RLS check', () => {
7780

7881
// An invoice owned by the member (system insert sidesteps authoring rules).
7982
invId = idOf(await ql.insert('showcase_invoice', { name: 'INV-D34', account: acct, owner: MEMBER, status: 'draft' }, SYS));
83+
84+
// [#25549] A real project, and the member's user id: the D7 contrast on
85+
// `showcase_project` is judged against a record's organization and a recipient.
86+
pjId = idOf(await ql.insert('showcase_project', { name: 'D34 Project', account: acct, status: 'planned' }, SYS));
87+
memberId = String((await ql.findOne('sys_user', { where: { email: MEMBER }, context: SYS.context }))?.id ?? '');
8088
}, 90_000);
8189

8290
afterAll(async () => { await stack?.stop(); });
@@ -108,8 +116,9 @@ describe('showcase: D3 compound sharing (#1887) + D4 RLS check', () => {
108116
});
109117

110118
it('[#9237] the grant the rule reconciles is one the gates CONSULT — not refused as inert', async () => {
111-
// The half this proof could never carry on `showcase_project`. The verdict
112-
// is caller-independent (ADR-0111 D7) and computed from the OWD alone, so
119+
// The half this proof could never carry on `showcase_project`. On a
120+
// private object the verdict is caller-independent (ADR-0111 D7) and
121+
// computed from the OWD alone, so
113122
// it is asserted directly rather than inferred from a reconcile count that
114123
// an empty recipient expansion would leave silently at zero — which is
115124
// exactly how the sibling rule on `showcase_project` produced no boot WARN
@@ -122,17 +131,30 @@ describe('showcase: D3 compound sharing (#1887) + D4 RLS check', () => {
122131
expect(granted, 'a share row on a private-OWD object is accepted').toBeTruthy();
123132

124133
// The contrast that names the retired rules' defect, on the object they
125-
// used to sit on: same call, same caller, refused for the OWD alone. The
126-
// record id deliberately names no row — the D7 verdict is computed from
127-
// the OBJECT before any record is read, which is precisely why it is
128-
// caller- and record-independent. Both the code and the object are
129-
// asserted, so a refusal arriving for some other reason cannot pass.
134+
// used to sit on: same call, same caller, refused. [#25549] On a public
135+
// object the D7 verdict is no longer the OWD's alone: the external OWD
136+
// floor consults a share there, so the verdict reads one fact about the
137+
// recipient — is it an `external` member of the RECORD's organization?
138+
// The retired rules' `position` recipients expand to that organization's
139+
// staff, so the probe is a real project and a staff member of its
140+
// organization (both preconditions asserted). Both the code and the reason
141+
// are asserted, so a refusal arriving for some other reason cannot pass —
142+
// a record the verdict cannot place answers "that organization could not
143+
// be resolved" instead.
144+
const pjOrg = (await ql.findOne('showcase_project', { where: { id: pjId }, fields: ['organization_id'], context: SYS.context }))?.organization_id;
145+
expect(pjOrg, 'fixture: the project carries an organization').toBeTruthy();
146+
const membership = await ql.findOne('sys_member', {
147+
where: { user_id: memberId, organization_id: pjOrg }, fields: ['role'], context: { ...SYS.context, tenantId: pjOrg },
148+
});
149+
expect(membership?.role, 'fixture: the member is staff of that organization, not external').toBe('member');
130150
await expect(
131151
sharing.grant(
132-
{ object: 'showcase_project', recordId: 'pj_absent', recipientType: 'user', recipientId: 'u_d34_probe', accessLevel: 'read' },
152+
{ object: 'showcase_project', recordId: pjId, recipientType: 'user', recipientId: memberId, accessLevel: 'read' },
133153
{ isSystem: true },
134154
),
135-
).rejects.toThrow(/SHARING_NOT_ENABLED: 'showcase_project' is not under record-sharing enforcement/);
155+
).rejects.toThrow(
156+
/SHARING_NOT_ENABLED: 'showcase_project' has a public sharing model, so a share row on it is consulted only for an external member of the record's organization, and the recipient is not one/,
157+
);
136158
});
137159

138160
// ── ADR-0058 D4 ────────────────────────────────────────────────────────────

0 commit comments

Comments
 (0)