зеркало из https://github.com/mozilla/fxa.git
Merge pull request #17101 from mozilla/FXA-9746
fix(fxa-shared): Prioritize price metadata over product metadata
This commit is contained in:
Коммит
ac8a3195aa
|
@ -89,8 +89,8 @@ export const urlsFromProductConfig = (
|
|||
DEFAULT_PRODUCT_DETAILS.privacyNoticeDownloadURL!,
|
||||
cancellationSurvey: planMetadataConfig.cancellationSurveyURL,
|
||||
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!,
|
||||
cancellationSurvey: planMetadataConfig.cancellationSurveyURL,
|
||||
successActionButton:
|
||||
plan.product_metadata?.successActionButtonURL ||
|
||||
plan.plan_metadata?.successActionButtonURL ||
|
||||
plan.product_metadata?.downloadURL ||
|
||||
plan.plan_metadata?.downloadURL,
|
||||
plan.product_metadata?.successActionButtonURL ||
|
||||
plan.plan_metadata?.downloadURL ||
|
||||
plan.product_metadata?.downloadURL,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
} from '../../../subscriptions/configuration/helpers';
|
||||
import { PlanConfigurationDtoT } from '../../../dto/auth/payments/plan-configuration';
|
||||
|
||||
const PLAN: Plan = {
|
||||
export const PLAN: Plan = {
|
||||
plan_id: 'plan_8675309',
|
||||
plan_name: '',
|
||||
product_id: 'prod_8675309',
|
||||
|
@ -25,10 +25,10 @@ const PLAN: Plan = {
|
|||
product_metadata: null,
|
||||
};
|
||||
|
||||
const PLAN_WITH_METADATA: Plan = {
|
||||
export const PLAN_WITH_METADATA: Plan = {
|
||||
...PLAN,
|
||||
plan_name: 'The Plan',
|
||||
product_metadata: {
|
||||
plan_metadata: {
|
||||
productSet: 'foo',
|
||||
productOrder: '2',
|
||||
webIconURL: 'https://example.org/webicon.png',
|
||||
|
@ -41,6 +41,7 @@ const PLAN_WITH_METADATA: Plan = {
|
|||
'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',
|
||||
|
@ -66,9 +67,49 @@ const PLAN_WITH_METADATA: Plan = {
|
|||
'product:termsOfServiceURL:xx-partial':
|
||||
'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',
|
||||
privacyNotice: 'https://privacynotice',
|
||||
termsOfService: 'httsp://termsofservice',
|
||||
|
@ -76,20 +117,20 @@ const CONFIGURATION_URLS = {
|
|||
webIcon: 'https://webicon',
|
||||
};
|
||||
|
||||
const CONFIGURATION_UI_CONTENT = {
|
||||
export 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 = {
|
||||
export const LOCALE_CONFIGURATION_NONE = {
|
||||
urls: CONFIGURATION_URLS,
|
||||
uiContent: CONFIGURATION_UI_CONTENT,
|
||||
support: {},
|
||||
};
|
||||
|
||||
const LOCALE_CONFIGURATION_FR = {
|
||||
export const LOCALE_CONFIGURATION_FR = {
|
||||
urls: {
|
||||
successActionButton: 'https://download/fr',
|
||||
privacyNotice: 'https://privacynotice/fr',
|
||||
|
@ -127,7 +168,7 @@ const LOCALE_CONFIGURATION_ENUS = {
|
|||
support: {},
|
||||
};
|
||||
|
||||
const CONFIGURATION: PlanConfigurationDtoT = {
|
||||
export const CONFIGURATION: PlanConfigurationDtoT = {
|
||||
...LOCALE_CONFIGURATION_NONE,
|
||||
locales: {
|
||||
fr: LOCALE_CONFIGURATION_FR,
|
||||
|
@ -140,7 +181,7 @@ const CONFIGURATION: PlanConfigurationDtoT = {
|
|||
productOrder: 1,
|
||||
};
|
||||
|
||||
const PLAN_WITH_CONFIGURATION: Plan = {
|
||||
export const PLAN_WITH_CONFIGURATION: Plan = {
|
||||
...PLAN,
|
||||
plan_name: 'Plan Name',
|
||||
plan_metadata: {},
|
||||
|
@ -248,6 +289,22 @@ describe('subscriptions/configuration/helpers', () => {
|
|||
false
|
||||
);
|
||||
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,
|
||||
webIconBackground:
|
||||
PLAN_WITH_METADATA.product_metadata!.webIconBackground,
|
||||
|
@ -283,18 +340,16 @@ describe('subscriptions/configuration/helpers', () => {
|
|||
false
|
||||
);
|
||||
expect(actual).to.deep.equal({
|
||||
subtitle: PLAN_WITH_METADATA.product_metadata!['product:subtitle'],
|
||||
subtitle: PLAN_WITH_METADATA.plan_metadata!['product:subtitle'],
|
||||
details: [
|
||||
PLAN_WITH_METADATA.product_metadata!['product:details:1'],
|
||||
PLAN_WITH_METADATA.product_metadata!['product:details:2'],
|
||||
PLAN_WITH_METADATA.product_metadata!['product:details:3'],
|
||||
PLAN_WITH_METADATA.product_metadata!['product:details:4'],
|
||||
PLAN_WITH_METADATA.plan_metadata!['product:details:1'],
|
||||
PLAN_WITH_METADATA.plan_metadata!['product:details:2'],
|
||||
PLAN_WITH_METADATA.plan_metadata!['product:details:3'],
|
||||
PLAN_WITH_METADATA.plan_metadata!['product:details:4'],
|
||||
],
|
||||
successActionButtonLabel:
|
||||
PLAN_WITH_METADATA.product_metadata![
|
||||
'product:successActionButtonLabel'
|
||||
],
|
||||
upgradeCTA: PLAN_WITH_METADATA.product_metadata!.upgradeCTA,
|
||||
PLAN_WITH_METADATA.plan_metadata!['product:successActionButtonLabel'],
|
||||
upgradeCTA: PLAN_WITH_METADATA.plan_metadata!.upgradeCTA,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -359,8 +414,8 @@ describe('subscriptions/configuration/helpers', () => {
|
|||
it('returns product update config from plan metadata if featureFlag is false', () => {
|
||||
const actual = productUpgradeFromProductConfig(PLAN_WITH_METADATA, false);
|
||||
expect(actual).to.deep.equal({
|
||||
productOrder: PLAN_WITH_METADATA.product_metadata!.productOrder,
|
||||
productSet: PLAN_WITH_METADATA.product_metadata!.productSet.split(','),
|
||||
productOrder: PLAN_WITH_METADATA.plan_metadata!.productOrder,
|
||||
productSet: PLAN_WITH_METADATA.plan_metadata!.productSet.split(','),
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -12,145 +12,16 @@ import {
|
|||
urlsFromProductConfig,
|
||||
webIconConfigFromProductConfig,
|
||||
} from '../../../subscriptions/configuration/utils';
|
||||
import { Plan } from '../../../subscriptions/types';
|
||||
|
||||
const PLAN: Plan = {
|
||||
plan_id: 'plan_8675309',
|
||||
plan_name: '',
|
||||
product_id: 'prod_8675309',
|
||||
product_name: 'Example product',
|
||||
currency: 'usd',
|
||||
amount: 599,
|
||||
interval: 'month' as const,
|
||||
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,
|
||||
};
|
||||
import {
|
||||
CONFIGURATION,
|
||||
CONFIGURATION_UI_CONTENT,
|
||||
CONFIGURATION_URLS,
|
||||
LOCALE_CONFIGURATION_NONE,
|
||||
LOCALE_CONFIGURATION_FR,
|
||||
PLAN,
|
||||
PLAN_WITH_CONFIGURATION,
|
||||
PLAN_WITH_METADATA,
|
||||
} from '../configuration/helpers';
|
||||
|
||||
const missingPlanConfigMessage = (planId: string) =>
|
||||
`Plan configuration for ${planId} not found.`;
|
||||
|
@ -334,6 +205,7 @@ describe('product configuration util functions', () => {
|
|||
['de'],
|
||||
true
|
||||
);
|
||||
console.log('hi', actual, 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', () => {
|
||||
try {
|
||||
urlsFromProductConfig(PLAN, ['de'], true);
|
||||
|
@ -379,9 +271,8 @@ describe('product configuration util functions', () => {
|
|||
false
|
||||
);
|
||||
expect(actual).to.deep.equal({
|
||||
webIcon: PLAN_WITH_METADATA.product_metadata!.webIconURL,
|
||||
webIconBackground:
|
||||
PLAN_WITH_METADATA.product_metadata!.webIconBackground,
|
||||
webIcon: PLAN_WITH_METADATA.plan_metadata!.webIconURL,
|
||||
webIconBackground: PLAN_WITH_METADATA.plan_metadata!.webIconBackground,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -412,19 +303,17 @@ describe('product configuration util functions', () => {
|
|||
false
|
||||
);
|
||||
expect(actual).to.deep.equal({
|
||||
name: PLAN_WITH_METADATA.product_metadata!['product:name'],
|
||||
subtitle: PLAN_WITH_METADATA.product_metadata!['product:subtitle'],
|
||||
name: PLAN_WITH_METADATA.plan_metadata!['product:name'],
|
||||
subtitle: PLAN_WITH_METADATA.plan_metadata!['product:subtitle'],
|
||||
details: [
|
||||
PLAN_WITH_METADATA.product_metadata!['product:details:1'],
|
||||
PLAN_WITH_METADATA.product_metadata!['product:details:2'],
|
||||
PLAN_WITH_METADATA.product_metadata!['product:details:3'],
|
||||
PLAN_WITH_METADATA.product_metadata!['product:details:4'],
|
||||
PLAN_WITH_METADATA.plan_metadata!['product:details:1'],
|
||||
PLAN_WITH_METADATA.plan_metadata!['product:details:2'],
|
||||
PLAN_WITH_METADATA.plan_metadata!['product:details:3'],
|
||||
PLAN_WITH_METADATA.plan_metadata!['product:details:4'],
|
||||
],
|
||||
successActionButtonLabel:
|
||||
PLAN_WITH_METADATA.product_metadata![
|
||||
'product:successActionButtonLabel'
|
||||
],
|
||||
upgradeCTA: PLAN_WITH_METADATA.product_metadata!.upgradeCTA,
|
||||
PLAN_WITH_METADATA.plan_metadata!['product:successActionButtonLabel'],
|
||||
upgradeCTA: PLAN_WITH_METADATA.plan_metadata!.upgradeCTA,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -487,8 +376,8 @@ describe('product configuration util functions', () => {
|
|||
it('returns product update config from plan metadata if featureFlag is false', () => {
|
||||
const actual = productUpgradeFromProductConfig(PLAN_WITH_METADATA, false);
|
||||
expect(actual).to.deep.equal({
|
||||
productOrder: PLAN_WITH_METADATA.product_metadata!.productOrder,
|
||||
productSet: PLAN_WITH_METADATA.product_metadata!.productSet.split(','),
|
||||
productOrder: PLAN_WITH_METADATA.plan_metadata!.productOrder,
|
||||
productSet: PLAN_WITH_METADATA.plan_metadata!.productSet.split(','),
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче