-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathmetadata-create-seeds.test.ts
More file actions
64 lines (59 loc) · 3 KB
/
Copy pathmetadata-create-seeds.test.ts
File metadata and controls
64 lines (59 loc) · 3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.
import { describe, it, expect } from 'vitest';
import {
getMetadataCreateSeed,
listMetadataCreateSeedTypes,
} from './metadata-create-seeds';
import {
getMetadataTypeSchema,
listMetadataTypeSchemaTypes,
} from './metadata-type-schemas';
/**
* THE canonical guard for the "designer create shape ≠ spec required" family:
* every authoritative minimal create seed MUST validate against its type's
* spec schema. If a schema tightens a requirement (e.g. action's `body`,
* dashboard's old `layout`), the matching seed fails here — right next to the
* schema — instead of 422-ing only when a user clicks Save in Studio.
*/
describe('metadata create seeds validate against their spec schemas', () => {
for (const type of listMetadataCreateSeedTypes()) {
it(`${type}: minimal create seed is spec-valid`, () => {
const schema = getMetadataTypeSchema(type);
expect(schema, `no schema registered for seeded type '${type}'`).toBeDefined();
const seed = getMetadataCreateSeed(type);
const result = schema!.safeParse(seed);
expect(
result.success,
result.success ? '' : `seed for '${type}' rejected: ${JSON.stringify(result.error.issues)}`,
).toBe(true);
});
}
it('sanity: seeds the core Studio-designer types', () => {
const seeded = new Set(listMetadataCreateSeedTypes());
for (const t of ['dashboard', 'action', 'page', 'view', 'flow', 'validation', 'hook', 'dataset', 'object']) {
expect(seeded.has(t), `core type '${t}' has no create seed`).toBe(true);
}
});
it('getMetadataCreateSeed returns a fresh clone (callers may mutate)', () => {
const a = getMetadataCreateSeed('dashboard') as { widgets: unknown[] };
const b = getMetadataCreateSeed('dashboard') as { widgets: unknown[] };
expect(a).not.toBe(b);
a.widgets.push({});
expect((getMetadataCreateSeed('dashboard') as { widgets: unknown[] }).widgets).toHaveLength(0);
});
it('surfaces schema-backed authorable types still missing a seed (no silent cap)', () => {
// Types that have a runtime-editable schema but no create seed yet. Canvas-
// create types (report builds its dataset on the canvas) and code-only /
// identity types legitimately have no static minimal create literal.
const KNOWN_UNSEEDED = new Set([
'report', // canvas-create: dataset/measures picked interactively
'app', 'field', 'seed', 'job', 'datasource', 'translation', 'doc', 'book',
'permission', 'profile', 'role', 'agent', 'tool', 'skill', 'email_template',
]);
const seeded = new Set(listMetadataCreateSeedTypes());
const missing = listMetadataTypeSchemaTypes().filter((t) => !seeded.has(t) && !KNOWN_UNSEEDED.has(t));
// eslint-disable-next-line no-console
if (missing.length) console.log(`[create-seeds] schema'd types still needing a seed: ${missing.join(', ')}`);
expect(missing, `unaccounted schema'd types without a seed: ${missing.join(', ')}`).toEqual([]);
});
});