|
3 | 3 | // (ADR-0086 D3 provenance consumed at last; ADR-0090 D5 "no ghost grants"). |
4 | 4 |
|
5 | 5 | import { describe, it, expect } from 'vitest'; |
6 | | -import { cleanupPackagePermissions as cleanup } from './cleanup-package-permissions'; |
| 6 | +import { cleanupPackagePermissions } from './cleanup-package-permissions'; |
7 | 7 |
|
8 | 8 | /** |
9 | | - * The sweep, with the declared-names argument C3 stage 8 adds. Spelled through |
10 | | - * this signature so the suite compiles against the module before and after |
11 | | - * that stage: before it, the sweep finds the package's sets by its catalog |
12 | | - * rows and ignores the names; after it, it finds them by the names. |
| 9 | + * The permission-set names the uninstalling door read off the package before |
| 10 | + * its withdrawal (`UninstallDeclared`, ADR-0131 D4). Handed to the sweep, they |
| 11 | + * revoke the same grants whether it also finds the package's sets by their |
| 12 | + * catalog rows (before C3 stage 8) or by these names alone (after it). |
13 | 13 | */ |
14 | | -const cleanupPackagePermissions = cleanup as ( |
15 | | - ql: any, |
16 | | - packageId: string, |
17 | | - logger?: Parameters<typeof cleanup>[2], |
18 | | - declaredSetNames?: readonly string[], |
19 | | -) => ReturnType<typeof cleanup>; |
20 | | - |
21 | | -/** The permission-set names the uninstalled package declared (read off it before its withdrawal). */ |
22 | | -const DECLARED = ['crm_readonly', 'crm_admin']; |
| 14 | +const DECLARED = { permission: ['crm_readonly', 'crm_admin'] }; |
23 | 15 |
|
24 | 16 | /** |
25 | 17 | * A store holding both shapes a grant has carried: every grant names its set |
@@ -188,17 +180,25 @@ describe('[ADR-0131 D4, ADR-0090 D5] the grants naming a set the package declare |
188 | 180 |
|
189 | 181 | it('revokes every user grant naming a declared set, and only those', async () => { |
190 | 182 | const ql = withNamedGrants(); |
191 | | - const out = await cleanupPackagePermissions(ql, 'com.example.crm', undefined, { permission: ['crm_catalog_user'] }); |
| 183 | + const out = await cleanupPackagePermissions(ql, 'com.example.crm', undefined, { |
| 184 | + permission: [...DECLARED.permission, 'crm_catalog_user'], |
| 185 | + }); |
192 | 186 |
|
193 | | - expect(out.userGrants).toBe(3); // the legacy row's grant (ups_1) and the two naming the declared set |
194 | | - expect(ql.tables.sys_user_permission_set.map((r: any) => r.id)).toEqual(['ups_env', 'ups_named_other']); |
| 187 | + // The two grants naming the package's row-backed sets and the two naming |
| 188 | + // its registry-only set. |
| 189 | + expect(out.userGrants).toBe(4); |
| 190 | + expect(ql.tables.sys_user_permission_set.map((r: any) => r.id)).toEqual(['ups_env', 'ups_other', 'ups_named_other']); |
195 | 191 | }); |
196 | 192 |
|
197 | | - it('control — handed no names, a grant naming a catalog set survives: the cleanup is as it was', async () => { |
| 193 | + it('control — handed no names, a grant naming a registry-only set survives', async () => { |
198 | 194 | const ql = withNamedGrants(); |
199 | 195 | const out = await cleanupPackagePermissions(ql, 'com.example.crm'); |
200 | 196 |
|
201 | | - expect(out).toEqual({ sets: 2, positionBindings: 2, userGrants: 1, suggestions: 2, refused: 0 }); |
202 | | - expect(ql.tables.sys_user_permission_set.map((r: any) => r.id)).toEqual(['ups_env', 'ups_named_1', 'ups_named_2', 'ups_named_other']); |
| 197 | + expect(out).toMatchObject({ suggestions: 2, refused: 0 }); |
| 198 | + // Whatever the row legs reach while the catalog rows still exist, no grant |
| 199 | + // naming a set the sweep was not handed is revoked. |
| 200 | + expect(ql.tables.sys_user_permission_set.map((r: any) => r.id)).toEqual( |
| 201 | + expect.arrayContaining(['ups_env', 'ups_other', 'ups_named_1', 'ups_named_2', 'ups_named_other']), |
| 202 | + ); |
203 | 203 | }); |
204 | 204 | }); |
0 commit comments