Skip to content

Commit 7495483

Browse files
committed
test: jest
1 parent 353e20e commit 7495483

File tree

7 files changed

+289
-105
lines changed

7 files changed

+289
-105
lines changed

src/Resources/app/administration/src/module/swag-migration/component/swag-migration-error-resolution/swag-migration-error-resolution-field/swag-migration-error-resolution-field-scalar/index.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,6 @@ export default Shopware.Component.wrapComponentConfig({
3232
type: Object as PropType<Property>,
3333
required: true,
3434
},
35-
entityName: {
36-
type: String,
37-
required: true,
38-
},
3935
fieldName: {
4036
type: String,
4137
required: true,

src/Resources/app/administration/src/module/swag-migration/component/swag-migration-error-resolution/swag-migration-error-resolution-modal/index.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -249,21 +249,24 @@ export default Shopware.Component.wrapComponentConfig({
249249
this.createNotificationError({
250250
message: this.$tc('swag-migration.index.error-resolution.errors.validationFailed'),
251251
});
252-
253-
return false;
252+
return null;
254253
});
255254

256-
if (serializationError?.valid === true) {
255+
if (!serializationError) {
256+
return false;
257+
}
258+
259+
if (serializationError.valid === true) {
257260
return true;
258261
}
259262

260-
if (!serializationError?.violations?.length) {
263+
const message = serializationError.violations?.at(0)?.message;
264+
265+
if (!message) {
261266
return false;
262267
}
263268

264-
this.fieldError = {
265-
detail: serializationError.violations.at(0)?.message,
266-
};
269+
this.fieldError = { detail: message };
267270

268271
return false;
269272
},

tests/Jest/src/core/service/api/swag-migration.api.service.spec.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,4 +376,39 @@ describe('src/core/service/api/swag-migration.api.service', () => {
376376
expect(clientMock.history.post[0].data).toBe(JSON.stringify(data));
377377
expect(clientMock.history.post[0].headers['test-header']).toBe('test-value');
378378
});
379+
380+
it('should validate resolution', async () => {
381+
const { migrationApiService, clientMock } = createMigrationApiService();
382+
383+
const data = {
384+
entityName: 'product',
385+
fieldName: 'name',
386+
fieldValue: 'New Product Name',
387+
};
388+
389+
await migrationApiService.validateResolution(data.entityName, data.fieldName, data.fieldValue, {
390+
'test-header': 'test-value',
391+
});
392+
393+
expect(clientMock.history.post[0].url).toBe('_action/migration/error-resolution/validate');
394+
expect(clientMock.history.post[0].data).toBe(JSON.stringify(data));
395+
expect(clientMock.history.post[0].headers['test-header']).toBe('test-value');
396+
});
397+
398+
it('should get example field structure', async () => {
399+
const { migrationApiService, clientMock } = createMigrationApiService();
400+
401+
const data = {
402+
entityName: 'product',
403+
fieldName: 'name',
404+
};
405+
406+
await migrationApiService.getExampleFieldStructure(data.entityName, data.fieldName, {
407+
'test-header': 'test-value',
408+
});
409+
410+
expect(clientMock.history.post[0].url).toBe('_action/migration/error-resolution/example-field-structure');
411+
expect(clientMock.history.post[0].data).toBe(JSON.stringify(data));
412+
expect(clientMock.history.post[0].headers['test-header']).toBe('test-value');
413+
});
379414
});

tests/Jest/src/module/swag-migration/component/swag-migration-error-resolution/swag-migration-error-resolution-field/swag-migration-error-resolution-field-scalar.spec.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const updateFieldValueMock = jest.fn();
1010

1111
const defaultProps = {
1212
componentType: 'text',
13+
entityNAme: 'customer',
1314
entityField: {
1415
entity: 'customer',
1516
type: 'string',
@@ -175,4 +176,42 @@ describe('src/module/swag-migration/component/swag-migration-error-resolution/sw
175176
await wrapper.setProps({ disabled: true });
176177
expect(wrapper.find('.sw-migration-error-resolution-field__datepicker input').attributes('disabled')).toBeDefined();
177178
});
179+
180+
it('should init bool field value for switch component', async () => {
181+
const props = {
182+
...defaultProps,
183+
componentType: 'switch',
184+
entityField: {
185+
entity: 'customer',
186+
type: 'bool',
187+
},
188+
fieldName: 'active',
189+
};
190+
191+
const wrapper = await createWrapper(props);
192+
193+
expect(wrapper.vm.fieldValue).toBe(false);
194+
expect(wrapper.find('.sw-migration-error-resolution-field__switch input').element.checked).toBe(false);
195+
});
196+
197+
it('should init example value when set', async () => {
198+
const props = {
199+
...defaultProps,
200+
componentType: 'editor',
201+
entityField: {
202+
entity: 'product',
203+
type: 'string',
204+
},
205+
fieldName: 'price',
206+
};
207+
208+
const wrapper = await createWrapper(props);
209+
expect(wrapper.find('.sw-migration-error-resolution-field__editor').exists()).toBe(true);
210+
211+
expect(wrapper.vm.fieldValue).toBeNull();
212+
213+
const example = 'Sample example value';
214+
await wrapper.setProps({ exampleValue: example });
215+
expect(wrapper.vm.fieldValue).toBe(example);
216+
});
178217
});

