@happyvertical/smrt-fields 0.53.0 → 0.53.2
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.js +1 -1
- package/dist/manifest.json +1 -1
- package/dist/smrt-knowledge.json +3 -3
- package/package.json +10 -10
- package/dist/svelte/__tests__/FieldPolicyControlPanel.test.js +0 -277
- package/dist/svelte/__tests__/FieldPolicyGear.test.js +0 -503
- package/dist/svelte/__tests__/FormHelp.test.js +0 -146
- package/dist/svelte/__tests__/ModeUX.test.js +0 -109
- package/dist/svelte/__tests__/ObjectForm.test.js +0 -725
- package/dist/svelte/__tests__/ObjectFormGeneratedApi.integration.test.js +0 -437
- package/dist/svelte/__tests__/PolicyField.test.js +0 -373
- package/dist/svelte/__tests__/UsageLearning.test.js +0 -140
- package/dist/svelte/__tests__/fixtures/AdvancedFieldsFixture.svelte +0 -30
- package/dist/svelte/__tests__/fixtures/AdvancedFieldsFixture.svelte.d.ts +0 -9
- package/dist/svelte/__tests__/fixtures/AdvancedFieldsFixture.svelte.d.ts.map +0 -1
- package/dist/svelte/__tests__/fixtures/DomPrefillFixture.svelte +0 -33
- package/dist/svelte/__tests__/fixtures/DomPrefillFixture.svelte.d.ts +0 -10
- package/dist/svelte/__tests__/fixtures/DomPrefillFixture.svelte.d.ts.map +0 -1
- package/dist/svelte/__tests__/fixtures/FormHelpFixture.svelte +0 -19
- package/dist/svelte/__tests__/fixtures/FormHelpFixture.svelte.d.ts +0 -10
- package/dist/svelte/__tests__/fixtures/FormHelpFixture.svelte.d.ts.map +0 -1
- package/dist/svelte/__tests__/fixtures/GeneratedApiGearFixture.svelte +0 -18
- package/dist/svelte/__tests__/fixtures/GeneratedApiGearFixture.svelte.d.ts +0 -11
- package/dist/svelte/__tests__/fixtures/GeneratedApiGearFixture.svelte.d.ts.map +0 -1
- package/dist/svelte/__tests__/fixtures/GracefulDegradeFixture.svelte +0 -11
- package/dist/svelte/__tests__/fixtures/GracefulDegradeFixture.svelte.d.ts +0 -19
- package/dist/svelte/__tests__/fixtures/GracefulDegradeFixture.svelte.d.ts.map +0 -1
- package/dist/svelte/__tests__/fixtures/ModeSwitchFixture.svelte +0 -18
- package/dist/svelte/__tests__/fixtures/ModeSwitchFixture.svelte.d.ts +0 -8
- package/dist/svelte/__tests__/fixtures/ModeSwitchFixture.svelte.d.ts.map +0 -1
- package/dist/svelte/__tests__/fixtures/NoIdFixture.svelte +0 -24
- package/dist/svelte/__tests__/fixtures/NoIdFixture.svelte.d.ts +0 -13
- package/dist/svelte/__tests__/fixtures/NoIdFixture.svelte.d.ts.map +0 -1
- package/dist/svelte/__tests__/fixtures/ObjectFormActionsFixture.svelte +0 -37
- package/dist/svelte/__tests__/fixtures/ObjectFormActionsFixture.svelte.d.ts +0 -15
- package/dist/svelte/__tests__/fixtures/ObjectFormActionsFixture.svelte.d.ts.map +0 -1
- package/dist/svelte/__tests__/fixtures/ObjectFormFixture.svelte +0 -17
- package/dist/svelte/__tests__/fixtures/ObjectFormFixture.svelte.d.ts +0 -10
- package/dist/svelte/__tests__/fixtures/ObjectFormFixture.svelte.d.ts.map +0 -1
- package/dist/svelte/__tests__/fixtures/ObjectFormRegistryFixture.svelte +0 -25
- package/dist/svelte/__tests__/fixtures/ObjectFormRegistryFixture.svelte.d.ts +0 -10
- package/dist/svelte/__tests__/fixtures/ObjectFormRegistryFixture.svelte.d.ts.map +0 -1
- package/dist/svelte/__tests__/fixtures/ObjectFormSnippetFixture.svelte +0 -34
- package/dist/svelte/__tests__/fixtures/ObjectFormSnippetFixture.svelte.d.ts +0 -10
- package/dist/svelte/__tests__/fixtures/ObjectFormSnippetFixture.svelte.d.ts.map +0 -1
- package/dist/svelte/__tests__/fixtures/ObjectFormSourceFixture.svelte +0 -29
- package/dist/svelte/__tests__/fixtures/ObjectFormSourceFixture.svelte.d.ts +0 -11
- package/dist/svelte/__tests__/fixtures/ObjectFormSourceFixture.svelte.d.ts.map +0 -1
- package/dist/svelte/__tests__/fixtures/ObjectFormSourceSnippetFixture.svelte +0 -33
- package/dist/svelte/__tests__/fixtures/ObjectFormSourceSnippetFixture.svelte.d.ts +0 -9
- package/dist/svelte/__tests__/fixtures/ObjectFormSourceSnippetFixture.svelte.d.ts.map +0 -1
- package/dist/svelte/__tests__/fixtures/PolicyDataTableFixture.svelte +0 -40
- package/dist/svelte/__tests__/fixtures/PolicyDataTableFixture.svelte.d.ts +0 -8
- package/dist/svelte/__tests__/fixtures/PolicyDataTableFixture.svelte.d.ts.map +0 -1
- package/dist/svelte/__tests__/fixtures/PrefillFixture.svelte +0 -26
- package/dist/svelte/__tests__/fixtures/PrefillFixture.svelte.d.ts +0 -13
- package/dist/svelte/__tests__/fixtures/PrefillFixture.svelte.d.ts.map +0 -1
- package/dist/svelte/__tests__/fixtures/ProviderFieldFixture.svelte +0 -39
- package/dist/svelte/__tests__/fixtures/ProviderFieldFixture.svelte.d.ts +0 -17
- package/dist/svelte/__tests__/fixtures/ProviderFieldFixture.svelte.d.ts.map +0 -1
- package/dist/svelte/__tests__/fixtures/RegistryInput.svelte +0 -15
- package/dist/svelte/__tests__/fixtures/RegistryInput.svelte.d.ts +0 -5
- package/dist/svelte/__tests__/fixtures/RegistryInput.svelte.d.ts.map +0 -1
- package/dist/svelte/__tests__/fixtures/RevealPrefillFixture.svelte +0 -29
- package/dist/svelte/__tests__/fixtures/RevealPrefillFixture.svelte.d.ts +0 -14
- package/dist/svelte/__tests__/fixtures/RevealPrefillFixture.svelte.d.ts.map +0 -1
- package/dist/svelte/__tests__/fixtures/SettingsCatalogStub.svelte +0 -24
- package/dist/svelte/__tests__/fixtures/SettingsCatalogStub.svelte.d.ts +0 -14
- package/dist/svelte/__tests__/fixtures/SettingsCatalogStub.svelte.d.ts.map +0 -1
- package/dist/svelte/__tests__/fixtures/SnippetFixture.svelte +0 -28
- package/dist/svelte/__tests__/fixtures/SnippetFixture.svelte.d.ts +0 -13
- package/dist/svelte/__tests__/fixtures/SnippetFixture.svelte.d.ts.map +0 -1
- package/dist/svelte/__tests__/fixtures/SuggestionGearFixture.svelte +0 -23
- package/dist/svelte/__tests__/fixtures/SuggestionGearFixture.svelte.d.ts +0 -10
- package/dist/svelte/__tests__/fixtures/SuggestionGearFixture.svelte.d.ts.map +0 -1
- package/dist/svelte/__tests__/fixtures/ToggleModeButton.svelte +0 -14
- package/dist/svelte/__tests__/fixtures/ToggleModeButton.svelte.d.ts +0 -19
- package/dist/svelte/__tests__/fixtures/ToggleModeButton.svelte.d.ts.map +0 -1
- package/dist/svelte/__tests__/fixtures/TooltipFixture.svelte +0 -25
- package/dist/svelte/__tests__/fixtures/TooltipFixture.svelte.d.ts +0 -14
- package/dist/svelte/__tests__/fixtures/TooltipFixture.svelte.d.ts.map +0 -1
- package/dist/svelte/__tests__/playground.test.js +0 -66
- package/dist/svelte/__tests__/settings-catalog.test.js +0 -161
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
// @vitest-environment jsdom
|
|
2
|
-
import { render, screen, userEvent } from '@happyvertical/smrt-vitest/svelte';
|
|
3
|
-
import { describe, expect, it, vi } from 'vitest';
|
|
4
|
-
import FieldPolicyControlPanel from '../components/FieldPolicyControlPanel.svelte';
|
|
5
|
-
import SettingsCatalogStub from './fixtures/SettingsCatalogStub.svelte';
|
|
6
|
-
const objectRef = '@test/smrt-fields:ControlPanelDocument';
|
|
7
|
-
function editorState() {
|
|
8
|
-
return {
|
|
9
|
-
capabilities: { manage: true, personalize: false },
|
|
10
|
-
personalLowerDefaultUsable: { title: false },
|
|
11
|
-
policy: {
|
|
12
|
-
objectRef,
|
|
13
|
-
fields: {
|
|
14
|
-
title: {
|
|
15
|
-
fieldName: 'title',
|
|
16
|
-
hasDefault: false,
|
|
17
|
-
defaultValue: undefined,
|
|
18
|
-
visibility: 'basic',
|
|
19
|
-
help: null,
|
|
20
|
-
label: 'Title',
|
|
21
|
-
order: 1,
|
|
22
|
-
group: null,
|
|
23
|
-
locked: false,
|
|
24
|
-
required: false,
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
layers: { title: [] },
|
|
28
|
-
},
|
|
29
|
-
rows: {
|
|
30
|
-
app: [],
|
|
31
|
-
tenant: [
|
|
32
|
-
{
|
|
33
|
-
id: 'org-title',
|
|
34
|
-
fieldName: 'title',
|
|
35
|
-
scopeType: 'tenant',
|
|
36
|
-
tenantId: 'tenant',
|
|
37
|
-
userId: null,
|
|
38
|
-
defaultValue: null,
|
|
39
|
-
displayOrder: null,
|
|
40
|
-
help: null,
|
|
41
|
-
label: null,
|
|
42
|
-
locked: null,
|
|
43
|
-
visibility: null,
|
|
44
|
-
},
|
|
45
|
-
],
|
|
46
|
-
user: [],
|
|
47
|
-
},
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
function audit(orgIds = ['org-title'], drift = true) {
|
|
51
|
-
return {
|
|
52
|
-
caller: {
|
|
53
|
-
tenantId: 'tenant',
|
|
54
|
-
userId: 'user',
|
|
55
|
-
canManageOrg: true,
|
|
56
|
-
canPersonalize: false,
|
|
57
|
-
},
|
|
58
|
-
appRows: [],
|
|
59
|
-
orgRows: orgIds.map((id) => ({
|
|
60
|
-
id,
|
|
61
|
-
objectRef,
|
|
62
|
-
fieldName: 'title',
|
|
63
|
-
scopeType: 'tenant',
|
|
64
|
-
tenantId: 'tenant',
|
|
65
|
-
userId: null,
|
|
66
|
-
updatedBy: null,
|
|
67
|
-
createdAt: null,
|
|
68
|
-
updatedAt: null,
|
|
69
|
-
defaultValue: null,
|
|
70
|
-
displayOrder: null,
|
|
71
|
-
help: null,
|
|
72
|
-
label: null,
|
|
73
|
-
locked: null,
|
|
74
|
-
visibility: null,
|
|
75
|
-
})),
|
|
76
|
-
inheritedOrgKeys: {},
|
|
77
|
-
userOverrideCounts: {},
|
|
78
|
-
driftRows: drift
|
|
79
|
-
? [
|
|
80
|
-
{
|
|
81
|
-
id: 'stale-row',
|
|
82
|
-
objectRef,
|
|
83
|
-
fieldName: 'retired',
|
|
84
|
-
scopeType: 'tenant',
|
|
85
|
-
tenantId: 'tenant',
|
|
86
|
-
userId: null,
|
|
87
|
-
updatedBy: null,
|
|
88
|
-
createdAt: null,
|
|
89
|
-
updatedAt: null,
|
|
90
|
-
reason: 'unknown-field',
|
|
91
|
-
prunable: true,
|
|
92
|
-
},
|
|
93
|
-
]
|
|
94
|
-
: [],
|
|
95
|
-
policies: {
|
|
96
|
-
[objectRef]: editorState().policy,
|
|
97
|
-
},
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
function data(pageSize = 25) {
|
|
101
|
-
const selected = {
|
|
102
|
-
id: `${objectRef}::title`,
|
|
103
|
-
label: 'title',
|
|
104
|
-
objectRef,
|
|
105
|
-
fieldName: 'title',
|
|
106
|
-
className: 'ControlPanelDocument',
|
|
107
|
-
packageName: '@test/smrt-fields',
|
|
108
|
-
fields: { title: { type: 'text' } },
|
|
109
|
-
};
|
|
110
|
-
return {
|
|
111
|
-
page: {
|
|
112
|
-
items: [selected],
|
|
113
|
-
selected,
|
|
114
|
-
query: '',
|
|
115
|
-
page: 1,
|
|
116
|
-
pageSize,
|
|
117
|
-
total: 1,
|
|
118
|
-
},
|
|
119
|
-
audit: audit(),
|
|
120
|
-
objects: [],
|
|
121
|
-
packages: [],
|
|
122
|
-
filters: {
|
|
123
|
-
packageFilter: null,
|
|
124
|
-
objectFilter: null,
|
|
125
|
-
customizedOnly: false,
|
|
126
|
-
},
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
function deferred() {
|
|
130
|
-
let resolve;
|
|
131
|
-
let reject;
|
|
132
|
-
const promise = new Promise((nextResolve, nextReject) => {
|
|
133
|
-
resolve = nextResolve;
|
|
134
|
-
reject = nextReject;
|
|
135
|
-
});
|
|
136
|
-
return { promise, resolve, reject };
|
|
137
|
-
}
|
|
138
|
-
function adapter(options = {}) {
|
|
139
|
-
return {
|
|
140
|
-
load: vi.fn(async () => {
|
|
141
|
-
options.calls?.push('load');
|
|
142
|
-
return editorState();
|
|
143
|
-
}),
|
|
144
|
-
loadAudit: vi.fn(async (input) => {
|
|
145
|
-
options.calls?.push('audit');
|
|
146
|
-
return audit();
|
|
147
|
-
}),
|
|
148
|
-
create: vi.fn(async () => undefined),
|
|
149
|
-
update: vi.fn(async () => {
|
|
150
|
-
options.calls?.push('update');
|
|
151
|
-
}),
|
|
152
|
-
delete: vi.fn(async ({ id }) => {
|
|
153
|
-
options.calls?.push(`delete:${id}`);
|
|
154
|
-
await options.onDelete?.(id);
|
|
155
|
-
}),
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
function renderPanel(panelAdapter = adapter(), options = {}) {
|
|
159
|
-
return render(FieldPolicyControlPanel, {
|
|
160
|
-
props: {
|
|
161
|
-
data: options.panelData ?? data(),
|
|
162
|
-
adapter: panelAdapter,
|
|
163
|
-
catalog: SettingsCatalogStub,
|
|
164
|
-
baseUrl: '/settings/fields',
|
|
165
|
-
confirmAction: options.confirmAction,
|
|
166
|
-
onchanged: options.onchanged,
|
|
167
|
-
suggestionAdapter: options.suggestionAdapter,
|
|
168
|
-
},
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
describe('FieldPolicyControlPanel', () => {
|
|
172
|
-
it('surfaces a reviewed pending-suggestion queue through the structural host adapter', async () => {
|
|
173
|
-
const pendingSuggestions = vi.fn(async () => ({
|
|
174
|
-
suggestions: [
|
|
175
|
-
{
|
|
176
|
-
id: 'suggestion-title',
|
|
177
|
-
objectRef,
|
|
178
|
-
fieldName: 'title',
|
|
179
|
-
kind: 'promote',
|
|
180
|
-
proposedValue: null,
|
|
181
|
-
evidence: { summary: '3 users set this field 5 times.' },
|
|
182
|
-
status: 'pending',
|
|
183
|
-
},
|
|
184
|
-
],
|
|
185
|
-
total: 1,
|
|
186
|
-
}));
|
|
187
|
-
renderPanel(adapter(), {
|
|
188
|
-
suggestionAdapter: {
|
|
189
|
-
pendingSuggestions,
|
|
190
|
-
acceptSuggestion: async () => undefined,
|
|
191
|
-
dismissSuggestion: async () => undefined,
|
|
192
|
-
},
|
|
193
|
-
});
|
|
194
|
-
await vi.waitFor(() => expect(screen.getByRole('heading', { name: 'Pending field suggestions' })).toBeVisible());
|
|
195
|
-
expect(pendingSuggestions).toHaveBeenCalledWith({
|
|
196
|
-
objectRefs: [objectRef],
|
|
197
|
-
});
|
|
198
|
-
});
|
|
199
|
-
it('uses SSR data for the first render and preserves pageSize in catalog navigation', () => {
|
|
200
|
-
renderPanel();
|
|
201
|
-
expect(screen.getByRole('heading', { name: 'Field settings' })).toBeVisible();
|
|
202
|
-
expect(screen.getByText('Title')).toBeVisible();
|
|
203
|
-
expect(screen.getByRole('link', { name: 'catalog navigation' })).toHaveAttribute('href', '/settings/fields?pageSize=25');
|
|
204
|
-
});
|
|
205
|
-
it('refreshes audit with drift and reloads editor state before notifying after an editor mutation', async () => {
|
|
206
|
-
const calls = [];
|
|
207
|
-
const panelAdapter = adapter({ calls });
|
|
208
|
-
const onchanged = () => calls.push('changed');
|
|
209
|
-
renderPanel(panelAdapter, { onchanged });
|
|
210
|
-
await vi.waitFor(() => expect(panelAdapter.load).toHaveBeenCalledTimes(1));
|
|
211
|
-
calls.length = 0;
|
|
212
|
-
await userEvent.click(screen.getByRole('button', { name: 'Edit settings' }));
|
|
213
|
-
await userEvent.click(screen.getByRole('button', { name: 'Save', exact: true }));
|
|
214
|
-
await vi.waitFor(() => expect(calls).toEqual(['update', 'audit', 'load', 'changed']));
|
|
215
|
-
expect(panelAdapter.loadAudit).toHaveBeenLastCalledWith({
|
|
216
|
-
objectRefs: [objectRef],
|
|
217
|
-
countObjectRefs: [objectRef],
|
|
218
|
-
includeDrift: true,
|
|
219
|
-
});
|
|
220
|
-
});
|
|
221
|
-
it('does not reset organization rows or prune drift when confirmation is declined', async () => {
|
|
222
|
-
const panelAdapter = adapter();
|
|
223
|
-
const confirmAction = vi.fn(() => false);
|
|
224
|
-
renderPanel(panelAdapter, { confirmAction });
|
|
225
|
-
await vi.waitFor(() => expect(panelAdapter.load).toHaveBeenCalledTimes(1));
|
|
226
|
-
vi.mocked(panelAdapter.delete).mockClear();
|
|
227
|
-
await userEvent.click(screen.getByRole('button', {
|
|
228
|
-
name: 'Reset all organization overrides for this object',
|
|
229
|
-
}));
|
|
230
|
-
await userEvent.click(screen.getByRole('button', { name: 'Prune' }));
|
|
231
|
-
expect(confirmAction).toHaveBeenCalledTimes(2);
|
|
232
|
-
expect(panelAdapter.delete).not.toHaveBeenCalled();
|
|
233
|
-
});
|
|
234
|
-
it('refreshes audit and editor state after a partial organization reset failure', async () => {
|
|
235
|
-
const calls = [];
|
|
236
|
-
const panelAdapter = adapter({
|
|
237
|
-
calls,
|
|
238
|
-
onDelete: async (id) => {
|
|
239
|
-
if (id === 'org-second')
|
|
240
|
-
throw new Error('second delete failed');
|
|
241
|
-
},
|
|
242
|
-
});
|
|
243
|
-
renderPanel(panelAdapter, {
|
|
244
|
-
confirmAction: () => true,
|
|
245
|
-
panelData: { ...data(), audit: audit(['org-first', 'org-second']) },
|
|
246
|
-
});
|
|
247
|
-
await vi.waitFor(() => expect(panelAdapter.load).toHaveBeenCalledTimes(1));
|
|
248
|
-
calls.length = 0;
|
|
249
|
-
await userEvent.click(screen.getByRole('button', {
|
|
250
|
-
name: 'Reset all organization overrides for this object',
|
|
251
|
-
}));
|
|
252
|
-
await vi.waitFor(() => expect(calls).toEqual([
|
|
253
|
-
'delete:org-first',
|
|
254
|
-
'delete:org-second',
|
|
255
|
-
'audit',
|
|
256
|
-
'load',
|
|
257
|
-
]));
|
|
258
|
-
expect(screen.getByRole('alert')).toHaveTextContent('second delete failed');
|
|
259
|
-
});
|
|
260
|
-
it('does not let an older deferred audit refresh overwrite newer panel data', async () => {
|
|
261
|
-
const staleAudit = deferred();
|
|
262
|
-
const panelAdapter = adapter();
|
|
263
|
-
panelAdapter.loadAudit = vi.fn(() => staleAudit.promise);
|
|
264
|
-
const rendered = renderPanel(panelAdapter);
|
|
265
|
-
await vi.waitFor(() => expect(panelAdapter.load).toHaveBeenCalledTimes(1));
|
|
266
|
-
await userEvent.click(screen.getByRole('button', { name: 'Edit settings' }));
|
|
267
|
-
await userEvent.click(screen.getByRole('button', { name: 'Save', exact: true }));
|
|
268
|
-
await vi.waitFor(() => expect(panelAdapter.loadAudit).toHaveBeenCalledTimes(1));
|
|
269
|
-
await rendered.rerender({
|
|
270
|
-
data: { ...data(), audit: audit([], false) },
|
|
271
|
-
});
|
|
272
|
-
expect(screen.queryByRole('heading', { name: 'Manifest drift' })).toBeNull();
|
|
273
|
-
staleAudit.resolve(audit());
|
|
274
|
-
await Promise.resolve();
|
|
275
|
-
expect(screen.queryByRole('heading', { name: 'Manifest drift' })).toBeNull();
|
|
276
|
-
});
|
|
277
|
-
});
|