Skip to content

Commit

Permalink
Merge pull request #75 from ScottLogic/SDE-171-test-calculate-user-da…
Browse files Browse the repository at this point in the history
…ily-digest

SDE-171: Calculate User Daily Digest Test
  • Loading branch information
antreaspas authored Oct 21, 2019
2 parents 3e1210b + 93f5357 commit 46218b6
Show file tree
Hide file tree
Showing 5 changed files with 1,379 additions and 24 deletions.
65 changes: 42 additions & 23 deletions functions/calculateUserDailyDigest.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,6 @@ import ConnectionClass from 'http-aws-es';
import ESSearch from '../common/search/search';
import buildQueryJson from '../common/query';

const { ES_SEARCH_API, EMAIL_MAX_POSTS, SEND_DIGEST_EMAIL_LAMBDA_NAME: FunctionName } = process.env;
const ESConnectOptions = {
host: ES_SEARCH_API,
connectionClass: ConnectionClass,
awsConfig: new Config({
credentials: new EnvironmentCredentials('AWS')
})
};
const esSearchClient = new ESSearch(ESConnectOptions);
const lambda = new Lambda();

// Midnight yesterday
const getDateBegin = () => {
const dateBegin = new Date();
Expand Down Expand Up @@ -64,7 +53,7 @@ const compareSortedArrays = (arr1, arr2) => {
return true;
};

const transformMultiSearchResult = (userID, subscriptions, mSearchResult) => {
const transformMultiSearchResult = (userID, subscriptions, mSearchResult, EMAIL_MAX_POSTS) => {
const searchHits = mSearchResult.responses
.map(response => response.hits.hits.map(hit => ({
PostId: hit._id,
Expand Down Expand Up @@ -116,22 +105,25 @@ const transformMultiSearchResult = (userID, subscriptions, mSearchResult) => {
return { userID, results };
};

const sendDailyDigestEmail = async result => lambda
const sendDailyDigestEmail = async (result, FunctionName, lambda) => lambda
.invoke({
FunctionName,
InvocationType: 'Event',
Payload: JSON.stringify(result)
})
.promise();

const processUserSubscriptions = async (userID, subscriptions) => {
const processUserSubscriptions = async (
userID,
subscriptions,
EMAIL_MAX_POSTS,
FunctionName,
esSearchClient,
lambda
) => {
console.log(`Processing ${subscriptions.length} subscriptions of user with ID: ${userID}`);

const buildQueryInput = formatInputQueryBody(
subscriptions,
getDateBegin(),
getDateEnd()
);
const buildQueryInput = formatInputQueryBody(subscriptions, getDateBegin(), getDateEnd());

const body = [];
for (const input of buildQueryInput) {
Expand All @@ -142,14 +134,41 @@ const processUserSubscriptions = async (userID, subscriptions) => {

const mSearchResult = await esSearchClient.doMultiSearch(mSearchInput);

const result = transformMultiSearchResult(userID, subscriptions, mSearchResult);
const result = transformMultiSearchResult(userID, subscriptions, mSearchResult, EMAIL_MAX_POSTS);
if (result.results.length) {
await sendDailyDigestEmail(result);
// eslint-disable-next-line no-use-before-define
await exportedFunctions.sendDailyDigestEmail(result, FunctionName, lambda);
console.log(`Sent ${result.results.length} digest updates to user ${userID}`);
}
};

export const handler = async (event) => {
const handler = async (event) => {
const {
ES_SEARCH_API,
EMAIL_MAX_POSTS,
SEND_DIGEST_EMAIL_LAMBDA_NAME: FunctionName
} = process.env;
const esSearchClient = new ESSearch({
host: ES_SEARCH_API,
connectionClass: ConnectionClass,
awsConfig: new Config({
credentials: new EnvironmentCredentials('AWS')
})
});
const lambda = new Lambda();

const { userId: userID, subscriptions } = event;
await processUserSubscriptions(userID, subscriptions);
await processUserSubscriptions(
userID,
subscriptions,
EMAIL_MAX_POSTS,
FunctionName,
esSearchClient,
lambda
);
};

export const exportedFunctions = {
handler,
sendDailyDigestEmail
};
2 changes: 1 addition & 1 deletion serverless.yml
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ functions:
SUBSCRIPTIONS_TABLE: ${self:custom.subscriptionsTableName}
USER_DIGEST_LAMBDA_NAME: ${self:service}-${self:custom.stage}-calculateUserDailyDigest
calculateUserDailyDigest:
handler: functions/calculateUserDailyDigest.handler
handler: functions/calculateUserDailyDigest.exportedFunctions.handler
description: Calculates and collates previous day's new posts which matching the user's daily subscriptions
role: calculateUserDailyDigestLambdaRole
environment:
Expand Down
40 changes: 40 additions & 0 deletions tests/calculateUserDailyDigest.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import ESSearch from '../common/search/search';
import { exportedFunctions } from '../functions/calculateUserDailyDigest';

const esSearchResult = require('./test_data/esSearchResult');
const lambdaResult = require('./test_data/lambdaResult');

jest.mock('aws-sdk');
jest.mock('http-aws-es');
jest.mock('../common/search/search');
jest.mock('../common/query');

const handlerInput = {
userId: 1,
subscriptions: ['test', 'math']
};

describe('calculateUserDailyDigest function', () => {
beforeAll(() => {
process.env = Object.assign(process.env, {
ES_SEARCH_API: 'elasticsearch/api',
EMAIL_MAX_POSTS: 100,
SEND_DIGEST_EMAIL_LAMBDA_NAME: 'sendDigestEmail'
});
});

it('invokes calculateUserDailyDigest for each user with at least one subscription', async () => {
ESSearch.mockImplementation(() => ({
doMultiSearch: jest.fn().mockReturnValue(esSearchResult)
}));

exportedFunctions.sendDailyDigestEmail = jest.fn();

await exportedFunctions.handler(handlerInput);
expect(exportedFunctions.sendDailyDigestEmail).toBeCalledWith(
lambdaResult,
expect.anything(),
expect.anything()
);
});
});
Loading

0 comments on commit 46218b6

Please sign in to comment.