@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.
Files changed (37) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-CkJM0rEy.js → CreatedOnBrandCrowd-de-de-DpeSEnwP.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-CKOotMQK.js → CreatedOnBrandCrowd-en-us-CxYv3NzT.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-mrDI8AaY.js → CreatedOnBrandCrowd-es-es-CzQ1HRHw.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-DtmVXezM.js → CreatedOnBrandCrowd-fr-ca-J77YZaT1.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-DtmVXezM.js → CreatedOnBrandCrowd-fr-fr-J77YZaT1.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-C8Cy74df.js → CreatedOnBrandCrowd-pt-br-1vh4Smqt.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-C8Cy74df.js → CreatedOnBrandCrowd-pt-pt-1vh4Smqt.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-FVl5OqQM.js → CreatedOnDcom-de-de-CXX6W_29.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-e0s7gZGG.js → CreatedOnDcom-en-us-D78BmX6f.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-BXMekiTg.js → CreatedOnDcom-es-es-FfbPM2vD.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-74Vm0wzS.js → CreatedOnDcom-fr-ca-C6L60rxJ.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-C6TT73Rw.js → CreatedOnDcom-fr-fr-BEDnW9w-.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-Drg2eaLk.js → CreatedOnDcom-pt-br-CZXVvc1n.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-BgsEIMfv.js → CreatedOnDcom-pt-pt-IQq744nb.js} +1 -1
  15. package/lib/src/brand-page/utils/logo.util.js +2 -2
  16. package/lib/src/brand-page/utils/migration/migration-07.js +3 -2
  17. package/lib/src/brand-page/utils/migration/migration-08.js +3 -2
  18. package/lib/src/clients/fabric-render-client.d.ts +20 -0
  19. package/lib/src/clients/fabric-render-client.js +43 -0
  20. package/lib/src/index.mjs +1 -1
  21. package/lib/src/{lib--ZDYWLFf.js → lib-CyVd3FMn.js} +3399 -3361
  22. package/lib/src/shared/content-settings/components/GenericTextInput.mixin.d.ts +1 -1
  23. package/lib/src/shared/content-settings/components/email-field/EmailField.mixin.d.ts +1 -1
  24. package/lib/src/shared/content-settings/components/tel-field/TelField.mixin.d.ts +1 -1
  25. package/lib/src/shared/content-settings/components/text-field/TextField.mixin.d.ts +1 -1
  26. package/lib/src/shared/content-settings/components/textarea-field/TextareaField.mixin.d.ts +1 -1
  27. package/lib/src/shared/content-settings/components/url-field/UrlField.mixin.d.ts +1 -1
  28. package/lib/src/shared/content-settings/components/youtube-video-field/YoutubeVideoField.mixin.d.ts +1 -1
  29. package/package.json +1 -1
  30. package/src/brand-page/utils/logo.util.recalculate.test.ts +204 -0
  31. package/src/brand-page/utils/logo.util.ts +2 -2
  32. package/src/brand-page/utils/migration/migration-07.dimension.test.ts +274 -0
  33. package/src/brand-page/utils/migration/migration-07.ts +3 -2
  34. package/src/brand-page/utils/migration/migration-08.test.ts +181 -22
  35. package/src/brand-page/utils/migration/migration-08.ts +3 -2
  36. package/src/clients/fabric-render-client.test.ts +198 -0
  37. 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;
@@ -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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@designcrowd/library.brand-page",
3
3
  "description": "A collection of Maker/Designer applications",
4
- "version": "6.2.5",
4
+ "version": "6.2.6",
5
5
  "author": "Design.com Eng",
6
6
  "license": "UNLICENSED",
7
7
  "type": "module",
@@ -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().getLogoSvgUrlByLogoImageAsync(
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().getLogoSvgUrlByLogoImageAsync(
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.getLogoSvgUrlByLogoTemplateImageAsync(
54
+ ? await fabricClient.getLogoDimensionsByLogoTemplateImageAsync(
54
55
  section.config.logoTemplateImage,
55
56
  )
56
- : await fabricClient.getLogoSvgUrlByLogoImageAsync(
57
+ : await fabricClient.getLogoDimensionsByLogoImageAsync(
57
58
  section.config.logoImage,
58
59
  );
59
60