Skip to content

Commit 1e59d73

Browse files
committed
test(dogfood): the organization-isolation suite's tenant fixture is company.legal_name, offered under a wall
Claude-Session: https://claude.ai/code/session_01UmqzD97e14iws6hmVhgZ5y Co-authored-by: Claude <noreply@anthropic.com>
1 parent ee555e8 commit 1e59d73

1 file changed

Lines changed: 30 additions & 26 deletions

File tree

‎packages/qa/dogfood/test/settings-organization-isolation.dogfood.test.ts‎

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,15 @@
3030
* organization) and two organization owners who each create their OWN
3131
* organization, so the two tenants carry different active organizations —
3232
* asserted, not assumed.
33-
* - namespaces: the shipped `branding` manifest (tenant scope, read
34-
* `setup.access`, write `setup.write`) for 1 and 3; two fixture manifests
35-
* registered on the booted service for 2 and 4, because no shipped manifest
36-
* has a global key an organization may read, or a read capability stricter
37-
* than its write capability.
33+
* - namespaces: the shipped `company` manifest (tenant scope, read
34+
* `setup.access`, write `setup.write`; its `legal_name` key, which declares
35+
* no default) for 1 and 3; two fixture manifests registered on the booted
36+
* service for 2 and 4, because no shipped manifest has a global key an
37+
* organization may read, or a read capability stricter than its write
38+
* capability. ⛔ Not `branding`: since #24766 the settings service does not
39+
* offer that namespace under a walled posture (it answers
40+
* `404 UNKNOWN_NAMESPACE` here), so a suite booting `isolated` cannot use it
41+
* as its tenant-scope fixture.
3842
*/
3943

4044
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
@@ -132,35 +136,35 @@ describe('settings values are per organization, and the generic read door applie
132136
});
133137

134138
it('two organizations each set and read their own tenant-scope value', async () => {
135-
const putA = await settingsCall(tenantAToken, 'PUT', 'branding', { workspace_name: 'Org A Workspace' });
139+
const putA = await settingsCall(tenantAToken, 'PUT', 'company', { legal_name: 'Org A Ltd' });
136140
expect(putA.status, await putA.clone().text()).toBe(200);
137141
// Organization B has written nothing: it does not read A's value.
138-
expect((await readValue(tenantBToken, 'branding', 'workspace_name')).source).toBe('default');
142+
expect((await readValue(tenantBToken, 'company', 'legal_name')).source).toBe('default');
139143

140-
const putB = await settingsCall(tenantBToken, 'PUT', 'branding', { workspace_name: 'Org B Workspace' });
144+
const putB = await settingsCall(tenantBToken, 'PUT', 'company', { legal_name: 'Org B Ltd' });
141145
expect(putB.status, await putB.clone().text()).toBe(200);
142146

143-
expect((await readValue(tenantAToken, 'branding', 'workspace_name')).value).toBe('Org A Workspace');
144-
expect((await readValue(tenantBToken, 'branding', 'workspace_name')).value).toBe('Org B Workspace');
147+
expect((await readValue(tenantAToken, 'company', 'legal_name')).value).toBe('Org A Ltd');
148+
expect((await readValue(tenantBToken, 'company', 'legal_name')).value).toBe('Org B Ltd');
145149

146150
// Two stored rows, each carrying the organization that wrote it.
147-
const rows = (await storedRows('branding')).filter((r) => r.key === 'workspace_name');
151+
const rows = (await storedRows('company')).filter((r) => r.key === 'legal_name');
148152
expect(rows.map((r) => [r.organization_id, r.value]).sort()).toEqual(
149-
[[orgAId, 'Org A Workspace'], [orgBId, 'Org B Workspace']].sort(),
153+
[[orgAId, 'Org A Ltd'], [orgBId, 'Org B Ltd']].sort(),
150154
);
151155
});
152156

