chore(shared-cms): strapi 5 upgrade

Because:

- We want to use Strapi 5

This commit:

- Upgrades our queries and libraries to use Strapi 5

Closes FXA-10454
This commit is contained in:
julianpoyourow 2024-10-07 17:31:51 +00:00
Родитель a2e3ee8ead
Коммит b32169036f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: EA0570ABC73D47D3
59 изменённых файлов: 1760 добавлений и 6064 удалений

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

@ -4,5 +4,6 @@
# Autogenerated files # Autogenerated files
packages/fxa-admin-server/src/schema.gql packages/fxa-admin-server/src/schema.gql
packages/fxa-admin-server/src/graphql.ts packages/fxa-admin-server/src/graphql.ts
libs/shared/cms/src/__generated__/**/*
/.nx/workspace-data /.nx/workspace-data

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

@ -71,10 +71,8 @@ export default async function RootLayout({
/> />
} }
purchaseDetails={ purchaseDetails={
cms.defaultPurchase.data.attributes.purchaseDetails.data.attributes.localizations.data.at( cms.defaultPurchase.purchaseDetails.localizations.at(0) ||
0 cms.defaultPurchase.purchaseDetails
)?.attributes ||
cms.defaultPurchase.data.attributes.purchaseDetails.data.attributes
} }
> >
<Details <Details
@ -82,11 +80,8 @@ export default async function RootLayout({
interval={cart.interval} interval={cart.interval}
invoice={cart.invoicePreview} invoice={cart.invoicePreview}
purchaseDetails={ purchaseDetails={
cms.defaultPurchase.data.attributes.purchaseDetails.data.attributes.localizations.data.at( cms.defaultPurchase.purchaseDetails.localizations.at(0) ||
0 cms.defaultPurchase.purchaseDetails
)?.attributes ||
cms.defaultPurchase.data.attributes.purchaseDetails.data
.attributes
} }
/> />
</PurchaseDetails> </PurchaseDetails>
@ -103,13 +98,9 @@ export default async function RootLayout({
<TermsAndPrivacy <TermsAndPrivacy
l10n={l10n} l10n={l10n}
{...cart} {...cart}
{...(cms.commonContent.data.attributes.localizations.data.at(0) {...(cms.commonContent.localizations.at(0) || cms.commonContent)}
?.attributes || cms.commonContent.data.attributes)} {...(cms.defaultPurchase.purchaseDetails.localizations.at(0) ||
{...(cms.defaultPurchase.data.attributes.purchaseDetails.data.attributes.localizations.data.at( cms.defaultPurchase.purchaseDetails)}
0
)?.attributes ||
cms.defaultPurchase.data.attributes.purchaseDetails.data
.attributes)}
contentServerUrl={config.contentServerUrl} contentServerUrl={config.contentServerUrl}
showFXALinks={true} showFXALinks={true}
/> />

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

@ -75,13 +75,10 @@ export default async function CheckoutSuccess({
]); ]);
const { productName } = const { productName } =
cms.defaultPurchase.data.attributes.purchaseDetails.data.attributes.localizations.data.at( cms.defaultPurchase.purchaseDetails.localizations.at(0) ||
0 cms.defaultPurchase.purchaseDetails;
)?.attributes ||
cms.defaultPurchase.data.attributes.purchaseDetails.data.attributes;
const { successActionButtonUrl, successActionButtonLabel } = const { successActionButtonUrl, successActionButtonLabel } =
cms.commonContent.data.attributes.localizations.data.at(0)?.attributes || cms.commonContent.localizations.at(0) || cms.commonContent;
cms.commonContent.data.attributes;
return ( return (
<> <>

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

@ -21,7 +21,6 @@ import {
ServicesWithCapabilitiesResult, ServicesWithCapabilitiesResult,
StrapiClient, StrapiClient,
MockStrapiClientConfigProvider, MockStrapiClientConfigProvider,
StrapiEntityFactory,
} from '@fxa/shared/cms'; } from '@fxa/shared/cms';
import { MockFirestoreProvider } from '@fxa/shared/db/firestore'; import { MockFirestoreProvider } from '@fxa/shared/db/firestore';
import { MockStatsDProvider } from '@fxa/shared/metrics/statsd'; import { MockStatsDProvider } from '@fxa/shared/metrics/statsd';
@ -53,39 +52,21 @@ describe('CapabilityManager', () => {
describe('getClients', () => { describe('getClients', () => {
it('should return services with capabilities', async () => { it('should return services with capabilities', async () => {
const clientResults = [ const clientResults = [
StrapiEntityFactory( ServiceResultFactory({
ServiceResultFactory({ oauthClientId: 'client1',
oauthClientId: 'client1', capabilities: [
capabilities: { CapabilitiesResultFactory({ slug: 'exampleCap8' }),
data: [ CapabilitiesResultFactory({ slug: 'exampleCap0' }),
StrapiEntityFactory( CapabilitiesResultFactory({ slug: 'exampleCap2' }),
CapabilitiesResultFactory({ slug: 'exampleCap8' }) CapabilitiesResultFactory({ slug: 'exampleCap4' }),
), CapabilitiesResultFactory({ slug: 'exampleCap5' }),
StrapiEntityFactory( CapabilitiesResultFactory({ slug: 'exampleCap6' }),
CapabilitiesResultFactory({ slug: 'exampleCap0' }) ],
), }),
StrapiEntityFactory(
CapabilitiesResultFactory({ slug: 'exampleCap2' })
),
StrapiEntityFactory(
CapabilitiesResultFactory({ slug: 'exampleCap4' })
),
StrapiEntityFactory(
CapabilitiesResultFactory({ slug: 'exampleCap5' })
),
StrapiEntityFactory(
CapabilitiesResultFactory({ slug: 'exampleCap6' })
),
],
},
})
),
]; ];
const mockServicesWithCapabilitiesQuery = const mockServicesWithCapabilitiesQuery =
ServicesWithCapabilitiesQueryFactory({ ServicesWithCapabilitiesQueryFactory({
services: { services: clientResults,
data: clientResults,
},
}); });
jest jest
.spyOn(productConfigurationManager, 'getServicesWithCapabilities') .spyOn(productConfigurationManager, 'getServicesWithCapabilities')
@ -99,8 +80,8 @@ describe('CapabilityManager', () => {
expect(result.length).toBe(1); expect(result.length).toBe(1);
expect(result.at(0)?.clientId).toBe('client1'); expect(result.at(0)?.clientId).toBe('client1');
const actualCapabilities = clientResults[0].attributes.capabilities.data const actualCapabilities = clientResults[0].capabilities
.map((capability) => capability.attributes.slug) .map((capability) => capability.slug)
.sort(); .sort();
expect(result.at(0)?.capabilities).toHaveLength(6); expect(result.at(0)?.capabilities).toHaveLength(6);
@ -118,9 +99,9 @@ describe('CapabilityManager', () => {
'getPurchaseDetailsForCapabilityServiceByPlanIds' 'getPurchaseDetailsForCapabilityServiceByPlanIds'
) )
.mockResolvedValue( .mockResolvedValue(
new CapabilityServiceByPlanIdsResultUtil([ new CapabilityServiceByPlanIdsResultUtil(
mockCapabilityServiceByPlanIdsQuery, mockCapabilityServiceByPlanIdsQuery as CapabilityServiceByPlanIdsResult
] as CapabilityServiceByPlanIdsResult[]) )
); );
const result = await capabilityManager.priceIdsToClientCapabilities([ const result = await capabilityManager.priceIdsToClientCapabilities([
'planId1', 'planId1',
@ -129,30 +110,15 @@ describe('CapabilityManager', () => {
}); });
it('should return empty results when there are no capability collection items', async () => { it('should return empty results when there are no capability collection items', async () => {
const mockCapabilityOfferingResult = StrapiEntityFactory( const mockCapabilityOfferingResult = CapabilityOfferingResultFactory({
CapabilityOfferingResultFactory({ capabilities: [],
capabilities: { });
data: [], const mockCapabilityPurchaseResult = CapabilityPurchaseResultFactory({
}, offering: mockCapabilityOfferingResult,
}) });
);
const mockCapabilityPurchaseResult = StrapiEntityFactory(
CapabilityPurchaseResultFactory({
offering: {
data: mockCapabilityOfferingResult,
},
})
);
const mockCapabilityServiceByPlanIdsQuery = const mockCapabilityServiceByPlanIdsQuery =
CapabilityServiceByPlanIdsQueryFactory({ CapabilityServiceByPlanIdsQueryFactory({
purchases: { purchases: [mockCapabilityPurchaseResult],
meta: {
pagination: {
total: 1,
},
},
data: [mockCapabilityPurchaseResult],
},
}); });
jest jest
.spyOn( .spyOn(
@ -160,9 +126,9 @@ describe('CapabilityManager', () => {
'getPurchaseDetailsForCapabilityServiceByPlanIds' 'getPurchaseDetailsForCapabilityServiceByPlanIds'
) )
.mockResolvedValue( .mockResolvedValue(
new CapabilityServiceByPlanIdsResultUtil([ new CapabilityServiceByPlanIdsResultUtil(
mockCapabilityServiceByPlanIdsQuery, mockCapabilityServiceByPlanIdsQuery as CapabilityServiceByPlanIdsResult
] as CapabilityServiceByPlanIdsResult[]) )
); );
const result = await capabilityManager.priceIdsToClientCapabilities([ const result = await capabilityManager.priceIdsToClientCapabilities([
@ -172,39 +138,20 @@ describe('CapabilityManager', () => {
}); });
it('should return empty results when there are no service collection items', async () => { it('should return empty results when there are no service collection items', async () => {
const mockCapabilityOfferingResult = StrapiEntityFactory( const mockCapabilityOfferingResult = CapabilityOfferingResultFactory({
CapabilityOfferingResultFactory({ capabilities: [
capabilities: { CapabilityCapabilitiesResultFactory({
data: [ slug: 'slug1',
StrapiEntityFactory( services: [],
CapabilityCapabilitiesResultFactory({ }),
slug: 'slug1', ],
services: { });
data: [], const mockCapabilityPurchaseResult = CapabilityPurchaseResultFactory({
}, offering: mockCapabilityOfferingResult,
}) });
),
],
},
})
);
const mockCapabilityPurchaseResult = StrapiEntityFactory(
CapabilityPurchaseResultFactory({
offering: {
data: mockCapabilityOfferingResult,
},
})
);
const mockCapabilityServiceByPlanIdsQuery = const mockCapabilityServiceByPlanIdsQuery =
CapabilityServiceByPlanIdsQueryFactory({ CapabilityServiceByPlanIdsQueryFactory({
purchases: { purchases: [mockCapabilityPurchaseResult],
meta: {
pagination: {
total: 1,
},
},
data: [mockCapabilityPurchaseResult],
},
}); });
jest jest
.spyOn( .spyOn(
@ -212,9 +159,9 @@ describe('CapabilityManager', () => {
'getPurchaseDetailsForCapabilityServiceByPlanIds' 'getPurchaseDetailsForCapabilityServiceByPlanIds'
) )
.mockResolvedValue( .mockResolvedValue(
new CapabilityServiceByPlanIdsResultUtil([ new CapabilityServiceByPlanIdsResultUtil(
mockCapabilityServiceByPlanIdsQuery, mockCapabilityServiceByPlanIdsQuery as CapabilityServiceByPlanIdsResult
] as CapabilityServiceByPlanIdsResult[]) )
); );
const result = await capabilityManager.priceIdsToClientCapabilities([ const result = await capabilityManager.priceIdsToClientCapabilities([
@ -224,74 +171,41 @@ describe('CapabilityManager', () => {
}); });
it('should return planIds to client capabilities', async () => { it('should return planIds to client capabilities', async () => {
const mockCapabilityOfferingResult = StrapiEntityFactory( const mockCapabilityOfferingResult = CapabilityOfferingResultFactory({
CapabilityOfferingResultFactory({ capabilities: [
capabilities: { CapabilityCapabilitiesResultFactory({
data: [ slug: 'slug1',
StrapiEntityFactory( services: [
CapabilityCapabilitiesResultFactory({ CapabilityServicesResultFactory({
slug: 'slug1', oauthClientId: 'clientId1',
services: { }),
data: [
StrapiEntityFactory(
CapabilityServicesResultFactory({
oauthClientId: 'clientId1',
})
),
],
},
})
),
StrapiEntityFactory(
CapabilityCapabilitiesResultFactory({
slug: 'slug2a',
services: {
data: [
StrapiEntityFactory(
CapabilityServicesResultFactory({
oauthClientId: 'clientId2',
})
),
],
},
})
),
StrapiEntityFactory(
CapabilityCapabilitiesResultFactory({
slug: 'slug2b',
services: {
data: [
StrapiEntityFactory(
CapabilityServicesResultFactory({
oauthClientId: 'clientId2',
})
),
],
},
})
),
], ],
}, }),
}) CapabilityCapabilitiesResultFactory({
); slug: 'slug2a',
const mockCapabilityPurchaseResult = StrapiEntityFactory( services: [
CapabilityPurchaseResultFactory({ CapabilityServicesResultFactory({
stripePlanChoices: [{ stripePlanChoice: 'planId1' }], oauthClientId: 'clientId2',
offering: { }),
data: mockCapabilityOfferingResult, ],
}, }),
}) CapabilityCapabilitiesResultFactory({
); slug: 'slug2b',
services: [
CapabilityServicesResultFactory({
oauthClientId: 'clientId2',
}),
],
}),
],
});
const mockCapabilityPurchaseResult = CapabilityPurchaseResultFactory({
stripePlanChoices: [{ stripePlanChoice: 'planId1' }],
offering: mockCapabilityOfferingResult,
});
const mockCapabilityServiceByPlanIdsQuery = const mockCapabilityServiceByPlanIdsQuery =
CapabilityServiceByPlanIdsQueryFactory({ CapabilityServiceByPlanIdsQueryFactory({
purchases: { purchases: [mockCapabilityPurchaseResult],
meta: {
pagination: {
total: 1,
},
},
data: [mockCapabilityPurchaseResult],
},
}); });
jest jest
.spyOn( .spyOn(
@ -299,9 +213,9 @@ describe('CapabilityManager', () => {
'getPurchaseDetailsForCapabilityServiceByPlanIds' 'getPurchaseDetailsForCapabilityServiceByPlanIds'
) )
.mockResolvedValue( .mockResolvedValue(
new CapabilityServiceByPlanIdsResultUtil([ new CapabilityServiceByPlanIdsResultUtil(
mockCapabilityServiceByPlanIdsQuery, mockCapabilityServiceByPlanIdsQuery as CapabilityServiceByPlanIdsResult
] as CapabilityServiceByPlanIdsResult[]) )
); );
const result = await capabilityManager.priceIdsToClientCapabilities([ const result = await capabilityManager.priceIdsToClientCapabilities([

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

@ -17,8 +17,8 @@ export class CapabilityManager {
).getServices(); ).getServices();
return clients.map((client: ServiceResult) => { return clients.map((client: ServiceResult) => {
const capabilities = client.capabilities.data.map( const capabilities = client.capabilities.map(
(capability) => capability.attributes.slug (capability) => capability.slug
); );
const sortedCapabilities = capabilities.sort(); const sortedCapabilities = capabilities.sort();
return { return {
@ -50,20 +50,16 @@ export class CapabilityManager {
purchaseDetails.capabilityOfferingForPlanId(subscribedPrice); purchaseDetails.capabilityOfferingForPlanId(subscribedPrice);
// continue if neither offering nor capabilities exist // continue if neither offering nor capabilities exist
if (!capabilityOffering || !capabilityOffering?.capabilities?.data) if (!capabilityOffering || !capabilityOffering?.capabilities) continue;
continue;
for (const capabilityCollection of capabilityOffering.capabilities.data) { for (const capabilityCollection of capabilityOffering.capabilities) {
// continue if individual capability does not contain any services // continue if individual capability does not contain any services
if (!capabilityCollection.attributes.services.data) continue; if (!capabilityCollection.services) continue;
for (const capability of capabilityCollection.attributes.services for (const capability of capabilityCollection.services) {
.data) { result[capability.oauthClientId] ||= [];
result[capability.attributes.oauthClientId] ||= [];
result[capability.attributes.oauthClientId].push( result[capability.oauthClientId].push(capabilityCollection.slug);
capabilityCollection.attributes.slug
);
} }
} }
} }

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

@ -24,7 +24,6 @@ import {
MockStrapiClientConfigProvider, MockStrapiClientConfigProvider,
ProductConfigurationManager, ProductConfigurationManager,
StrapiClient, StrapiClient,
StrapiEntityFactory,
} from '@fxa/shared/cms'; } from '@fxa/shared/cms';
import { CartEligibilityStatus } from '@fxa/shared/db/mysql/account'; import { CartEligibilityStatus } from '@fxa/shared/db/mysql/account';
@ -66,9 +65,9 @@ describe('EligibilityManager', () => {
jest jest
.spyOn(productConfigurationManager, 'getPurchaseDetailsForEligibility') .spyOn(productConfigurationManager, 'getPurchaseDetailsForEligibility')
.mockResolvedValue( .mockResolvedValue(
new EligibilityContentByPlanIdsResultUtil([ new EligibilityContentByPlanIdsResultUtil(
EligibilityContentByPlanIdsResultFactory(), EligibilityContentByPlanIdsResultFactory()
]) )
); );
const result = await manager.getOfferingOverlap(['test'], [], 'test'); const result = await manager.getOfferingOverlap(['test'], [], 'test');
@ -77,7 +76,7 @@ describe('EligibilityManager', () => {
it('should return same offeringStripeProductIds as same comparison', async () => { it('should return same offeringStripeProductIds as same comparison', async () => {
const eligibilityContentByPlanIdsResultUtil = const eligibilityContentByPlanIdsResultUtil =
new EligibilityContentByPlanIdsResultUtil([]); new EligibilityContentByPlanIdsResultUtil({ purchases: [] });
jest jest
.spyOn(productConfigurationManager, 'getPurchaseDetailsForEligibility') .spyOn(productConfigurationManager, 'getPurchaseDetailsForEligibility')
.mockResolvedValue(eligibilityContentByPlanIdsResultUtil); .mockResolvedValue(eligibilityContentByPlanIdsResultUtil);
@ -100,39 +99,27 @@ describe('EligibilityManager', () => {
it('should return subgroup upgrade target offeringStripeProductIds as upgrade comparison', async () => { it('should return subgroup upgrade target offeringStripeProductIds as upgrade comparison', async () => {
const mockOfferingResult = EligibilityOfferingResultFactory({ const mockOfferingResult = EligibilityOfferingResultFactory({
stripeProductId: 'prod_test3', stripeProductId: 'prod_test3',
subGroups: { subGroups: [
data: [ EligibilitySubgroupResultFactory({
StrapiEntityFactory( offerings: [
EligibilitySubgroupResultFactory({ EligibilitySubgroupOfferingResultFactory({
offerings: { stripeProductId: 'prod_test',
data: [ countries: ['usa'],
StrapiEntityFactory( }),
EligibilitySubgroupOfferingResultFactory({ EligibilitySubgroupOfferingResultFactory({
stripeProductId: 'prod_test', stripeProductId: 'prod_test2',
countries: ['usa'], countries: ['usa'],
}) }),
), EligibilitySubgroupOfferingResultFactory({
StrapiEntityFactory( stripeProductId: 'prod_test3',
EligibilitySubgroupOfferingResultFactory({ countries: ['usa'],
stripeProductId: 'prod_test2', }),
countries: ['usa'], ],
}) }),
), ],
StrapiEntityFactory(
EligibilitySubgroupOfferingResultFactory({
stripeProductId: 'prod_test3',
countries: ['usa'],
})
),
],
},
})
),
],
},
}); });
const eligibilityContentByPlanIdsResultUtil = const eligibilityContentByPlanIdsResultUtil =
new EligibilityContentByPlanIdsResultUtil([]); new EligibilityContentByPlanIdsResultUtil({ purchases: [] });
jest jest
.spyOn(productConfigurationManager, 'getPurchaseDetailsForEligibility') .spyOn(productConfigurationManager, 'getPurchaseDetailsForEligibility')
.mockResolvedValue(eligibilityContentByPlanIdsResultUtil); .mockResolvedValue(eligibilityContentByPlanIdsResultUtil);
@ -152,33 +139,23 @@ describe('EligibilityManager', () => {
it('should return subgroup downgrade target offeringStripeProductIds as downgrade comparison', async () => { it('should return subgroup downgrade target offeringStripeProductIds as downgrade comparison', async () => {
const mockOfferingResult = EligibilityOfferingResultFactory({ const mockOfferingResult = EligibilityOfferingResultFactory({
stripeProductId: 'prod_test', stripeProductId: 'prod_test',
subGroups: { subGroups: [
data: [ EligibilitySubgroupResultFactory({
StrapiEntityFactory( offerings: [
EligibilitySubgroupResultFactory({ EligibilitySubgroupOfferingResultFactory({
offerings: { stripeProductId: 'prod_test',
data: [ countries: ['usa'],
StrapiEntityFactory( }),
EligibilitySubgroupOfferingResultFactory({ EligibilitySubgroupOfferingResultFactory({
stripeProductId: 'prod_test', stripeProductId: 'prod_test2',
countries: ['usa'], countries: ['usa'],
}) }),
), ],
StrapiEntityFactory( }),
EligibilitySubgroupOfferingResultFactory({ ],
stripeProductId: 'prod_test2',
countries: ['usa'],
})
),
],
},
})
),
],
},
}); });
const eligibilityContentByPlanIdsResultUtil = const eligibilityContentByPlanIdsResultUtil =
new EligibilityContentByPlanIdsResultUtil([]); new EligibilityContentByPlanIdsResultUtil({ purchases: [] });
jest jest
.spyOn(productConfigurationManager, 'getPurchaseDetailsForEligibility') .spyOn(productConfigurationManager, 'getPurchaseDetailsForEligibility')
.mockResolvedValue(eligibilityContentByPlanIdsResultUtil); .mockResolvedValue(eligibilityContentByPlanIdsResultUtil);
@ -203,7 +180,7 @@ describe('EligibilityManager', () => {
stripeProductId: 'prod_test', stripeProductId: 'prod_test',
}); });
const eligibilityContentByPlanIdsResultUtil = const eligibilityContentByPlanIdsResultUtil =
new EligibilityContentByPlanIdsResultUtil([]); new EligibilityContentByPlanIdsResultUtil({ purchases: [] });
jest jest
.spyOn(productConfigurationManager, 'getPurchaseDetailsForEligibility') .spyOn(productConfigurationManager, 'getPurchaseDetailsForEligibility')
.mockResolvedValue(eligibilityContentByPlanIdsResultUtil); .mockResolvedValue(eligibilityContentByPlanIdsResultUtil);
@ -224,36 +201,26 @@ describe('EligibilityManager', () => {
it('should return upgrade comparison for upgrade priceId', async () => { it('should return upgrade comparison for upgrade priceId', async () => {
const mockOfferingResult = EligibilityOfferingResultFactory({ const mockOfferingResult = EligibilityOfferingResultFactory({
stripeProductId: 'prod_test2', stripeProductId: 'prod_test2',
subGroups: { subGroups: [
data: [ EligibilitySubgroupResultFactory({
StrapiEntityFactory( offerings: [
EligibilitySubgroupResultFactory({ EligibilitySubgroupOfferingResultFactory({
offerings: { stripeProductId: 'prod_test',
data: [ countries: ['usa'],
StrapiEntityFactory( }),
EligibilitySubgroupOfferingResultFactory({ EligibilitySubgroupOfferingResultFactory({
stripeProductId: 'prod_test', stripeProductId: 'prod_test2',
countries: ['usa'], countries: ['usa'],
}) }),
), ],
StrapiEntityFactory( }),
EligibilitySubgroupOfferingResultFactory({ ],
stripeProductId: 'prod_test2',
countries: ['usa'],
})
),
],
},
})
),
],
},
}); });
const existingResult = EligibilityOfferingResultFactory({ const existingResult = EligibilityOfferingResultFactory({
stripeProductId: 'prod_test', stripeProductId: 'prod_test',
}); });
const eligibilityContentByPlanIdsResultUtil = const eligibilityContentByPlanIdsResultUtil =
new EligibilityContentByPlanIdsResultUtil([]); new EligibilityContentByPlanIdsResultUtil({ purchases: [] });
jest jest
.spyOn(productConfigurationManager, 'getPurchaseDetailsForEligibility') .spyOn(productConfigurationManager, 'getPurchaseDetailsForEligibility')
.mockResolvedValue(eligibilityContentByPlanIdsResultUtil); .mockResolvedValue(eligibilityContentByPlanIdsResultUtil);
@ -274,62 +241,42 @@ describe('EligibilityManager', () => {
it('should return multiple comparisons in multiple subgroups', async () => { it('should return multiple comparisons in multiple subgroups', async () => {
const mockOfferingResult = EligibilityOfferingResultFactory({ const mockOfferingResult = EligibilityOfferingResultFactory({
stripeProductId: 'prod_test2', stripeProductId: 'prod_test2',
subGroups: { subGroups: [
data: [ EligibilitySubgroupResultFactory({
StrapiEntityFactory( offerings: [
EligibilitySubgroupResultFactory({ EligibilitySubgroupOfferingResultFactory({
offerings: { stripeProductId: 'prod_test',
data: [ countries: ['usa'],
StrapiEntityFactory( }),
EligibilitySubgroupOfferingResultFactory({ EligibilitySubgroupOfferingResultFactory({
stripeProductId: 'prod_test', stripeProductId: 'prod_test2',
countries: ['usa'], countries: ['usa'],
}) }),
), EligibilitySubgroupOfferingResultFactory({
StrapiEntityFactory( stripeProductId: 'prod_test3',
EligibilitySubgroupOfferingResultFactory({ countries: ['usa'],
stripeProductId: 'prod_test2', }),
countries: ['usa'], ],
}) }),
), EligibilitySubgroupResultFactory({
StrapiEntityFactory( offerings: [
EligibilitySubgroupOfferingResultFactory({ EligibilitySubgroupOfferingResultFactory({
stripeProductId: 'prod_test3', stripeProductId: 'prod_test',
countries: ['usa'], countries: ['usa'],
}) }),
), EligibilitySubgroupOfferingResultFactory({
], stripeProductId: 'prod_test2',
}, countries: ['usa'],
}) }),
), ],
StrapiEntityFactory( }),
EligibilitySubgroupResultFactory({ ],
offerings: {
data: [
StrapiEntityFactory(
EligibilitySubgroupOfferingResultFactory({
stripeProductId: 'prod_test',
countries: ['usa'],
})
),
StrapiEntityFactory(
EligibilitySubgroupOfferingResultFactory({
stripeProductId: 'prod_test2',
countries: ['usa'],
})
),
],
},
})
),
],
},
}); });
const existingResult = EligibilityOfferingResultFactory({ const existingResult = EligibilityOfferingResultFactory({
stripeProductId: 'prod_test', stripeProductId: 'prod_test',
}); });
const eligibilityContentByPlanIdsResultUtil = const eligibilityContentByPlanIdsResultUtil =
new EligibilityContentByPlanIdsResultUtil([]); new EligibilityContentByPlanIdsResultUtil({ purchases: [] });
jest jest
.spyOn(productConfigurationManager, 'getPurchaseDetailsForEligibility') .spyOn(productConfigurationManager, 'getPurchaseDetailsForEligibility')
.mockResolvedValue(eligibilityContentByPlanIdsResultUtil); .mockResolvedValue(eligibilityContentByPlanIdsResultUtil);
@ -385,33 +332,21 @@ describe('EligibilityManager', () => {
it('should return subgroup upgrade target offeringStripeProductIds as upgrade comparison', async () => { it('should return subgroup upgrade target offeringStripeProductIds as upgrade comparison', async () => {
const mockTargetOfferingResult = EligibilityContentOfferingResultFactory({ const mockTargetOfferingResult = EligibilityContentOfferingResultFactory({
stripeProductId: 'prod_test3', stripeProductId: 'prod_test3',
subGroups: { subGroups: [
data: [ EligibilityContentSubgroupResultFactory({
StrapiEntityFactory( offerings: [
EligibilityContentSubgroupResultFactory({ EligibilityContentSubgroupOfferingResultFactory({
offerings: { stripeProductId: 'prod_test',
data: [ }),
StrapiEntityFactory( EligibilityContentSubgroupOfferingResultFactory({
EligibilityContentSubgroupOfferingResultFactory({ stripeProductId: 'prod_test2',
stripeProductId: 'prod_test', }),
}) EligibilityContentSubgroupOfferingResultFactory({
), stripeProductId: 'prod_test3',
StrapiEntityFactory( }),
EligibilityContentSubgroupOfferingResultFactory({ ],
stripeProductId: 'prod_test2', }),
}) ],
),
StrapiEntityFactory(
EligibilityContentSubgroupOfferingResultFactory({
stripeProductId: 'prod_test3',
})
),
],
},
})
),
],
},
}); });
const result = manager.getProductIdOverlap( const result = manager.getProductIdOverlap(
@ -425,28 +360,18 @@ describe('EligibilityManager', () => {
it('should return subgroup downgrade target offeringStripeProductIds as downgrade comparison', async () => { it('should return subgroup downgrade target offeringStripeProductIds as downgrade comparison', async () => {
const mockTargetOfferingResult = EligibilityContentOfferingResultFactory({ const mockTargetOfferingResult = EligibilityContentOfferingResultFactory({
stripeProductId: 'prod_test', stripeProductId: 'prod_test',
subGroups: { subGroups: [
data: [ EligibilityContentSubgroupResultFactory({
StrapiEntityFactory( offerings: [
EligibilityContentSubgroupResultFactory({ EligibilityContentSubgroupOfferingResultFactory({
offerings: { stripeProductId: 'prod_test',
data: [ }),
StrapiEntityFactory( EligibilityContentSubgroupOfferingResultFactory({
EligibilityContentSubgroupOfferingResultFactory({ stripeProductId: 'prod_test2',
stripeProductId: 'prod_test', }),
}) ],
), }),
StrapiEntityFactory( ],
EligibilityContentSubgroupOfferingResultFactory({
stripeProductId: 'prod_test2',
})
),
],
},
})
),
],
},
}); });
const result = manager.getProductIdOverlap( const result = manager.getProductIdOverlap(
@ -473,28 +398,18 @@ describe('EligibilityManager', () => {
it('should return upgrade comparison for upgrade priceId', async () => { it('should return upgrade comparison for upgrade priceId', async () => {
const mockTargetOfferingResult = EligibilityContentOfferingResultFactory({ const mockTargetOfferingResult = EligibilityContentOfferingResultFactory({
stripeProductId: 'prod_test2', stripeProductId: 'prod_test2',
subGroups: { subGroups: [
data: [ EligibilityContentSubgroupResultFactory({
StrapiEntityFactory( offerings: [
EligibilityContentSubgroupResultFactory({ EligibilityContentSubgroupOfferingResultFactory({
offerings: { stripeProductId: 'prod_test',
data: [ }),
StrapiEntityFactory( EligibilityContentSubgroupOfferingResultFactory({
EligibilityContentSubgroupOfferingResultFactory({ stripeProductId: 'prod_test2',
stripeProductId: 'prod_test', }),
}) ],
), }),
StrapiEntityFactory( ],
EligibilityContentSubgroupOfferingResultFactory({
stripeProductId: 'prod_test2',
})
),
],
},
})
),
],
},
}); });
const result = manager.getProductIdOverlap( const result = manager.getProductIdOverlap(
['prod_test'], ['prod_test'],
@ -507,51 +422,31 @@ describe('EligibilityManager', () => {
it('should return multiple comparisons in multiple subgroups', async () => { it('should return multiple comparisons in multiple subgroups', async () => {
const mockTargetOfferingResult = EligibilityContentOfferingResultFactory({ const mockTargetOfferingResult = EligibilityContentOfferingResultFactory({
stripeProductId: 'prod_test2', stripeProductId: 'prod_test2',
subGroups: { subGroups: [
data: [ EligibilityContentSubgroupResultFactory({
StrapiEntityFactory( offerings: [
EligibilityContentSubgroupResultFactory({ EligibilityContentSubgroupOfferingResultFactory({
offerings: { stripeProductId: 'prod_test',
data: [ }),
StrapiEntityFactory( EligibilityContentSubgroupOfferingResultFactory({
EligibilityContentSubgroupOfferingResultFactory({ stripeProductId: 'prod_test2',
stripeProductId: 'prod_test', }),
}) EligibilityContentSubgroupOfferingResultFactory({
), stripeProductId: 'prod_test3',
StrapiEntityFactory( }),
EligibilityContentSubgroupOfferingResultFactory({ ],
stripeProductId: 'prod_test2', }),
}) EligibilityContentSubgroupResultFactory({
), offerings: [
StrapiEntityFactory( EligibilityContentSubgroupOfferingResultFactory({
EligibilityContentSubgroupOfferingResultFactory({ stripeProductId: 'prod_test',
stripeProductId: 'prod_test3', }),
}) EligibilityContentSubgroupOfferingResultFactory({
), stripeProductId: 'prod_test2',
], }),
}, ],
}) }),
), ],
StrapiEntityFactory(
EligibilityContentSubgroupResultFactory({
offerings: {
data: [
StrapiEntityFactory(
EligibilityContentSubgroupOfferingResultFactory({
stripeProductId: 'prod_test',
})
),
StrapiEntityFactory(
EligibilityContentSubgroupOfferingResultFactory({
stripeProductId: 'prod_test2',
})
),
],
},
})
),
],
},
}); });
const result = manager.getProductIdOverlap( const result = manager.getProductIdOverlap(
['prod_test2', 'prod_test3'], ['prod_test2', 'prod_test3'],

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

@ -112,8 +112,7 @@ export class EligibilityManager {
if (overlap.comparison === OfferingComparison.DOWNGRADE) if (overlap.comparison === OfferingComparison.DOWNGRADE)
return EligibilityStatus.DOWNGRADE; return EligibilityStatus.DOWNGRADE;
const targetPriceIds = const targetPriceIds = targetOffering.defaultPurchase.stripePlanChoices;
targetOffering.defaultPurchase.data.attributes.stripePlanChoices;
const targetPrice = await this.priceManager.retrieveByInterval( const targetPrice = await this.priceManager.retrieveByInterval(
targetPriceIds.map((el) => el.stripePlanChoice), targetPriceIds.map((el) => el.stripePlanChoice),
interval interval

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

@ -20,7 +20,6 @@ import {
MockStrapiClientConfigProvider, MockStrapiClientConfigProvider,
ProductConfigurationManager, ProductConfigurationManager,
StrapiClient, StrapiClient,
StrapiEntityFactory,
} from '@fxa/shared/cms'; } from '@fxa/shared/cms';
import { MockFirestoreProvider } from '@fxa/shared/db/firestore'; import { MockFirestoreProvider } from '@fxa/shared/db/firestore';
import { MockStatsDProvider } from '@fxa/shared/metrics/statsd'; import { MockStatsDProvider } from '@fxa/shared/metrics/statsd';
@ -84,7 +83,7 @@ describe('EligibilityService', () => {
.mockResolvedValue( .mockResolvedValue(
new EligibilityContentByOfferingResultUtil( new EligibilityContentByOfferingResultUtil(
EligibilityContentByOfferingResultFactory({ EligibilityContentByOfferingResultFactory({
offerings: { data: [] }, offerings: [],
}) })
) )
); );
@ -115,9 +114,7 @@ describe('EligibilityService', () => {
.mockResolvedValue( .mockResolvedValue(
new EligibilityContentByOfferingResultUtil( new EligibilityContentByOfferingResultUtil(
EligibilityContentByOfferingResultFactory({ EligibilityContentByOfferingResultFactory({
offerings: { offerings: [mockOffering],
data: [StrapiEntityFactory(mockOffering)],
},
}) })
) )
); );

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

@ -24,15 +24,15 @@ export const offeringComparison = (
) => { ) => {
if (targetOffering.stripeProductId === fromOfferingProductId) if (targetOffering.stripeProductId === fromOfferingProductId)
return OfferingComparison.SAME; return OfferingComparison.SAME;
const commonSubgroups = targetOffering.subGroups.data.filter( const commonSubgroups = targetOffering.subGroups.filter(
(subgroup) => (subgroup) =>
!!subgroup.attributes.offerings.data.find( !!subgroup.offerings.find(
(oc) => oc.attributes.stripeProductId === fromOfferingProductId (oc) => oc.stripeProductId === fromOfferingProductId
) )
); );
if (!commonSubgroups.length) return null; if (!commonSubgroups.length) return null;
const subgroupProductIds = commonSubgroups[0].attributes.offerings.data.map( const subgroupProductIds = commonSubgroups[0].offerings.map(
(o) => o.attributes.stripeProductId (o) => o.stripeProductId
); );
const existingIndex = subgroupProductIds.indexOf(fromOfferingProductId); const existingIndex = subgroupProductIds.indexOf(fromOfferingProductId);
const targetIndex = subgroupProductIds.indexOf( const targetIndex = subgroupProductIds.indexOf(

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

@ -19,7 +19,6 @@ import {
PurchaseDetailsTransformedFactory, PurchaseDetailsTransformedFactory,
StrapiClient, StrapiClient,
MockStrapiClientConfigProvider, MockStrapiClientConfigProvider,
StrapiEntityFactory,
} from '@fxa/shared/cms'; } from '@fxa/shared/cms';
import { MockFirestoreProvider } from '@fxa/shared/db/firestore'; import { MockFirestoreProvider } from '@fxa/shared/db/firestore';
import { MockStatsDProvider } from '@fxa/shared/metrics/statsd'; import { MockStatsDProvider } from '@fxa/shared/metrics/statsd';
@ -149,7 +148,7 @@ describe('StripeMapperService', () => {
it('should return data from cms default locale if no localization data is available', async () => { it('should return data from cms default locale if no localization data is available', async () => {
const expected = PurchaseWithDetailsOfferingContentTransformedFactory(); const expected = PurchaseWithDetailsOfferingContentTransformedFactory();
expected.purchaseDetails.data.attributes.localizations.data = []; expected.purchaseDetails.localizations = [];
mockCMSConfigUtil.transformedPurchaseWithCommonContentForPlanId.mockReturnValueOnce( mockCMSConfigUtil.transformedPurchaseWithCommonContentForPlanId.mockReturnValueOnce(
expected expected
); );
@ -165,10 +164,10 @@ describe('StripeMapperService', () => {
await stripeMapper.mapCMSToStripePlans([stripePlan], 'en', false); await stripeMapper.mapCMSToStripePlans([stripePlan], 'en', false);
const actualProduct = mappedPlans[0].product as Stripe.Product; const actualProduct = mappedPlans[0].product as Stripe.Product;
expect(mappedPlans[0].metadata?.['webIconURL']).toBe( expect(mappedPlans[0].metadata?.['webIconURL']).toBe(
expected.purchaseDetails.data.attributes.webIcon expected.purchaseDetails.webIcon
); );
expect(actualProduct.metadata?.['webIconURL']).toBe( expect(actualProduct.metadata?.['webIconURL']).toBe(
expected.purchaseDetails.data.attributes.webIcon expected.purchaseDetails.webIcon
); );
expect(actualProduct.metadata?.['productSet']).toBe( expect(actualProduct.metadata?.['productSet']).toBe(
productMetadata.productSet productMetadata.productSet
@ -196,12 +195,10 @@ describe('StripeMapperService', () => {
await stripeMapper.mapCMSToStripePlans([stripePlan], 'en', false); await stripeMapper.mapCMSToStripePlans([stripePlan], 'en', false);
const actualProduct = mappedPlans[0].product as Stripe.Product; const actualProduct = mappedPlans[0].product as Stripe.Product;
expect(mappedPlans[0].metadata?.['webIconURL']).toBe( expect(mappedPlans[0].metadata?.['webIconURL']).toBe(
expected.purchaseDetails.data.attributes.localizations.data[0] expected.purchaseDetails.localizations[0].webIcon
.attributes.webIcon
); );
expect(actualProduct.metadata?.['webIconURL']).toBe( expect(actualProduct.metadata?.['webIconURL']).toBe(
expected.purchaseDetails.data.attributes.localizations.data[0] expected.purchaseDetails.localizations[0].webIcon
.attributes.webIcon
); );
expect(actualProduct.metadata?.['productSet']).toBe( expect(actualProduct.metadata?.['productSet']).toBe(
productMetadata.productSet productMetadata.productSet
@ -215,13 +212,9 @@ describe('StripeMapperService', () => {
it('should return data from CMS and not error on locale plan', async () => { it('should return data from CMS and not error on locale plan', async () => {
const expected = PurchaseWithDetailsOfferingContentTransformedFactory({ const expected = PurchaseWithDetailsOfferingContentTransformedFactory({
purchaseDetails: { purchaseDetails: {
data: StrapiEntityFactory({ localizations: [],
localizations: { ...PurchaseDetailsTransformedFactory({
data: [], details: ['Detail 1 in English'],
},
...PurchaseDetailsTransformedFactory({
details: ['Detail 1 in English'],
}),
}), }),
}, },
}); });
@ -260,10 +253,10 @@ describe('StripeMapperService', () => {
const actualProduct1 = mappedPlans[0].product as Stripe.Product; const actualProduct1 = mappedPlans[0].product as Stripe.Product;
const actualProduct2 = mappedPlans[1].product as Stripe.Product; const actualProduct2 = mappedPlans[1].product as Stripe.Product;
expect(mappedPlans[0].metadata?.['product:details:1']).toBe( expect(mappedPlans[0].metadata?.['product:details:1']).toBe(
expected.purchaseDetails.data.attributes.details[0] expected.purchaseDetails.details[0]
); );
expect(actualProduct1.metadata?.['product:details:1']).toBe( expect(actualProduct1.metadata?.['product:details:1']).toBe(
expected.purchaseDetails.data.attributes.details[0] expected.purchaseDetails.details[0]
); );
expect(mappedPlans[1].metadata?.['product:details:1']).toBe( expect(mappedPlans[1].metadata?.['product:details:1']).toBe(
'Detail 1 in French' 'Detail 1 in French'
@ -276,13 +269,9 @@ describe('StripeMapperService', () => {
it('should return data from Stripe and concat errors for product', async () => { it('should return data from Stripe and concat errors for product', async () => {
const expected = PurchaseWithDetailsOfferingContentTransformedFactory({ const expected = PurchaseWithDetailsOfferingContentTransformedFactory({
purchaseDetails: { purchaseDetails: {
data: StrapiEntityFactory({ localizations: [],
localizations: { ...PurchaseDetailsTransformedFactory({
data: [], details: ['Detail 1 in English'],
},
...PurchaseDetailsTransformedFactory({
details: ['Detail 1 in English'],
}),
}), }),
}, },
}); });

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

@ -95,18 +95,16 @@ export class StripeMapperService {
continue; continue;
} }
const commonContentAttributes = const commonContentAttributes = cmsConfigData.offering.commonContent;
cmsConfigData.offering.data.attributes.commonContent.data.attributes;
const commonContentAttributesLocalized = commonContentAttributes const commonContentAttributesLocalized = commonContentAttributes
.localizations.data.length .localizations.length
? commonContentAttributes.localizations.data[0].attributes ? commonContentAttributes.localizations[0]
: commonContentAttributes; : commonContentAttributes;
const purchaseDetailsAttributes = const purchaseDetailsAttributes = cmsConfigData.purchaseDetails;
cmsConfigData.purchaseDetails.data.attributes;
const purchaseDetailsLocalizedAttributes = purchaseDetailsAttributes const purchaseDetailsLocalizedAttributes = purchaseDetailsAttributes
.localizations.data.length .localizations.length
? purchaseDetailsAttributes.localizations.data[0].attributes ? purchaseDetailsAttributes.localizations[0]
: purchaseDetailsAttributes; : purchaseDetailsAttributes;
const planMapper = new PlanMapperUtil( const planMapper = new PlanMapperUtil(

55
libs/shared/cms/src/__generated__/fragment-masking.ts сгенерированный
Просмотреть файл

@ -1,15 +1,13 @@
/* eslint-disable */ /* eslint-disable */
import { import { ResultOf, DocumentTypeDecoration, TypedDocumentNode } from '@graphql-typed-document-node/core';
ResultOf,
DocumentTypeDecoration,
TypedDocumentNode,
} from '@graphql-typed-document-node/core';
import { FragmentDefinitionNode } from 'graphql'; import { FragmentDefinitionNode } from 'graphql';
import { Incremental } from './graphql'; import { Incremental } from './graphql';
export type FragmentType<
TDocumentType extends DocumentTypeDecoration<any, any> export type FragmentType<TDocumentType extends DocumentTypeDecoration<any, any>> = TDocumentType extends DocumentTypeDecoration<
> = TDocumentType extends DocumentTypeDecoration<infer TType, any> infer TType,
any
>
? [TType] extends [{ ' $fragmentName'?: infer TKey }] ? [TType] extends [{ ' $fragmentName'?: infer TKey }]
? TKey extends string ? TKey extends string
? { ' $fragmentRefs'?: { [key in TKey]: TType } } ? { ' $fragmentRefs'?: { [key in TKey]: TType } }
@ -35,10 +33,7 @@ export function useFragment<TType>(
// return nullable if `fragmentType` is nullable or undefined // return nullable if `fragmentType` is nullable or undefined
export function useFragment<TType>( export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>, _documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null | undefined
| FragmentType<DocumentTypeDecoration<TType, any>>
| null
| undefined
): TType | null | undefined; ): TType | null | undefined;
// return array of non-nullable if `fragmentType` is array of non-nullable // return array of non-nullable if `fragmentType` is array of non-nullable
export function useFragment<TType>( export function useFragment<TType>(
@ -48,10 +43,7 @@ export function useFragment<TType>(
// return array of nullable if `fragmentType` is array of nullable // return array of nullable if `fragmentType` is array of nullable
export function useFragment<TType>( export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>, _documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: fragmentType: Array<FragmentType<DocumentTypeDecoration<TType, any>>> | null | undefined
| Array<FragmentType<DocumentTypeDecoration<TType, any>>>
| null
| undefined
): Array<TType> | null | undefined; ): Array<TType> | null | undefined;
// return readonly array of non-nullable if `fragmentType` is array of non-nullable // return readonly array of non-nullable if `fragmentType` is array of non-nullable
export function useFragment<TType>( export function useFragment<TType>(
@ -61,23 +53,16 @@ export function useFragment<TType>(
// return readonly array of nullable if `fragmentType` is array of nullable // return readonly array of nullable if `fragmentType` is array of nullable
export function useFragment<TType>( export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>, _documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: fragmentType: ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>> | null | undefined
| ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>>
| null
| undefined
): ReadonlyArray<TType> | null | undefined; ): ReadonlyArray<TType> | null | undefined;
export function useFragment<TType>( export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>, _documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | Array<FragmentType<DocumentTypeDecoration<TType, any>>> | ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>> | null | undefined
| FragmentType<DocumentTypeDecoration<TType, any>>
| Array<FragmentType<DocumentTypeDecoration<TType, any>>>
| ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>>
| null
| undefined
): TType | Array<TType> | ReadonlyArray<TType> | null | undefined { ): TType | Array<TType> | ReadonlyArray<TType> | null | undefined {
return fragmentType as any; return fragmentType as any;
} }
export function makeFragmentData< export function makeFragmentData<
F extends DocumentTypeDecoration<any, any>, F extends DocumentTypeDecoration<any, any>,
FT extends ResultOf<F> FT extends ResultOf<F>
@ -87,24 +72,16 @@ export function makeFragmentData<
export function isFragmentReady<TQuery, TFrag>( export function isFragmentReady<TQuery, TFrag>(
queryNode: DocumentTypeDecoration<TQuery, any>, queryNode: DocumentTypeDecoration<TQuery, any>,
fragmentNode: TypedDocumentNode<TFrag>, fragmentNode: TypedDocumentNode<TFrag>,
data: data: FragmentType<TypedDocumentNode<Incremental<TFrag>, any>> | null | undefined
| FragmentType<TypedDocumentNode<Incremental<TFrag>, any>>
| null
| undefined
): data is FragmentType<typeof fragmentNode> { ): data is FragmentType<typeof fragmentNode> {
const deferredFields = ( const deferredFields = (queryNode as { __meta__?: { deferredFields: Record<string, (keyof TFrag)[]> } }).__meta__
queryNode as { ?.deferredFields;
__meta__?: { deferredFields: Record<string, (keyof TFrag)[]> };
}
).__meta__?.deferredFields;
if (!deferredFields) return true; if (!deferredFields) return true;
const fragDef = fragmentNode.definitions[0] as const fragDef = fragmentNode.definitions[0] as FragmentDefinitionNode | undefined;
| FragmentDefinitionNode
| undefined;
const fragName = fragDef?.name?.value; const fragName = fragDef?.name?.value;
const fields = (fragName && deferredFields[fragName]) || []; const fields = (fragName && deferredFields[fragName]) || [];
return fields.length > 0 && fields.every((field) => data && field in data); return fields.length > 0 && fields.every(field => data && field in data);
} }

59
libs/shared/cms/src/__generated__/gql.ts сгенерированный
Просмотреть файл

@ -13,22 +13,14 @@ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/
* Therefore it is highly recommended to use the babel or swc plugin for production. * Therefore it is highly recommended to use the babel or swc plugin for production.
*/ */
const documents = { const documents = {
'\n query CapabilityServiceByPlanIds(\n $skip: Int!\n $limit: Int!\n $stripePlanIds: [String]!\n ) {\n purchases(\n filters: {\n or: [\n { stripePlanChoices: { stripePlanChoice: { in: $stripePlanIds } } }\n {\n offering: {\n stripeLegacyPlans: { stripeLegacyPlan: { in: $stripePlanIds } }\n }\n }\n ]\n }\n pagination: { start: $skip, limit: $limit }\n ) {\n meta {\n pagination {\n total\n }\n }\n data {\n attributes {\n stripePlanChoices {\n stripePlanChoice\n }\n offering {\n data {\n attributes {\n stripeLegacyPlans(pagination: { limit: 200 }) {\n stripeLegacyPlan\n }\n capabilities {\n data {\n attributes {\n slug\n services {\n data {\n attributes {\n oauthClientId\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n': "\n query CapabilityServiceByPlanIds($stripePlanIds: [String]!) {\n purchases(\n filters: {\n or: [\n { stripePlanChoices: { stripePlanChoice: { in: $stripePlanIds } } }\n {\n offering: {\n stripeLegacyPlans: { stripeLegacyPlan: { in: $stripePlanIds } }\n }\n }\n ]\n }\n pagination: { limit: 200 }\n ) {\n stripePlanChoices {\n stripePlanChoice\n }\n offering {\n stripeLegacyPlans(pagination: { limit: 200 }) {\n stripeLegacyPlan\n }\n capabilities {\n slug\n services {\n oauthClientId\n }\n }\n }\n }\n }\n": types.CapabilityServiceByPlanIdsDocument,
types.CapabilityServiceByPlanIdsDocument, "\n query EligibilityContentByOffering($apiIdentifier: String!) {\n offerings(\n filters: { apiIdentifier: { eq: $apiIdentifier } }\n pagination: { limit: 200 }\n ) {\n apiIdentifier\n stripeProductId\n defaultPurchase {\n stripePlanChoices {\n stripePlanChoice\n }\n }\n subGroups {\n groupName\n offerings {\n apiIdentifier\n stripeProductId\n defaultPurchase {\n stripePlanChoices {\n stripePlanChoice\n }\n }\n }\n }\n }\n }\n": types.EligibilityContentByOfferingDocument,
'\n query EligibilityContentByOffering($apiIdentifier: String!) {\n offerings(\n pagination: { start: 0, limit: 2 }\n filters: { apiIdentifier: { eq: $apiIdentifier } }\n ) {\n data {\n attributes {\n apiIdentifier\n stripeProductId\n defaultPurchase {\n data {\n attributes {\n stripePlanChoices {\n stripePlanChoice\n }\n }\n }\n }\n subGroups {\n data {\n attributes {\n groupName\n offerings {\n data {\n attributes {\n apiIdentifier\n stripeProductId\n defaultPurchase {\n data {\n attributes {\n stripePlanChoices {\n stripePlanChoice\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n': "\n query EligibilityContentByPlanIds($stripePlanIds: [String]!) {\n purchases(\n filters: {\n or: [\n { stripePlanChoices: { stripePlanChoice: { in: $stripePlanIds } } }\n {\n offering: {\n stripeLegacyPlans: { stripeLegacyPlan: { in: $stripePlanIds } }\n }\n }\n ]\n }\n pagination: { limit: 200 }\n ) {\n stripePlanChoices {\n stripePlanChoice\n }\n offering {\n stripeProductId\n stripeLegacyPlans(pagination: { limit: 200 }) {\n stripeLegacyPlan\n }\n countries\n subGroups {\n groupName\n offerings {\n stripeProductId\n stripeLegacyPlans(pagination: { limit: 200 }) {\n stripeLegacyPlan\n }\n countries\n }\n }\n }\n }\n }\n": types.EligibilityContentByPlanIdsDocument,
types.EligibilityContentByOfferingDocument, "\n query Locales {\n i18NLocales {\n code\n }\n }\n": types.LocalesDocument,
'\n query EligibilityContentByPlanIds(\n $skip: Int!\n $limit: Int!\n $stripePlanIds: [String]!\n ) {\n purchases(\n pagination: { start: $skip, limit: $limit }\n filters: {\n or: [\n { stripePlanChoices: { stripePlanChoice: { in: $stripePlanIds } } }\n {\n offering: {\n stripeLegacyPlans: { stripeLegacyPlan: { in: $stripePlanIds } }\n }\n }\n ]\n }\n ) {\n meta {\n pagination {\n total\n }\n }\n data {\n attributes {\n stripePlanChoices {\n stripePlanChoice\n }\n offering {\n data {\n attributes {\n stripeProductId\n stripeLegacyPlans(pagination: { limit: 200 }) {\n stripeLegacyPlan\n }\n countries\n subGroups {\n data {\n attributes {\n groupName\n offerings {\n data {\n attributes {\n stripeProductId\n stripeLegacyPlans(pagination: { limit: 200 }) {\n stripeLegacyPlan\n }\n countries\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n': "\n query Offering($id: ID!, $locale: String!) {\n offering(documentId: $id) {\n stripeProductId\n countries\n defaultPurchase {\n purchaseDetails {\n productName\n details\n subtitle\n webIcon\n localizations(filters: { locale: { eq: $locale } }) {\n productName\n details\n subtitle\n webIcon\n }\n }\n }\n }\n }\n": types.OfferingDocument,
types.EligibilityContentByPlanIdsDocument, "\n query PageContentForOffering($locale: String!, $apiIdentifier: String!) {\n offerings(\n filters: { apiIdentifier: { eq: $apiIdentifier } }\n pagination: { limit: 200 }\n ) {\n apiIdentifier\n stripeProductId\n defaultPurchase {\n purchaseDetails {\n details\n productName\n subtitle\n webIcon\n localizations(filters: { locale: { eq: $locale } }) {\n details\n productName\n subtitle\n webIcon\n }\n }\n }\n commonContent {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n localizations(filters: { locale: { eq: $locale } }) {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n }\n }\n }\n }\n": types.PageContentForOfferingDocument,
'\n query Locales {\n i18NLocales {\n data {\n attributes {\n code\n }\n }\n }\n }\n': "\n query PurchaseWithDetailsOfferingContent(\n $locale: String!\n $stripePlanIds: [String]!\n ) {\n purchases(\n filters: {\n or: [\n { stripePlanChoices: { stripePlanChoice: { in: $stripePlanIds } } }\n {\n offering: {\n stripeLegacyPlans: { stripeLegacyPlan: { in: $stripePlanIds } }\n }\n }\n ]\n }\n pagination: { limit: 500 }\n ) {\n stripePlanChoices {\n stripePlanChoice\n }\n purchaseDetails {\n details\n productName\n subtitle\n webIcon\n localizations(filters: { locale: { eq: $locale } }) {\n details\n productName\n subtitle\n webIcon\n }\n }\n offering {\n stripeProductId\n stripeLegacyPlans(pagination: { limit: 200 }) {\n stripeLegacyPlan\n }\n commonContent {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n localizations(filters: { locale: { eq: $locale } }) {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n }\n }\n }\n }\n }\n": types.PurchaseWithDetailsOfferingContentDocument,
types.LocalesDocument, "\n query ServicesWithCapabilities {\n services(pagination: { limit: 500 }) {\n oauthClientId\n capabilities {\n slug\n }\n }\n }\n": types.ServicesWithCapabilitiesDocument,
'\n query Offering($id: ID!, $locale: String!) {\n offering(id: $id) {\n data {\n attributes {\n stripeProductId\n countries\n defaultPurchase {\n data {\n attributes {\n purchaseDetails {\n data {\n attributes {\n productName\n details\n subtitle\n webIcon\n localizations(filters: { locale: { eq: $locale } }) {\n data {\n attributes {\n productName\n details\n subtitle\n webIcon\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n':
types.OfferingDocument,
'\n query PageContentForOffering($locale: String!, $apiIdentifier: String!) {\n offerings(\n pagination: { start: 0, limit: 2 }\n filters: { apiIdentifier: { eq: $apiIdentifier } }\n ) {\n meta {\n pagination {\n total\n }\n }\n data {\n attributes {\n apiIdentifier\n stripeProductId\n defaultPurchase {\n data {\n attributes {\n purchaseDetails {\n data {\n attributes {\n details\n productName\n subtitle\n webIcon\n localizations(filters: { locale: { eq: $locale } }) {\n data {\n attributes {\n details\n productName\n subtitle\n webIcon\n }\n }\n }\n }\n }\n }\n }\n }\n }\n commonContent {\n data {\n attributes {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n localizations(filters: { locale: { eq: $locale } }) {\n data {\n attributes {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n':
types.PageContentForOfferingDocument,
'\n query PurchaseWithDetailsOfferingContent(\n $skip: Int!\n $limit: Int!\n $locale: String!\n $stripePlanIds: [String]!\n ) {\n purchases(\n pagination: { start: $skip, limit: $limit }\n filters: {\n or: [\n { stripePlanChoices: { stripePlanChoice: { in: $stripePlanIds } } }\n {\n offering: {\n stripeLegacyPlans: { stripeLegacyPlan: { in: $stripePlanIds } }\n }\n }\n ]\n }\n ) {\n data {\n attributes {\n stripePlanChoices {\n stripePlanChoice\n }\n purchaseDetails {\n data {\n attributes {\n details\n productName\n subtitle\n webIcon\n localizations(filters: { locale: { eq: $locale } }) {\n data {\n attributes {\n details\n productName\n subtitle\n webIcon\n }\n }\n }\n }\n }\n }\n offering {\n data {\n attributes {\n stripeProductId\n stripeLegacyPlans(pagination: { limit: 200 }) {\n stripeLegacyPlan\n }\n commonContent {\n data {\n attributes {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n localizations(filters: { locale: { eq: $locale } }) {\n data {\n attributes {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n':
types.PurchaseWithDetailsOfferingContentDocument,
'\n query ServicesWithCapabilities($skip: Int!, $limit: Int!) {\n services(pagination: { start: $skip, limit: $limit }) {\n data {\n attributes {\n oauthClientId\n capabilities {\n data {\n attributes {\n slug\n }\n }\n }\n }\n }\n }\n }\n':
types.ServicesWithCapabilitiesDocument,
}; };
/** /**
@ -48,55 +40,38 @@ export function graphql(source: string): unknown;
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n query CapabilityServiceByPlanIds($stripePlanIds: [String]!) {\n purchases(\n filters: {\n or: [\n { stripePlanChoices: { stripePlanChoice: { in: $stripePlanIds } } }\n {\n offering: {\n stripeLegacyPlans: { stripeLegacyPlan: { in: $stripePlanIds } }\n }\n }\n ]\n }\n pagination: { limit: 200 }\n ) {\n stripePlanChoices {\n stripePlanChoice\n }\n offering {\n stripeLegacyPlans(pagination: { limit: 200 }) {\n stripeLegacyPlan\n }\n capabilities {\n slug\n services {\n oauthClientId\n }\n }\n }\n }\n }\n"): (typeof documents)["\n query CapabilityServiceByPlanIds($stripePlanIds: [String]!) {\n purchases(\n filters: {\n or: [\n { stripePlanChoices: { stripePlanChoice: { in: $stripePlanIds } } }\n {\n offering: {\n stripeLegacyPlans: { stripeLegacyPlan: { in: $stripePlanIds } }\n }\n }\n ]\n }\n pagination: { limit: 200 }\n ) {\n stripePlanChoices {\n stripePlanChoice\n }\n offering {\n stripeLegacyPlans(pagination: { limit: 200 }) {\n stripeLegacyPlan\n }\n capabilities {\n slug\n services {\n oauthClientId\n }\n }\n }\n }\n }\n"];
source: '\n query CapabilityServiceByPlanIds(\n $skip: Int!\n $limit: Int!\n $stripePlanIds: [String]!\n ) {\n purchases(\n filters: {\n or: [\n { stripePlanChoices: { stripePlanChoice: { in: $stripePlanIds } } }\n {\n offering: {\n stripeLegacyPlans: { stripeLegacyPlan: { in: $stripePlanIds } }\n }\n }\n ]\n }\n pagination: { start: $skip, limit: $limit }\n ) {\n meta {\n pagination {\n total\n }\n }\n data {\n attributes {\n stripePlanChoices {\n stripePlanChoice\n }\n offering {\n data {\n attributes {\n stripeLegacyPlans(pagination: { limit: 200 }) {\n stripeLegacyPlan\n }\n capabilities {\n data {\n attributes {\n slug\n services {\n data {\n attributes {\n oauthClientId\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n'
): (typeof documents)['\n query CapabilityServiceByPlanIds(\n $skip: Int!\n $limit: Int!\n $stripePlanIds: [String]!\n ) {\n purchases(\n filters: {\n or: [\n { stripePlanChoices: { stripePlanChoice: { in: $stripePlanIds } } }\n {\n offering: {\n stripeLegacyPlans: { stripeLegacyPlan: { in: $stripePlanIds } }\n }\n }\n ]\n }\n pagination: { start: $skip, limit: $limit }\n ) {\n meta {\n pagination {\n total\n }\n }\n data {\n attributes {\n stripePlanChoices {\n stripePlanChoice\n }\n offering {\n data {\n attributes {\n stripeLegacyPlans(pagination: { limit: 200 }) {\n stripeLegacyPlan\n }\n capabilities {\n data {\n attributes {\n slug\n services {\n data {\n attributes {\n oauthClientId\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n'];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n query EligibilityContentByOffering($apiIdentifier: String!) {\n offerings(\n filters: { apiIdentifier: { eq: $apiIdentifier } }\n pagination: { limit: 200 }\n ) {\n apiIdentifier\n stripeProductId\n defaultPurchase {\n stripePlanChoices {\n stripePlanChoice\n }\n }\n subGroups {\n groupName\n offerings {\n apiIdentifier\n stripeProductId\n defaultPurchase {\n stripePlanChoices {\n stripePlanChoice\n }\n }\n }\n }\n }\n }\n"): (typeof documents)["\n query EligibilityContentByOffering($apiIdentifier: String!) {\n offerings(\n filters: { apiIdentifier: { eq: $apiIdentifier } }\n pagination: { limit: 200 }\n ) {\n apiIdentifier\n stripeProductId\n defaultPurchase {\n stripePlanChoices {\n stripePlanChoice\n }\n }\n subGroups {\n groupName\n offerings {\n apiIdentifier\n stripeProductId\n defaultPurchase {\n stripePlanChoices {\n stripePlanChoice\n }\n }\n }\n }\n }\n }\n"];
source: '\n query EligibilityContentByOffering($apiIdentifier: String!) {\n offerings(\n pagination: { start: 0, limit: 2 }\n filters: { apiIdentifier: { eq: $apiIdentifier } }\n ) {\n data {\n attributes {\n apiIdentifier\n stripeProductId\n defaultPurchase {\n data {\n attributes {\n stripePlanChoices {\n stripePlanChoice\n }\n }\n }\n }\n subGroups {\n data {\n attributes {\n groupName\n offerings {\n data {\n attributes {\n apiIdentifier\n stripeProductId\n defaultPurchase {\n data {\n attributes {\n stripePlanChoices {\n stripePlanChoice\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n'
): (typeof documents)['\n query EligibilityContentByOffering($apiIdentifier: String!) {\n offerings(\n pagination: { start: 0, limit: 2 }\n filters: { apiIdentifier: { eq: $apiIdentifier } }\n ) {\n data {\n attributes {\n apiIdentifier\n stripeProductId\n defaultPurchase {\n data {\n attributes {\n stripePlanChoices {\n stripePlanChoice\n }\n }\n }\n }\n subGroups {\n data {\n attributes {\n groupName\n offerings {\n data {\n attributes {\n apiIdentifier\n stripeProductId\n defaultPurchase {\n data {\n attributes {\n stripePlanChoices {\n stripePlanChoice\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n'];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n query EligibilityContentByPlanIds($stripePlanIds: [String]!) {\n purchases(\n filters: {\n or: [\n { stripePlanChoices: { stripePlanChoice: { in: $stripePlanIds } } }\n {\n offering: {\n stripeLegacyPlans: { stripeLegacyPlan: { in: $stripePlanIds } }\n }\n }\n ]\n }\n pagination: { limit: 200 }\n ) {\n stripePlanChoices {\n stripePlanChoice\n }\n offering {\n stripeProductId\n stripeLegacyPlans(pagination: { limit: 200 }) {\n stripeLegacyPlan\n }\n countries\n subGroups {\n groupName\n offerings {\n stripeProductId\n stripeLegacyPlans(pagination: { limit: 200 }) {\n stripeLegacyPlan\n }\n countries\n }\n }\n }\n }\n }\n"): (typeof documents)["\n query EligibilityContentByPlanIds($stripePlanIds: [String]!) {\n purchases(\n filters: {\n or: [\n { stripePlanChoices: { stripePlanChoice: { in: $stripePlanIds } } }\n {\n offering: {\n stripeLegacyPlans: { stripeLegacyPlan: { in: $stripePlanIds } }\n }\n }\n ]\n }\n pagination: { limit: 200 }\n ) {\n stripePlanChoices {\n stripePlanChoice\n }\n offering {\n stripeProductId\n stripeLegacyPlans(pagination: { limit: 200 }) {\n stripeLegacyPlan\n }\n countries\n subGroups {\n groupName\n offerings {\n stripeProductId\n stripeLegacyPlans(pagination: { limit: 200 }) {\n stripeLegacyPlan\n }\n countries\n }\n }\n }\n }\n }\n"];
source: '\n query EligibilityContentByPlanIds(\n $skip: Int!\n $limit: Int!\n $stripePlanIds: [String]!\n ) {\n purchases(\n pagination: { start: $skip, limit: $limit }\n filters: {\n or: [\n { stripePlanChoices: { stripePlanChoice: { in: $stripePlanIds } } }\n {\n offering: {\n stripeLegacyPlans: { stripeLegacyPlan: { in: $stripePlanIds } }\n }\n }\n ]\n }\n ) {\n meta {\n pagination {\n total\n }\n }\n data {\n attributes {\n stripePlanChoices {\n stripePlanChoice\n }\n offering {\n data {\n attributes {\n stripeProductId\n stripeLegacyPlans(pagination: { limit: 200 }) {\n stripeLegacyPlan\n }\n countries\n subGroups {\n data {\n attributes {\n groupName\n offerings {\n data {\n attributes {\n stripeProductId\n stripeLegacyPlans(pagination: { limit: 200 }) {\n stripeLegacyPlan\n }\n countries\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n'
): (typeof documents)['\n query EligibilityContentByPlanIds(\n $skip: Int!\n $limit: Int!\n $stripePlanIds: [String]!\n ) {\n purchases(\n pagination: { start: $skip, limit: $limit }\n filters: {\n or: [\n { stripePlanChoices: { stripePlanChoice: { in: $stripePlanIds } } }\n {\n offering: {\n stripeLegacyPlans: { stripeLegacyPlan: { in: $stripePlanIds } }\n }\n }\n ]\n }\n ) {\n meta {\n pagination {\n total\n }\n }\n data {\n attributes {\n stripePlanChoices {\n stripePlanChoice\n }\n offering {\n data {\n attributes {\n stripeProductId\n stripeLegacyPlans(pagination: { limit: 200 }) {\n stripeLegacyPlan\n }\n countries\n subGroups {\n data {\n attributes {\n groupName\n offerings {\n data {\n attributes {\n stripeProductId\n stripeLegacyPlans(pagination: { limit: 200 }) {\n stripeLegacyPlan\n }\n countries\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n'];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n query Locales {\n i18NLocales {\n code\n }\n }\n"): (typeof documents)["\n query Locales {\n i18NLocales {\n code\n }\n }\n"];
source: '\n query Locales {\n i18NLocales {\n data {\n attributes {\n code\n }\n }\n }\n }\n'
): (typeof documents)['\n query Locales {\n i18NLocales {\n data {\n attributes {\n code\n }\n }\n }\n }\n'];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n query Offering($id: ID!, $locale: String!) {\n offering(documentId: $id) {\n stripeProductId\n countries\n defaultPurchase {\n purchaseDetails {\n productName\n details\n subtitle\n webIcon\n localizations(filters: { locale: { eq: $locale } }) {\n productName\n details\n subtitle\n webIcon\n }\n }\n }\n }\n }\n"): (typeof documents)["\n query Offering($id: ID!, $locale: String!) {\n offering(documentId: $id) {\n stripeProductId\n countries\n defaultPurchase {\n purchaseDetails {\n productName\n details\n subtitle\n webIcon\n localizations(filters: { locale: { eq: $locale } }) {\n productName\n details\n subtitle\n webIcon\n }\n }\n }\n }\n }\n"];
source: '\n query Offering($id: ID!, $locale: String!) {\n offering(id: $id) {\n data {\n attributes {\n stripeProductId\n countries\n defaultPurchase {\n data {\n attributes {\n purchaseDetails {\n data {\n attributes {\n productName\n details\n subtitle\n webIcon\n localizations(filters: { locale: { eq: $locale } }) {\n data {\n attributes {\n productName\n details\n subtitle\n webIcon\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n'
): (typeof documents)['\n query Offering($id: ID!, $locale: String!) {\n offering(id: $id) {\n data {\n attributes {\n stripeProductId\n countries\n defaultPurchase {\n data {\n attributes {\n purchaseDetails {\n data {\n attributes {\n productName\n details\n subtitle\n webIcon\n localizations(filters: { locale: { eq: $locale } }) {\n data {\n attributes {\n productName\n details\n subtitle\n webIcon\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n'];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n query PageContentForOffering($locale: String!, $apiIdentifier: String!) {\n offerings(\n filters: { apiIdentifier: { eq: $apiIdentifier } }\n pagination: { limit: 200 }\n ) {\n apiIdentifier\n stripeProductId\n defaultPurchase {\n purchaseDetails {\n details\n productName\n subtitle\n webIcon\n localizations(filters: { locale: { eq: $locale } }) {\n details\n productName\n subtitle\n webIcon\n }\n }\n }\n commonContent {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n localizations(filters: { locale: { eq: $locale } }) {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n }\n }\n }\n }\n"): (typeof documents)["\n query PageContentForOffering($locale: String!, $apiIdentifier: String!) {\n offerings(\n filters: { apiIdentifier: { eq: $apiIdentifier } }\n pagination: { limit: 200 }\n ) {\n apiIdentifier\n stripeProductId\n defaultPurchase {\n purchaseDetails {\n details\n productName\n subtitle\n webIcon\n localizations(filters: { locale: { eq: $locale } }) {\n details\n productName\n subtitle\n webIcon\n }\n }\n }\n commonContent {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n localizations(filters: { locale: { eq: $locale } }) {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n }\n }\n }\n }\n"];
source: '\n query PageContentForOffering($locale: String!, $apiIdentifier: String!) {\n offerings(\n pagination: { start: 0, limit: 2 }\n filters: { apiIdentifier: { eq: $apiIdentifier } }\n ) {\n meta {\n pagination {\n total\n }\n }\n data {\n attributes {\n apiIdentifier\n stripeProductId\n defaultPurchase {\n data {\n attributes {\n purchaseDetails {\n data {\n attributes {\n details\n productName\n subtitle\n webIcon\n localizations(filters: { locale: { eq: $locale } }) {\n data {\n attributes {\n details\n productName\n subtitle\n webIcon\n }\n }\n }\n }\n }\n }\n }\n }\n }\n commonContent {\n data {\n attributes {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n localizations(filters: { locale: { eq: $locale } }) {\n data {\n attributes {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n'
): (typeof documents)['\n query PageContentForOffering($locale: String!, $apiIdentifier: String!) {\n offerings(\n pagination: { start: 0, limit: 2 }\n filters: { apiIdentifier: { eq: $apiIdentifier } }\n ) {\n meta {\n pagination {\n total\n }\n }\n data {\n attributes {\n apiIdentifier\n stripeProductId\n defaultPurchase {\n data {\n attributes {\n purchaseDetails {\n data {\n attributes {\n details\n productName\n subtitle\n webIcon\n localizations(filters: { locale: { eq: $locale } }) {\n data {\n attributes {\n details\n productName\n subtitle\n webIcon\n }\n }\n }\n }\n }\n }\n }\n }\n }\n commonContent {\n data {\n attributes {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n localizations(filters: { locale: { eq: $locale } }) {\n data {\n attributes {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n'];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n query PurchaseWithDetailsOfferingContent(\n $locale: String!\n $stripePlanIds: [String]!\n ) {\n purchases(\n filters: {\n or: [\n { stripePlanChoices: { stripePlanChoice: { in: $stripePlanIds } } }\n {\n offering: {\n stripeLegacyPlans: { stripeLegacyPlan: { in: $stripePlanIds } }\n }\n }\n ]\n }\n pagination: { limit: 500 }\n ) {\n stripePlanChoices {\n stripePlanChoice\n }\n purchaseDetails {\n details\n productName\n subtitle\n webIcon\n localizations(filters: { locale: { eq: $locale } }) {\n details\n productName\n subtitle\n webIcon\n }\n }\n offering {\n stripeProductId\n stripeLegacyPlans(pagination: { limit: 200 }) {\n stripeLegacyPlan\n }\n commonContent {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n localizations(filters: { locale: { eq: $locale } }) {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n }\n }\n }\n }\n }\n"): (typeof documents)["\n query PurchaseWithDetailsOfferingContent(\n $locale: String!\n $stripePlanIds: [String]!\n ) {\n purchases(\n filters: {\n or: [\n { stripePlanChoices: { stripePlanChoice: { in: $stripePlanIds } } }\n {\n offering: {\n stripeLegacyPlans: { stripeLegacyPlan: { in: $stripePlanIds } }\n }\n }\n ]\n }\n pagination: { limit: 500 }\n ) {\n stripePlanChoices {\n stripePlanChoice\n }\n purchaseDetails {\n details\n productName\n subtitle\n webIcon\n localizations(filters: { locale: { eq: $locale } }) {\n details\n productName\n subtitle\n webIcon\n }\n }\n offering {\n stripeProductId\n stripeLegacyPlans(pagination: { limit: 200 }) {\n stripeLegacyPlan\n }\n commonContent {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n localizations(filters: { locale: { eq: $locale } }) {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n }\n }\n }\n }\n }\n"];
source: '\n query PurchaseWithDetailsOfferingContent(\n $skip: Int!\n $limit: Int!\n $locale: String!\n $stripePlanIds: [String]!\n ) {\n purchases(\n pagination: { start: $skip, limit: $limit }\n filters: {\n or: [\n { stripePlanChoices: { stripePlanChoice: { in: $stripePlanIds } } }\n {\n offering: {\n stripeLegacyPlans: { stripeLegacyPlan: { in: $stripePlanIds } }\n }\n }\n ]\n }\n ) {\n data {\n attributes {\n stripePlanChoices {\n stripePlanChoice\n }\n purchaseDetails {\n data {\n attributes {\n details\n productName\n subtitle\n webIcon\n localizations(filters: { locale: { eq: $locale } }) {\n data {\n attributes {\n details\n productName\n subtitle\n webIcon\n }\n }\n }\n }\n }\n }\n offering {\n data {\n attributes {\n stripeProductId\n stripeLegacyPlans(pagination: { limit: 200 }) {\n stripeLegacyPlan\n }\n commonContent {\n data {\n attributes {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n localizations(filters: { locale: { eq: $locale } }) {\n data {\n attributes {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n'
): (typeof documents)['\n query PurchaseWithDetailsOfferingContent(\n $skip: Int!\n $limit: Int!\n $locale: String!\n $stripePlanIds: [String]!\n ) {\n purchases(\n pagination: { start: $skip, limit: $limit }\n filters: {\n or: [\n { stripePlanChoices: { stripePlanChoice: { in: $stripePlanIds } } }\n {\n offering: {\n stripeLegacyPlans: { stripeLegacyPlan: { in: $stripePlanIds } }\n }\n }\n ]\n }\n ) {\n data {\n attributes {\n stripePlanChoices {\n stripePlanChoice\n }\n purchaseDetails {\n data {\n attributes {\n details\n productName\n subtitle\n webIcon\n localizations(filters: { locale: { eq: $locale } }) {\n data {\n attributes {\n details\n productName\n subtitle\n webIcon\n }\n }\n }\n }\n }\n }\n offering {\n data {\n attributes {\n stripeProductId\n stripeLegacyPlans(pagination: { limit: 200 }) {\n stripeLegacyPlan\n }\n commonContent {\n data {\n attributes {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n localizations(filters: { locale: { eq: $locale } }) {\n data {\n attributes {\n privacyNoticeUrl\n privacyNoticeDownloadUrl\n termsOfServiceUrl\n termsOfServiceDownloadUrl\n cancellationUrl\n emailIcon\n successActionButtonUrl\n successActionButtonLabel\n newsletterLabelTextCode\n newsletterSlug\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n'];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n query ServicesWithCapabilities {\n services(pagination: { limit: 500 }) {\n oauthClientId\n capabilities {\n slug\n }\n }\n }\n"): (typeof documents)["\n query ServicesWithCapabilities {\n services(pagination: { limit: 500 }) {\n oauthClientId\n capabilities {\n slug\n }\n }\n }\n"];
source: '\n query ServicesWithCapabilities($skip: Int!, $limit: Int!) {\n services(pagination: { start: $skip, limit: $limit }) {\n data {\n attributes {\n oauthClientId\n capabilities {\n data {\n attributes {\n slug\n }\n }\n }\n }\n }\n }\n }\n'
): (typeof documents)['\n query ServicesWithCapabilities($skip: Int!, $limit: Int!) {\n services(pagination: { start: $skip, limit: $limit }) {\n data {\n attributes {\n oauthClientId\n capabilities {\n data {\n attributes {\n slug\n }\n }\n }\n }\n }\n }\n }\n'];
export function graphql(source: string) { export function graphql(source: string) {
return (documents as any)[source] ?? {}; return (documents as any)[source] ?? {};
} }
export type DocumentType<TDocumentNode extends DocumentNode<any, any>> = export type DocumentType<TDocumentNode extends DocumentNode<any, any>> = TDocumentNode extends DocumentNode< infer TType, any> ? TType : never;
TDocumentNode extends DocumentNode<infer TType, any> ? TType : never;

5396
libs/shared/cms/src/__generated__/graphql.ts сгенерированный

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

4
libs/shared/cms/src/__generated__/index.ts сгенерированный
Просмотреть файл

@ -1,2 +1,2 @@
export * from './fragment-masking'; export * from "./fragment-masking";
export * from './gql'; export * from "./gql";

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

@ -4,7 +4,6 @@
export * from './lib/cms.error'; export * from './lib/cms.error';
export * from './lib/constants'; export * from './lib/constants';
export * from './lib/factories';
export * from './lib/product-configuration.manager'; export * from './lib/product-configuration.manager';
export * from './lib/queries/capability-service-by-plan-ids'; export * from './lib/queries/capability-service-by-plan-ids';
export * from './lib/queries/eligibility-content-by-offering'; export * from './lib/queries/eligibility-content-by-offering';

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

@ -1,41 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { ApolloQueryResult, NetworkStatus } from '@apollo/client';
import { faker } from '@faker-js/faker';
import { TypedDocumentNode } from '@graphql-typed-document-node/core';
import { ContentfulErrorResponse } from './types';
/**
* Generates a graphql response from the contentful client based on the passed query.
* Use one of the query factories to provide data for the factory result.
*
* @param query The query to generate a result for
* @param data The result of a QueryFactory matching the query passed
*/
export const ContentfulClientQueryFactory = <Result, Variables>(
query: TypedDocumentNode<Result, Variables>,
data: Result,
override?: ApolloQueryResult<Result>
): ApolloQueryResult<Result> => ({
data: data, // Must be used to negotiate the type inference for Result
loading: false,
networkStatus: NetworkStatus.ready,
...override,
});
export const ContentfulCDNErrorFactory = (
override?: ContentfulErrorResponse
): ContentfulErrorResponse => ({
sys: { type: 'Error', id: faker.string.alpha() },
message: faker.string.alpha(),
requestId: faker.string.uuid(),
...override,
});
export const StrapiEntityFactory = <T>(attributes: T) => {
return {
attributes,
};
};

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

@ -15,20 +15,16 @@ import {
import { MockFirestoreProvider } from '@fxa/shared/db/firestore'; import { MockFirestoreProvider } from '@fxa/shared/db/firestore';
import { MockStatsDProvider, StatsDService } from '@fxa/shared/metrics/statsd'; import { MockStatsDProvider, StatsDService } from '@fxa/shared/metrics/statsd';
import { import {
CapabilityPurchaseResult,
CapabilityPurchaseResultFactory, CapabilityPurchaseResultFactory,
CapabilityServiceByPlanIdsQueryFactory, CapabilityServiceByPlanIdsQueryFactory,
CapabilityServiceByPlanIdsResultUtil, CapabilityServiceByPlanIdsResultUtil,
EligibilityContentByOfferingResultUtil, EligibilityContentByOfferingResultUtil,
EligibilityContentByPlanIdsQueryFactory, EligibilityContentByPlanIdsQueryFactory,
EligibilityContentByPlanIdsResultUtil, EligibilityContentByPlanIdsResultUtil,
EligibilityPurchaseResult,
EligibilityPurchaseResultFactory, EligibilityPurchaseResultFactory,
ProductConfigError, ProductConfigError,
ServicesWithCapabilitiesQueryFactory, ServicesWithCapabilitiesQueryFactory,
ServicesWithCapabilitiesResultUtil, ServicesWithCapabilitiesResultUtil,
StrapiEntity,
StrapiEntityFactory,
} from '../../src'; } from '../../src';
import { ProductConfigurationManager } from './product-configuration.manager'; import { ProductConfigurationManager } from './product-configuration.manager';
import { import {
@ -88,14 +84,7 @@ describe('productConfigurationManager', () => {
it('should call statsd for incoming events', async () => { it('should call statsd for incoming events', async () => {
const queryData = EligibilityContentByPlanIdsQueryFactory({ const queryData = EligibilityContentByPlanIdsQueryFactory({
purchases: { purchases: [],
data: [],
meta: {
pagination: {
total: 0,
},
},
},
}); });
jest.spyOn(strapiClient.client, 'request').mockResolvedValue(queryData); jest.spyOn(strapiClient.client, 'request').mockResolvedValue(queryData);
jest.spyOn(mockStatsd, 'timing'); jest.spyOn(mockStatsd, 'timing');
@ -139,7 +128,7 @@ describe('productConfigurationManager', () => {
describe('getEligibilityContentByOffering', () => { describe('getEligibilityContentByOffering', () => {
it('should return empty result', async () => { it('should return empty result', async () => {
const queryData = EligibilityContentByOfferingQueryFactory({ const queryData = EligibilityContentByOfferingQueryFactory({
offerings: { data: [] }, offerings: [],
}); });
jest.spyOn(strapiClient, 'query').mockResolvedValue(queryData); jest.spyOn(strapiClient, 'query').mockResolvedValue(queryData);
@ -154,14 +143,10 @@ describe('productConfigurationManager', () => {
it('should return successfully with results', async () => { it('should return successfully with results', async () => {
const apiIdentifier = 'test'; const apiIdentifier = 'test';
const offeringResult = [ const offeringResult = [
StrapiEntityFactory( EligibilityContentOfferingResultFactory({ apiIdentifier }),
EligibilityContentOfferingResultFactory({ apiIdentifier })
),
]; ];
const queryData = EligibilityContentByOfferingQueryFactory({ const queryData = EligibilityContentByOfferingQueryFactory({
offerings: { offerings: offeringResult,
data: offeringResult,
},
}); });
jest.spyOn(strapiClient, 'query').mockResolvedValue(queryData); jest.spyOn(strapiClient, 'query').mockResolvedValue(queryData);
@ -178,7 +163,7 @@ describe('productConfigurationManager', () => {
describe('getPageContentForOffering', () => { describe('getPageContentForOffering', () => {
it('should return empty result', async () => { it('should return empty result', async () => {
const queryData = PageContentForOfferingQueryFactory({ const queryData = PageContentForOfferingQueryFactory({
offerings: { data: [], meta: { pagination: { total: 0 } } }, offerings: [],
}); });
jest.spyOn(strapiClient, 'query').mockResolvedValue(queryData); jest.spyOn(strapiClient, 'query').mockResolvedValue(queryData);
@ -190,23 +175,16 @@ describe('productConfigurationManager', () => {
'en' 'en'
); );
expect(result).toBeInstanceOf(PageContentForOfferingResultUtil); expect(result).toBeInstanceOf(PageContentForOfferingResultUtil);
expect(result.offerings.data).toHaveLength(0); expect(result.offerings).toHaveLength(0);
}); });
it('should return successfully with page content for offering', async () => { it('should return successfully with page content for offering', async () => {
const apiIdentifier = 'test'; const apiIdentifier = 'test';
const offeringResult = [ const offeringResult = PageContentOfferingResultFactory({
StrapiEntityFactory( apiIdentifier,
PageContentOfferingResultFactory({ });
apiIdentifier,
})
),
];
const queryData = PageContentForOfferingQueryFactory({ const queryData = PageContentForOfferingQueryFactory({
offerings: { offerings: [offeringResult],
data: offeringResult,
meta: { pagination: { total: offeringResult.length } },
},
}); });
jest.spyOn(strapiClient, 'query').mockResolvedValue(queryData); jest.spyOn(strapiClient, 'query').mockResolvedValue(queryData);
@ -218,23 +196,14 @@ describe('productConfigurationManager', () => {
'en' 'en'
); );
expect(result).toBeInstanceOf(PageContentForOfferingResultUtil); expect(result).toBeInstanceOf(PageContentForOfferingResultUtil);
expect( expect(result.getOffering().defaultPurchase.purchaseDetails).toEqual({
result.getOffering().defaultPurchase.data.attributes.purchaseDetails
.data.attributes
).toEqual({
...result.purchaseDetailsTransform( ...result.purchaseDetailsTransform(
offeringResult[0].attributes.defaultPurchase?.data.attributes offeringResult.defaultPurchase?.purchaseDetails
.purchaseDetails.data.attributes
), ),
localizations: { localizations:
data: offeringResult[0].attributes.defaultPurchase?.data.attributes.purchaseDetails.data.attributes.localizations.data.map( offeringResult.defaultPurchase.purchaseDetails.localizations.map(
(localization) => ({ (localization) => result.purchaseDetailsTransform(localization)
attributes: result.purchaseDetailsTransform(
localization.attributes
),
})
), ),
},
}); });
}); });
}); });
@ -242,14 +211,7 @@ describe('productConfigurationManager', () => {
describe('getPurchaseDetailsForEligibility', () => { describe('getPurchaseDetailsForEligibility', () => {
it('should return empty result', async () => { it('should return empty result', async () => {
const queryData = EligibilityContentByPlanIdsQueryFactory({ const queryData = EligibilityContentByPlanIdsQueryFactory({
purchases: { purchases: [],
data: [],
meta: {
pagination: {
total: 0,
},
},
},
}); });
jest.spyOn(strapiClient, 'query').mockResolvedValue(queryData); jest.spyOn(strapiClient, 'query').mockResolvedValue(queryData);
@ -260,27 +222,18 @@ describe('productConfigurationManager', () => {
]); ]);
expect(result).toBeInstanceOf(EligibilityContentByPlanIdsResultUtil); expect(result).toBeInstanceOf(EligibilityContentByPlanIdsResultUtil);
expect(result.offeringForPlanId('test')).toBeUndefined; expect(result.offeringForPlanId('test')).toBeUndefined;
expect(result.purchases.data).toHaveLength(0); expect(result.purchases).toHaveLength(0);
}); });
it('should return successfully with subgroups and offering', async () => { it('should return successfully with subgroups and offering', async () => {
const planId = 'test'; const planId = 'test';
const purchaseResult = [ const purchaseResult = [
StrapiEntityFactory( EligibilityPurchaseResultFactory({
EligibilityPurchaseResultFactory({ stripePlanChoices: [{ stripePlanChoice: planId }],
stripePlanChoices: [{ stripePlanChoice: planId }], }),
})
),
]; ];
const queryData = EligibilityContentByPlanIdsQueryFactory({ const queryData = EligibilityContentByPlanIdsQueryFactory({
purchases: { purchases: purchaseResult,
data: purchaseResult,
meta: {
pagination: {
total: purchaseResult.length,
},
},
},
}); });
jest.spyOn(strapiClient, 'query').mockResolvedValue(queryData); jest.spyOn(strapiClient, 'query').mockResolvedValue(queryData);
@ -290,27 +243,17 @@ describe('productConfigurationManager', () => {
'test', 'test',
]); ]);
expect(result).toBeInstanceOf(EligibilityContentByPlanIdsResultUtil); expect(result).toBeInstanceOf(EligibilityContentByPlanIdsResultUtil);
expect(result.offeringForPlanId(planId)?.subGroups.data).toHaveLength(1); expect(result.offeringForPlanId(planId)?.subGroups).toHaveLength(1);
expect(result.offeringForPlanId(planId)).toBeDefined(); expect(result.offeringForPlanId(planId)).toBeDefined();
}); });
it('should return successfully with paging', async () => { it('should return successfully', async () => {
const pageSize = 20; const purchaseResult = [
const purchaseResult: StrapiEntity<EligibilityPurchaseResult>[] = []; EligibilityPurchaseResultFactory(),
for (let i = 0; i < pageSize + 1; i += 1) { EligibilityPurchaseResultFactory(),
purchaseResult.push( ];
StrapiEntityFactory(EligibilityPurchaseResultFactory())
);
}
const queryData = EligibilityContentByPlanIdsQueryFactory({ const queryData = EligibilityContentByPlanIdsQueryFactory({
purchases: { purchases: purchaseResult,
data: purchaseResult,
meta: {
pagination: {
total: purchaseResult.length,
},
},
},
}); });
jest.spyOn(strapiClient, 'query').mockResolvedValue(queryData); jest.spyOn(strapiClient, 'query').mockResolvedValue(queryData);
@ -320,21 +263,14 @@ describe('productConfigurationManager', () => {
'test', 'test',
]); ]);
expect(result).toBeInstanceOf(EligibilityContentByPlanIdsResultUtil); expect(result).toBeInstanceOf(EligibilityContentByPlanIdsResultUtil);
expect(strapiClient.query).toBeCalledTimes(2); expect(strapiClient.query).toBeCalledTimes(1);
}); });
}); });
describe('getPurchaseDetailsForCapabilityServiceByPlanId', () => { describe('getPurchaseDetailsForCapabilityServiceByPlanId', () => {
it('should return empty result', async () => { it('should return empty result', async () => {
const queryData = CapabilityServiceByPlanIdsQueryFactory({ const queryData = CapabilityServiceByPlanIdsQueryFactory({
purchases: { purchases: [],
data: [],
meta: {
pagination: {
total: 0,
},
},
},
}); });
jest.spyOn(strapiClient, 'query').mockResolvedValue(queryData); jest.spyOn(strapiClient, 'query').mockResolvedValue(queryData);
@ -349,22 +285,11 @@ describe('productConfigurationManager', () => {
it('should return successfully with results', async () => { it('should return successfully with results', async () => {
const planId = 'test'; const planId = 'test';
const purchaseResult = [ const purchaseResult = CapabilityPurchaseResultFactory({
StrapiEntityFactory( stripePlanChoices: [{ stripePlanChoice: planId }],
CapabilityPurchaseResultFactory({ });
stripePlanChoices: [{ stripePlanChoice: planId }],
})
),
];
const queryData = CapabilityServiceByPlanIdsQueryFactory({ const queryData = CapabilityServiceByPlanIdsQueryFactory({
purchases: { purchases: [purchaseResult],
data: purchaseResult,
meta: {
pagination: {
total: purchaseResult.length,
},
},
},
}); });
jest.spyOn(strapiClient, 'query').mockResolvedValue(queryData); jest.spyOn(strapiClient, 'query').mockResolvedValue(queryData);
@ -377,23 +302,13 @@ describe('productConfigurationManager', () => {
expect(result.capabilityOfferingForPlanId(planId)).toBeDefined(); expect(result.capabilityOfferingForPlanId(planId)).toBeDefined();
}); });
it('should return successfully with paging', async () => { it('should return successfully', async () => {
const pageSize = 20; const purchaseResult = [
const purchaseResult: StrapiEntity<CapabilityPurchaseResult>[] = []; CapabilityPurchaseResultFactory(),
for (let i = 0; i < pageSize + 1; i += 1) { CapabilityPurchaseResultFactory(),
purchaseResult.push( ];
StrapiEntityFactory(CapabilityPurchaseResultFactory())
);
}
const queryData = CapabilityServiceByPlanIdsQueryFactory({ const queryData = CapabilityServiceByPlanIdsQueryFactory({
purchases: { purchases: purchaseResult,
data: purchaseResult,
meta: {
pagination: {
total: purchaseResult.length,
},
},
},
}); });
jest.spyOn(strapiClient, 'query').mockResolvedValue(queryData); jest.spyOn(strapiClient, 'query').mockResolvedValue(queryData);
@ -403,23 +318,21 @@ describe('productConfigurationManager', () => {
['test'] ['test']
); );
expect(result).toBeInstanceOf(CapabilityServiceByPlanIdsResultUtil); expect(result).toBeInstanceOf(CapabilityServiceByPlanIdsResultUtil);
expect(strapiClient.query).toBeCalledTimes(2); expect(strapiClient.query).toBeCalledTimes(1);
}); });
}); });
describe('getServicesWithCapabilities', () => { describe('getServicesWithCapabilities', () => {
it('should return results', async () => { it('should return results', async () => {
const queryData = ServicesWithCapabilitiesQueryFactory({ const queryData = ServicesWithCapabilitiesQueryFactory({
services: { services: [],
data: [],
},
}); });
jest.spyOn(strapiClient, 'query').mockResolvedValue(queryData); jest.spyOn(strapiClient, 'query').mockResolvedValue(queryData);
const result = const result =
await productConfigurationManager.getServicesWithCapabilities(); await productConfigurationManager.getServicesWithCapabilities();
expect(result).toBeInstanceOf(ServicesWithCapabilitiesResultUtil); expect(result).toBeInstanceOf(ServicesWithCapabilitiesResultUtil);
expect(result.services.data).toHaveLength(0); expect(result.services).toHaveLength(0);
}); });
it('should return successfully with services and capabilities', async () => { it('should return successfully with services and capabilities', async () => {
@ -430,7 +343,7 @@ describe('productConfigurationManager', () => {
const result = const result =
await productConfigurationManager.getServicesWithCapabilities(); await productConfigurationManager.getServicesWithCapabilities();
expect(result).toBeInstanceOf(ServicesWithCapabilitiesResultUtil); expect(result).toBeInstanceOf(ServicesWithCapabilitiesResultUtil);
expect(result.services.data).toHaveLength(1); expect(result.services).toHaveLength(1);
}); });
}); });
@ -438,7 +351,7 @@ describe('productConfigurationManager', () => {
it('should return empty result', async () => { it('should return empty result', async () => {
const queryData = const queryData =
PurchaseWithDetailsOfferingContentByPlanIdsResultFactory({ PurchaseWithDetailsOfferingContentByPlanIdsResultFactory({
purchases: { data: [] }, purchases: [],
}); });
jest.spyOn(strapiClient, 'query').mockResolvedValue(queryData); jest.spyOn(strapiClient, 'query').mockResolvedValue(queryData);
jest.spyOn(strapiClient, 'getLocale').mockResolvedValue('en'); jest.spyOn(strapiClient, 'getLocale').mockResolvedValue('en');
@ -449,13 +362,13 @@ describe('productConfigurationManager', () => {
'en' 'en'
); );
expect(result).toBeInstanceOf(PurchaseWithDetailsOfferingContentUtil); expect(result).toBeInstanceOf(PurchaseWithDetailsOfferingContentUtil);
expect(result.purchases.data).toHaveLength(0); expect(result.purchases).toHaveLength(0);
}); });
it('should return successfully with purchase details and offering', async () => { it('should return successfully with purchase details and offering', async () => {
const queryData = const queryData =
PurchaseWithDetailsOfferingContentByPlanIdsResultFactory(); PurchaseWithDetailsOfferingContentByPlanIdsResultFactory();
const queryDataItem = queryData.purchases.data[0]; const queryDataItem = queryData.purchases[0];
jest.spyOn(strapiClient, 'query').mockResolvedValue(queryData); jest.spyOn(strapiClient, 'query').mockResolvedValue(queryData);
jest.spyOn(strapiClient, 'getLocale').mockResolvedValue('en'); jest.spyOn(strapiClient, 'getLocale').mockResolvedValue('en');
@ -465,31 +378,22 @@ describe('productConfigurationManager', () => {
['test'], ['test'],
'en' 'en'
); );
const { stripePlanChoice } = const { stripePlanChoice } = result.purchases[0].stripePlanChoices?.[0];
result.purchases.data[0].attributes.stripePlanChoices?.[0];
expect(result).toBeInstanceOf(PurchaseWithDetailsOfferingContentUtil); expect(result).toBeInstanceOf(PurchaseWithDetailsOfferingContentUtil);
expect( expect(
result.transformedPurchaseWithCommonContentForPlanId( result.transformedPurchaseWithCommonContentForPlanId(
stripePlanChoice ?? '' stripePlanChoice ?? ''
)?.offering )?.offering
).toEqual(queryDataItem.attributes.offering); ).toEqual(queryDataItem.offering);
expect( expect(
result.transformedPurchaseWithCommonContentForPlanId( result.transformedPurchaseWithCommonContentForPlanId(
stripePlanChoice ?? '' stripePlanChoice ?? ''
)?.purchaseDetails.data.attributes )?.purchaseDetails
).toEqual({ ).toEqual({
...result.purchaseDetailsTransform( ...result.purchaseDetailsTransform(queryDataItem.purchaseDetails),
queryDataItem.attributes.purchaseDetails.data.attributes localizations: queryDataItem.purchaseDetails.localizations.map(
(localization) => result.purchaseDetailsTransform(localization)
), ),
localizations: {
data: queryDataItem.attributes.purchaseDetails.data.attributes.localizations.data.map(
(localization) => ({
attributes: result.purchaseDetailsTransform(
localization.attributes
),
})
),
},
}); });
}); });
}); });
@ -500,11 +404,7 @@ describe('productConfigurationManager', () => {
const mockPlan = StripePlanFactory(); const mockPlan = StripePlanFactory();
const mockOffering = EligibilityContentOfferingResultFactory({ const mockOffering = EligibilityContentOfferingResultFactory({
defaultPurchase: { defaultPurchase: {
data: { stripePlanChoices: [{ stripePlanChoice: mockPlan.id }],
attributes: {
stripePlanChoices: [{ stripePlanChoice: mockPlan.id }],
},
},
}, },
}); });
const mockOfferingResult = {} as EligibilityContentByOfferingResultUtil; const mockOfferingResult = {} as EligibilityContentByOfferingResultUtil;
@ -528,11 +428,7 @@ describe('productConfigurationManager', () => {
const mockInterval = SubplatInterval.Monthly; const mockInterval = SubplatInterval.Monthly;
const mockOffering = EligibilityContentOfferingResultFactory({ const mockOffering = EligibilityContentOfferingResultFactory({
defaultPurchase: { defaultPurchase: {
data: { stripePlanChoices: [{ stripePlanChoice: mockPrice.id }],
attributes: {
stripePlanChoices: [{ stripePlanChoice: mockPrice.id }],
},
},
}, },
}); });

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

@ -112,66 +112,39 @@ export class ProductConfigurationManager {
async getPurchaseDetailsForCapabilityServiceByPlanIds( async getPurchaseDetailsForCapabilityServiceByPlanIds(
stripePlanIds: string[] stripePlanIds: string[]
): Promise<CapabilityServiceByPlanIdsResultUtil> { ): Promise<CapabilityServiceByPlanIdsResultUtil> {
let total: number | undefined; const queryResult = await this.strapiClient.query(
let count = 0; capabilityServiceByPlanIdsQuery,
const queryResults: DeepNonNullable<CapabilityServiceByPlanIdsQuery>[] = []; {
const pageSize = 20; locale: DEFAULT_LOCALE,
stripePlanIds,
}
);
while (total === undefined || count < total) { return new CapabilityServiceByPlanIdsResultUtil(
const queryResult = (await this.strapiClient.query( queryResult as DeepNonNullable<CapabilityServiceByPlanIdsQuery>
capabilityServiceByPlanIdsQuery, );
{
skip: count,
limit: pageSize,
locale: DEFAULT_LOCALE,
stripePlanIds,
}
)) as DeepNonNullable<CapabilityServiceByPlanIdsQuery>;
queryResults.push(queryResult);
count += pageSize;
total = queryResult.purchases.meta.pagination.total;
}
return new CapabilityServiceByPlanIdsResultUtil(queryResults);
} }
async getPurchaseDetailsForEligibility( async getPurchaseDetailsForEligibility(
stripePlanIds: string[] stripePlanIds: string[]
): Promise<EligibilityContentByPlanIdsResultUtil> { ): Promise<EligibilityContentByPlanIdsResultUtil> {
let total: number | undefined; const queryResult = await this.strapiClient.query(
let count = 0; eligibilityContentByPlanIdsQuery,
const queryResults: DeepNonNullable<EligibilityContentByPlanIdsQuery>[] = {
[]; locale: DEFAULT_LOCALE,
const pageSize = 20; stripePlanIds,
}
);
while (total === undefined || count < total) { return new EligibilityContentByPlanIdsResultUtil(
const queryResult = (await this.strapiClient.query( queryResult as DeepNonNullable<EligibilityContentByPlanIdsQuery>
eligibilityContentByPlanIdsQuery, );
{
skip: count,
limit: pageSize,
locale: DEFAULT_LOCALE,
stripePlanIds,
}
)) as DeepNonNullable<EligibilityContentByPlanIdsQuery>;
queryResults.push(queryResult);
count += pageSize;
total = queryResult.purchases.meta.pagination.total;
}
return new EligibilityContentByPlanIdsResultUtil(queryResults);
} }
async getServicesWithCapabilities(): Promise<ServicesWithCapabilitiesResultUtil> { async getServicesWithCapabilities(): Promise<ServicesWithCapabilitiesResultUtil> {
const queryResult = await this.strapiClient.query( const queryResult = await this.strapiClient.query(
servicesWithCapabilitiesQuery, servicesWithCapabilitiesQuery,
{ {}
skip: 0,
limit: 100,
locale: DEFAULT_LOCALE,
}
); );
return new ServicesWithCapabilitiesResultUtil( return new ServicesWithCapabilitiesResultUtil(
@ -184,30 +157,18 @@ export class ProductConfigurationManager {
acceptLanguage: string acceptLanguage: string
): Promise<PurchaseWithDetailsOfferingContentUtil> { ): Promise<PurchaseWithDetailsOfferingContentUtil> {
const locale = await this.strapiClient.getLocale(acceptLanguage); const locale = await this.strapiClient.getLocale(acceptLanguage);
const queryResults: DeepNonNullable<PurchaseWithDetailsOfferingContentQuery>[] =
[];
const stripePlans: string[][] = [];
// reduce query size by making multiple calls to CMS const queryResult = await this.strapiClient.query(
for (let i = 0; i < stripePlanIds.length; i += 100) { purchaseWithDetailsOfferingContentQuery,
stripePlans.push(stripePlanIds.slice(i, i + 100)); {
} locale,
stripePlanIds,
}
);
while (stripePlans.length > 0) { return new PurchaseWithDetailsOfferingContentUtil(
const queryResult = (await this.strapiClient.query( queryResult as DeepNonNullable<PurchaseWithDetailsOfferingContentQuery>
purchaseWithDetailsOfferingContentQuery, );
{
skip: 0,
limit: 100,
locale,
stripePlanIds: stripePlans[0],
}
)) as DeepNonNullable<PurchaseWithDetailsOfferingContentQuery>;
queryResults.push(queryResult);
stripePlans.shift();
}
return new PurchaseWithDetailsOfferingContentUtil(queryResults);
} }
async getOfferingPlanIds(apiIdentifier: string) { async getOfferingPlanIds(apiIdentifier: string) {
@ -215,10 +176,9 @@ export class ProductConfigurationManager {
apiIdentifier apiIdentifier
); );
const offering = offeringResult.getOffering(); const offering = offeringResult.getOffering();
const planIds = const planIds = offering.defaultPurchase.stripePlanChoices.map(
offering.defaultPurchase.data.attributes.stripePlanChoices.map( (el) => el.stripePlanChoice
(el) => el.stripePlanChoice );
);
return planIds; return planIds;
} }

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

@ -11,21 +11,12 @@ import {
CapabilityCapabilitiesResult, CapabilityCapabilitiesResult,
CapabilityServicesResult, CapabilityServicesResult,
} from '.'; } from '.';
import { StrapiEntityFactory } from '../../factories';
export const CapabilityServiceByPlanIdsQueryFactory = ( export const CapabilityServiceByPlanIdsQueryFactory = (
override?: Partial<CapabilityServiceByPlanIdsQuery> override?: Partial<CapabilityServiceByPlanIdsQuery>
): CapabilityServiceByPlanIdsQuery => { ): CapabilityServiceByPlanIdsQuery => {
const data = [StrapiEntityFactory(CapabilityPurchaseResultFactory())];
return { return {
purchases: { purchases: [CapabilityPurchaseResultFactory()],
meta: {
pagination: {
total: data.length,
},
},
data,
},
...override, ...override,
}; };
}; };
@ -38,9 +29,7 @@ export const CapabilityPurchaseResultFactory = (
stripePlanChoice: faker.string.sample(), stripePlanChoice: faker.string.sample(),
}, },
], ],
offering: { offering: CapabilityOfferingResultFactory(),
data: StrapiEntityFactory(CapabilityOfferingResultFactory()),
},
...override, ...override,
}); });
@ -53,9 +42,7 @@ export const CapabilityOfferingResultFactory = (
stripeLegacyPlan: faker.string.alpha(10), stripeLegacyPlan: faker.string.alpha(10),
}) })
), ),
capabilities: { capabilities: [CapabilityCapabilitiesResultFactory()],
data: [StrapiEntityFactory(CapabilityCapabilitiesResultFactory())],
},
...override, ...override,
}); });
@ -63,9 +50,7 @@ export const CapabilityCapabilitiesResultFactory = (
override?: Partial<CapabilityCapabilitiesResult> override?: Partial<CapabilityCapabilitiesResult>
): CapabilityCapabilitiesResult => ({ ): CapabilityCapabilitiesResult => ({
slug: faker.string.sample(), slug: faker.string.sample(),
services: { services: [CapabilityServicesResultFactory()],
data: [StrapiEntityFactory(CapabilityServicesResultFactory())],
},
...override, ...override,
}); });

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

@ -5,11 +5,7 @@
import { graphql } from '../../../__generated__/gql'; import { graphql } from '../../../__generated__/gql';
export const capabilityServiceByPlanIdsQuery = graphql(` export const capabilityServiceByPlanIdsQuery = graphql(`
query CapabilityServiceByPlanIds( query CapabilityServiceByPlanIds($stripePlanIds: [String]!) {
$skip: Int!
$limit: Int!
$stripePlanIds: [String]!
) {
purchases( purchases(
filters: { filters: {
or: [ or: [
@ -21,40 +17,19 @@ export const capabilityServiceByPlanIdsQuery = graphql(`
} }
] ]
} }
pagination: { start: $skip, limit: $limit } pagination: { limit: 200 }
) { ) {
meta { stripePlanChoices {
pagination { stripePlanChoice
total
}
} }
data { offering {
attributes { stripeLegacyPlans(pagination: { limit: 200 }) {
stripePlanChoices { stripeLegacyPlan
stripePlanChoice }
} capabilities {
offering { slug
data { services {
attributes { oauthClientId
stripeLegacyPlans(pagination: { limit: 200 }) {
stripeLegacyPlan
}
capabilities {
data {
attributes {
slug
services {
data {
attributes {
oauthClientId
}
}
}
}
}
}
}
}
} }
} }
} }

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

@ -2,44 +2,29 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { StrapiEntity } from '../../types';
export interface CapabilityServicesResult { export interface CapabilityServicesResult {
oauthClientId: string; oauthClientId: string;
} }
export interface CapabilityCapabilitiesResult { export interface CapabilityCapabilitiesResult {
slug: string; slug: string;
services: { services: CapabilityServicesResult[];
data: StrapiEntity<CapabilityServicesResult>[];
};
} }
export interface CapabilityOfferingResult { export interface CapabilityOfferingResult {
stripeLegacyPlans: { stripeLegacyPlans: {
stripeLegacyPlan: string; stripeLegacyPlan: string;
}[]; }[];
capabilities: { capabilities: CapabilityCapabilitiesResult[];
data: StrapiEntity<CapabilityCapabilitiesResult>[];
};
} }
export interface CapabilityPurchaseResult { export interface CapabilityPurchaseResult {
stripePlanChoices: { stripePlanChoices: {
stripePlanChoice: string; stripePlanChoice: string;
}[]; }[];
offering: { offering: CapabilityOfferingResult;
data: StrapiEntity<CapabilityOfferingResult>;
};
} }
export interface CapabilityServiceByPlanIdsResult { export interface CapabilityServiceByPlanIdsResult {
purchases: { purchases: CapabilityPurchaseResult[];
meta: {
pagination: {
total: number;
};
};
data: StrapiEntity<CapabilityPurchaseResult>[];
};
} }

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

@ -9,15 +9,12 @@ import { CapabilityServiceByPlanIdsResultUtil } from './util';
describe('CapabilityServiceByPlanIdsResultUtil', () => { describe('CapabilityServiceByPlanIdsResultUtil', () => {
it('should create a util from response', () => { it('should create a util from response', () => {
const result = CapabilityServiceByPlanIdsQueryFactory(); const result = CapabilityServiceByPlanIdsQueryFactory();
const purchase = result.purchases?.data[0]; const purchase = result.purchases[0];
const planId = purchase?.attributes?.stripePlanChoices?.[0]; const planId = purchase?.stripePlanChoices?.[0];
const legacyPlanId = const legacyPlanId = purchase?.offering?.stripeLegacyPlans?.[0];
purchase?.attributes?.offering?.data?.attributes?.stripeLegacyPlans?.[0]; const util = new CapabilityServiceByPlanIdsResultUtil(
const result2 = CapabilityServiceByPlanIdsQueryFactory(); result as CapabilityServiceByPlanIdsResult
const util = new CapabilityServiceByPlanIdsResultUtil([ );
result as CapabilityServiceByPlanIdsResult,
result2 as CapabilityServiceByPlanIdsResult,
]);
expect(util).toBeDefined(); expect(util).toBeDefined();
expect( expect(

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

@ -11,20 +11,15 @@ import {
export class CapabilityServiceByPlanIdsResultUtil { export class CapabilityServiceByPlanIdsResultUtil {
private purchaseByPlanId: Record<string, CapabilityPurchaseResult> = {}; private purchaseByPlanId: Record<string, CapabilityPurchaseResult> = {};
constructor(rawResults: CapabilityServiceByPlanIdsResult[]) { constructor(rawResult: CapabilityServiceByPlanIdsResult) {
for (const rawResult of rawResults) { for (const purchase of rawResult.purchases) {
for (const purchase of rawResult.purchases.data) { for (const stripePlanChoice of purchase.stripePlanChoices ?? []) {
purchase.attributes.stripePlanChoices?.forEach( this.purchaseByPlanId[stripePlanChoice.stripePlanChoice] = purchase;
({ stripePlanChoice }) => { }
this.purchaseByPlanId[stripePlanChoice] = purchase.attributes;
}
);
purchase.attributes.offering.data.attributes.stripeLegacyPlans?.forEach( for (const stripeLegacyPlan of purchase.offering.stripeLegacyPlans ??
({ stripeLegacyPlan }) => { []) {
this.purchaseByPlanId[stripeLegacyPlan] = purchase.attributes; this.purchaseByPlanId[stripeLegacyPlan.stripeLegacyPlan] = purchase;
}
);
} }
} }
} }
@ -32,6 +27,6 @@ export class CapabilityServiceByPlanIdsResultUtil {
capabilityOfferingForPlanId( capabilityOfferingForPlanId(
planId: string planId: string
): CapabilityOfferingResult | undefined { ): CapabilityOfferingResult | undefined {
return this.purchaseByPlanId[planId]?.offering.data.attributes; return this.purchaseByPlanId[planId]?.offering;
} }
} }

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

@ -11,15 +11,12 @@ import {
EligibilityContentSubgroupResult, EligibilityContentSubgroupResult,
EligibilityContentByOfferingResult, EligibilityContentByOfferingResult,
} from '.'; } from '.';
import { StrapiEntityFactory } from '../../factories';
export const EligibilityContentByOfferingQueryFactory = ( export const EligibilityContentByOfferingQueryFactory = (
override?: Partial<EligibilityContentByOfferingQuery> override?: Partial<EligibilityContentByOfferingQuery>
): EligibilityContentByOfferingQuery => { ): EligibilityContentByOfferingQuery => {
return { return {
offerings: { offerings: [EligibilityContentOfferingResultFactory()],
data: [StrapiEntityFactory(EligibilityContentOfferingResultFactory())],
},
...override, ...override,
}; };
}; };
@ -28,9 +25,7 @@ export const EligibilityContentByOfferingResultFactory = (
override?: Partial<EligibilityContentByOfferingResult> override?: Partial<EligibilityContentByOfferingResult>
): EligibilityContentByOfferingResult => { ): EligibilityContentByOfferingResult => {
return { return {
offerings: { offerings: [EligibilityContentOfferingResultFactory()],
data: [StrapiEntityFactory(EligibilityContentOfferingResultFactory())],
},
...override, ...override,
}; };
}; };
@ -41,17 +36,13 @@ export const EligibilityContentOfferingResultFactory = (
apiIdentifier: faker.string.sample(), apiIdentifier: faker.string.sample(),
stripeProductId: faker.string.sample(), stripeProductId: faker.string.sample(),
defaultPurchase: { defaultPurchase: {
data: StrapiEntityFactory({ stripePlanChoices: [
stripePlanChoices: [ {
{ stripePlanChoice: faker.string.sample(),
stripePlanChoice: faker.string.sample(), },
}, ],
],
}),
},
subGroups: {
data: [StrapiEntityFactory(EligibilityContentSubgroupResultFactory())],
}, },
subGroups: [EligibilityContentSubgroupResultFactory()],
...override, ...override,
}); });
@ -59,23 +50,7 @@ export const EligibilityContentSubgroupResultFactory = (
override?: Partial<EligibilityContentSubgroupResult> override?: Partial<EligibilityContentSubgroupResult>
): EligibilityContentSubgroupResult => ({ ): EligibilityContentSubgroupResult => ({
groupName: faker.string.sample(), groupName: faker.string.sample(),
offerings: { offerings: [EligibilityContentSubgroupOfferingResultFactory()],
data: [
StrapiEntityFactory({
apiIdentifier: faker.string.sample(),
stripeProductId: faker.string.sample(),
defaultPurchase: {
data: StrapiEntityFactory({
stripePlanChoices: [
{
stripePlanChoice: faker.string.sample(),
},
],
}),
},
}),
],
},
...override, ...override,
}); });
@ -85,13 +60,11 @@ export const EligibilityContentSubgroupOfferingResultFactory = (
apiIdentifier: faker.string.sample(), apiIdentifier: faker.string.sample(),
stripeProductId: faker.string.sample(), stripeProductId: faker.string.sample(),
defaultPurchase: { defaultPurchase: {
data: StrapiEntityFactory({ stripePlanChoices: [
stripePlanChoices: [ {
{ stripePlanChoice: faker.string.sample(),
stripePlanChoice: faker.string.sample(), },
}, ],
],
}),
}, },
...override, ...override,
}); });

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

@ -7,44 +7,24 @@ import { graphql } from '../../../__generated__/gql';
export const eligibilityContentByOfferingQuery = graphql(` export const eligibilityContentByOfferingQuery = graphql(`
query EligibilityContentByOffering($apiIdentifier: String!) { query EligibilityContentByOffering($apiIdentifier: String!) {
offerings( offerings(
pagination: { start: 0, limit: 2 }
filters: { apiIdentifier: { eq: $apiIdentifier } } filters: { apiIdentifier: { eq: $apiIdentifier } }
pagination: { limit: 200 }
) { ) {
data { apiIdentifier
attributes { stripeProductId
defaultPurchase {
stripePlanChoices {
stripePlanChoice
}
}
subGroups {
groupName
offerings {
apiIdentifier apiIdentifier
stripeProductId stripeProductId
defaultPurchase { defaultPurchase {
data { stripePlanChoices {
attributes { stripePlanChoice
stripePlanChoices {
stripePlanChoice
}
}
}
}
subGroups {
data {
attributes {
groupName
offerings {
data {
attributes {
apiIdentifier
stripeProductId
defaultPurchase {
data {
attributes {
stripePlanChoices {
stripePlanChoice
}
}
}
}
}
}
}
}
} }
} }
} }

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

@ -2,43 +2,32 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { StrapiEntity } from '../../types';
export interface EligibilityContentSubgroupOfferingResult { export interface EligibilityContentSubgroupOfferingResult {
apiIdentifier: string; apiIdentifier: string;
stripeProductId: string; stripeProductId: string;
defaultPurchase: { defaultPurchase: {
data: StrapiEntity<{ stripePlanChoices: {
stripePlanChoices: { stripePlanChoice: string;
stripePlanChoice: string; }[];
}[];
}>;
}; };
} }
export interface EligibilityContentSubgroupResult { export interface EligibilityContentSubgroupResult {
groupName: string; groupName: string;
offerings: { offerings: EligibilityContentSubgroupOfferingResult[];
data: StrapiEntity<EligibilityContentSubgroupOfferingResult>[];
};
} }
export interface EligibilityContentOfferingResult { export interface EligibilityContentOfferingResult {
apiIdentifier: string; apiIdentifier: string;
stripeProductId: string; stripeProductId: string;
defaultPurchase: { defaultPurchase: {
data: StrapiEntity<{ stripePlanChoices: {
stripePlanChoices: { stripePlanChoice: string;
stripePlanChoice: string; }[];
}[];
}>;
};
subGroups: {
data: StrapiEntity<EligibilityContentSubgroupResult>[];
}; };
subGroups: EligibilityContentSubgroupResult[];
} }
export interface EligibilityContentByOfferingResult { export interface EligibilityContentByOfferingResult {
offerings: { offerings: EligibilityContentOfferingResult[];
data: StrapiEntity<EligibilityContentOfferingResult>[];
};
} }

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

@ -8,7 +8,6 @@ import {
EligibilityContentByOfferingResultUtil, EligibilityContentByOfferingResultUtil,
EligibilityContentOfferingResultFactory, EligibilityContentOfferingResultFactory,
} from '.'; } from '.';
import { StrapiEntityFactory } from '../../factories';
describe('EligibilityByOfferingResultUtil', () => { describe('EligibilityByOfferingResultUtil', () => {
it('should create a util from response', () => { it('should create a util from response', () => {
@ -18,12 +17,12 @@ describe('EligibilityByOfferingResultUtil', () => {
); );
expect(util).toBeDefined(); expect(util).toBeDefined();
expect(util.getOffering()).toBeDefined(); expect(util.getOffering()).toBeDefined();
expect(util.offerings.data).toHaveLength(1); expect(util.offerings).toHaveLength(1);
}); });
it('returns empty if no offering is returned', () => { it('returns empty if no offering is returned', () => {
const result = EligibilityContentByOfferingQueryFactory({ const result = EligibilityContentByOfferingQueryFactory({
offerings: { data: [] }, offerings: [],
}); });
const util = new EligibilityContentByOfferingResultUtil( const util = new EligibilityContentByOfferingResultUtil(
result as EligibilityContentByOfferingResult result as EligibilityContentByOfferingResult
@ -34,12 +33,12 @@ describe('EligibilityByOfferingResultUtil', () => {
}); });
it('throws error if more than offering is returned', () => { it('throws error if more than offering is returned', () => {
const data = [ const offerings = [
StrapiEntityFactory(EligibilityContentOfferingResultFactory()), EligibilityContentOfferingResultFactory(),
StrapiEntityFactory(EligibilityContentOfferingResultFactory()), EligibilityContentOfferingResultFactory(),
]; ];
const result = EligibilityContentByOfferingQueryFactory({ const result = EligibilityContentByOfferingQueryFactory({
offerings: { data }, offerings,
}); });
const util = new EligibilityContentByOfferingResultUtil( const util = new EligibilityContentByOfferingResultUtil(
result as EligibilityContentByOfferingResult result as EligibilityContentByOfferingResult

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

@ -11,11 +11,11 @@ export class EligibilityContentByOfferingResultUtil {
constructor(private rawResult: EligibilityContentByOfferingResult) {} constructor(private rawResult: EligibilityContentByOfferingResult) {}
getOffering(): EligibilityContentOfferingResult { getOffering(): EligibilityContentOfferingResult {
const offering = this.offerings.data.at(0); const offering = this.offerings.at(0);
if (!offering) throw Error('getOffering - No offering exists'); if (!offering) throw Error('getOffering - No offering exists');
if (this.offerings.data.length > 1) if (this.offerings.length > 1)
throw Error('getOffering - More than one offering'); throw Error('getOffering - More than one offering');
return offering.attributes; return offering;
} }
get offerings(): EligibilityContentByOfferingResult['offerings'] { get offerings(): EligibilityContentByOfferingResult['offerings'] {

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

@ -12,21 +12,12 @@ import {
EligibilitySubgroupResult, EligibilitySubgroupResult,
type EligibilityContentByPlanIdsResult, type EligibilityContentByPlanIdsResult,
} from '.'; } from '.';
import { StrapiEntityFactory } from '../../factories';
export const EligibilityContentByPlanIdsQueryFactory = ( export const EligibilityContentByPlanIdsQueryFactory = (
override?: Partial<EligibilityContentByPlanIdsQuery> override?: Partial<EligibilityContentByPlanIdsQuery>
): EligibilityContentByPlanIdsQuery => { ): EligibilityContentByPlanIdsQuery => {
const data = [StrapiEntityFactory(EligibilityPurchaseResultFactory())];
return { return {
purchases: { purchases: [EligibilityPurchaseResultFactory()],
meta: {
pagination: {
total: data.length,
},
},
data,
},
...override, ...override,
}; };
}; };
@ -34,16 +25,8 @@ export const EligibilityContentByPlanIdsQueryFactory = (
export const EligibilityContentByPlanIdsResultFactory = ( export const EligibilityContentByPlanIdsResultFactory = (
override?: Partial<EligibilityContentByPlanIdsResult> override?: Partial<EligibilityContentByPlanIdsResult>
): EligibilityContentByPlanIdsResult => { ): EligibilityContentByPlanIdsResult => {
const data = [StrapiEntityFactory(EligibilityPurchaseResultFactory())];
return { return {
purchases: { purchases: [EligibilityPurchaseResultFactory()],
meta: {
pagination: {
total: data.length,
},
},
data,
},
...override, ...override,
}; };
}; };
@ -56,9 +39,7 @@ export const EligibilityPurchaseResultFactory = (
stripePlanChoice: faker.string.sample(), stripePlanChoice: faker.string.sample(),
}, },
], ],
offering: { offering: EligibilityOfferingResultFactory(),
data: StrapiEntityFactory(EligibilityOfferingResultFactory()),
},
...override, ...override,
}); });
@ -73,9 +54,7 @@ export const EligibilityOfferingResultFactory = (
}) })
), ),
countries: [faker.string.sample()], countries: [faker.string.sample()],
subGroups: { subGroups: [EligibilitySubgroupResultFactory()],
data: [StrapiEntityFactory(EligibilitySubgroupResultFactory())],
},
...override, ...override,
}); });
@ -83,9 +62,7 @@ export const EligibilitySubgroupResultFactory = (
override?: Partial<EligibilitySubgroupResult> override?: Partial<EligibilitySubgroupResult>
): EligibilitySubgroupResult => ({ ): EligibilitySubgroupResult => ({
groupName: faker.string.sample(), groupName: faker.string.sample(),
offerings: { offerings: [EligibilitySubgroupOfferingResultFactory()],
data: [StrapiEntityFactory(EligibilitySubgroupOfferingResultFactory())],
},
...override, ...override,
}); });

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

@ -5,13 +5,8 @@
import { graphql } from '../../../__generated__/gql'; import { graphql } from '../../../__generated__/gql';
export const eligibilityContentByPlanIdsQuery = graphql(` export const eligibilityContentByPlanIdsQuery = graphql(`
query EligibilityContentByPlanIds( query EligibilityContentByPlanIds($stripePlanIds: [String]!) {
$skip: Int!
$limit: Int!
$stripePlanIds: [String]!
) {
purchases( purchases(
pagination: { start: $skip, limit: $limit }
filters: { filters: {
or: [ or: [
{ stripePlanChoices: { stripePlanChoice: { in: $stripePlanIds } } } { stripePlanChoices: { stripePlanChoice: { in: $stripePlanIds } } }
@ -22,45 +17,25 @@ export const eligibilityContentByPlanIdsQuery = graphql(`
} }
] ]
} }
pagination: { limit: 200 }
) { ) {
meta { stripePlanChoices {
pagination { stripePlanChoice
total
}
} }
data { offering {
attributes { stripeProductId
stripePlanChoices { stripeLegacyPlans(pagination: { limit: 200 }) {
stripePlanChoice stripeLegacyPlan
} }
offering { countries
data { subGroups {
attributes { groupName
stripeProductId offerings {
stripeLegacyPlans(pagination: { limit: 200 }) { stripeProductId
stripeLegacyPlan stripeLegacyPlans(pagination: { limit: 200 }) {
} stripeLegacyPlan
countries
subGroups {
data {
attributes {
groupName
offerings {
data {
attributes {
stripeProductId
stripeLegacyPlans(pagination: { limit: 200 }) {
stripeLegacyPlan
}
countries
}
}
}
}
}
}
}
} }
countries
} }
} }
} }

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

@ -2,8 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { StrapiEntity } from '../../types';
export interface EligibilitySubgroupOfferingResult { export interface EligibilitySubgroupOfferingResult {
stripeProductId: string; stripeProductId: string;
stripeLegacyPlans: { stripeLegacyPlans: {
@ -14,9 +12,7 @@ export interface EligibilitySubgroupOfferingResult {
export interface EligibilitySubgroupResult { export interface EligibilitySubgroupResult {
groupName: string; groupName: string;
offerings: { offerings: EligibilitySubgroupOfferingResult[];
data: StrapiEntity<EligibilitySubgroupOfferingResult>[];
};
} }
export interface EligibilityOfferingResult { export interface EligibilityOfferingResult {
@ -25,27 +21,16 @@ export interface EligibilityOfferingResult {
stripeLegacyPlan: string; stripeLegacyPlan: string;
}[]; }[];
countries: string[]; countries: string[];
subGroups: { subGroups: EligibilitySubgroupResult[];
data: StrapiEntity<EligibilitySubgroupResult>[];
};
} }
export interface EligibilityPurchaseResult { export interface EligibilityPurchaseResult {
stripePlanChoices: { stripePlanChoices: {
stripePlanChoice: string; stripePlanChoice: string;
}[]; }[];
offering: { offering: EligibilityOfferingResult;
data: StrapiEntity<EligibilityOfferingResult>;
};
} }
export interface EligibilityContentByPlanIdsResult { export interface EligibilityContentByPlanIdsResult {
purchases: { purchases: EligibilityPurchaseResult[];
meta: {
pagination: {
total: number;
};
};
data: StrapiEntity<EligibilityPurchaseResult>[];
};
} }

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

@ -11,13 +11,12 @@ import {
describe('EligibilityContentByPlanIdsResultUtil', () => { describe('EligibilityContentByPlanIdsResultUtil', () => {
it('should create a util from response', () => { it('should create a util from response', () => {
const result = EligibilityContentByPlanIdsQueryFactory(); const result = EligibilityContentByPlanIdsQueryFactory();
const purchase = result.purchases?.data[0]; const purchase = result.purchases[0];
const planId = purchase?.attributes?.stripePlanChoices?.[0]; const planId = purchase?.stripePlanChoices?.[0];
const legacyPlanId = const legacyPlanId = purchase?.offering?.stripeLegacyPlans?.[0];
purchase?.attributes?.offering?.data?.attributes?.stripeLegacyPlans?.[0]; const util = new EligibilityContentByPlanIdsResultUtil(
const util = new EligibilityContentByPlanIdsResultUtil([ result as EligibilityContentByPlanIdsResult
result as EligibilityContentByPlanIdsResult, );
]);
expect(util).toBeDefined(); expect(util).toBeDefined();
expect( expect(
util.offeringForPlanId(planId?.stripePlanChoice ?? '')?.stripeProductId util.offeringForPlanId(planId?.stripePlanChoice ?? '')?.stripeProductId
@ -26,6 +25,6 @@ describe('EligibilityContentByPlanIdsResultUtil', () => {
util.offeringForPlanId(legacyPlanId?.stripeLegacyPlan ?? '') util.offeringForPlanId(legacyPlanId?.stripeLegacyPlan ?? '')
?.stripeProductId ?.stripeProductId
).toBeDefined(); ).toBeDefined();
expect(util.purchases.data.length).toBe(1); expect(util.purchases.length).toBe(1);
}); });
}); });

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

@ -11,45 +11,23 @@ import {
export class EligibilityContentByPlanIdsResultUtil { export class EligibilityContentByPlanIdsResultUtil {
private purchaseByPlanId: Record<string, EligibilityPurchaseResult> = {}; private purchaseByPlanId: Record<string, EligibilityPurchaseResult> = {};
constructor(private rawResults: EligibilityContentByPlanIdsResult[]) { constructor(private rawResult: EligibilityContentByPlanIdsResult) {
for (const rawResult of rawResults) { for (const purchase of rawResult.purchases) {
for (const purchase of rawResult.purchases.data) { purchase.stripePlanChoices?.forEach(({ stripePlanChoice }) => {
purchase.attributes.stripePlanChoices?.forEach( this.purchaseByPlanId[stripePlanChoice] = purchase;
({ stripePlanChoice }) => { });
this.purchaseByPlanId[stripePlanChoice] = purchase.attributes;
}
);
purchase.attributes.offering.data.attributes.stripeLegacyPlans?.forEach( purchase.offering.stripeLegacyPlans?.forEach(({ stripeLegacyPlan }) => {
({ stripeLegacyPlan }) => { this.purchaseByPlanId[stripeLegacyPlan] = purchase;
this.purchaseByPlanId[stripeLegacyPlan] = purchase.attributes; });
}
);
}
} }
} }
offeringForPlanId(planId: string): EligibilityOfferingResult | undefined { offeringForPlanId(planId: string): EligibilityOfferingResult | undefined {
return this.purchaseByPlanId[planId]?.offering.data.attributes; return this.purchaseByPlanId[planId]?.offering;
} }
get purchases(): EligibilityContentByPlanIdsResult['purchases'] { get purchases(): EligibilityPurchaseResult[] {
return { return this.rawResult.purchases;
meta: {
pagination: {
total: this.rawResults
.map((rawResult) => rawResult.purchases.meta.pagination.total)
.reduce((acc, curr) => acc + curr, 0),
},
},
data: [
...new Map(
this.rawResults
.map((rawResult) => rawResult.purchases.data)
.flat()
.map((res) => [JSON.stringify(res), res])
).values(),
],
};
} }
} }

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

@ -5,14 +5,11 @@
import { faker } from '@faker-js/faker'; import { faker } from '@faker-js/faker';
import { Locale, LocalesResult } from '.'; import { Locale, LocalesResult } from '.';
import { StrapiEntityFactory } from '../../factories';
export const LocalesResultFactory = ( export const LocalesResultFactory = (
override?: Partial<LocalesResult> override?: Partial<LocalesResult>
): LocalesResult => ({ ): LocalesResult => ({
i18NLocales: { i18NLocales: [LocaleFactory()],
data: [StrapiEntityFactory(LocaleFactory())],
},
...override, ...override,
}); });

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

@ -7,11 +7,7 @@ import { graphql } from '../../../__generated__/gql';
export const localesQuery = graphql(` export const localesQuery = graphql(`
query Locales { query Locales {
i18NLocales { i18NLocales {
data { code
attributes {
code
}
}
} }
} }
`); `);

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

@ -2,14 +2,10 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { StrapiEntity } from '../../types';
export interface Locale { export interface Locale {
code: string; code: string;
} }
export interface LocalesResult { export interface LocalesResult {
i18NLocales: { i18NLocales: Locale[];
data: StrapiEntity<Locale>[];
};
} }

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

@ -10,14 +10,11 @@ import {
OfferingDefaultPurchaseResult, OfferingDefaultPurchaseResult,
OfferingResult, OfferingResult,
} from '.'; } from '.';
import { StrapiEntityFactory } from '../../factories';
export const OfferingQueryFactory = ( export const OfferingQueryFactory = (
override?: Partial<OfferingQuery> override?: Partial<OfferingQuery>
): OfferingQuery => ({ ): OfferingQuery => ({
offering: { offering: OfferingResultFactory(),
data: StrapiEntityFactory(OfferingResultFactory()),
},
...override, ...override,
}); });
@ -27,9 +24,7 @@ export const OfferingResultFactory = (
return { return {
stripeProductId: faker.string.sample(), stripeProductId: faker.string.sample(),
countries: [faker.string.sample()], countries: [faker.string.sample()],
defaultPurchase: { defaultPurchase: OfferingDefaultPurchaseResultFactory(),
data: StrapiEntityFactory(OfferingDefaultPurchaseResultFactory()),
},
...override, ...override,
}; };
}; };
@ -38,12 +33,8 @@ export const OfferingDefaultPurchaseResultFactory = (
override?: Partial<OfferingDefaultPurchaseResult> override?: Partial<OfferingDefaultPurchaseResult>
): OfferingDefaultPurchaseResult => ({ ): OfferingDefaultPurchaseResult => ({
purchaseDetails: { purchaseDetails: {
data: StrapiEntityFactory({ ...OfferingPurchaseResultFactory(),
...OfferingPurchaseResultFactory(), localizations: [OfferingPurchaseResultFactory()],
localizations: {
data: [StrapiEntityFactory(OfferingPurchaseResultFactory())],
},
}),
}, },
...override, ...override,
}); });

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

@ -6,36 +6,20 @@ import { graphql } from '../../../__generated__/gql';
export const offeringQuery = graphql(` export const offeringQuery = graphql(`
query Offering($id: ID!, $locale: String!) { query Offering($id: ID!, $locale: String!) {
offering(id: $id) { offering(documentId: $id) {
data { stripeProductId
attributes { countries
stripeProductId defaultPurchase {
countries purchaseDetails {
defaultPurchase { productName
data { details
attributes { subtitle
purchaseDetails { webIcon
data { localizations(filters: { locale: { eq: $locale } }) {
attributes { productName
productName details
details subtitle
subtitle webIcon
webIcon
localizations(filters: { locale: { eq: $locale } }) {
data {
attributes {
productName
details
subtitle
webIcon
}
}
}
}
}
}
}
}
} }
} }
} }

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

@ -2,8 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { StrapiEntity } from '../../types';
export interface OfferingPurchaseResult { export interface OfferingPurchaseResult {
productName: string; productName: string;
details: string; details: string;
@ -12,21 +10,13 @@ export interface OfferingPurchaseResult {
} }
export interface OfferingDefaultPurchaseResult { export interface OfferingDefaultPurchaseResult {
purchaseDetails: { purchaseDetails: OfferingPurchaseResult & {
data: StrapiEntity< localizations: OfferingPurchaseResult[];
OfferingPurchaseResult & {
localizations: {
data: StrapiEntity<OfferingPurchaseResult>[];
};
}
>;
}; };
} }
export interface OfferingResult { export interface OfferingResult {
stripeProductId: string; stripeProductId: string;
countries: string[]; countries: string[];
defaultPurchase: { defaultPurchase: OfferingDefaultPurchaseResult;
data: StrapiEntity<OfferingDefaultPurchaseResult>;
};
} }

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

@ -15,19 +15,11 @@ import {
PageContentPurchaseDetailsResult, PageContentPurchaseDetailsResult,
PageContentPurchaseDetailsTransformed, PageContentPurchaseDetailsTransformed,
} from '.'; } from '.';
import { StrapiEntityFactory } from '../../factories';
export const PageContentForOfferingQueryFactory = ( export const PageContentForOfferingQueryFactory = (
override?: Partial<PageContentForOfferingQuery> override?: Partial<PageContentForOfferingQuery>
): PageContentForOfferingQuery => ({ ): PageContentForOfferingQuery => ({
offerings: { offerings: [PageContentOfferingResultFactory()],
meta: {
pagination: {
total: 1,
},
},
data: [StrapiEntityFactory(PageContentOfferingResultFactory())],
},
...override, ...override,
}); });
@ -35,12 +27,8 @@ export const PageContentOfferingDefaultPurchaseResultFactory = (
override?: Partial<PageContentOfferingDefaultPurchaseResult> override?: Partial<PageContentOfferingDefaultPurchaseResult>
): PageContentOfferingDefaultPurchaseResult => ({ ): PageContentOfferingDefaultPurchaseResult => ({
purchaseDetails: { purchaseDetails: {
data: StrapiEntityFactory({ ...PageContentPurchaseDetailsResultFactory(),
...PageContentPurchaseDetailsResultFactory(), localizations: [PageContentPurchaseDetailsResultFactory()],
localizations: {
data: [StrapiEntityFactory(PageContentPurchaseDetailsResultFactory())],
},
}),
}, },
...override, ...override,
}); });
@ -49,14 +37,8 @@ export const PageContentOfferingDefaultPurchaseTransformedFactory = (
override?: Partial<PageContentOfferingDefaultPurchaseTransformed> override?: Partial<PageContentOfferingDefaultPurchaseTransformed>
): PageContentOfferingDefaultPurchaseTransformed => ({ ): PageContentOfferingDefaultPurchaseTransformed => ({
purchaseDetails: { purchaseDetails: {
data: StrapiEntityFactory({ ...PageContentPurchaseDetailsTransformedFactory(),
...PageContentPurchaseDetailsTransformedFactory(), localizations: [PageContentPurchaseDetailsTransformedFactory()],
localizations: {
data: [
StrapiEntityFactory(PageContentPurchaseDetailsTransformedFactory()),
],
},
}),
}, },
...override, ...override,
}); });
@ -66,25 +48,10 @@ export const PageContentOfferingResultFactory = (
): PageContentOfferingResult => ({ ): PageContentOfferingResult => ({
apiIdentifier: faker.string.sample(), apiIdentifier: faker.string.sample(),
stripeProductId: faker.string.sample(), stripeProductId: faker.string.sample(),
defaultPurchase: { defaultPurchase: PageContentOfferingDefaultPurchaseResultFactory(),
data: StrapiEntityFactory({
...PageContentOfferingDefaultPurchaseResultFactory(),
localizations: {
data: [
StrapiEntityFactory(
PageContentOfferingDefaultPurchaseResultFactory()
),
],
},
}),
},
commonContent: { commonContent: {
data: StrapiEntityFactory({ ...PageContentCommonContentResultFactory(),
...PageContentCommonContentResultFactory(), localizations: [PageContentCommonContentResultFactory()],
localizations: {
data: [StrapiEntityFactory(PageContentCommonContentResultFactory())],
},
}),
}, },
...override, ...override,
}); });
@ -93,18 +60,7 @@ export const PageContentOfferingTransformedFactory = (
override?: Partial<PageContentOfferingTransformed> override?: Partial<PageContentOfferingTransformed>
): PageContentOfferingTransformed => ({ ): PageContentOfferingTransformed => ({
...PageContentOfferingResultFactory(), ...PageContentOfferingResultFactory(),
defaultPurchase: { defaultPurchase: PageContentOfferingDefaultPurchaseTransformedFactory(),
data: StrapiEntityFactory({
...PageContentOfferingDefaultPurchaseTransformedFactory(),
localizations: {
data: [
StrapiEntityFactory(
PageContentOfferingDefaultPurchaseTransformedFactory()
),
],
},
}),
},
...override, ...override,
}); });

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

@ -7,76 +7,47 @@ import { graphql } from '../../../__generated__/gql';
export const pageContentForOfferingQuery = graphql(` export const pageContentForOfferingQuery = graphql(`
query PageContentForOffering($locale: String!, $apiIdentifier: String!) { query PageContentForOffering($locale: String!, $apiIdentifier: String!) {
offerings( offerings(
pagination: { start: 0, limit: 2 }
filters: { apiIdentifier: { eq: $apiIdentifier } } filters: { apiIdentifier: { eq: $apiIdentifier } }
pagination: { limit: 200 }
) { ) {
meta { apiIdentifier
pagination { stripeProductId
total defaultPurchase {
purchaseDetails {
details
productName
subtitle
webIcon
localizations(filters: { locale: { eq: $locale } }) {
details
productName
subtitle
webIcon
}
} }
} }
data { commonContent {
attributes { privacyNoticeUrl
apiIdentifier privacyNoticeDownloadUrl
stripeProductId termsOfServiceUrl
defaultPurchase { termsOfServiceDownloadUrl
data { cancellationUrl
attributes { emailIcon
purchaseDetails { successActionButtonUrl
data { successActionButtonLabel
attributes { newsletterLabelTextCode
details newsletterSlug
productName localizations(filters: { locale: { eq: $locale } }) {
subtitle privacyNoticeUrl
webIcon privacyNoticeDownloadUrl
localizations(filters: { locale: { eq: $locale } }) { termsOfServiceUrl
data { termsOfServiceDownloadUrl
attributes { cancellationUrl
details emailIcon
productName successActionButtonUrl
subtitle successActionButtonLabel
webIcon newsletterLabelTextCode
} newsletterSlug
}
}
}
}
}
}
}
}
commonContent {
data {
attributes {
privacyNoticeUrl
privacyNoticeDownloadUrl
termsOfServiceUrl
termsOfServiceDownloadUrl
cancellationUrl
emailIcon
successActionButtonUrl
successActionButtonLabel
newsletterLabelTextCode
newsletterSlug
localizations(filters: { locale: { eq: $locale } }) {
data {
attributes {
privacyNoticeUrl
privacyNoticeDownloadUrl
termsOfServiceUrl
termsOfServiceDownloadUrl
cancellationUrl
emailIcon
successActionButtonUrl
successActionButtonLabel
newsletterLabelTextCode
newsletterSlug
}
}
}
}
}
}
} }
} }
} }

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

@ -2,8 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { StrapiEntity } from '../../types';
export interface PageContentCommonContentResult { export interface PageContentCommonContentResult {
privacyNoticeUrl: string; privacyNoticeUrl: string;
privacyNoticeDownloadUrl: string; privacyNoticeDownloadUrl: string;
@ -30,60 +28,31 @@ export interface PageContentPurchaseDetailsTransformed
} }
export interface PageContentOfferingDefaultPurchaseResult { export interface PageContentOfferingDefaultPurchaseResult {
purchaseDetails: { purchaseDetails: PageContentPurchaseDetailsResult & {
data: StrapiEntity< localizations: PageContentPurchaseDetailsResult[];
PageContentPurchaseDetailsResult & {
localizations: {
data: StrapiEntity<PageContentPurchaseDetailsResult>[];
};
}
>;
}; };
} }
export interface PageContentOfferingDefaultPurchaseTransformed { export interface PageContentOfferingDefaultPurchaseTransformed {
purchaseDetails: { purchaseDetails: PageContentPurchaseDetailsTransformed & {
data: StrapiEntity< localizations: PageContentPurchaseDetailsTransformed[];
PageContentPurchaseDetailsTransformed & {
localizations: {
data: StrapiEntity<PageContentPurchaseDetailsTransformed>[];
};
}
>;
}; };
} }
export interface PageContentOfferingTransformed export interface PageContentOfferingTransformed
extends Omit<PageContentOfferingResult, 'defaultPurchase'> { extends Omit<PageContentOfferingResult, 'defaultPurchase'> {
defaultPurchase: { defaultPurchase: PageContentOfferingDefaultPurchaseTransformed;
data: StrapiEntity<PageContentOfferingDefaultPurchaseTransformed>;
};
} }
export interface PageContentOfferingResult { export interface PageContentOfferingResult {
apiIdentifier: string; apiIdentifier: string;
stripeProductId: string; stripeProductId: string;
defaultPurchase: { defaultPurchase: PageContentOfferingDefaultPurchaseResult;
data: StrapiEntity<PageContentOfferingDefaultPurchaseResult>; commonContent: PageContentCommonContentResult & {
}; localizations: PageContentCommonContentResult[];
commonContent: {
data: StrapiEntity<
PageContentCommonContentResult & {
localizations: {
data: StrapiEntity<PageContentCommonContentResult>[];
};
}
>;
}; };
} }
export interface PageContentForOfferingResult { export interface PageContentForOfferingResult {
offerings: { offerings: PageContentOfferingResult[];
meta: {
pagination: {
total: number;
};
};
data: StrapiEntity<PageContentOfferingResult>[];
};
} }

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

@ -16,7 +16,7 @@ describe('PageContentForOfferingUtil', () => {
result as PageContentForOfferingResult result as PageContentForOfferingResult
); );
expect(util).toBeDefined(); expect(util).toBeDefined();
expect(util.offerings.data).toHaveLength(1); expect(util.offerings).toHaveLength(1);
}); });
describe('transformPageContentPurchaseDetails', () => { describe('transformPageContentPurchaseDetails', () => {

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

@ -17,36 +17,22 @@ export class PageContentForOfferingResultUtil {
} }
getOffering(): PageContentOfferingTransformed { getOffering(): PageContentOfferingTransformed {
const offering = this.offerings.data.at(0); const offering = this.offerings.at(0);
if (!offering) throw Error('getOffering - No offering exists'); if (!offering) throw Error('getOffering - No offering exists');
if (this.offerings.data.length > 1) if (this.offerings.length > 1)
throw Error('getOffering - More than one offering'); throw Error('getOffering - More than one offering');
return { return {
...offering.attributes, ...offering,
defaultPurchase: { defaultPurchase: {
data: { purchaseDetails: {
attributes: { ...this.purchaseDetailsTransform(
purchaseDetails: { offering.defaultPurchase.purchaseDetails
data: { ),
attributes: { localizations:
...this.purchaseDetailsTransform( offering.defaultPurchase.purchaseDetails.localizations.map(
offering.attributes.defaultPurchase.data.attributes (localization) => this.purchaseDetailsTransform(localization)
.purchaseDetails.data.attributes ),
),
localizations: {
data: offering.attributes.defaultPurchase.data.attributes.purchaseDetails.data.attributes.localizations.data.map(
(localization) => ({
attributes: this.purchaseDetailsTransform(
localization.attributes
),
})
),
},
},
},
},
},
}, },
}, },
}; };

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

@ -11,7 +11,6 @@ import {
PurchaseWithDetailsOfferingContentResult, PurchaseWithDetailsOfferingContentResult,
PurchaseWithDetailsOfferingContentTransformed, PurchaseWithDetailsOfferingContentTransformed,
} from './types'; } from './types';
import { StrapiEntityFactory } from '../../factories';
export const PurchaseDetailsResultFactory = ( export const PurchaseDetailsResultFactory = (
override?: Partial<PurchaseDetailsResult> override?: Partial<PurchaseDetailsResult>
@ -69,12 +68,8 @@ export const PurchaseOfferingResultFactory = (
}) })
), ),
commonContent: { commonContent: {
data: StrapiEntityFactory({ ...OfferingCommonContentResultFactory(),
...OfferingCommonContentResultFactory(), localizations: [OfferingCommonContentResultFactory()],
localizations: {
data: [StrapiEntityFactory(OfferingCommonContentResultFactory())],
},
}),
}, },
...override, ...override,
}); });
@ -89,16 +84,10 @@ export const PurchaseWithDetailsOfferingContentResultFactory = (
}) })
), ),
purchaseDetails: { purchaseDetails: {
data: StrapiEntityFactory({ ...PurchaseDetailsResultFactory(),
...PurchaseDetailsResultFactory(), localizations: [PurchaseDetailsResultFactory()],
localizations: {
data: [StrapiEntityFactory(PurchaseDetailsResultFactory())],
},
}),
},
offering: {
data: StrapiEntityFactory(PurchaseOfferingResultFactory()),
}, },
offering: PurchaseOfferingResultFactory(),
...override, ...override,
}); });
@ -107,12 +96,8 @@ export const PurchaseWithDetailsOfferingContentTransformedFactory = (
): PurchaseWithDetailsOfferingContentTransformed => ({ ): PurchaseWithDetailsOfferingContentTransformed => ({
...PurchaseWithDetailsOfferingContentResultFactory(), ...PurchaseWithDetailsOfferingContentResultFactory(),
purchaseDetails: { purchaseDetails: {
data: StrapiEntityFactory({ ...PurchaseDetailsTransformedFactory(),
...PurchaseDetailsTransformedFactory(), localizations: [PurchaseDetailsTransformedFactory()],
localizations: {
data: [StrapiEntityFactory(PurchaseDetailsTransformedFactory())],
},
}),
}, },
...override, ...override,
}); });
@ -120,10 +105,6 @@ export const PurchaseWithDetailsOfferingContentTransformedFactory = (
export const PurchaseWithDetailsOfferingContentByPlanIdsResultFactory = ( export const PurchaseWithDetailsOfferingContentByPlanIdsResultFactory = (
override?: Partial<PurchaseWithDetailsOfferingContentByPlanIdsResult> override?: Partial<PurchaseWithDetailsOfferingContentByPlanIdsResult>
): PurchaseWithDetailsOfferingContentByPlanIdsResult => ({ ): PurchaseWithDetailsOfferingContentByPlanIdsResult => ({
purchases: { purchases: [PurchaseWithDetailsOfferingContentResultFactory()],
data: [
StrapiEntityFactory(PurchaseWithDetailsOfferingContentResultFactory()),
],
},
...override, ...override,
}); });

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

@ -5,13 +5,10 @@ import { graphql } from '../../../__generated__/gql';
export const purchaseWithDetailsOfferingContentQuery = graphql(` export const purchaseWithDetailsOfferingContentQuery = graphql(`
query PurchaseWithDetailsOfferingContent( query PurchaseWithDetailsOfferingContent(
$skip: Int!
$limit: Int!
$locale: String! $locale: String!
$stripePlanIds: [String]! $stripePlanIds: [String]!
) { ) {
purchases( purchases(
pagination: { start: $skip, limit: $limit }
filters: { filters: {
or: [ or: [
{ stripePlanChoices: { stripePlanChoice: { in: $stripePlanIds } } } { stripePlanChoices: { stripePlanChoice: { in: $stripePlanIds } } }
@ -22,73 +19,50 @@ export const purchaseWithDetailsOfferingContentQuery = graphql(`
} }
] ]
} }
pagination: { limit: 500 }
) { ) {
data { stripePlanChoices {
attributes { stripePlanChoice
stripePlanChoices { }
stripePlanChoice purchaseDetails {
} details
purchaseDetails { productName
data { subtitle
attributes { webIcon
details localizations(filters: { locale: { eq: $locale } }) {
productName details
subtitle productName
webIcon subtitle
localizations(filters: { locale: { eq: $locale } }) { webIcon
data { }
attributes { }
details offering {
productName stripeProductId
subtitle stripeLegacyPlans(pagination: { limit: 200 }) {
webIcon stripeLegacyPlan
} }
} commonContent {
} privacyNoticeUrl
} privacyNoticeDownloadUrl
} termsOfServiceUrl
} termsOfServiceDownloadUrl
offering { cancellationUrl
data { emailIcon
attributes { successActionButtonUrl
stripeProductId successActionButtonLabel
stripeLegacyPlans(pagination: { limit: 200 }) { newsletterLabelTextCode
stripeLegacyPlan newsletterSlug
} localizations(filters: { locale: { eq: $locale } }) {
commonContent { privacyNoticeUrl
data { privacyNoticeDownloadUrl
attributes { termsOfServiceUrl
privacyNoticeUrl termsOfServiceDownloadUrl
privacyNoticeDownloadUrl cancellationUrl
termsOfServiceUrl emailIcon
termsOfServiceDownloadUrl successActionButtonUrl
cancellationUrl successActionButtonLabel
emailIcon newsletterLabelTextCode
successActionButtonUrl newsletterSlug
successActionButtonLabel
newsletterLabelTextCode
newsletterSlug
localizations(filters: { locale: { eq: $locale } }) {
data {
attributes {
privacyNoticeUrl
privacyNoticeDownloadUrl
termsOfServiceUrl
termsOfServiceDownloadUrl
cancellationUrl
emailIcon
successActionButtonUrl
successActionButtonLabel
newsletterLabelTextCode
newsletterSlug
}
}
}
}
}
}
}
}
} }
} }
} }

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

@ -2,8 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { StrapiEntity } from '../../types';
export interface PurchaseDetailsResult { export interface PurchaseDetailsResult {
details: string; details: string;
productName: string; productName: string;
@ -34,14 +32,8 @@ export interface PurchaseOfferingResult {
stripeLegacyPlans: { stripeLegacyPlans: {
stripeLegacyPlan: string; stripeLegacyPlan: string;
}[]; }[];
commonContent: { commonContent: OfferingCommonContentResult & {
data: StrapiEntity< localizations: OfferingCommonContentResult[];
OfferingCommonContentResult & {
localizations: {
data: StrapiEntity<OfferingCommonContentResult>[];
};
}
>;
}; };
} }
@ -49,35 +41,19 @@ export interface PurchaseWithDetailsOfferingContentResult {
stripePlanChoices: { stripePlanChoices: {
stripePlanChoice: string; stripePlanChoice: string;
}[]; }[];
purchaseDetails: { purchaseDetails: PurchaseDetailsResult & {
data: StrapiEntity< localizations: PurchaseDetailsResult[];
PurchaseDetailsResult & {
localizations: {
data: StrapiEntity<PurchaseDetailsResult>[];
};
}
>;
};
offering: {
data: StrapiEntity<PurchaseOfferingResult>;
}; };
offering: PurchaseOfferingResult;
} }
export interface PurchaseWithDetailsOfferingContentTransformed export interface PurchaseWithDetailsOfferingContentTransformed
extends Omit<PurchaseWithDetailsOfferingContentResult, 'purchaseDetails'> { extends Omit<PurchaseWithDetailsOfferingContentResult, 'purchaseDetails'> {
purchaseDetails: { purchaseDetails: PurchaseDetailsTransformed & {
data: StrapiEntity< localizations: PurchaseDetailsTransformed[];
PurchaseDetailsTransformed & {
localizations: {
data: StrapiEntity<PurchaseDetailsTransformed>[];
};
}
>;
}; };
} }
export interface PurchaseWithDetailsOfferingContentByPlanIdsResult { export interface PurchaseWithDetailsOfferingContentByPlanIdsResult {
purchases: { purchases: PurchaseWithDetailsOfferingContentResult[];
data: StrapiEntity<PurchaseWithDetailsOfferingContentResult>[];
};
} }

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

@ -5,42 +5,34 @@ import {
PurchaseDetailsResultFactory, PurchaseDetailsResultFactory,
PurchaseWithDetailsOfferingContentByPlanIdsResultFactory, PurchaseWithDetailsOfferingContentByPlanIdsResultFactory,
} from './factories'; } from './factories';
import { PurchaseWithDetailsOfferingContentByPlanIdsResult } from './types';
import { PurchaseWithDetailsOfferingContentUtil } from './util'; import { PurchaseWithDetailsOfferingContentUtil } from './util';
describe('PurchaseWithDetailsOfferingContentUtil', () => { describe('PurchaseWithDetailsOfferingContentUtil', () => {
it('should create a util from response', () => { it('should create a util from response', () => {
const result = PurchaseWithDetailsOfferingContentByPlanIdsResultFactory(); const result = PurchaseWithDetailsOfferingContentByPlanIdsResultFactory();
const result2 = PurchaseWithDetailsOfferingContentByPlanIdsResultFactory(); const purchase = result.purchases[0];
const purchase = result.purchases?.data[0]; const planId = purchase.stripePlanChoices?.[0];
const planId = purchase.attributes.stripePlanChoices?.[0]; const legacyPlanId = purchase.offering.stripeLegacyPlans?.[0];
const legacyPlanId = const util = new PurchaseWithDetailsOfferingContentUtil(result);
purchase.attributes.offering.data.attributes.stripeLegacyPlans?.[0];
const util = new PurchaseWithDetailsOfferingContentUtil([
result as PurchaseWithDetailsOfferingContentByPlanIdsResult,
result2 as PurchaseWithDetailsOfferingContentByPlanIdsResult,
]);
expect(util).toBeDefined(); expect(util).toBeDefined();
expect( expect(
util.transformedPurchaseWithCommonContentForPlanId( util.transformedPurchaseWithCommonContentForPlanId(
planId.stripePlanChoice ?? '' planId.stripePlanChoice ?? ''
)?.offering.data.attributes.stripeProductId )?.offering.stripeProductId
).toBeDefined(); ).toBeDefined();
expect( expect(
util.transformedPurchaseWithCommonContentForPlanId( util.transformedPurchaseWithCommonContentForPlanId(
legacyPlanId.stripeLegacyPlan ?? '' legacyPlanId.stripeLegacyPlan ?? ''
)?.offering.data.attributes.stripeProductId )?.offering.stripeProductId
).toBeDefined(); ).toBeDefined();
expect(util.purchases.data.length).toBe(2); expect(util.purchases.length).toBe(1);
}); });
describe('transformPurchaseDetails', () => { describe('transformPurchaseDetails', () => {
let util: PurchaseWithDetailsOfferingContentUtil; let util: PurchaseWithDetailsOfferingContentUtil;
beforeAll(() => { beforeAll(() => {
const result = PurchaseWithDetailsOfferingContentByPlanIdsResultFactory(); const result = PurchaseWithDetailsOfferingContentByPlanIdsResultFactory();
util = new PurchaseWithDetailsOfferingContentUtil([ util = new PurchaseWithDetailsOfferingContentUtil(result);
result as PurchaseWithDetailsOfferingContentByPlanIdsResult,
]);
}); });
it('should transform details', () => { it('should transform details', () => {

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

@ -15,61 +15,31 @@ export class PurchaseWithDetailsOfferingContentUtil {
> = {}; > = {};
constructor( constructor(
private rawResults: PurchaseWithDetailsOfferingContentByPlanIdsResult[] private rawResult: PurchaseWithDetailsOfferingContentByPlanIdsResult
) { ) {
for (const rawResult of rawResults) { for (const purchase of rawResult.purchases) {
for (const purchase of rawResult.purchases.data) { purchase.stripePlanChoices?.forEach(({ stripePlanChoice }) => {
purchase.attributes.stripePlanChoices?.forEach( this.transformedPurchaseByPlanId[stripePlanChoice] = {
({ stripePlanChoice }) => { ...purchase,
this.transformedPurchaseByPlanId[stripePlanChoice] = { purchaseDetails: {
...purchase.attributes, ...this.purchaseDetailsTransform(purchase.purchaseDetails),
purchaseDetails: { localizations: purchase.purchaseDetails.localizations.map(
data: { (localization) => this.purchaseDetailsTransform(localization)
attributes: { ),
...this.purchaseDetailsTransform( },
purchase.attributes.purchaseDetails.data.attributes };
), });
localizations: { purchase.offering.stripeLegacyPlans?.forEach(({ stripeLegacyPlan }) => {
data: purchase.attributes.purchaseDetails.data.attributes.localizations.data.map( this.transformedPurchaseByPlanId[stripeLegacyPlan] = {
(localization) => ({ ...purchase,
attributes: this.purchaseDetailsTransform( purchaseDetails: {
localization.attributes ...this.purchaseDetailsTransform(purchase.purchaseDetails),
), localizations: purchase.purchaseDetails.localizations.map(
}) (localization) => this.purchaseDetailsTransform(localization)
), ),
}, },
}, };
}, });
},
};
}
);
purchase.attributes.offering.data.attributes.stripeLegacyPlans?.forEach(
({ stripeLegacyPlan }) => {
this.transformedPurchaseByPlanId[stripeLegacyPlan] = {
...purchase.attributes,
purchaseDetails: {
data: {
attributes: {
...this.purchaseDetailsTransform(
purchase.attributes.purchaseDetails.data.attributes
),
localizations: {
data: purchase.attributes.purchaseDetails.data.attributes.localizations.data.map(
(localization) => ({
attributes: this.purchaseDetailsTransform(
localization.attributes
),
})
),
},
},
},
},
};
}
);
}
} }
} }
@ -93,17 +63,6 @@ export class PurchaseWithDetailsOfferingContentUtil {
} }
get purchases(): PurchaseWithDetailsOfferingContentByPlanIdsResult['purchases'] { get purchases(): PurchaseWithDetailsOfferingContentByPlanIdsResult['purchases'] {
// Deduplicating items as there could be duplicates from splitting up the return this.rawResult.purchases;
// stripePlanIds and making multiple CMS calls
return {
data: [
...new Map(
this.rawResults
.map((rawResult) => rawResult.purchases.data)
.flat()
.map((res) => [JSON.stringify(res), res])
).values(),
],
};
} }
} }

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

@ -6,14 +6,11 @@ import { faker } from '@faker-js/faker';
import { ServicesWithCapabilitiesQuery } from '../../../__generated__/graphql'; import { ServicesWithCapabilitiesQuery } from '../../../__generated__/graphql';
import { CapabilitiesResult, ServiceResult } from '.'; import { CapabilitiesResult, ServiceResult } from '.';
import { StrapiEntityFactory } from '../../factories';
export const ServicesWithCapabilitiesQueryFactory = ( export const ServicesWithCapabilitiesQueryFactory = (
override?: Partial<ServicesWithCapabilitiesQuery> override?: Partial<ServicesWithCapabilitiesQuery>
): ServicesWithCapabilitiesQuery => ({ ): ServicesWithCapabilitiesQuery => ({
services: { services: [ServiceResultFactory()],
data: [StrapiEntityFactory(ServiceResultFactory())],
},
...override, ...override,
}); });
@ -21,9 +18,7 @@ export const ServiceResultFactory = (
override?: Partial<ServiceResult> override?: Partial<ServiceResult>
): ServiceResult => ({ ): ServiceResult => ({
oauthClientId: faker.string.sample(), oauthClientId: faker.string.sample(),
capabilities: { capabilities: [CapabilitiesResultFactory()],
data: [StrapiEntityFactory(CapabilitiesResultFactory())],
},
...override, ...override,
}); });

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

@ -5,19 +5,11 @@
import { graphql } from '../../../__generated__/gql'; import { graphql } from '../../../__generated__/gql';
export const servicesWithCapabilitiesQuery = graphql(` export const servicesWithCapabilitiesQuery = graphql(`
query ServicesWithCapabilities($skip: Int!, $limit: Int!) { query ServicesWithCapabilities {
services(pagination: { start: $skip, limit: $limit }) { services(pagination: { limit: 500 }) {
data { oauthClientId
attributes { capabilities {
oauthClientId slug
capabilities {
data {
attributes {
slug
}
}
}
}
} }
} }
} }

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

@ -2,21 +2,15 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { StrapiEntity } from '../../types';
export interface CapabilitiesResult { export interface CapabilitiesResult {
slug: string; slug: string;
} }
export interface ServiceResult { export interface ServiceResult {
oauthClientId: string; oauthClientId: string;
capabilities: { capabilities: CapabilitiesResult[];
data: StrapiEntity<CapabilitiesResult>[];
};
} }
export interface ServicesWithCapabilitiesResult { export interface ServicesWithCapabilitiesResult {
services: { services: ServiceResult[];
data: StrapiEntity<ServiceResult>[];
};
} }

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

@ -15,7 +15,7 @@ describe('ServicesWithCapabilitiesResultUtil', () => {
result as ServicesWithCapabilitiesResult result as ServicesWithCapabilitiesResult
); );
expect(util).toBeDefined(); expect(util).toBeDefined();
expect(util.services.data.length).toBe(1); expect(util.services.length).toBe(1);
}); });
it('getServices - should return services and capabilities', () => { it('getServices - should return services and capabilities', () => {
@ -25,12 +25,11 @@ describe('ServicesWithCapabilitiesResultUtil', () => {
); );
expect(util.getServices()[0].oauthClientId).toBeDefined(); expect(util.getServices()[0].oauthClientId).toBeDefined();
expect(util.getServices()[0].oauthClientId).toEqual( expect(util.getServices()[0].oauthClientId).toEqual(
result.services?.data[0]?.attributes?.oauthClientId result.services?.[0]?.oauthClientId
); );
expect(util.getServices()[0].capabilities.data).toBeDefined(); expect(util.getServices()[0].capabilities).toBeDefined();
expect(util.getServices()[0].capabilities.data[0].attributes.slug).toEqual( expect(util.getServices()[0].capabilities[0].slug).toEqual(
result.services?.data[0]?.attributes?.capabilities?.data[0].attributes result.services?.[0]?.capabilities?.[0]?.slug
?.slug
); );
}); });
}); });

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

@ -8,8 +8,9 @@ export class ServicesWithCapabilitiesResultUtil {
constructor(private rawResult: ServicesWithCapabilitiesResult) {} constructor(private rawResult: ServicesWithCapabilitiesResult) {}
getServices(): ServiceResult[] { getServices(): ServiceResult[] {
return this.services.data.map((el) => el.attributes); return this.services;
} }
get services() { get services() {
return this.rawResult.services; return this.rawResult.services;
} }

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

@ -132,12 +132,7 @@ describe('StrapiClient', () => {
describe('getLocale', () => { describe('getLocale', () => {
const ACCEPT_LANGUAGE = 'en-US,fr-FR;q=0.7,de-DE;q=0.3'; const ACCEPT_LANGUAGE = 'en-US,fr-FR;q=0.7,de-DE;q=0.3';
const localesQueryResult = LocalesResultFactory({ const localesQueryResult = LocalesResultFactory({
i18NLocales: { i18NLocales: [{ code: 'en' }, { code: 'fr-FR' }],
data: [
{ attributes: { code: 'en' } },
{ attributes: { code: 'fr-FR' } },
],
},
}); });
beforeEach(() => { beforeEach(() => {

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

@ -144,10 +144,7 @@ export class StrapiClient {
private async getLocales(): Promise<string[]> { private async getLocales(): Promise<string[]> {
const localesResult = (await this.query(localesQuery, {})) as LocalesResult; const localesResult = (await this.query(localesQuery, {})) as LocalesResult;
return ( return localesResult.i18NLocales.map((locale) => locale.code) || [];
localesResult.i18NLocales.data.map((locale) => locale.attributes.code) ||
[]
);
} }
private setupCacheBust() { private setupCacheBust() {

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

@ -17,7 +17,3 @@ export type ContentfulErrorResponse = {
requestId: string; requestId: string;
details?: NonNullable<unknown>; details?: NonNullable<unknown>;
}; };
export interface StrapiEntity<T> {
attributes: T;
}

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

@ -3427,8 +3427,8 @@ describe('#integration - StripeHelper', () => {
transformedPurchaseWithCommonContentForPlanId: (planId) => { transformedPurchaseWithCommonContentForPlanId: (planId) => {
const mockValue = const mockValue =
PurchaseWithDetailsOfferingContentTransformedFactory(); PurchaseWithDetailsOfferingContentTransformedFactory();
mockValue.purchaseDetails.data.attributes.webIcon = newWebIconURL; mockValue.purchaseDetails.webIcon = newWebIconURL;
mockValue.purchaseDetails.data.attributes.localizations.data = []; mockValue.purchaseDetails.localizations = [];
return mockValue; return mockValue;
}, },
}; };