Merge pull request #17101 from mozilla/FXA-9746

fix(fxa-shared): Prioritize price metadata over product metadata
This commit is contained in:
Lisa Chan 2024-06-11 10:45:26 -04:00 коммит произвёл GitHub
Родитель 541129daa1 d4780d74db
Коммит ac8a3195aa
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
4 изменённых файлов: 123 добавлений и 179 удалений

Просмотреть файл

@ -89,8 +89,8 @@ export const urlsFromProductConfig = (
DEFAULT_PRODUCT_DETAILS.privacyNoticeDownloadURL!, DEFAULT_PRODUCT_DETAILS.privacyNoticeDownloadURL!,
cancellationSurvey: planMetadataConfig.cancellationSurveyURL, cancellationSurvey: planMetadataConfig.cancellationSurveyURL,
successActionButton: successActionButton:
plan.product_metadata?.successActionButtonURL || plan.plan_metadata?.successActionButtonURL ||
plan.plan_metadata?.successActionButtonURL, plan.product_metadata?.successActionButtonURL,
}; };
} }
}; };

Просмотреть файл

@ -172,10 +172,10 @@ export const urlsFromProductConfig = (
DEFAULT_PRODUCT_DETAILS.privacyNoticeDownloadURL!, DEFAULT_PRODUCT_DETAILS.privacyNoticeDownloadURL!,
cancellationSurvey: planMetadataConfig.cancellationSurveyURL, cancellationSurvey: planMetadataConfig.cancellationSurveyURL,
successActionButton: successActionButton:
plan.product_metadata?.successActionButtonURL ||
plan.plan_metadata?.successActionButtonURL || plan.plan_metadata?.successActionButtonURL ||
plan.product_metadata?.downloadURL || plan.product_metadata?.successActionButtonURL ||
plan.plan_metadata?.downloadURL, plan.plan_metadata?.downloadURL ||
plan.product_metadata?.downloadURL,
}; };
} }
}; };

Просмотреть файл

@ -11,7 +11,7 @@ import {
} from '../../../subscriptions/configuration/helpers'; } from '../../../subscriptions/configuration/helpers';
import { PlanConfigurationDtoT } from '../../../dto/auth/payments/plan-configuration'; import { PlanConfigurationDtoT } from '../../../dto/auth/payments/plan-configuration';
const PLAN: Plan = { export const PLAN: Plan = {
plan_id: 'plan_8675309', plan_id: 'plan_8675309',
plan_name: '', plan_name: '',
product_id: 'prod_8675309', product_id: 'prod_8675309',
@ -25,10 +25,10 @@ const PLAN: Plan = {
product_metadata: null, product_metadata: null,
}; };
const PLAN_WITH_METADATA: Plan = { export const PLAN_WITH_METADATA: Plan = {
...PLAN, ...PLAN,
plan_name: 'The Plan', plan_name: 'The Plan',
product_metadata: { plan_metadata: {
productSet: 'foo', productSet: 'foo',
productOrder: '2', productOrder: '2',
webIconURL: 'https://example.org/webicon.png', webIconURL: 'https://example.org/webicon.png',
@ -41,6 +41,7 @@ const PLAN_WITH_METADATA: Plan = {
'product:privacyNoticeDownloadURL': 'product:privacyNoticeDownloadURL':
'https://example.org/en-US/privacy/download', 'https://example.org/en-US/privacy/download',
'product:ignoreme': 'Unknown name here', 'product:ignoreme': 'Unknown name here',
'product:name': 'Name override!!',
'product:subtitle': 'Great Full-device VPN', 'product:subtitle': 'Great Full-device VPN',
'product:details:3': 'Baz Connects 5 devices with one subscription', 'product:details:3': 'Baz Connects 5 devices with one subscription',
'product:details:1': 'Foo Device-level encryption', 'product:details:1': 'Foo Device-level encryption',
@ -66,9 +67,49 @@ const PLAN_WITH_METADATA: Plan = {
'product:termsOfServiceURL:xx-partial': 'product:termsOfServiceURL:xx-partial':
'https://example.org/xx-partial/terms', 'https://example.org/xx-partial/terms',
}, },
product_metadata: {
productSet: 'bar',
productOrder: '20',
webIconURL: 'https://example.org/webicon2.png',
webIconBackground: '#ffff00',
upgradeCTA: 'upgradeCTA2',
'product:termsOfServiceURL': 'https://example.org/en-US/terms2',
'product:privacyNoticeURL': 'https://example.org/en-US/privacy2',
'product:termsOfServiceDownloadURL':
'https://example.org/en-US/terms/download2',
'product:privacyNoticeDownloadURL':
'https://example.org/en-US/privacy/download2',
'product:ignoreme': 'Unknown name here 2',
'product:name': 'Name override!!',
'product:subtitle': 'Best Full-device VPN',
'product:details:3': 'Bar Connects 5 devices with one subscription',
'product:details:1': 'Bar Device-level encryption',
'product:details:2': 'Baz Servers in 30+ countries',
'product:details:4': 'Foo Available for Windows, iOS and Android',
'product:successActionButtonLabel': 'Do something else maybe',
'product:subtitle:xx-pirate': 'VPN fer yer full-device arr',
'product:foobar:9:xx-pirate': 'what even arrs this',
'product:details:4:xx-pirate': "Available fer Windows, iOS an' Android arr",
'product:details:1:xx-pirate': 'Device-level encryption arr matey',
'product:details:3:xx-pirate':
"Connects 5 devices wit' one subscription arr",
'product:details:2:xx-pirate': 'Servers is 30+ countries arr',
'product:termsOfServiceURL:xx-pirate':
'https://example.org/xx-pirate/terms2',
'product:privacyNoticeURL:xx-pirate':
'https://example.org/xx-pirate/privacy2',
'product:termsOfServiceDownloadURL:xx-pirate':
'https://example.org/xx-pirate/terms/download2',
'product:privacyNoticeDownloadURL:xx-pirate':
'https://example.org/xx-pirate/privacy/download2',
'product:successActionButtonLabel:xx-pirate': 'Yarr matey...',
'product:subtitle:xx-partial': 'Partial localization2',
'product:termsOfServiceURL:xx-partial':
'https://example.org/xx-partial/terms2',
},
}; };
const CONFIGURATION_URLS = { export const CONFIGURATION_URLS = {
successActionButton: 'https://download', successActionButton: 'https://download',
privacyNotice: 'https://privacynotice', privacyNotice: 'https://privacynotice',
termsOfService: 'httsp://termsofservice', termsOfService: 'httsp://termsofservice',
@ -76,20 +117,20 @@ const CONFIGURATION_URLS = {
webIcon: 'https://webicon', webIcon: 'https://webicon',
}; };
const CONFIGURATION_UI_CONTENT = { export const CONFIGURATION_UI_CONTENT = {
successActionButtonLabel: 'Success Label', successActionButtonLabel: 'Success Label',
subtitle: 'VPN Subtitle', subtitle: 'VPN Subtitle',
details: ['Detail line 1', 'Detail line 2', 'Detail line 3'], details: ['Detail line 1', 'Detail line 2', 'Detail line 3'],
upgradeCTA: 'Upgrade', upgradeCTA: 'Upgrade',
}; };
const LOCALE_CONFIGURATION_NONE = { export const LOCALE_CONFIGURATION_NONE = {
urls: CONFIGURATION_URLS, urls: CONFIGURATION_URLS,
uiContent: CONFIGURATION_UI_CONTENT, uiContent: CONFIGURATION_UI_CONTENT,
support: {}, support: {},
}; };
const LOCALE_CONFIGURATION_FR = { export const LOCALE_CONFIGURATION_FR = {
urls: { urls: {
successActionButton: 'https://download/fr', successActionButton: 'https://download/fr',
privacyNotice: 'https://privacynotice/fr', privacyNotice: 'https://privacynotice/fr',
@ -127,7 +168,7 @@ const LOCALE_CONFIGURATION_ENUS = {
support: {}, support: {},
}; };
const CONFIGURATION: PlanConfigurationDtoT = { export const CONFIGURATION: PlanConfigurationDtoT = {
...LOCALE_CONFIGURATION_NONE, ...LOCALE_CONFIGURATION_NONE,
locales: { locales: {
fr: LOCALE_CONFIGURATION_FR, fr: LOCALE_CONFIGURATION_FR,
@ -140,7 +181,7 @@ const CONFIGURATION: PlanConfigurationDtoT = {
productOrder: 1, productOrder: 1,
}; };
const PLAN_WITH_CONFIGURATION: Plan = { export const PLAN_WITH_CONFIGURATION: Plan = {
...PLAN, ...PLAN,
plan_name: 'Plan Name', plan_name: 'Plan Name',
plan_metadata: {}, plan_metadata: {},
@ -248,6 +289,22 @@ describe('subscriptions/configuration/helpers', () => {
false false
); );
expect(actual).to.deep.equal({ expect(actual).to.deep.equal({
webIcon: PLAN_WITH_METADATA.plan_metadata!.webIconURL,
webIconBackground: PLAN_WITH_METADATA.plan_metadata!.webIconBackground,
});
});
it('prioritizes plan metadata over product metadata', () => {
const actual = webIconConfigFromProductConfig(
PLAN_WITH_METADATA,
['de'],
false
);
expect(actual).to.deep.equal({
webIcon: PLAN_WITH_METADATA.plan_metadata!.webIconURL,
webIconBackground: PLAN_WITH_METADATA.plan_metadata!.webIconBackground,
});
expect(actual).to.not.deep.equal({
webIcon: PLAN_WITH_METADATA.product_metadata!.webIconURL, webIcon: PLAN_WITH_METADATA.product_metadata!.webIconURL,
webIconBackground: webIconBackground:
PLAN_WITH_METADATA.product_metadata!.webIconBackground, PLAN_WITH_METADATA.product_metadata!.webIconBackground,
@ -283,18 +340,16 @@ describe('subscriptions/configuration/helpers', () => {
false false
); );
expect(actual).to.deep.equal({ expect(actual).to.deep.equal({
subtitle: PLAN_WITH_METADATA.product_metadata!['product:subtitle'], subtitle: PLAN_WITH_METADATA.plan_metadata!['product:subtitle'],
details: [ details: [
PLAN_WITH_METADATA.product_metadata!['product:details:1'], PLAN_WITH_METADATA.plan_metadata!['product:details:1'],
PLAN_WITH_METADATA.product_metadata!['product:details:2'], PLAN_WITH_METADATA.plan_metadata!['product:details:2'],
PLAN_WITH_METADATA.product_metadata!['product:details:3'], PLAN_WITH_METADATA.plan_metadata!['product:details:3'],
PLAN_WITH_METADATA.product_metadata!['product:details:4'], PLAN_WITH_METADATA.plan_metadata!['product:details:4'],
], ],
successActionButtonLabel: successActionButtonLabel:
PLAN_WITH_METADATA.product_metadata![ PLAN_WITH_METADATA.plan_metadata!['product:successActionButtonLabel'],
'product:successActionButtonLabel' upgradeCTA: PLAN_WITH_METADATA.plan_metadata!.upgradeCTA,
],
upgradeCTA: PLAN_WITH_METADATA.product_metadata!.upgradeCTA,
}); });
}); });
@ -359,8 +414,8 @@ describe('subscriptions/configuration/helpers', () => {
it('returns product update config from plan metadata if featureFlag is false', () => { it('returns product update config from plan metadata if featureFlag is false', () => {
const actual = productUpgradeFromProductConfig(PLAN_WITH_METADATA, false); const actual = productUpgradeFromProductConfig(PLAN_WITH_METADATA, false);
expect(actual).to.deep.equal({ expect(actual).to.deep.equal({
productOrder: PLAN_WITH_METADATA.product_metadata!.productOrder, productOrder: PLAN_WITH_METADATA.plan_metadata!.productOrder,
productSet: PLAN_WITH_METADATA.product_metadata!.productSet.split(','), productSet: PLAN_WITH_METADATA.plan_metadata!.productSet.split(','),
}); });
}); });

Просмотреть файл

@ -12,145 +12,16 @@ import {
urlsFromProductConfig, urlsFromProductConfig,
webIconConfigFromProductConfig, webIconConfigFromProductConfig,
} from '../../../subscriptions/configuration/utils'; } from '../../../subscriptions/configuration/utils';
import { Plan } from '../../../subscriptions/types'; import {
CONFIGURATION,
const PLAN: Plan = { CONFIGURATION_UI_CONTENT,
plan_id: 'plan_8675309', CONFIGURATION_URLS,
plan_name: '', LOCALE_CONFIGURATION_NONE,
product_id: 'prod_8675309', LOCALE_CONFIGURATION_FR,
product_name: 'Example product', PLAN,
currency: 'usd', PLAN_WITH_CONFIGURATION,
amount: 599, PLAN_WITH_METADATA,
interval: 'month' as const, } from '../configuration/helpers';
interval_count: 1,
active: true,
plan_metadata: null,
product_metadata: null,
};
const PLAN_WITH_METADATA: Plan = {
...PLAN,
plan_name: 'The Plan',
product_metadata: {
productSet: 'foo',
productOrder: '2',
webIconURL: 'https://example.org/webicon.png',
webIconBackground: '#ffffff',
upgradeCTA: 'upgradeCTA',
'product:termsOfServiceURL': 'https://example.org/en-US/terms',
'product:privacyNoticeURL': 'https://example.org/en-US/privacy',
'product:termsOfServiceDownloadURL':
'https://example.org/en-US/terms/download',
'product:privacyNoticeDownloadURL':
'https://example.org/en-US/privacy/download',
'product:ignoreme': 'Unknown name here',
'product:name': 'Name override!',
'product:subtitle': 'Great Full-device VPN',
'product:details:3': 'Baz Connects 5 devices with one subscription',
'product:details:1': 'Foo Device-level encryption',
'product:details:2': 'Bar Servers in 30+ countries',
'product:details:4': 'Quux Available for Windows, iOS and Android',
'product:successActionButtonLabel': 'Do something else',
'product:subtitle:xx-pirate': 'VPN fer yer full-device',
'product:foobar:9:xx-pirate': 'what even is this',
'product:details:4:xx-pirate': "Available fer Windows, iOS an' Android",
'product:details:1:xx-pirate': 'Device-level encryption arr',
'product:details:3:xx-pirate': "Connects 5 devices wit' one subscription",
'product:details:2:xx-pirate': 'Servers is 30+ countries matey',
'product:termsOfServiceURL:xx-pirate':
'https://example.org/xx-pirate/terms',
'product:privacyNoticeURL:xx-pirate':
'https://example.org/xx-pirate/privacy',
'product:termsOfServiceDownloadURL:xx-pirate':
'https://example.org/xx-pirate/terms/download',
'product:privacyNoticeDownloadURL:xx-pirate':
'https://example.org/xx-pirate/privacy/download',
'product:successActionButtonLabel:xx-pirate': 'Yarr...',
'product:subtitle:xx-partial': 'Partial localization',
'product:termsOfServiceURL:xx-partial':
'https://example.org/xx-partial/terms',
},
};
const CONFIGURATION_URLS = {
successActionButton: 'https://download',
privacyNotice: 'https://privacynotice',
termsOfService: 'httsp://termsofservice',
termsOfServiceDownload: 'https://termsofservicedownload',
webIcon: 'https://webicon',
};
const CONFIGURATION_UI_CONTENT = {
successActionButtonLabel: 'Success Label',
subtitle: 'VPN Subtitle',
details: ['Detail line 1', 'Detail line 2', 'Detail line 3'],
upgradeCTA: 'Upgrade',
};
const LOCALE_CONFIGURATION_NONE = {
urls: CONFIGURATION_URLS,
uiContent: CONFIGURATION_UI_CONTENT,
support: {},
};
const LOCALE_CONFIGURATION_FR = {
urls: {
successActionButton: 'https://download/fr',
privacyNotice: 'https://privacynotice/fr',
termsOfService: 'httsp://termsofservice/fr',
termsOfServiceDownload: 'https://termsofservicedownload/fr',
webIcon: 'https://webicon/fr',
},
uiContent: {
successActionButtonLabel: 'Success Label - FR',
subtitle: 'VPN Subtitle - FR',
details: ['Detail line 1 - FR', 'Detail line 2 - FR', 'Detail line 3 - FR'],
upgradeCTA: 'Upgrade - FR',
},
support: {},
};
const LOCALE_CONFIGURATION_ENUS = {
urls: {
download: 'https://download/enUS',
privacyNotice: 'https://privacynotice/enUS',
termsOfService: 'httsp://termsofservice/enUS',
termsOfServiceDownload: 'https://termsofservicedownload/enUS',
webIcon: 'https://webicon/enUS',
},
uiContent: {
successActionButtonLabel: 'Success Label - enUS',
subtitle: 'VPN Subtitle - enUS',
details: [
'Detail line 1 - enUS',
'Detail line 2 - enUS',
'Detail line 3 - enUS',
],
upgradeCTA: 'Upgrade - enUS',
},
support: {},
};
const CONFIGURATION: PlanConfigurationDtoT = {
...LOCALE_CONFIGURATION_NONE,
locales: {
fr: LOCALE_CONFIGURATION_FR,
enUS: LOCALE_CONFIGURATION_ENUS,
},
styles: {
webIconBackground: 'webbackgroundfr',
},
productSet: ['Set 1'],
productOrder: 1,
};
const PLAN_WITH_CONFIGURATION: Plan = {
...PLAN,
plan_name: 'Plan Name',
plan_metadata: {},
product_metadata: {},
configuration: CONFIGURATION,
};
const missingPlanConfigMessage = (planId: string) => const missingPlanConfigMessage = (planId: string) =>
`Plan configuration for ${planId} not found.`; `Plan configuration for ${planId} not found.`;
@ -334,6 +205,7 @@ describe('product configuration util functions', () => {
['de'], ['de'],
true true
); );
console.log('hi', actual, CONFIGURATION_URLS);
expect(actual).to.equal(CONFIGURATION_URLS); expect(actual).to.equal(CONFIGURATION_URLS);
}); });
@ -349,6 +221,26 @@ describe('product configuration util functions', () => {
}); });
}); });
it('prioritizes url from plan metadata over product_metadata', () => {
const actual = urlsFromProductConfig(PLAN_WITH_METADATA, ['de'], false);
expect(actual).to.deep.equal({
termsOfService: 'https://example.org/en-US/terms',
privacyNotice: 'https://example.org/en-US/privacy',
termsOfServiceDownload: 'https://example.org/en-US/terms/download',
privacyNoticeDownload: 'https://example.org/en-US/privacy/download',
successActionButton: undefined,
cancellationSurvey: undefined,
});
expect(actual).to.not.deep.equal({
termsOfService: 'https://example.org/en-US/terms2',
privacyNotice: 'https://example.org/en-US/privacy2',
termsOfServiceDownload: 'https://example.org/en-US/terms/download2',
privacyNoticeDownload: 'https://example.org/en-US/privacy/download2',
successActionButton: undefined,
cancellationSurvey: undefined,
});
});
it('throws an error if no plan configuration is available and featureFlag is true', () => { it('throws an error if no plan configuration is available and featureFlag is true', () => {
try { try {
urlsFromProductConfig(PLAN, ['de'], true); urlsFromProductConfig(PLAN, ['de'], true);
@ -379,9 +271,8 @@ describe('product configuration util functions', () => {
false false
); );
expect(actual).to.deep.equal({ expect(actual).to.deep.equal({
webIcon: PLAN_WITH_METADATA.product_metadata!.webIconURL, webIcon: PLAN_WITH_METADATA.plan_metadata!.webIconURL,
webIconBackground: webIconBackground: PLAN_WITH_METADATA.plan_metadata!.webIconBackground,
PLAN_WITH_METADATA.product_metadata!.webIconBackground,
}); });
}); });
@ -412,19 +303,17 @@ describe('product configuration util functions', () => {
false false
); );
expect(actual).to.deep.equal({ expect(actual).to.deep.equal({
name: PLAN_WITH_METADATA.product_metadata!['product:name'], name: PLAN_WITH_METADATA.plan_metadata!['product:name'],
subtitle: PLAN_WITH_METADATA.product_metadata!['product:subtitle'], subtitle: PLAN_WITH_METADATA.plan_metadata!['product:subtitle'],
details: [ details: [
PLAN_WITH_METADATA.product_metadata!['product:details:1'], PLAN_WITH_METADATA.plan_metadata!['product:details:1'],
PLAN_WITH_METADATA.product_metadata!['product:details:2'], PLAN_WITH_METADATA.plan_metadata!['product:details:2'],
PLAN_WITH_METADATA.product_metadata!['product:details:3'], PLAN_WITH_METADATA.plan_metadata!['product:details:3'],
PLAN_WITH_METADATA.product_metadata!['product:details:4'], PLAN_WITH_METADATA.plan_metadata!['product:details:4'],
], ],
successActionButtonLabel: successActionButtonLabel:
PLAN_WITH_METADATA.product_metadata![ PLAN_WITH_METADATA.plan_metadata!['product:successActionButtonLabel'],
'product:successActionButtonLabel' upgradeCTA: PLAN_WITH_METADATA.plan_metadata!.upgradeCTA,
],
upgradeCTA: PLAN_WITH_METADATA.product_metadata!.upgradeCTA,
}); });
}); });
@ -487,8 +376,8 @@ describe('product configuration util functions', () => {
it('returns product update config from plan metadata if featureFlag is false', () => { it('returns product update config from plan metadata if featureFlag is false', () => {
const actual = productUpgradeFromProductConfig(PLAN_WITH_METADATA, false); const actual = productUpgradeFromProductConfig(PLAN_WITH_METADATA, false);
expect(actual).to.deep.equal({ expect(actual).to.deep.equal({
productOrder: PLAN_WITH_METADATA.product_metadata!.productOrder, productOrder: PLAN_WITH_METADATA.plan_metadata!.productOrder,
productSet: PLAN_WITH_METADATA.product_metadata!.productSet.split(','), productSet: PLAN_WITH_METADATA.plan_metadata!.productSet.split(','),
}); });
}); });