153157
it('one organization\'s write, and its reset, leave the other\'s value unchanged', async () => {
154-
const putA = await settingsCall(tenantAToken, 'PUT', 'branding', { workspace_name: 'Org A Renamed' });
158+
const putA = await settingsCall(tenantAToken, 'PUT', 'company', { legal_name: 'Org A Renamed Ltd' });
155159
expect(putA.status, await putA.clone().text()).toBe(200);
156-
expect((await readValue(tenantBToken, 'branding', 'workspace_name')).value).toBe('Org B Workspace');
160+
expect((await readValue(tenantBToken, 'company', 'legal_name')).value).toBe('Org B Ltd');
157161

158-
const reset = await settingsCall(tenantAToken, 'POST', 'branding/reset', {});
162+
const reset = await settingsCall(tenantAToken, 'POST', 'company/reset', {});
159163
expect(reset.status, await reset.clone().text()).toBe(200);
160-
expect((await readValue(tenantAToken, 'branding', 'workspace_name')).source).toBe('default');
164+
expect((await readValue(tenantAToken, 'company', 'legal_name')).source).toBe('default');
161165

162-
const other = await readValue(tenantBToken, 'branding', 'workspace_name');
163-
expect(other.value).toBe('Org B Workspace');
166+
const other = await readValue(tenantBToken, 'company', 'legal_name');
167+
expect(other.value).toBe('Org B Ltd');
164168
expect(other.source).toBe('tenant');
165169
});
166170

@@ -176,20 +180,20 @@ describe('settings values are per organization, and the generic read door applie
176180
});
177181

178182
it('a tenant-scope write that names no organization is refused under the walled posture, and writes nothing; the same write from an organization lands', async () => {
179-
const before = (await storedRows('branding')).length;
183+
const before = (await storedRows('company')).length;
180184

181-
const refused = await settingsCall(adminToken, 'PUT', 'branding', { workspace_name: 'No Organization' });
185+
const refused = await settingsCall(adminToken, 'PUT', 'company', { legal_name: 'No Organization' });
182186
expect(refused.status).toBe(400);
183187
const body = (await refused.json()) as ApiError;
184188
expect(body.error?.code).toBe('SETTINGS_VALIDATION');
185-
expect(body.error?.details?.fields?.[0]).toMatchObject({ field: 'workspace_name', code: 'invalid_value' });
186-
expect((await storedRows('branding')).length).toBe(before);
187-
expect((await storedRows('branding')).some((r) => r.value === 'No Organization')).toBe(false);
189+
expect(body.error?.details?.fields?.[0]).toMatchObject({ field: 'legal_name', code: 'invalid_value' });
190+
expect((await storedRows('company')).length).toBe(before);
191+
expect((await storedRows('company')).some((r) => r.value === 'No Organization')).toBe(false);
188192

189193
// Positive control: the identical write, from inside an organization.
190-
const landed = await settingsCall(tenantAToken, 'PUT', 'branding', { workspace_name: 'No Organization' });
194+
const landed = await settingsCall(tenantAToken, 'PUT', 'company', { legal_name: 'No Organization' });
191195
expect(landed.status, await landed.clone().text()).toBe(200);
192-
expect((await readValue(tenantAToken, 'branding', 'workspace_name')).value).toBe('No Organization');
196+
expect((await readValue(tenantAToken, 'company', 'legal_name')).value).toBe('No Organization');
193197
});
194198

195199
it('the generic data-API read of sys_setting withholds a namespace\'s rows from a principal lacking its readPermission', async () => {
@@ -214,7 +218,7 @@ describe('settings values are per organization, and the generic read door applie
214218

215219
// Positive control 1: the same principal reads its own row of a namespace
216220
// whose read capability it holds.
217-
const own = await stack.apiAs(tenantAToken, 'GET', '/data/sys_setting?namespace=branding');
221+
const own = await stack.apiAs(tenantAToken, 'GET', '/data/sys_setting?namespace=company');
218222
expect(own.status, await own.clone().text()).toBe(200);
219223
const ownRows = ((await own.json()) as { data?: Array<Record<string, unknown>>; records?: Array<Record<string, unknown>> });
220224
expect((ownRows.data ?? ownRows.records ?? []).some((r) => r.organization_id === orgAId)).toBe(true);

0 commit comments

Comments
 (0)