Skip to content

Commit 51d33df

Browse files
committed
test(plugin-approvals): control that the raw snapshot panel's gate is judged by the props call
The page schema's parse does not judge a node's props bag, so the pin that the panel's requiredPermissions holds is the props call's refusal of a panel without it. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018VqJPGA1NDNSCZsnecsChP
1 parent 789ccf3 commit 51d33df

1 file changed

Lines changed: 19 additions & 0 deletions

File tree

‎packages/plugins/plugin-approvals/src/sys-approval-request-page.test.ts‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import { describe, it, expect } from 'vitest';
2929
import { ObjectStackDefinitionSchema, normalizeStackInput } from '@objectstack/spec';
3030
import { PageSchema } from '@objectstack/spec/ui';
3131
import {
32+
COMPONENT_PROPS_INVALID,
3233
COMPONENT_PROPS_UNKNOWN_KEY,
3334
COMPONENT_TYPE_UNKNOWN,
3435
runAuthoringRules,
@@ -108,6 +109,14 @@ function pageBuildFindings(page: AnyRec) {
108109
/** The page with its decision node replaced. */
109110
const withDecisionNode = (node: AnyRec): AnyRec => ({ ...PAGE, slots: { ...SLOTS, actions: [node] } });
110111

112+
/** The page with the Details tab's raw snapshot panel given other properties. */
113+
const withRawPanelProps = (properties: AnyRec): AnyRec => {
114+
const [details, ...rest] = TAB_ITEMS;
115+
const children = [(details.children as AnyRec[])[0], { type: 'record:json', properties }];
116+
const items = [{ ...details, children }, ...rest];
117+
return { ...PAGE, slots: { ...SLOTS, tabs: { ...SLOTS.tabs, properties: { ...SLOTS.tabs.properties, items } } } };
118+
};
119+
111120
/** The subject-record snapshot a stored request row holds in `payload_json`. */
112121
const SNAPSHOT = { id: 'exp_1', title: 'Q1 travel', amount: 1200 };
113122
const SUBMITTER = 'employee_7';
@@ -273,6 +282,16 @@ describe('sys_approval_request detail page — what `os validate` judges a page
273282
expect(findings.map((f) => f.rule)).toEqual([COMPONENT_PROPS_UNKNOWN_KEY]);
274283
});
275284

285+
it('control: the raw snapshot panel without its required gate is refused by the same call', () => {
286+
// The page schema's parse does not judge a node's props bag; the props
287+
// row does, so this call is what holds the panel's gate in place.
288+
const { requiredPermissions: _gate, ...ungated } = (TAB_ITEMS[0].children as AnyRec[])[1].properties as AnyRec;
289+
const findings = validateComponentProps({ pages: [withRawPanelProps(ungated)] });
290+
expect(findings.map((f) => [f.rule, f.path])).toEqual([
291+
[COMPONENT_PROPS_INVALID, 'pages[0].slots.tabs.properties.items[0].children[1].properties.requiredPermissions'],
292+
]);
293+
});
294+
276295
it('the build rules raise no error on the page, in a stack beside the two objects it binds', () => {
277296
const { errors } = splitBySeverity(pageBuildFindings(PAGE));
278297
expect(errors, JSON.stringify(errors, null, 2)).toEqual([]);

0 commit comments

Comments
 (0)