@substrat-run/contract-tests 0.105.0 → 0.107.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/scope-host-suite.d.ts.map +1 -1
- package/dist/scope-host-suite.js +35 -34
- package/dist/scope-host-suite.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -20,6 +20,6 @@ export { nodeOnlySuite, declaredNodeOnlySuite } from './node-only-suite.js';
|
|
|
20
20
|
export type { NodeOnlyOptions } from './node-only-suite.js';
|
|
21
21
|
export { declareEntityChecks, declareNodeOnly, assertNodeOnly } from './conformance.js';
|
|
22
22
|
export type { ConformanceDeclaration, DrivenConformance, DeclaredNodeOnlyConformance, AssertedNodeOnlyConformance, } from './conformance.js';
|
|
23
|
-
export { atomicMod, billedMod, brokenMod, connectorMod, contractTestBareOps, contractTestInitialModules, contractTestModules, permMod, scheduleMod, freshnessMod, searchMod, searchModManifest, listMod, listModManifest, parseMod, parseModManifest, } from './modules.js';
|
|
23
|
+
export { atomicMod, billedMod, brokenMod, connectorMod, contractTestBareOps, contractTestInitialModules, contractTestModules, permMod, scheduleMod, testMod, freshnessMod, searchMod, searchModManifest, listMod, listModManifest, parseMod, parseModManifest, } from './modules.js';
|
|
24
24
|
export { connectorCalls, connectorTestFetch, resetConnectorCalls, type ConnectorCall, } from './connector-fixture.js';
|
|
25
25
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,YAAY,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,YAAY,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAC/F,YAAY,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACzG,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC5E,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACxF,YAAY,EACV,sBAAsB,EACtB,iBAAiB,EACjB,2BAA2B,EAC3B,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,YAAY,EACZ,mBAAmB,EACnB,0BAA0B,EAC1B,mBAAmB,EACnB,OAAO,EACP,WAAW,EACX,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,OAAO,EACP,eAAe,EACf,QAAQ,EACR,gBAAgB,GACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,KAAK,aAAa,GACnB,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,YAAY,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,YAAY,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAC/F,YAAY,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACzG,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC5E,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACxF,YAAY,EACV,sBAAsB,EACtB,iBAAiB,EACjB,2BAA2B,EAC3B,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,YAAY,EACZ,mBAAmB,EACnB,0BAA0B,EAC1B,mBAAmB,EACnB,OAAO,EACP,WAAW,EACX,OAAO,EACP,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,OAAO,EACP,eAAe,EACf,QAAQ,EACR,gBAAgB,GACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,KAAK,aAAa,GACnB,MAAM,wBAAwB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -15,6 +15,6 @@ export { grantExpiryContractSuite } from './grant-expiry-suite.js';
|
|
|
15
15
|
export { entityCheckConformanceSuite, planEntityCheckCoverage } from './entity-check-suite.js';
|
|
16
16
|
export { nodeOnlySuite, declaredNodeOnlySuite } from './node-only-suite.js';
|
|
17
17
|
export { declareEntityChecks, declareNodeOnly, assertNodeOnly } from './conformance.js';
|
|
18
|
-
export { atomicMod, billedMod, brokenMod, connectorMod, contractTestBareOps, contractTestInitialModules, contractTestModules, permMod, scheduleMod, freshnessMod, searchMod, searchModManifest, listMod, listModManifest, parseMod, parseModManifest, } from './modules.js';
|
|
18
|
+
export { atomicMod, billedMod, brokenMod, connectorMod, contractTestBareOps, contractTestInitialModules, contractTestModules, permMod, scheduleMod, testMod, freshnessMod, searchMod, searchModManifest, listMod, listModManifest, parseMod, parseModManifest, } from './modules.js';
|
|
19
19
|
export { connectorCalls, connectorTestFetch, resetConnectorCalls, } from './connector-fixture.js';
|
|
20
20
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAEnE,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAE/F,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE5E,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAOxF,OAAO,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,YAAY,EACZ,mBAAmB,EACnB,0BAA0B,EAC1B,mBAAmB,EACnB,OAAO,EACP,WAAW,EACX,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,OAAO,EACP,eAAe,EACf,QAAQ,EACR,gBAAgB,GACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,mBAAmB,GAEpB,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAEnE,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAE/F,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE5E,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAOxF,OAAO,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,YAAY,EACZ,mBAAmB,EACnB,0BAA0B,EAC1B,mBAAmB,EACnB,OAAO,EACP,WAAW,EACX,OAAO,EACP,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,OAAO,EACP,eAAe,EACf,QAAQ,EACR,gBAAgB,GACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,mBAAmB,GAEpB,MAAM,wBAAwB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scope-host-suite.d.ts","sourceRoot":"","sources":["../src/scope-host-suite.ts"],"names":[],"mappings":"AAuBA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,sBAAsB,CAAC;AAW9B,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,SAAS,CAAC;IAChB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AA2BD,iFAAiF;AACjF,MAAM,WAAW,qBAAqB;IACpC;;;;;;OAMG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACvC;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,EAC5C,IAAI,GAAE,qBAA0B,GAC/B,IAAI,
|
|
1
|
+
{"version":3,"file":"scope-host-suite.d.ts","sourceRoot":"","sources":["../src/scope-host-suite.ts"],"names":[],"mappings":"AAuBA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,sBAAsB,CAAC;AAW9B,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,SAAS,CAAC;IAChB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AA2BD,iFAAiF;AACjF,MAAM,WAAW,qBAAqB;IACpC;;;;;;OAMG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACvC;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,EAC5C,IAAI,GAAE,qBAA0B,GAC/B,IAAI,CA83JN"}
|
package/dist/scope-host-suite.js
CHANGED
|
@@ -2940,30 +2940,30 @@ export function scopeHostContractSuite(adapterName, makeFixture, opts = {}) {
|
|
|
2940
2940
|
};
|
|
2941
2941
|
it('a private vertical version lands ADMITTED on push, noted as auto-admission', async () => {
|
|
2942
2942
|
await host.admin.registerVertical(staff, {
|
|
2943
|
-
slug: '
|
|
2944
|
-
name: '
|
|
2943
|
+
slug: 'tenant-a/crm',
|
|
2944
|
+
name: 'Tenant A CRM',
|
|
2945
2945
|
source: 'cli',
|
|
2946
2946
|
ownerTenant: t2,
|
|
2947
2947
|
});
|
|
2948
|
-
const vid = await publishPrivate('
|
|
2949
|
-
const [v] = await host.admin.listVersions(staff, '
|
|
2948
|
+
const vid = await publishPrivate('tenant-a/crm', '0.1.0');
|
|
2949
|
+
const [v] = await host.admin.listVersions(staff, 'tenant-a/crm');
|
|
2950
2950
|
expect(v?.admission).toBe('admitted');
|
|
2951
2951
|
expect(v?.admissionNote).toBe(AUTO_ADMISSION_NOTE);
|
|
2952
2952
|
// Promotable immediately — for a private vertical, push + promote IS the deploy.
|
|
2953
|
-
await host.admin.promoteVersion(staff, '
|
|
2954
|
-
expect((await host.admin.listChannels(staff, '
|
|
2953
|
+
await host.admin.promoteVersion(staff, 'tenant-a/crm', 'prod', vid);
|
|
2954
|
+
expect((await host.admin.listChannels(staff, 'tenant-a/crm')).find((c) => c.channel === 'prod')?.versionId).toBe(vid);
|
|
2955
2955
|
});
|
|
2956
2956
|
it('getVersion reads ONE version by id, and fails closed across a lineage', async () => {
|
|
2957
2957
|
// The read that replaced "list every version this vertical ever pushed, then
|
|
2958
2958
|
// .find() one". Correctness first: same row, same shape as the list gives.
|
|
2959
|
-
const vid = await publishPrivate('
|
|
2959
|
+
const vid = await publishPrivate('tenant-a/crm', '0.9.0');
|
|
2960
2960
|
const one = await host.admin.getVersion(staff, vid);
|
|
2961
2961
|
expect(one?.id).toBe(vid);
|
|
2962
|
-
expect(one).toEqual((await host.admin.listVersions(staff, '
|
|
2962
|
+
expect(one).toEqual((await host.admin.listVersions(staff, 'tenant-a/crm')).find((v) => v.id === vid));
|
|
2963
2963
|
// Narrowed, it keeps what the old `.find()`-inside-one-slug's-list gave for free:
|
|
2964
2964
|
// a version of ANOTHER vertical is absent, not returned across the boundary. Without
|
|
2965
2965
|
// this, the slug in the URL stops constraining which version a route can hand back.
|
|
2966
|
-
expect((await host.admin.getVersion(staff, vid, '
|
|
2966
|
+
expect((await host.admin.getVersion(staff, vid, 'tenant-a/crm'))?.id).toBe(vid);
|
|
2967
2967
|
expect(await host.admin.getVersion(staff, vid, 'callout')).toBeUndefined();
|
|
2968
2968
|
// An id nobody published is absent, not a throw — callers branch on undefined.
|
|
2969
2969
|
expect(await host.admin.getVersion(staff, ulid())).toBeUndefined();
|
|
@@ -2976,15 +2976,15 @@ export function scopeHostContractSuite(adapterName, makeFixture, opts = {}) {
|
|
|
2976
2976
|
expect(versions.find((v) => v.version === '9.9.9')?.admission).toBe('pending');
|
|
2977
2977
|
});
|
|
2978
2978
|
it('promotion appends to the channel history — the go-live timeline rollback picks from', async () => {
|
|
2979
|
-
const first = (await host.admin.listChannelHistory(staff, '
|
|
2979
|
+
const first = (await host.admin.listChannelHistory(staff, 'tenant-a/crm', 'prod'));
|
|
2980
2980
|
expect(first).toHaveLength(1);
|
|
2981
2981
|
expect(first[0].fromVersionId).toBeNull(); // nothing before the first go-live
|
|
2982
|
-
const v2 = await publishPrivate('
|
|
2983
|
-
await host.admin.promoteVersion(staff, '
|
|
2982
|
+
const v2 = await publishPrivate('tenant-a/crm', '0.2.0');
|
|
2983
|
+
await host.admin.promoteVersion(staff, 'tenant-a/crm', 'prod', v2);
|
|
2984
2984
|
// Rollback is a NEW promotion of the older version — the timeline only grows.
|
|
2985
2985
|
const v1 = first[0].versionId;
|
|
2986
|
-
await host.admin.promoteVersion(staff, '
|
|
2987
|
-
const timeline = await host.admin.listChannelHistory(staff, '
|
|
2986
|
+
await host.admin.promoteVersion(staff, 'tenant-a/crm', 'prod', v1);
|
|
2987
|
+
const timeline = await host.admin.listChannelHistory(staff, 'tenant-a/crm', 'prod');
|
|
2988
2988
|
expect(timeline.map((h) => h.versionId)).toEqual([v1, v2, v1]); // newest first
|
|
2989
2989
|
expect(timeline[0].fromVersionId).toBe(v2);
|
|
2990
2990
|
expect(timeline[1].fromVersionId).toBe(v1);
|
|
@@ -3001,33 +3001,33 @@ export function scopeHostContractSuite(adapterName, makeFixture, opts = {}) {
|
|
|
3001
3001
|
const appScope = scopeId.parse(ulid());
|
|
3002
3002
|
await host.provisionScope(staff, { tenantId: t2, scopeId: appScope });
|
|
3003
3003
|
await host.admin.activateScope(staff, t2, appScope);
|
|
3004
|
-
const prodNow = (await host.admin.listChannels(staff, '
|
|
3004
|
+
const prodNow = (await host.admin.listChannels(staff, 'tenant-a/crm')).find((c) => c.channel === 'prod')
|
|
3005
3005
|
.versionId;
|
|
3006
3006
|
await host.admin.bindScopeVersion(staff, t2, appScope, prodNow);
|
|
3007
|
-
const v3 = await publishPrivate('
|
|
3008
|
-
await host.admin.promoteVersion(staff, '
|
|
3007
|
+
const v3 = await publishPrivate('tenant-a/crm', '0.3.0');
|
|
3008
|
+
await host.admin.promoteVersion(staff, 'tenant-a/crm', 'prod', v3);
|
|
3009
3009
|
expect((await host.admin.getScopeRecord(staff, t2, appScope))?.verticalVersionId).toBe(v3);
|
|
3010
3010
|
});
|
|
3011
3011
|
it('publish refuses an auto-admitted prod version until a staff admit vouches for it', async () => {
|
|
3012
3012
|
// Listing is the moment OTHER tenants start trusting this code, so the version
|
|
3013
3013
|
// they would install needs a recorded human decision — the auto-admission note
|
|
3014
3014
|
// is exactly what marks its absence.
|
|
3015
|
-
await expect(host.admin.setVerticalListed(staff, '
|
|
3015
|
+
await expect(host.admin.setVerticalListed(staff, 'tenant-a/crm', true)).rejects.toThrow(/auto-admitted.*staff admit/);
|
|
3016
3016
|
// A staff admit of the already-admitted version upgrades it to a manual vouch
|
|
3017
3017
|
// (clears the note, audited) — then listing passes.
|
|
3018
|
-
const prodNow = (await host.admin.listChannels(staff, '
|
|
3018
|
+
const prodNow = (await host.admin.listChannels(staff, 'tenant-a/crm')).find((c) => c.channel === 'prod')
|
|
3019
3019
|
.versionId;
|
|
3020
3020
|
await host.admin.admitVersion(staff, prodNow);
|
|
3021
|
-
const upgraded = (await host.admin.listVersions(staff, '
|
|
3021
|
+
const upgraded = (await host.admin.listVersions(staff, 'tenant-a/crm')).find((v) => v.id === prodNow);
|
|
3022
3022
|
expect(upgraded?.admission).toBe('admitted');
|
|
3023
3023
|
expect(upgraded?.admissionNote).toBeNull();
|
|
3024
|
-
await host.admin.setVerticalListed(staff, '
|
|
3024
|
+
await host.admin.setVerticalListed(staff, 'tenant-a/crm', true);
|
|
3025
3025
|
// Listed now: the next push lands PENDING — staff admission is back in the
|
|
3026
3026
|
// path exactly when the audience widened.
|
|
3027
|
-
const v4 = await publishPrivate('
|
|
3028
|
-
expect((await host.admin.listVersions(staff, '
|
|
3027
|
+
const v4 = await publishPrivate('tenant-a/crm', '0.4.0');
|
|
3028
|
+
expect((await host.admin.listVersions(staff, 'tenant-a/crm')).find((v) => v.id === v4)?.admission).toBe('pending');
|
|
3029
3029
|
// Unlist again so later suites see the vertical private (and pushes self-admit).
|
|
3030
|
-
await host.admin.setVerticalListed(staff, '
|
|
3030
|
+
await host.admin.setVerticalListed(staff, 'tenant-a/crm', false);
|
|
3031
3031
|
});
|
|
3032
3032
|
// -- the provisioning state (K-31) ---------------------------------------
|
|
3033
3033
|
it('provisions a scope as `provisioning`, not `active`', async () => {
|
|
@@ -3703,9 +3703,10 @@ export function scopeHostContractSuite(adapterName, makeFixture, opts = {}) {
|
|
|
3703
3703
|
const stub = await host.getScope(alice, t4, s4);
|
|
3704
3704
|
// Holding nothing: the denial says so, rather than leaving "held" to the imagination.
|
|
3705
3705
|
await expect(stub.invoke('billed/act')).rejects.toThrow(/holds: none/);
|
|
3706
|
-
// The
|
|
3707
|
-
// manifest declares. Required-alone reads as "buy the
|
|
3708
|
-
// required-vs-held shows a near-miss at a
|
|
3706
|
+
// The slug-prefixed-key shape (#691): the tenant DOES hold keys — just not
|
|
3707
|
+
// under the name the manifest declares. Required-alone reads as "buy the
|
|
3708
|
+
// SKU" and sends you shopping; required-vs-held shows a near-miss at a
|
|
3709
|
+
// glance, which is the actual diagnosis.
|
|
3709
3710
|
await host.admin.grantEntitlement(staff, t4, 't-0wv2mwk4j5/billed');
|
|
3710
3711
|
await host.admin.grantEntitlement(staff, t4, 'workorder');
|
|
3711
3712
|
const err = await stub.invoke('billed/act').then(() => null, (e) => e.message);
|
|
@@ -4102,12 +4103,12 @@ export function scopeHostContractSuite(adapterName, makeFixture, opts = {}) {
|
|
|
4102
4103
|
expect(seen).toEqual(all.map((v) => v.slug));
|
|
4103
4104
|
});
|
|
4104
4105
|
it('flips listVersions to newest-first on order desc, cursor still exclusive', async () => {
|
|
4105
|
-
const asc = await host.admin.listVersions(staff, '
|
|
4106
|
+
const asc = await host.admin.listVersions(staff, 'tenant-a/crm');
|
|
4106
4107
|
expect(asc.length).toBeGreaterThanOrEqual(4);
|
|
4107
|
-
const desc = await host.admin.listVersions(staff, '
|
|
4108
|
+
const desc = await host.admin.listVersions(staff, 'tenant-a/crm', { order: 'desc' });
|
|
4108
4109
|
expect(desc.map((v) => v.id)).toEqual([...asc.map((v) => v.id)].reverse());
|
|
4109
4110
|
// Descending pages backward from the cursor, strictly before it.
|
|
4110
|
-
const page = await host.admin.listVersions(staff, '
|
|
4111
|
+
const page = await host.admin.listVersions(staff, 'tenant-a/crm', {
|
|
4111
4112
|
order: 'desc',
|
|
4112
4113
|
limit: 2,
|
|
4113
4114
|
cursor: desc[0].id,
|
|
@@ -4115,19 +4116,19 @@ export function scopeHostContractSuite(adapterName, makeFixture, opts = {}) {
|
|
|
4115
4116
|
expect(page.map((v) => v.id)).toEqual(desc.slice(1, 3).map((v) => v.id));
|
|
4116
4117
|
});
|
|
4117
4118
|
it('keeps listChannelHistory newest-first by default and pages it; asc flips the walk', async () => {
|
|
4118
|
-
const newest = await host.admin.listChannelHistory(staff, '
|
|
4119
|
+
const newest = await host.admin.listChannelHistory(staff, 'tenant-a/crm', 'prod');
|
|
4119
4120
|
expect(newest.length).toBeGreaterThanOrEqual(4);
|
|
4120
4121
|
// Entry ids are ULIDs, so newest-first means descending ids — the shipped order.
|
|
4121
4122
|
expect(newest.map((h) => h.id)).toEqual([...newest.map((h) => h.id)].sort().reverse());
|
|
4122
|
-
const first = await host.admin.listChannelHistory(staff, '
|
|
4123
|
+
const first = await host.admin.listChannelHistory(staff, 'tenant-a/crm', 'prod', { limit: 2 });
|
|
4123
4124
|
expect(first.map((h) => h.id)).toEqual(newest.slice(0, 2).map((h) => h.id));
|
|
4124
|
-
const next = await host.admin.listChannelHistory(staff, '
|
|
4125
|
+
const next = await host.admin.listChannelHistory(staff, 'tenant-a/crm', 'prod', {
|
|
4125
4126
|
limit: 2,
|
|
4126
4127
|
cursor: first[1].id,
|
|
4127
4128
|
});
|
|
4128
4129
|
expect(next.map((h) => h.id)).toEqual(newest.slice(2, 4).map((h) => h.id));
|
|
4129
4130
|
// 'asc' flips to oldest-first — the whole timeline, reversed.
|
|
4130
|
-
const oldest = await host.admin.listChannelHistory(staff, '
|
|
4131
|
+
const oldest = await host.admin.listChannelHistory(staff, 'tenant-a/crm', 'prod', {
|
|
4131
4132
|
order: 'asc',
|
|
4132
4133
|
});
|
|
4133
4134
|
expect(oldest.map((h) => h.id)).toEqual([...newest.map((h) => h.id)].reverse());
|