|
3 | 3 | PLATFORM_CAPABILITY_TOKENS, |
4 | 4 | isKnownPlatformCapability, |
5 | 5 | PLATFORM_CAPABILITY_PROVIDERS, |
| 6 | + PLATFORM_ALWAYS_ON_CAPABILITIES, |
6 | 7 | classifyRequiredCapability, |
7 | 8 | } from './platform-capabilities'; |
8 | 9 |
|
@@ -114,3 +115,57 @@ describe('classifyRequiredCapability (#3366)', () => { |
114 | 115 | expect(seen).toEqual(['@objectstack/service-automation']); |
115 | 116 | }); |
116 | 117 | }); |
| 118 | + |
| 119 | +/** |
| 120 | + * The foundational slate (cloud#925, #3786). |
| 121 | + * |
| 122 | + * It moved here from `Serve.ALWAYS_ON_CAPABILITIES` because two runtimes mount |
| 123 | + * it — `objectstack serve` and cloud's per-tenant objectos-runtime — and the |
| 124 | + * second kept a copy under a comment that only said hosts "mirror this list". |
| 125 | + * They had already diverged by three entries. These assertions are what makes |
| 126 | + * the single declaration trustworthy for both readers. |
| 127 | + */ |
| 128 | +describe('PLATFORM_ALWAYS_ON_CAPABILITIES', () => { |
| 129 | + it('is frozen, non-empty and free of duplicates', () => { |
| 130 | + expect(Object.isFrozen(PLATFORM_ALWAYS_ON_CAPABILITIES)).toBe(true); |
| 131 | + expect(PLATFORM_ALWAYS_ON_CAPABILITIES.length).toBeGreaterThan(0); |
| 132 | + expect(PLATFORM_ALWAYS_ON_CAPABILITIES).toHaveLength( |
| 133 | + new Set(PLATFORM_ALWAYS_ON_CAPABILITIES).size, |
| 134 | + ); |
| 135 | + }); |
| 136 | + |
| 137 | + it('pins the foundational prefix — grow the slate AFTER these six', () => { |
| 138 | + // Order matters at mount time: settings/queue/job must precede the services |
| 139 | + // that bind to them during their own `kernel:ready` phase. |
| 140 | + expect(PLATFORM_ALWAYS_ON_CAPABILITIES.slice(0, 6)).toEqual([ |
| 141 | + 'queue', 'job', 'cache', 'settings', 'email', 'storage', |
| 142 | + ]); |
| 143 | + }); |
| 144 | + |
| 145 | + it('every member is a real platform capability token', () => { |
| 146 | + // A slate entry outside the vocabulary could never be classified, and every |
| 147 | + // runtime mounting the slate would force-add a token nothing provides. |
| 148 | + const unknown = PLATFORM_ALWAYS_ON_CAPABILITIES.filter( |
| 149 | + (c) => !(PLATFORM_CAPABILITY_TOKENS as readonly string[]).includes(c), |
| 150 | + ); |
| 151 | + expect(unknown).toEqual([]); |
| 152 | + }); |
| 153 | + |
| 154 | + it('every member has a declared provider', () => { |
| 155 | + // The slate is force-mounted, so a member with no provider entry would be |
| 156 | + // added to every app's `requires` and then fail to resolve for all of them. |
| 157 | + const providerless = PLATFORM_ALWAYS_ON_CAPABILITIES.filter( |
| 158 | + (c) => !PLATFORM_CAPABILITY_PROVIDERS[c], |
| 159 | + ); |
| 160 | + expect(providerless).toEqual([]); |
| 161 | + }); |
| 162 | + |
| 163 | + it('is open-edition only — the floor must be mountable without a licence', () => { |
| 164 | + // A cloud/enterprise-edition entry in the FLOOR would make the open |
| 165 | + // distribution unable to satisfy its own defaults. |
| 166 | + const gated = PLATFORM_ALWAYS_ON_CAPABILITIES.filter( |
| 167 | + (c) => PLATFORM_CAPABILITY_PROVIDERS[c]?.edition !== 'open', |
| 168 | + ); |
| 169 | + expect(gated).toEqual([]); |
| 170 | + }); |
| 171 | +}); |
0 commit comments