Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ describe('ADR-0131 D10 inventory — every censused object has one fate and a ci

it('the platform registry as it stands — a platform object without a row reds here, by name', () => {
const registered = Object.values(PLATFORM_OBJECTS_BY_PACKAGE).flat();
expect(registered.length).toBeGreaterThan(80);
// (The four retired catalog row objects left the registry with C3 stage 8.)
expect(registered.length).toBeGreaterThan(75);
expect(unlisted(registered)).toEqual([]);
});

Expand Down
23 changes: 13 additions & 10 deletions packages/cli/test/platform-page-i18n-parity.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -788,9 +788,10 @@ describe('shipped platform record pages -- i18n ownership (#14817)', () => {
// red here. What this refuses is the scan that finds NOTHING -- an empty
// population would satisfy every `for` loop below and report success over
// zero pages, which is the exact shape of the `0` that reads as "clean".
expect(RECORD_PAGES.length).toBeGreaterThanOrEqual(3);
// (`sys_position_detail` retired with the `sys_position` object, C3 stage 8.)
expect(RECORD_PAGES.length).toBeGreaterThanOrEqual(2);
expect(RECORD_PAGES.map((p) => p.name).sort()).toEqual(
expect.arrayContaining(['sys_organization_detail', 'sys_position_detail', 'sys_user_detail']),
expect.arrayContaining(['sys_organization_detail', 'sys_user_detail']),
);
expect(SHIPPED_LOCALES).toContain(EN);
expect(SHIPPED_LOCALES.length).toBeGreaterThan(1);
Expand Down Expand Up @@ -838,9 +839,10 @@ describe('shipped platform record pages -- i18n ownership (#14817)', () => {
const maps = RECORD_PAGES.flatMap((page) => inlineLocaleMaps(page, page.name));

// Same refusal as the population floor: zero maps means the walk broke, not
// that the pages went monolingual. [#15204 B2] 44: the user page's two
// grant lists dropped their `add` pickers, and with them two label maps.
expect(maps.length).toBeGreaterThanOrEqual(44);
// that the pages went monolingual. [#15204 B2] The user page's two grant
// lists dropped their `add` pickers, and with them two label maps.
// (`sys_position_detail` retired with the `sys_position` object, C3 stage 8.)
expect(maps.length).toBeGreaterThanOrEqual(38);

const incomplete = maps
.filter((m) => SHIPPED_LOCALES.some((locale) => !m.locales.includes(locale)))
Expand Down Expand Up @@ -1041,14 +1043,14 @@ describe('`pages.*` default-locale parity (#8764, moved off the nav roster by #1
// The anti-vacuity floor, stated before the verdict runs. A verdict over an
// empty or shrunken population is the ambiguous `0` this whole card is
// about: every loop below would be satisfied and report success.
expect(SOURCE_BY_NAME.size).toBeGreaterThanOrEqual(6);
// (`sys_position_detail` retired with the `sys_position` object, C3 stage 8.)
expect(SOURCE_BY_NAME.size).toBeGreaterThanOrEqual(5);
expect([...SOURCE_BY_NAME.keys()].sort()).toEqual(
expect.arrayContaining([
'cloud_connection_settings',
'connect_agent',
'marketplace_installed',
'sys_organization_detail',
'sys_position_detail',
'sys_user_detail',
]),
);
Expand All @@ -1063,7 +1065,7 @@ describe('`pages.*` default-locale parity (#8764, moved off the nav roster by #1
const enPages = pagesOf(EN);
// Absence is loud: an `en` section that lost its entries would make the
// verdict below compare nothing at all.
expect(Object.keys(enPages).length).toBeGreaterThanOrEqual(6);
expect(Object.keys(enPages).length).toBeGreaterThanOrEqual(5);

const findings = defaultLocalePageDrift(enPages, SOURCE_BY_NAME).map((f) => ({
...f,
Expand Down Expand Up @@ -1202,10 +1204,11 @@ describe('platform record page labels are translated in every shipped locale (#1
* wrong recorded source hash would serve the English source here and red this
* assertion rather than shipping a silent regression.
*/
const RECORD_PAGE_NAMES = ['sys_user_detail', 'sys_organization_detail', 'sys_position_detail'];
// (`sys_position_detail` retired with the `sys_position` object, C3 stage 8.)
const RECORD_PAGE_NAMES = ['sys_user_detail', 'sys_organization_detail'];
const TRANSLATED_LOCALES = SHIPPED_LOCALES.filter((locale) => locale !== EN);

it('has a real, non-English label for each of the three in each translated locale', () => {
it('has a real, non-English label for each record page in each translated locale', () => {
expect(TRANSLATED_LOCALES.length).toBeGreaterThanOrEqual(3);

const english = pagesOf(EN);
Expand Down
48 changes: 0 additions & 48 deletions packages/core/src/security/row-active.test.ts

This file was deleted.

22 changes: 7 additions & 15 deletions packages/lint/src/validate-capability-references.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,6 @@ describe('validateCapabilityReferences (ADR-0066 ⑨)', () => {
expect(findings).toEqual([]);
});

it('passes a reference to a capability shipped as a sys_capability seed row', () => {
const findings = validateCapabilityReferences({
data: [{ object: 'sys_capability', records: [{ name: 'approve_invoice' }] }],
objects: [{ name: 'inv_invoice', requiredPermissions: ['approve_invoice'] }],
});
expect(findings).toEqual([]);
});

it('warns on an object requiredPermissions typo (registered nowhere)', () => {
const findings = validateCapabilityReferences({
objects: [{ name: 'sys_license', requiredPermissions: ['mange_users'] }],
Expand Down Expand Up @@ -193,10 +185,11 @@ describe('[#22161] one-line verdicts — capability-reference-unknown', () => {
const findings = validateCapabilityReferences({
objects: [{ name: 'sys_license', requiredPermissions: ['mange_users'] }],
});
expect(findings.map((f) => f.message)).toEqual([
'requiredPermissions names capability "mange_users", which no built-in, `defineCapability`, '
+ '`systemPermissions` grant or `sys_capability` seed provides, so this gate fails closed',
]);
expect(findings).toHaveLength(1);
const [message] = findings.map((f) => f.message);
expect(message.startsWith('requiredPermissions names capability "mange_users", which no built-in, `defineCapability`')).toBe(true);
expect(message.endsWith('so this gate fails closed')).toBe(true);
expect(message.split('\n')).toHaveLength(1);
});

it('`os explain` carries what the verdict no longer says', () => {
Expand All @@ -218,18 +211,17 @@ describe('[#22161] one-line verdicts — capability-reference-unknown', () => {
});

it('each source of the known set the explanation names silences the rule', () => {
// The explanation module imports nothing, so its four sources are held to
// The explanation module imports nothing, so its sources are held to
// the rule by running the rule: each one makes the same reference known.
const text = explainRule(CAPABILITY_REFERENCE_UNKNOWN)!.paragraphs.join('\n');
for (const named of ['built-in platform capability', '`defineCapability`', '`systemPermissions`', '`sys_capability` seed row']) {
for (const named of ['built-in platform capability', '`defineCapability`', '`systemPermissions`']) {
expect(text, named).toContain(named);
}
const gated = { objects: [{ name: 'inv_invoice', requiredPermissions: ['approve_invoice'] }] };
expect(validateCapabilityReferencesUnrecorded(gated), 'lit control').toHaveLength(1);
for (const source of [
{ capabilities: [{ name: 'approve_invoice', label: 'Approve', scope: 'org' }] },
{ permissions: [{ name: 'p', systemPermissions: ['approve_invoice'] }] },
{ data: [{ object: 'sys_capability', records: [{ name: 'approve_invoice' }] }] },
]) {
expect(validateCapabilityReferencesUnrecorded({ ...gated, ...source }), JSON.stringify(source)).toEqual([]);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -369,10 +369,10 @@ describe('packagedBaseRefusal — each Regime C type names its OWN sanctioned pa

it(`\`permission\` — save names its clone and no switch (${environmentId ? 'environment' : 'host-config'} kernel)`, () => {
const message = expectRegimeC(refusalOn(environmentId, 'permission', 'pkg_perm', 'save'), 'permission', 'pkg_perm', 'save');
expect(message).toContain(
'Clone it under a new name to customize it (the "Clone" action on the permission set, '
+ 'or POST /api/v1/data/sys_permission_set with a new name).',
);
// The clone route's spelling moved with C3 stage 8 (the retired
// object's data route → the catalog's clone door); the sentence did not.
expect(message).toContain('Clone it under a new name to customize it (the "Clone" action on the permission set, or POST /api/v1/');
expect(message).toContain(' with a new name).');
expect(message.toLowerCase()).not.toContain('switch it off');
expect(message).not.toContain('_activation');
expect(message).not.toContain('/automation/');
Expand Down Expand Up @@ -411,7 +411,7 @@ describe('packagedBaseRefusal — each Regime C type names its OWN sanctioned pa
for (const [type, name, path] of [
['flow', 'pkg_flow', 'POST /api/v1/automation/:name/clone'],
['action', 'pkg_action', 'POST /api/v1/actions/_activation/:object/:action'],
['permission', 'pkg_perm', 'POST /api/v1/data/sys_permission_set'],
['permission', 'pkg_perm', 'the "Clone" action on the permission set, or POST /api/v1/'],
] as const) {
const r: any = p.packagedBaseRefusal({ type, name, operation: 'save', packageId: PACKAGE_ID });
expect({ code: r?.code, status: r?.status, lockSource: r?.lockSource, packageId: r?.packageId }, type)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ describe('#21490: runUninstallCleanups — the uninstall-cleanup registry\'s one

const res = await protocol.deletePackage(request);

expect(runner.mock.calls).toEqual([[request]]);
// Its own request — plus, when the package declared permission sets, their
// names (`declared`, ADR-0131 D4), read before its withdrawal.
expect(runner.mock.calls).toEqual([[expect.objectContaining(request)]]);
expect(res.cleanups).toEqual(await runner.mock.results[0]!.value);
expect(res.cleanups).toEqual([{ name: 'security.package-permissions', success: true, removed: 4 }]);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -574,10 +574,11 @@ describe('#7682 — the refusal discriminates on package writability', () => {
`Cannot overlay 'permission' in package '${READ_ONLY_PKG}': that package is read-only, and its packaged base `
+ 'is locked against in-place edits. ',
)).toBe(true);
expect(message).toContain(
'Clone it under a new name to customize it (the "Clone" action on the permission set, '
+ 'or POST /api/v1/data/sys_permission_set with a new name).',
);
// The clone route's spelling moved with C3 stage 8 (the data route of the
// retired `sys_permission_set` object → the catalog's clone door); the
// sentence around it did not.
expect(message).toContain('Clone it under a new name to customize it (the "Clone" action on the permission set, or POST /api/v1/');
expect(message).toContain(' with a new name).');
expect(message).not.toContain('OS_METADATA_WRITABLE');
expect(message).not.toContain('redeploy');
expect(message.endsWith('See docs/adr/0126-packaged-metadata-customization-model.md.')).toBe(true);
Expand Down Expand Up @@ -1253,8 +1254,17 @@ describe('[#20910] the repository doors name a Regime C type\'s sanctioned path,
const ADR_0126 = 'See docs/adr/0126-packaged-metadata-customization-model.md.';
const ACTION_SWITCH = 'Switch it off (POST /api/v1/actions/_activation/:object/:action, body {enabled: false}, '
+ ':object = global for an object-less action; operator-only where one install serves several organizations).';
// `{ROUTE}`: the clone route, whose spelling moved with C3 stage 8 (the
// retired object's data route → the catalog's clone door); see `sentenceMatches`.
const PERMISSION_CLONE = 'Clone it under a new name to customize it (the "Clone" action on the permission set, '
+ 'or POST /api/v1/data/sys_permission_set with a new name).';
+ 'or POST {ROUTE} with a new name).';
/** Exact equality, with a `{ROUTE}` placeholder standing for one `/api/v1/…` path. */
const sentenceMatches = (actual: string, expected: string): boolean => {
const [head, tail] = expected.split('{ROUTE}');
if (tail === undefined) return actual === expected;
return actual.startsWith(head) && actual.endsWith(tail)
&& /^\/api\/v1\/\S+$/.test(actual.slice(head.length, actual.length - tail.length));
};
const FLOW_PATHS = 'Clone it under a new name to customize it (POST /api/v1/automation/:name/clone, body {name, label}), '
+ 'or switch it off (POST /api/v1/automation/:name/toggle, body {enabled: false}; '
+ 'operator-only where one install serves several organizations).';
Expand Down Expand Up @@ -1286,10 +1296,9 @@ describe('[#20910] the repository doors name a Regime C type\'s sanctioned path,
it(`type door, save: a packaged ${type} is refused NOT_OVERRIDABLE with its row's path, no hatch`, async () => {
const err = await putWith(repo, { type, name: `pkg_${type}`, intent: 'override-artifact' }) as any;
expect(err).toMatchObject({ code: 'NOT_OVERRIDABLE', status: 403 });
expect(String(err.message)).toBe(
`Metadata item '${type}/pkg_${type}' is provided by a managed package and is sealed `
+ `against in-place edits. ${paths} ${ADR_0126}`,
);
const expected = `Metadata item '${type}/pkg_${type}' is provided by a managed package and is sealed `
+ `against in-place edits. ${paths} ${ADR_0126}`;
expect(sentenceMatches(String(err.message), expected), `${String(err.message)}\n≠ ${expected}`).toBe(true);
expect(Array.from(engine.rows.values())).toEqual([]);
});
}
Expand Down Expand Up @@ -1359,10 +1368,9 @@ describe('[#20910] the repository doors name a Regime C type\'s sanctioned path,
code: 'ITEM_LOCKED', status: 403, lockSource: 'package', packageId: READ_ONLY_PKG,
docs: 'docs/adr/0010-metadata-protection-model.md',
});
expect(String(err.message)).toBe(
`Cannot overlay '${type}' in package '${READ_ONLY_PKG}': that package is read-only, and its packaged base `
+ `is locked against in-place edits. ${paths} ${ADR_0126}`,
);
const expected = `Cannot overlay '${type}' in package '${READ_ONLY_PKG}': that package is read-only, and its packaged base `
+ `is locked against in-place edits. ${paths} ${ADR_0126}`;
expect(sentenceMatches(String(err.message), expected), `${String(err.message)}\n≠ ${expected}`).toBe(true);
});
}

Expand Down
Loading
Loading