@designcrowd/library.brand-page 6.2.5 → 6.2.6
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/lib/src/{CreatedOnBrandCrowd-de-de-CkJM0rEy.js → CreatedOnBrandCrowd-de-de-DpeSEnwP.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-en-us-CKOotMQK.js → CreatedOnBrandCrowd-en-us-CxYv3NzT.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-es-es-mrDI8AaY.js → CreatedOnBrandCrowd-es-es-CzQ1HRHw.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-fr-DtmVXezM.js → CreatedOnBrandCrowd-fr-ca-J77YZaT1.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-ca-DtmVXezM.js → CreatedOnBrandCrowd-fr-fr-J77YZaT1.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-pt-C8Cy74df.js → CreatedOnBrandCrowd-pt-br-1vh4Smqt.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-br-C8Cy74df.js → CreatedOnBrandCrowd-pt-pt-1vh4Smqt.js} +1 -1
- package/lib/src/{CreatedOnDcom-de-de-FVl5OqQM.js → CreatedOnDcom-de-de-CXX6W_29.js} +1 -1
- package/lib/src/{CreatedOnDcom-en-us-e0s7gZGG.js → CreatedOnDcom-en-us-D78BmX6f.js} +1 -1
- package/lib/src/{CreatedOnDcom-es-es-BXMekiTg.js → CreatedOnDcom-es-es-FfbPM2vD.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-ca-74Vm0wzS.js → CreatedOnDcom-fr-ca-C6L60rxJ.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-fr-C6TT73Rw.js → CreatedOnDcom-fr-fr-BEDnW9w-.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-br-Drg2eaLk.js → CreatedOnDcom-pt-br-CZXVvc1n.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-pt-BgsEIMfv.js → CreatedOnDcom-pt-pt-IQq744nb.js} +1 -1
- package/lib/src/brand-page/utils/logo.util.js +2 -2
- package/lib/src/brand-page/utils/migration/migration-07.js +3 -2
- package/lib/src/brand-page/utils/migration/migration-08.js +3 -2
- package/lib/src/clients/fabric-render-client.d.ts +20 -0
- package/lib/src/clients/fabric-render-client.js +43 -0
- package/lib/src/index.mjs +1 -1
- package/lib/src/{lib--ZDYWLFf.js → lib-CyVd3FMn.js} +3399 -3361
- package/lib/src/shared/content-settings/components/GenericTextInput.mixin.d.ts +1 -1
- package/lib/src/shared/content-settings/components/email-field/EmailField.mixin.d.ts +1 -1
- package/lib/src/shared/content-settings/components/tel-field/TelField.mixin.d.ts +1 -1
- package/lib/src/shared/content-settings/components/text-field/TextField.mixin.d.ts +1 -1
- package/lib/src/shared/content-settings/components/textarea-field/TextareaField.mixin.d.ts +1 -1
- package/lib/src/shared/content-settings/components/url-field/UrlField.mixin.d.ts +1 -1
- package/lib/src/shared/content-settings/components/youtube-video-field/YoutubeVideoField.mixin.d.ts +1 -1
- package/package.json +1 -1
- package/src/brand-page/utils/logo.util.recalculate.test.ts +204 -0
- package/src/brand-page/utils/logo.util.ts +2 -2
- package/src/brand-page/utils/migration/migration-07.dimension.test.ts +274 -0
- package/src/brand-page/utils/migration/migration-07.ts +3 -2
- package/src/brand-page/utils/migration/migration-08.test.ts +181 -22
- package/src/brand-page/utils/migration/migration-08.ts +3 -2
- package/src/clients/fabric-render-client.test.ts +198 -0
- package/src/clients/fabric-render-client.ts +85 -0
|
@@ -185,8 +185,8 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
185
185
|
}>, {
|
|
186
186
|
index: number;
|
|
187
187
|
settings: ContentItemFieldSettings;
|
|
188
|
-
styles: Record<string, any>;
|
|
189
188
|
value: string | false | undefined;
|
|
189
|
+
styles: Record<string, any>;
|
|
190
190
|
role: string;
|
|
191
191
|
placeholder: string;
|
|
192
192
|
minLength: number;
|
|
@@ -182,8 +182,8 @@ declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import
|
|
|
182
182
|
}>, {
|
|
183
183
|
index: number;
|
|
184
184
|
settings: import("../../models").ContentItemFieldSettings;
|
|
185
|
-
styles: Record<string, any>;
|
|
186
185
|
value: string | false | undefined;
|
|
186
|
+
styles: Record<string, any>;
|
|
187
187
|
role: string;
|
|
188
188
|
placeholder: string;
|
|
189
189
|
minLength: number;
|
|
@@ -182,8 +182,8 @@ declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import
|
|
|
182
182
|
}>, {
|
|
183
183
|
index: number;
|
|
184
184
|
settings: import("../../models").ContentItemFieldSettings;
|
|
185
|
-
styles: Record<string, any>;
|
|
186
185
|
value: string | false | undefined;
|
|
186
|
+
styles: Record<string, any>;
|
|
187
187
|
role: string;
|
|
188
188
|
placeholder: string;
|
|
189
189
|
minLength: number;
|
|
@@ -187,8 +187,8 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
187
187
|
}>, {
|
|
188
188
|
index: number;
|
|
189
189
|
settings: import("../../models").ContentItemFieldSettings;
|
|
190
|
-
styles: Record<string, any>;
|
|
191
190
|
value: string | false | undefined;
|
|
191
|
+
styles: Record<string, any>;
|
|
192
192
|
role: string;
|
|
193
193
|
placeholder: string;
|
|
194
194
|
minLength: number;
|
|
@@ -196,8 +196,8 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
196
196
|
}>, {
|
|
197
197
|
index: number;
|
|
198
198
|
settings: import("../../models").ContentItemFieldSettings;
|
|
199
|
-
styles: Record<string, any>;
|
|
200
199
|
value: string | false | undefined;
|
|
200
|
+
styles: Record<string, any>;
|
|
201
201
|
role: string;
|
|
202
202
|
placeholder: string;
|
|
203
203
|
minLength: number;
|
|
@@ -189,8 +189,8 @@ declare const _default: import("vue").DefineComponent<{}, {}, Record<string, any
|
|
|
189
189
|
}>, {
|
|
190
190
|
index: number;
|
|
191
191
|
settings: import("../../models").ContentItemFieldSettings;
|
|
192
|
-
styles: Record<string, any>;
|
|
193
192
|
value: string | false | undefined;
|
|
193
|
+
styles: Record<string, any>;
|
|
194
194
|
role: string;
|
|
195
195
|
placeholder: string;
|
|
196
196
|
minLength: number;
|
package/lib/src/shared/content-settings/components/youtube-video-field/YoutubeVideoField.mixin.d.ts
CHANGED
|
@@ -185,8 +185,8 @@ declare const _default: import("vue").DefineComponent<{}, {}, Record<string, any
|
|
|
185
185
|
}>, {
|
|
186
186
|
index: number;
|
|
187
187
|
settings: import("../../models").ContentItemFieldSettings;
|
|
188
|
-
styles: Record<string, any>;
|
|
189
188
|
value: string | false | undefined;
|
|
189
|
+
styles: Record<string, any>;
|
|
190
190
|
role: string;
|
|
191
191
|
placeholder: string;
|
|
192
192
|
minLength: number;
|
package/package.json
CHANGED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { describe, test, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { BRAND_PAGE_TYPES } from '../models';
|
|
3
|
+
import { FabricRenderClient } from '../../clients/fabric-render-client';
|
|
4
|
+
import {
|
|
5
|
+
recalculateHeaderLogoSizes,
|
|
6
|
+
recalculateLogoContentDimensions,
|
|
7
|
+
} from './logo.util';
|
|
8
|
+
|
|
9
|
+
const LOGO_IMAGE = {
|
|
10
|
+
logoDraftToken: 'draft-token',
|
|
11
|
+
logoVariation: 1 as const,
|
|
12
|
+
logoLastUpdate: '99',
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const createClient = () => ({
|
|
16
|
+
getLogoSvgUrlByLogoImageAsync: vi.fn(),
|
|
17
|
+
getLogoDimensionsByLogoImageAsync: vi.fn(),
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
let client: ReturnType<typeof createClient>;
|
|
21
|
+
|
|
22
|
+
const createHeaderStores = () => ({
|
|
23
|
+
pageSettingsStore: {
|
|
24
|
+
sections: {
|
|
25
|
+
header: {
|
|
26
|
+
desktop: {
|
|
27
|
+
logoImageHeight: '9rem',
|
|
28
|
+
logoImageWidth: '9rem',
|
|
29
|
+
logoVariation: 1,
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
logoSettingsStore: { selectedLogoImage: LOGO_IMAGE },
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const logoContent = () => ({
|
|
38
|
+
settings: {
|
|
39
|
+
content: {
|
|
40
|
+
type: 'logo',
|
|
41
|
+
logoImage: LOGO_IMAGE,
|
|
42
|
+
logoImageHeight: '12rem',
|
|
43
|
+
logoImageWidth: '12rem',
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const createPageData = () => ({
|
|
49
|
+
pages: [
|
|
50
|
+
{ contents: [logoContent(), { settings: { content: { type: 'text' } } }] },
|
|
51
|
+
{ contents: [logoContent()] },
|
|
52
|
+
],
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const contentSizes = (pageData: ReturnType<typeof createPageData>) =>
|
|
56
|
+
pageData.pages.flatMap((page) =>
|
|
57
|
+
page.contents
|
|
58
|
+
.filter((item) => item.settings.content.type === 'logo')
|
|
59
|
+
.map((item) => {
|
|
60
|
+
const { logoImageWidth, logoImageHeight } = item.settings
|
|
61
|
+
.content as ReturnType<typeof logoContent>['settings']['content'];
|
|
62
|
+
|
|
63
|
+
return [logoImageWidth, logoImageHeight];
|
|
64
|
+
}),
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
describe('logo.util resize lookups', () => {
|
|
68
|
+
beforeEach(() => {
|
|
69
|
+
client = createClient();
|
|
70
|
+
FabricRenderClient.overrideInstance(client);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
afterEach(() => {
|
|
74
|
+
FabricRenderClient.overrideInstance(undefined);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test('header: a post-purchase brand site sizes from a size-only lookup', async () => {
|
|
78
|
+
client.getLogoDimensionsByLogoImageAsync.mockResolvedValue({
|
|
79
|
+
width: 300,
|
|
80
|
+
height: 100,
|
|
81
|
+
});
|
|
82
|
+
const { pageSettingsStore, logoSettingsStore } = createHeaderStores();
|
|
83
|
+
|
|
84
|
+
await recalculateHeaderLogoSizes(
|
|
85
|
+
pageSettingsStore,
|
|
86
|
+
logoSettingsStore,
|
|
87
|
+
[],
|
|
88
|
+
BRAND_PAGE_TYPES.brandSite,
|
|
89
|
+
false,
|
|
90
|
+
true,
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
expect(client.getLogoDimensionsByLogoImageAsync).toHaveBeenCalledTimes(1);
|
|
94
|
+
expect(client.getLogoDimensionsByLogoImageAsync).toHaveBeenCalledWith(
|
|
95
|
+
LOGO_IMAGE,
|
|
96
|
+
);
|
|
97
|
+
expect(client.getLogoSvgUrlByLogoImageAsync).not.toHaveBeenCalled();
|
|
98
|
+
expect(pageSettingsStore.sections.header.desktop.logoImageWidth).toBe(
|
|
99
|
+
'10rem',
|
|
100
|
+
);
|
|
101
|
+
expect(pageSettingsStore.sections.header.desktop.logoImageHeight).toBe(
|
|
102
|
+
'10rem',
|
|
103
|
+
);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test('pre-purchase header: sizes from the editable variation, the size-only reply unused', async () => {
|
|
107
|
+
client.getLogoDimensionsByLogoImageAsync.mockResolvedValue({
|
|
108
|
+
width: 300,
|
|
109
|
+
height: 100,
|
|
110
|
+
});
|
|
111
|
+
const { pageSettingsStore, logoSettingsStore } = createHeaderStores();
|
|
112
|
+
|
|
113
|
+
await recalculateHeaderLogoSizes(
|
|
114
|
+
pageSettingsStore,
|
|
115
|
+
logoSettingsStore,
|
|
116
|
+
[{ variationId: 1, width: 100, height: 100 }],
|
|
117
|
+
BRAND_PAGE_TYPES.brandSite,
|
|
118
|
+
true,
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
expect(client.getLogoDimensionsByLogoImageAsync).toHaveBeenCalledTimes(1);
|
|
122
|
+
expect(client.getLogoSvgUrlByLogoImageAsync).not.toHaveBeenCalled();
|
|
123
|
+
expect(pageSettingsStore.sections.header.desktop.logoImageWidth).toBe(
|
|
124
|
+
'11rem',
|
|
125
|
+
);
|
|
126
|
+
expect(pageSettingsStore.sections.header.desktop.logoImageHeight).toBe(
|
|
127
|
+
'11rem',
|
|
128
|
+
);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
test('logo content: a post-purchase brand page sizes every logo content from a size-only lookup', async () => {
|
|
132
|
+
client.getLogoDimensionsByLogoImageAsync.mockResolvedValue({
|
|
133
|
+
width: 300,
|
|
134
|
+
height: 100,
|
|
135
|
+
});
|
|
136
|
+
const pageData = createPageData();
|
|
137
|
+
|
|
138
|
+
await recalculateLogoContentDimensions(pageData, [], LOGO_IMAGE, false);
|
|
139
|
+
|
|
140
|
+
expect(client.getLogoDimensionsByLogoImageAsync).toHaveBeenCalledTimes(1);
|
|
141
|
+
expect(client.getLogoDimensionsByLogoImageAsync).toHaveBeenCalledWith(
|
|
142
|
+
LOGO_IMAGE,
|
|
143
|
+
);
|
|
144
|
+
expect(client.getLogoSvgUrlByLogoImageAsync).not.toHaveBeenCalled();
|
|
145
|
+
expect(contentSizes(pageData)).toEqual([
|
|
146
|
+
['8rem', '8rem'],
|
|
147
|
+
['8rem', '8rem'],
|
|
148
|
+
]);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
test('known variation: a pre-purchase brand page makes no lookup', async () => {
|
|
152
|
+
const pageData = createPageData();
|
|
153
|
+
|
|
154
|
+
await recalculateLogoContentDimensions(
|
|
155
|
+
pageData,
|
|
156
|
+
[{ variationId: 1, width: 300, height: 100 }],
|
|
157
|
+
LOGO_IMAGE,
|
|
158
|
+
true,
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
expect(client.getLogoDimensionsByLogoImageAsync).not.toHaveBeenCalled();
|
|
162
|
+
expect(client.getLogoSvgUrlByLogoImageAsync).not.toHaveBeenCalled();
|
|
163
|
+
expect(contentSizes(pageData)).toEqual([
|
|
164
|
+
['8rem', '8rem'],
|
|
165
|
+
['8rem', '8rem'],
|
|
166
|
+
]);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
test.each([
|
|
170
|
+
['rejects', () => Promise.reject(new Error('fetch failed'))],
|
|
171
|
+
['answers nothing', () => Promise.resolve(undefined)],
|
|
172
|
+
])(
|
|
173
|
+
'lookup fails: when the lookup %s, header and content sizes are unchanged',
|
|
174
|
+
async (_case, answer) => {
|
|
175
|
+
client.getLogoDimensionsByLogoImageAsync.mockImplementation(answer);
|
|
176
|
+
client.getLogoSvgUrlByLogoImageAsync.mockImplementation(answer);
|
|
177
|
+
const { pageSettingsStore, logoSettingsStore } = createHeaderStores();
|
|
178
|
+
const pageData = createPageData();
|
|
179
|
+
|
|
180
|
+
await expect(
|
|
181
|
+
recalculateHeaderLogoSizes(
|
|
182
|
+
pageSettingsStore,
|
|
183
|
+
logoSettingsStore,
|
|
184
|
+
[],
|
|
185
|
+
BRAND_PAGE_TYPES.brandSite,
|
|
186
|
+
false,
|
|
187
|
+
true,
|
|
188
|
+
),
|
|
189
|
+
).resolves.toBeUndefined();
|
|
190
|
+
await expect(
|
|
191
|
+
recalculateLogoContentDimensions(pageData, [], LOGO_IMAGE, false),
|
|
192
|
+
).resolves.toBeUndefined();
|
|
193
|
+
|
|
194
|
+
expect(pageSettingsStore.sections.header.desktop).toMatchObject({
|
|
195
|
+
logoImageWidth: '9rem',
|
|
196
|
+
logoImageHeight: '9rem',
|
|
197
|
+
});
|
|
198
|
+
expect(contentSizes(pageData)).toEqual([
|
|
199
|
+
['12rem', '12rem'],
|
|
200
|
+
['12rem', '12rem'],
|
|
201
|
+
]);
|
|
202
|
+
},
|
|
203
|
+
);
|
|
204
|
+
});
|
|
@@ -440,7 +440,7 @@ export const recalculateLogoContentDimensions = async (
|
|
|
440
440
|
// For post-purchase or fallback, fetch from Fabric
|
|
441
441
|
if (!logoData || logoData.width <= 0 || logoData.height <= 0) {
|
|
442
442
|
logoData =
|
|
443
|
-
await FabricRenderClient.getInstance().
|
|
443
|
+
await FabricRenderClient.getInstance().getLogoDimensionsByLogoImageAsync(
|
|
444
444
|
logoImage,
|
|
445
445
|
);
|
|
446
446
|
}
|
|
@@ -493,7 +493,7 @@ export const recalculateHeaderLogoSizes = async (
|
|
|
493
493
|
);
|
|
494
494
|
|
|
495
495
|
const logoPostPurchase =
|
|
496
|
-
await FabricRenderClient.getInstance().
|
|
496
|
+
await FabricRenderClient.getInstance().getLogoDimensionsByLogoImageAsync(
|
|
497
497
|
logoSettingsStore.selectedLogoImage,
|
|
498
498
|
);
|
|
499
499
|
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import { describe, test, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { BrandPageModel, type BrandPageData } from '@brand-page/models';
|
|
3
|
+
import { migration07 } from './migration-07';
|
|
4
|
+
import {
|
|
5
|
+
GetLatestModelVersion,
|
|
6
|
+
migrateBrandPageModel,
|
|
7
|
+
type MigrationData,
|
|
8
|
+
} from '../migration.util';
|
|
9
|
+
import { FabricRenderClient } from '../../../clients/fabric-render-client';
|
|
10
|
+
|
|
11
|
+
// Kept apart from migration-07.test.ts, whose cases set no client instance and rely on the catch path.
|
|
12
|
+
|
|
13
|
+
type Size = { width?: number; height?: number } | undefined;
|
|
14
|
+
|
|
15
|
+
const templateImage = (token: string) => ({
|
|
16
|
+
logoTemplateToken: token,
|
|
17
|
+
logoTemplateText: 'Acme & Co',
|
|
18
|
+
logoTemplateVersion: 3,
|
|
19
|
+
layout: 'stacked',
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const draftImage = (token: string) => ({
|
|
23
|
+
logoDraftToken: token,
|
|
24
|
+
logoVariation: 2,
|
|
25
|
+
logoLastUpdate: '99',
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// Two template sections and two draft sections; the footer desktop keeps the default 9rem sizes.
|
|
29
|
+
const createBrandSiteData = (): BrandPageData =>
|
|
30
|
+
({
|
|
31
|
+
v: 6,
|
|
32
|
+
brandPageType: 'brandSite',
|
|
33
|
+
pageHeaderDesktop: {
|
|
34
|
+
logoImageWidth: '16rem',
|
|
35
|
+
logoImageHeight: '14rem',
|
|
36
|
+
logoTemplateImage: templateImage('template-wide'),
|
|
37
|
+
},
|
|
38
|
+
pageHeaderMobile: {
|
|
39
|
+
logoImageWidth: '8rem',
|
|
40
|
+
logoImageHeight: '7rem',
|
|
41
|
+
logoTemplateImage: templateImage('template-tall'),
|
|
42
|
+
},
|
|
43
|
+
pageFooterDesktop: {
|
|
44
|
+
logoImage: draftImage('draft-wide'),
|
|
45
|
+
},
|
|
46
|
+
pageFooterMobile: {
|
|
47
|
+
logoImageWidth: '6rem',
|
|
48
|
+
logoImageHeight: '9rem',
|
|
49
|
+
logoImage: draftImage('draft-tall'),
|
|
50
|
+
},
|
|
51
|
+
}) as unknown as BrandPageData;
|
|
52
|
+
|
|
53
|
+
const createMigrationData = (): MigrationData => ({
|
|
54
|
+
brandPageModel: new BrandPageModel(createBrandSiteData()),
|
|
55
|
+
useOldLogoRenderSize: false,
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const sizeFor = (token: string): Size =>
|
|
59
|
+
token.endsWith('-wide')
|
|
60
|
+
? { width: 300, height: 100 }
|
|
61
|
+
: { width: 100, height: 300 };
|
|
62
|
+
|
|
63
|
+
const createClient = () => ({
|
|
64
|
+
getLogoSvgUrlByLogoTemplateImageAsync: vi.fn(),
|
|
65
|
+
getLogoSvgUrlByLogoImageAsync: vi.fn(),
|
|
66
|
+
getLogoDimensionsByLogoTemplateImageAsync: vi.fn(),
|
|
67
|
+
getLogoDimensionsByLogoImageAsync: vi.fn(),
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
let client: ReturnType<typeof createClient>;
|
|
71
|
+
|
|
72
|
+
// The drawing and size-only lookups answer alike, so these pins hold before and after the switch (R3).
|
|
73
|
+
const answerBoth = (
|
|
74
|
+
template: (token: string) => Size | Promise<Size>,
|
|
75
|
+
draft: (token: string) => Size | Promise<Size>,
|
|
76
|
+
) => {
|
|
77
|
+
client.getLogoDimensionsByLogoTemplateImageAsync.mockImplementation(
|
|
78
|
+
async ({ logoTemplateToken }) => template(logoTemplateToken),
|
|
79
|
+
);
|
|
80
|
+
client.getLogoDimensionsByLogoImageAsync.mockImplementation(
|
|
81
|
+
async ({ logoDraftToken }) => draft(logoDraftToken),
|
|
82
|
+
);
|
|
83
|
+
client.getLogoSvgUrlByLogoTemplateImageAsync.mockImplementation(
|
|
84
|
+
async ({ logoTemplateToken }) => {
|
|
85
|
+
const size = await template(logoTemplateToken);
|
|
86
|
+
|
|
87
|
+
return size && { data: 'data:image/svg+xml;base64,', ...size };
|
|
88
|
+
},
|
|
89
|
+
);
|
|
90
|
+
client.getLogoSvgUrlByLogoImageAsync.mockImplementation(
|
|
91
|
+
async ({ logoDraftToken }) => {
|
|
92
|
+
const size = await draft(logoDraftToken);
|
|
93
|
+
|
|
94
|
+
return size && { data: 'data:image/svg+xml;base64,', ...size };
|
|
95
|
+
},
|
|
96
|
+
);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const sizesOf = (result: MigrationData) => {
|
|
100
|
+
const model = result.brandPageModel;
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
headerDesktop: [
|
|
104
|
+
model.pageHeaderDesktop.logoImageWidth,
|
|
105
|
+
model.pageHeaderDesktop.logoImageHeight,
|
|
106
|
+
],
|
|
107
|
+
headerMobile: [
|
|
108
|
+
model.pageHeaderMobile.logoImageWidth,
|
|
109
|
+
model.pageHeaderMobile.logoImageHeight,
|
|
110
|
+
],
|
|
111
|
+
footerDesktop: [
|
|
112
|
+
model.pageFooterDesktop.logoImageWidth,
|
|
113
|
+
model.pageFooterDesktop.logoImageHeight,
|
|
114
|
+
],
|
|
115
|
+
footerMobile: [
|
|
116
|
+
model.pageFooterMobile.logoImageWidth,
|
|
117
|
+
model.pageFooterMobile.logoImageHeight,
|
|
118
|
+
],
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const ORIGINAL_SIZES = {
|
|
123
|
+
headerDesktop: ['16rem', '14rem'],
|
|
124
|
+
headerMobile: ['8rem', '7rem'],
|
|
125
|
+
footerDesktop: ['9rem', '9rem'],
|
|
126
|
+
footerMobile: ['6rem', '9rem'],
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const OPTIONS = { isServerRender: false, isUserDraft: false };
|
|
130
|
+
|
|
131
|
+
describe('migration07 — size lookups', () => {
|
|
132
|
+
beforeEach(() => {
|
|
133
|
+
client = createClient();
|
|
134
|
+
FabricRenderClient.overrideInstance(client);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
afterEach(() => {
|
|
138
|
+
FabricRenderClient.overrideInstance(undefined);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
test('asks for size only, passing each section its own logo reference', async () => {
|
|
142
|
+
answerBoth(sizeFor, sizeFor);
|
|
143
|
+
const migrationData = createMigrationData();
|
|
144
|
+
const model = migrationData.brandPageModel;
|
|
145
|
+
|
|
146
|
+
await migration07(migrationData, OPTIONS);
|
|
147
|
+
|
|
148
|
+
expect(
|
|
149
|
+
client.getLogoDimensionsByLogoTemplateImageAsync,
|
|
150
|
+
).toHaveBeenCalledTimes(2);
|
|
151
|
+
expect(
|
|
152
|
+
client.getLogoDimensionsByLogoTemplateImageAsync,
|
|
153
|
+
).toHaveBeenCalledWith(model.pageHeaderDesktop.logoTemplateImage);
|
|
154
|
+
expect(
|
|
155
|
+
client.getLogoDimensionsByLogoTemplateImageAsync,
|
|
156
|
+
).toHaveBeenCalledWith(model.pageHeaderMobile.logoTemplateImage);
|
|
157
|
+
expect(client.getLogoDimensionsByLogoImageAsync).toHaveBeenCalledTimes(2);
|
|
158
|
+
expect(client.getLogoDimensionsByLogoImageAsync).toHaveBeenCalledWith(
|
|
159
|
+
model.pageFooterDesktop.logoImage,
|
|
160
|
+
);
|
|
161
|
+
expect(client.getLogoDimensionsByLogoImageAsync).toHaveBeenCalledWith(
|
|
162
|
+
model.pageFooterMobile.logoImage,
|
|
163
|
+
);
|
|
164
|
+
expect(client.getLogoSvgUrlByLogoTemplateImageAsync).not.toHaveBeenCalled();
|
|
165
|
+
expect(client.getLogoSvgUrlByLogoImageAsync).not.toHaveBeenCalled();
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
test('same sizes: pins each section from the reply', async () => {
|
|
169
|
+
answerBoth(sizeFor, sizeFor);
|
|
170
|
+
|
|
171
|
+
const result = await migration07(createMigrationData(), OPTIONS);
|
|
172
|
+
|
|
173
|
+
expect(result.useOldLogoRenderSize).toBe(false);
|
|
174
|
+
expect(sizesOf(result)).toEqual({
|
|
175
|
+
headerDesktop: ['6rem', '6rem'],
|
|
176
|
+
headerMobile: ['7rem', '7rem'],
|
|
177
|
+
footerDesktop: ['3rem', '3rem'],
|
|
178
|
+
footerMobile: ['9rem', '9rem'],
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
test('not OK: an empty reply shrinks every section by the fallback step', async () => {
|
|
183
|
+
answerBoth(
|
|
184
|
+
() => undefined,
|
|
185
|
+
() => undefined,
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
const result = await migration07(createMigrationData(), OPTIONS);
|
|
189
|
+
|
|
190
|
+
expect(result.useOldLogoRenderSize).toBe(false);
|
|
191
|
+
expect(sizesOf(result)).toEqual({
|
|
192
|
+
headerDesktop: ['10rem', '10rem'],
|
|
193
|
+
headerMobile: ['6rem', '6rem'],
|
|
194
|
+
footerDesktop: ['8rem', '8rem'],
|
|
195
|
+
footerMobile: ['8rem', '8rem'],
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test('request fails: leaves every size and flags the old render size', async () => {
|
|
200
|
+
answerBoth((token) => {
|
|
201
|
+
if (token === 'template-wide') {
|
|
202
|
+
throw new Error('fetch failed');
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return sizeFor(token);
|
|
206
|
+
}, sizeFor);
|
|
207
|
+
|
|
208
|
+
const result = await migration07(createMigrationData(), OPTIONS);
|
|
209
|
+
|
|
210
|
+
expect(result.useOldLogoRenderSize).toBe(true);
|
|
211
|
+
expect(sizesOf(result)).toEqual(ORIGINAL_SIZES);
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
test('missing size: a zero or absent dimension changes nothing and does not shrink', async () => {
|
|
215
|
+
answerBoth(
|
|
216
|
+
() => ({ width: 0, height: 100 }),
|
|
217
|
+
() => ({ width: 120 }),
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
const result = await migration07(createMigrationData(), OPTIONS);
|
|
221
|
+
|
|
222
|
+
expect(result.useOldLogoRenderSize).toBe(false);
|
|
223
|
+
expect(sizesOf(result)).toEqual(ORIGINAL_SIZES);
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
test.each([
|
|
227
|
+
['brandSite', { ...createBrandSiteData() }],
|
|
228
|
+
[
|
|
229
|
+
'default',
|
|
230
|
+
{
|
|
231
|
+
brandPageType: 'default',
|
|
232
|
+
pages: [
|
|
233
|
+
{
|
|
234
|
+
title: 'Home',
|
|
235
|
+
slug: 'home',
|
|
236
|
+
contents: [
|
|
237
|
+
{
|
|
238
|
+
id: '1',
|
|
239
|
+
type: 'logo',
|
|
240
|
+
logoImage: draftImage('draft-wide'),
|
|
241
|
+
logoImageHeight: '9rem',
|
|
242
|
+
logoImageWidth: '9rem',
|
|
243
|
+
isLogoVisible: true,
|
|
244
|
+
backgroundStyle: {},
|
|
245
|
+
},
|
|
246
|
+
],
|
|
247
|
+
},
|
|
248
|
+
],
|
|
249
|
+
},
|
|
250
|
+
],
|
|
251
|
+
])(
|
|
252
|
+
'already upgraded: a %s model at the latest version makes no lookup',
|
|
253
|
+
async (_type, data) => {
|
|
254
|
+
answerBoth(sizeFor, sizeFor);
|
|
255
|
+
|
|
256
|
+
await migrateBrandPageModel(
|
|
257
|
+
new BrandPageModel({
|
|
258
|
+
...(data as unknown as BrandPageData),
|
|
259
|
+
v: GetLatestModelVersion(),
|
|
260
|
+
}),
|
|
261
|
+
OPTIONS,
|
|
262
|
+
);
|
|
263
|
+
|
|
264
|
+
expect(
|
|
265
|
+
client.getLogoDimensionsByLogoTemplateImageAsync,
|
|
266
|
+
).not.toHaveBeenCalled();
|
|
267
|
+
expect(client.getLogoDimensionsByLogoImageAsync).not.toHaveBeenCalled();
|
|
268
|
+
expect(
|
|
269
|
+
client.getLogoSvgUrlByLogoTemplateImageAsync,
|
|
270
|
+
).not.toHaveBeenCalled();
|
|
271
|
+
expect(client.getLogoSvgUrlByLogoImageAsync).not.toHaveBeenCalled();
|
|
272
|
+
},
|
|
273
|
+
);
|
|
274
|
+
});
|
|
@@ -48,12 +48,13 @@ export const migration07 = async (
|
|
|
48
48
|
].filter((section) => section.config);
|
|
49
49
|
|
|
50
50
|
// Fetch logo data for all sections in parallel
|
|
51
|
+
// Size-only lookups, by recorded exception: 0031-released-logo-size-migrations-may-use-a-size-only-address.md
|
|
51
52
|
const logoDataPromises = sections.map(async (section) => {
|
|
52
53
|
const logoData = section.config?.logoTemplateImage?.logoTemplateToken
|
|
53
|
-
? await fabricClient.
|
|
54
|
+
? await fabricClient.getLogoDimensionsByLogoTemplateImageAsync(
|
|
54
55
|
section.config.logoTemplateImage,
|
|
55
56
|
)
|
|
56
|
-
: await fabricClient.
|
|
57
|
+
: await fabricClient.getLogoDimensionsByLogoImageAsync(
|
|
57
58
|
section.config.logoImage,
|
|
58
59
|
);
|
|
59
60
|
|