Skip to content

Commit

Permalink
Get benefits for identity ID specified in the path
Browse files Browse the repository at this point in the history
  • Loading branch information
tjmw committed Dec 20, 2024
1 parent db22eb2 commit 73c5301
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 8 deletions.
56 changes: 52 additions & 4 deletions handlers/user-benefits/src/benefitsIdentityId.ts
Original file line number Diff line number Diff line change
@@ -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<UserBenefitsResponse> => {
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<APIGatewayProxyResult> => {
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,
});
};
};
60 changes: 60 additions & 0 deletions handlers/user-benefits/test/benefitsIdentityId.test.ts
Original file line number Diff line number Diff line change
@@ -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,
);
});
});
21 changes: 17 additions & 4 deletions modules/product-benefits/src/userBenefits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<ProductBenefit[]> => {
const userProducts = await getUserProducts(
stage,
productCatalogHelper,
identityId,
);

return getUserBenefitsFromUserProducts(userProducts);
};

export const getUserBenefits = (
stage: Stage,
productCatalogHelper: ProductCatalogHelper,
userDetails: IdentityUserDetails,
): Promise<ProductBenefit[]> => {
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 = (
Expand Down

0 comments on commit 73c5301

Please sign in to comment.