tests/Jest/src/module/swag-migration/component/swag-migration-error-resolution/swag-migration-error-resolution-field/swag-migration-error-resolution-field-unhandled.spec.js

Lines changed: 19 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ async function createWrapper(props = defaultProps) {
2323
stubs: {
2424
'sw-code-editor': await wrapTestComponent('sw-code-editor'),
2525
'sw-base-field': await wrapTestComponent('sw-base-field'),
26+
'sw-field-error': await wrapTestComponent('sw-field-error'),
2627
'sw-inheritance-switch': true,
2728
'sw-ai-copilot-badge': true,
28-
'sw-field-error': true,
2929
'sw-circle-icon': true,
3030
'sw-help-text': true,
3131
'mt-banner': true,
@@ -71,113 +71,38 @@ describe('src/module/swag-migration/component/swag-migration-error-resolution/sw
7171
const wrapper = await createWrapper();
7272
await flushPromises();
7373

74-
expect(wrapper.find('.sw-code-editor__editor').attributes('content')).toBe('');
75-
expect(updateFieldValueMock).toHaveBeenCalledWith('');
76-
});
77-
78-
it.each([
79-
{ name: 'string', value: '"test string"', expected: 'test string' },
80-
{ name: 'number', value: '123', expected: 123 },
81-
{ name: 'boolean', value: 'true', expected: true },
82-
{ name: 'null', value: 'null', expected: null },
83-
{ name: 'object', value: '{"key": "value"}', expected: { key: 'value' } },
84-
{
85-
name: 'array',
86-
value: '[1, 2, 3]',
87-
expected: [
88-
1,
89-
2,
90-
3,
91-
],
92-
},
93-
])('should parse and publish JSON values: $name', async ({ value, expected }) => {
94-
const wrapper = await createWrapper();
95-
await flushPromises();
96-
jest.clearAllMocks();
97-
98-
await wrapper.setData({ fieldValue: value });
99-
await flushPromises();
100-
101-
expect(updateFieldValueMock).toHaveBeenCalledWith(expected);
102-
});
103-
104-
it.each([
105-
{
106-
name: 'trailing comma in object',
107-
value: '{"key": "value",}',
108-
},
109-
{
110-
name: 'trailing comma in array',
111-
value: '[1, 2, 3,]',
112-
},
113-
{
114-
name: 'nested trailing commas',
115-
value: '{"outer": {"inner": "value",},}',
116-
},
117-
])('should return null and set error for trailing commas: $name', async ({ value }) => {
118-
const wrapper = await createWrapper();
119-
await flushPromises();
120-
jest.clearAllMocks();
121-
122-
await wrapper.setData({ fieldValue: value });
123-
await flushPromises();
124-
74+
expect(wrapper.find('.sw-code-editor__editor').attributes('content')).toBeUndefined();
12575
expect(updateFieldValueMock).toHaveBeenCalledWith(null);
126-
expect(wrapper.vm.error).not.toBeNull();
127-
expect(wrapper.vm.error.detail).toBeDefined();
12876
});
12977

130-
it.each([
131-
{
132-
name: 'invalid JSON',
133-
value: 'not json',
134-
},
135-
{
136-
name: 'incomplete object',
137-
value: '{"key": ',
138-
},
139-
{
140-
name: 'single quotes',
141-
value: "{'key': 'value'}",
142-
},
143-
])('should return null and set error for invalid JSON: $name', async ({ value }) => {
78+
it('should display error message when passed', async () => {
14479
const wrapper = await createWrapper();
14580
await flushPromises();
146-
jest.clearAllMocks();
147-
148-
await wrapper.setData({ fieldValue: value });
149-
await flushPromises();
15081

151-
expect(updateFieldValueMock).toHaveBeenCalledWith(null);
152-
expect(wrapper.vm.error).not.toBeNull();
153-
expect(wrapper.vm.error.detail).toBeDefined();
154-
});
82+
expect(wrapper.find('.sw-field__error').exists()).toBe(false);
15583

156-
it('should trim whitespace from JSON string', async () => {
157-
const wrapper = await createWrapper();
158-
await flushPromises();
159-
jest.clearAllMocks();
160-
161-
await wrapper.setData({ fieldValue: ' {"key": "value"} ' });
162-
await flushPromises();
84+
const message = 'This is an error message';
85+
await wrapper.setProps({
86+
error: {
87+
detail: message,
88+
},
89+
});
16390

164-
expect(updateFieldValueMock).toHaveBeenCalledWith({ key: 'value' });
165-
expect(wrapper.vm.error).toBeNull();
91+
expect(wrapper.find('.sw-field__error').exists()).toBe(true);
92+
expect(wrapper.find('.sw-field__error').text()).toBe(message);
16693
});
16794

168-
it('should clear error when valid JSON is entered after invalid JSON', async () => {
95+
it('should init with example value when set', async () => {
16996
const wrapper = await createWrapper();
17097
await flushPromises();
17198

172-
await wrapper.setData({ fieldValue: 'invalid json' });
173-
await flushPromises();
174-
expect(wrapper.vm.error).not.toBeNull();
99+
expect(wrapper.find('.sw-code-editor__editor').attributes('content')).toBeUndefined();
175100

176-
jest.clearAllMocks();
177-
await wrapper.setData({ fieldValue: '{"valid": "json"}' });
178-
await flushPromises();
101+
const exampleValue = 'example content';
102+
await wrapper.setProps({
103+
exampleValue: exampleValue,
104+
});
179105

180-
expect(wrapper.vm.error).toBeNull();
181-
expect(updateFieldValueMock).toHaveBeenCalledWith({ valid: 'json' });
106+
expect(wrapper.find('.sw-code-editor__editor').attributes('content')).toBe(exampleValue);
182107
});
183108
});

tests/Jest/src/module/swag-migration/component/swag-migration-error-resolution/swag-migration-error-resolution-field/swag-migration-error-resolution-field.spec.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ import SwagMigrationErrorResolutionService from 'SwagMigrationAssistant/module/s
77

88
Shopware.Component.register('swag-migration-error-resolution-field', () => SwagMigrationErrorResolutionField);
99

10+
const migrationApiServiceMock = {
11+
getExampleFieldStructure: jest.fn().mockResolvedValue(
12+
Promise.resolve({
13+
example: 'Example Value',
14+
}),
15+
),
16+
};
17+
1018
const defaultProps = {
1119
log: {
1220
count: 10,
@@ -30,12 +38,17 @@ async function createWrapper(props = defaultProps) {
3038
},
3139
provide: {
3240
swagMigrationErrorResolutionService: new SwagMigrationErrorResolutionService(),
41+
migrationApiService: migrationApiServiceMock,
3342
},
3443
},
3544
});
3645
}
3746

3847
describe('src/module/swag-migration/component/swag-migration-error-resolution/swag-migration-error-resolution-field/swag-migration-error-resolution-field', () => {
48+
beforeEach(() => {
49+
Shopware.Store.get('notification').$reset();
50+
});
51+
3952
it('should display unhandled component & pass data', async () => {
4053
const props = {
4154
...defaultProps,
@@ -48,12 +61,16 @@ describe('src/module/swag-migration/component/swag-migration-error-resolution/sw
4861
};
4962

5063
const wrapper = await createWrapper(props);
64+
await flushPromises();
65+
66+
expect(migrationApiServiceMock.getExampleFieldStructure).toHaveBeenCalled();
5167

5268
const field = wrapper.find('swag-migration-error-resolution-field-unhandled-stub');
5369

5470
expect(field.exists()).toBe(true);
5571
expect(field.attributes('disabled')).toBe(String(props.disabled));
5672
expect(field.attributes('field-name')).toBe(props.log.fieldName);
73+
expect(field.attributes('example-value')).toBe('Example Value');
5774
});
5875

5976
it('should display scalar component & pass data', async () => {
@@ -68,6 +85,9 @@ describe('src/module/swag-migration/component/swag-migration-error-resolution/sw
6885
};
6986

7087
const wrapper = await createWrapper(props);
88+
await flushPromises();
89+
90+
expect(migrationApiServiceMock.getExampleFieldStructure).not.toHaveBeenCalled();
7191

7292
const field = wrapper.find('swag-migration-error-resolution-field-scalar-stub');
7393

@@ -89,11 +109,60 @@ describe('src/module/swag-migration/component/swag-migration-error-resolution/sw
89109
};
90110

91111
const wrapper = await createWrapper(props);
112+
await flushPromises();
113+
114+
expect(migrationApiServiceMock.getExampleFieldStructure).not.toHaveBeenCalled();
92115

93116
const field = wrapper.find('swag-migration-error-resolution-field-relation-stub');
94117

95118
expect(field.exists()).toBe(true);
96119
expect(field.attributes('disabled')).toBe(String(props.disabled));
97120
expect(field.attributes('field-name')).toBe(props.log.fieldName);
98121
});
122+
123+
it('should fetch example field value', async () => {
124+
const wrapper = await createWrapper({
125+
...defaultProps,
126+
log: {
127+
...defaultProps.log,
128+
entityName: 'product',
129+
fieldName: 'price',
130+
},
131+
});
132+
await flushPromises();
133+
134+
expect(migrationApiServiceMock.getExampleFieldStructure).toHaveBeenCalled();
135+
136+
expect(wrapper.find('swag-migration-error-resolution-field-scalar-stub').exists()).toBe(true);
137+
expect(wrapper.find('swag-migration-error-resolution-field-scalar-stub').attributes('example-value')).toBe(
138+
'Example Value',
139+
);
140+
});
141+
142+
it('should display error notification on fetch failure', async () => {
143+
migrationApiServiceMock.getExampleFieldStructure.mockRejectedValueOnce(new Error('Fetch failed'));
144+
145+
await createWrapper({
146+
...defaultProps,
147+
log: {
148+
...defaultProps.log,
149+
entityName: 'product',
150+
fieldName: 'price',
151+
},
152+
});
153+
await flushPromises();
154+
155+
expect(migrationApiServiceMock.getExampleFieldStructure).toHaveBeenCalled();
156+
157+
const notifications = Object.values(Shopware.Store.get('notification').notifications);
158+
159+
expect(notifications).toHaveLength(1);
160+
expect(notifications).toStrictEqual(
161+
expect.arrayContaining([
162+
expect.objectContaining({
163+
message: 'swag-migration.index.error-resolution.errors.fetchExampleFailed',
164+
}),
165+
]),
166+
);
167+
});
99168
});

0 commit comments

Comments
 (0)