diff --git a/handlers/user-benefits/src/benefitsIdentityId.ts b/handlers/user-benefits/src/benefitsIdentityId.ts index a9e5418ec..ee454bf55 100644 --- a/handlers/user-benefits/src/benefitsIdentityId.ts +++ b/handlers/user-benefits/src/benefitsIdentityId.ts @@ -1,16 +1,64 @@ +import { Lazy } from '@modules/lazy'; +import type { UserBenefitsResponse } from '@modules/product-benefits/schemas'; +import { getUserBenefitsExcludingStaff } from '@modules/product-benefits/userBenefits'; +import { getProductCatalogFromApi } from '@modules/product-catalog/api'; +import { ProductCatalogHelper } from '@modules/product-catalog/productCatalog'; +import type { Stage } from '@modules/stage'; import type { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda'; +import { getTrialInformation } from './trials'; -export const benefitsIdentityIdHandler = ( +const stage = process.env.STAGE as Stage; +const productCatalog = new Lazy( + async () => await getProductCatalogFromApi(stage), + 'Get product catalog', +); + +const getUserBenefitsResponse = async ( + stage: Stage, + productCatalogHelper: ProductCatalogHelper, + identityId: string, +): Promise => { + const benefits = await getUserBenefitsExcludingStaff( + stage, + productCatalogHelper, + identityId, + ); + console.log(`Benefits for user ${identityId} are: `, benefits); + const trials = getTrialInformation(benefits); + console.log(`Trials for user ${identityId} are: `, trials); + return { + benefits, + trials, + }; +}; + +export const benefitsIdentityIdHandler = async ( event: APIGatewayProxyEvent, ): Promise => { console.log(`Input is ${JSON.stringify(event)}`); - return Promise.resolve({ - body: JSON.stringify({ test: true }), + const identityId = event.pathParameters?.identityId; + if (!identityId) { + return { + statusCode: 400, + body: JSON.stringify({ + message: 'Identity ID missing from request path', + }), + }; + } + + const userBenefitsResponse = await getUserBenefitsResponse( + stage, + new ProductCatalogHelper(await productCatalog.get()), + identityId, + ); + + return { + body: JSON.stringify(userBenefitsResponse), // https://www.fastly.com/documentation/guides/concepts/edge-state/cache/cache-freshness/#preventing-content-from-being-cached headers: { 'Cache-Control': 'private, no-store', }, statusCode: 200, - }); + }; }; diff --git a/handlers/user-benefits/test/benefitsIdentityId.test.ts b/handlers/user-benefits/test/benefitsIdentityId.test.ts new file mode 100644 index 000000000..48bf1edb9 --- /dev/null +++ b/handlers/user-benefits/test/benefitsIdentityId.test.ts @@ -0,0 +1,60 @@ +import { getUserBenefitsExcludingStaff } from '@modules/product-benefits/userBenefits'; +import type { ProductCatalogHelper } from '@modules/product-catalog/productCatalog'; +import type { Stage } from '@modules/stage'; +import type { APIGatewayProxyEvent } from 'aws-lambda'; +import { benefitsIdentityIdHandler } from '../src/benefitsIdentityId'; + +jest.mock('@modules/product-catalog/api', () => ({ + getProductCatalogFromApi: () => ({}), +})); +const goodIdentityId = 'good-identity-id'; +jest.mock('@modules/product-benefits/userBenefits', () => ({ + getUserBenefitsExcludingStaff: jest.fn( + ( + stage: Stage, + productCatalogHelper: ProductCatalogHelper, + identityId: string, + ) => { + if (identityId === 'good-identity-id') { + return ['adFree']; + } else { + return []; + } + }, + ), +})); + +beforeEach(() => { + jest.clearAllMocks(); +}); + +describe('benefitsIdentityIdHandler', () => { + it('returns a 400 when the identityId path part is missing', async () => { + const requestEvent = { + path: '/benefits/', + httpMethod: 'GET', + pathParameters: { identityId: undefined }, + } as unknown as APIGatewayProxyEvent; + + const response = await benefitsIdentityIdHandler(requestEvent); + + expect(response.statusCode).toEqual(400); + }); + + it('returns a 200 with benefits retrieved for the identityId', async () => { + const requestEvent = { + path: `/benefits/${goodIdentityId}`, + httpMethod: 'GET', + pathParameters: { identityId: goodIdentityId }, + } as unknown as APIGatewayProxyEvent; + + const response = await benefitsIdentityIdHandler(requestEvent); + + expect(response.statusCode).toEqual(200); + expect(getUserBenefitsExcludingStaff).toHaveBeenCalledWith( + undefined, // stage isn't defined in tests and anything doesn't match undefined + expect.anything(), + goodIdentityId, + ); + }); +}); diff --git a/modules/product-benefits/src/userBenefits.ts b/modules/product-benefits/src/userBenefits.ts index 6318d25e0..2152f8461 100644 --- a/modules/product-benefits/src/userBenefits.ts +++ b/modules/product-benefits/src/userBenefits.ts @@ -50,20 +50,33 @@ export const getValidUserProducts = ( export const userHasGuardianEmail = (email: string): boolean => email.endsWith('@theguardian.com') || email.endsWith('@guardian.co.uk'); -export const getUserBenefits = async ( +export const getUserBenefitsExcludingStaff = async ( + stage: Stage, + productCatalogHelper: ProductCatalogHelper, + identityId: string, +): Promise => { + const userProducts = await getUserProducts( + stage, + productCatalogHelper, + identityId, + ); + + return getUserBenefitsFromUserProducts(userProducts); +}; + +export const getUserBenefits = ( stage: Stage, productCatalogHelper: ProductCatalogHelper, userDetails: IdentityUserDetails, ): Promise => { if (userHasGuardianEmail(userDetails.email)) { - return allProductBenefits; + return Promise.resolve(allProductBenefits); } - const userProducts = await getUserProducts( + return getUserBenefitsExcludingStaff( stage, productCatalogHelper, userDetails.identityId, ); - return getUserBenefitsFromUserProducts(userProducts); }; export const getUserBenefitsFromUserProducts = (