Skip to content

Commit

Permalink
separate each variance into individual cells (#368)
Browse files Browse the repository at this point in the history
Signed-off-by: David <daveclaveau@gmail.com>
  • Loading branch information
davidclaveau authored Aug 14, 2024
1 parent 4379531 commit 9264684
Show file tree
Hide file tree
Showing 5 changed files with 272 additions and 189 deletions.
154 changes: 76 additions & 78 deletions arSam/handlers/export-variance/__tests__/export-variance.tests.js
Original file line number Diff line number Diff line change
@@ -1,60 +1,60 @@
const { DynamoDBClient, PutItemCommand } = require('@aws-sdk/client-dynamodb');
const { REGION, ENDPOINT } = require("../../../__tests__/settings");
const { PARKSLIST, SUBAREAS, VARIANCE_JOBSLIST, VARIANCE_MOCKJOB } = require("../../../__tests__/mock_data.json");
const { getHashedText, deleteDB, createDB } = require("../../../__tests__/setup");
const { REGION, ENDPOINT } = require('../../../__tests__/settings');
const { PARKSLIST, SUBAREAS, VARIANCE_JOBSLIST, VARIANCE_MOCKJOB } = require('../../../__tests__/mock_data.json');
const { getHashedText, deleteDB, createDB } = require('../../../__tests__/setup');
const { marshall } = require('@aws-sdk/util-dynamodb');
const jwt = require("jsonwebtoken");
const jwt = require('jsonwebtoken');
const tokenContent = {
resource_access: { "attendance-and-revenue": { roles: ["sysadmin"] } },
resource_access: { 'attendance-and-revenue': { roles: ['sysadmin'] } },
};
const token = jwt.sign(tokenContent, "defaultSecret");
const token = jwt.sign(tokenContent, 'defaultSecret');

async function setupDb(TABLE_NAME) {
const dynamoClient = new DynamoDBClient({
region: REGION,
endpoint: ENDPOINT
endpoint: ENDPOINT,
});

for (const park of PARKSLIST) {
let params = {
TableName: TABLE_NAME,
Item: marshall(park),
}
TableName: TABLE_NAME,
Item: marshall(park),
};
await dynamoClient.send(new PutItemCommand(params));
}

for (const subarea of SUBAREAS) {
params = {
TableName: TABLE_NAME,
Item: marshall(subarea),
}
TableName: TABLE_NAME,
Item: marshall(subarea),
};
await dynamoClient.send(new PutItemCommand(params));
}

for (const job of VARIANCE_JOBSLIST) {
params = {
TableName: TABLE_NAME,
Item: marshall(job),
}
TableName: TABLE_NAME,
Item: marshall(job),
};
await dynamoClient.send(new PutItemCommand(params));
}
}

describe("Export Variance Report", () => {
describe('Export Variance Report', () => {
const OLD_ENV = process.env;
let hash
let TABLE_NAME
let NAME_CACHE_TABLE_NAME
let CONFIG_TABLE_NAME
let hash;
let TABLE_NAME;
let NAME_CACHE_TABLE_NAME;
let CONFIG_TABLE_NAME;

beforeEach(async () => {
jest.resetModules();
process.env = { ...OLD_ENV }; // Make a copy of environment
hash = getHashedText(expect.getState().currentTestName);
process.env.TABLE_NAME = hash
process.env.TABLE_NAME = hash;
TABLE_NAME = process.env.TABLE_NAME;
NAME_CACHE_TABLE_NAME = TABLE_NAME.concat("-nameCache");
CONFIG_TABLE_NAME = TABLE_NAME.concat("-config");
NAME_CACHE_TABLE_NAME = TABLE_NAME.concat('-nameCache');
CONFIG_TABLE_NAME = TABLE_NAME.concat('-config');
await createDB(TABLE_NAME, NAME_CACHE_TABLE_NAME, CONFIG_TABLE_NAME);
await setupDb(TABLE_NAME);
});
Expand All @@ -64,135 +64,133 @@ describe("Export Variance Report", () => {
process.env = OLD_ENV; // Restore old environment
});

test("Handler - 403 GET Invalid Auth", async () => {
test('Handler - 403 GET Invalid Auth', async () => {
const event = {
headers: {
Authorization: "Bearer " + token,
},
httpMethod: "GET",
requestContext: {
authorizer: {
roles: "[\"public\"]",
isAdmin: false,
isAuthenticated: false,
},
headers: {
Authorization: 'Bearer ' + token,
},
httpMethod: 'GET',
requestContext: {
authorizer: {
roles: '["public"]',
isAdmin: false,
isAuthenticated: false,
},
},
};

const varianceExportGET = require("../GET/index");
const varianceExportGET = require('../GET/index');
const response = await varianceExportGET.handler(event, null);

expect(response.statusCode).toBe(403);
});

test("Handler - 400 no fiscal year provided", async () => {
const dateField = "dateGenerated"
test('Handler - 400 no fiscal year provided', async () => {
const dateField = 'dateGenerated';
const event = {
headers: {
Authorization: "Bearer " + token,
Authorization: 'Bearer ' + token,
},
httpMethod: "GET",
httpMethod: 'GET',
requestContext: {
authorizer: {
roles: "[\"sysadmin\"]",
roles: '["sysadmin"]',
isAdmin: true,
isAuthenticated: true,
},
},
queryStringParameters: {
getJob: "true"
getJob: 'true',
},
};

const varianceExportGET = require("../GET/index");
const varianceExportGET = require('../GET/index');
const result = await varianceExportGET.handler(event, null);
let body;
try {
body = JSON.parse(result.body)
body = JSON.parse(result.body);
} catch (e) {
body = 'fail'
body = 'fail';
}
expect(result).toEqual(
expect.objectContaining({
headers: {
"Access-Control-Allow-Headers":
"Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token",
"Access-Control-Allow-Methods": "OPTIONS,GET,POST,PUT,DELETE",
"Access-Control-Allow-Origin": "*",
"Content-Type": "application/json",
'Access-Control-Allow-Headers': 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token',
'Access-Control-Allow-Methods': 'OPTIONS,GET,POST,PUT,DELETE',
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
},
statusCode: 400,
}),
);
})
});

test("Handler - 200 GET, with no jobs", async () => {
process.env.IS_OFFLINE = 'true'
const dateField = "dateGenerated"
test('Handler - 200 GET, with no jobs', async () => {
process.env.IS_OFFLINE = 'true';
const dateField = 'dateGenerated';
const event = {
headers: {
Authorization: "Bearer " + token,
Authorization: 'Bearer ' + token,
},
httpMethod: "GET",
httpMethod: 'GET',
requestContext: {
authorizer: {
roles: "[\"sysadmin\"]",
roles: '["sysadmin"]',
isAdmin: true,
isAuthenticated: true,
},
},
queryStringParameters: {
getJob: "true",
fiscalYearEnd: 2023
getJob: 'true',
fiscalYearEnd: 2023,
},
};

const varianceExportGET = require("../GET/index");
const varianceExportGET = require('../GET/index');
const result = await varianceExportGET.handler(event, null);
let body;
try {
body = JSON.parse(result.body)
body = JSON.parse(result.body);
console.log('body:', body);
} catch (e) {
body = 'fail'
body = 'fail';
}
expect(result).toEqual(
expect.objectContaining({
headers: {
"Access-Control-Allow-Headers":
"Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token",
"Access-Control-Allow-Methods": "OPTIONS,GET,POST,PUT,DELETE",
"Access-Control-Allow-Origin": "*",
"Content-Type": "application/json",
'Access-Control-Allow-Headers': 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token',
'Access-Control-Allow-Methods': 'OPTIONS,GET,POST,PUT,DELETE',
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
},
statusCode: 200,
}),
);
expect(body.jobObj[dateField]).toMatch(VARIANCE_JOBSLIST[0][dateField])
})
expect(body.jobObj[dateField]).toMatch(VARIANCE_JOBSLIST[0][dateField]);
});

test("Handler - 200 GET, generate report", async () => {
test('Handler - 200 GET, generate report', async () => {
const event = {
headers: {
Authorization: "Bearer " + token,
Authorization: 'Bearer ' + token,
},
httpMethod: "GET",
httpMethod: 'GET',
requestContext: {
authorizer: {
roles: "[\"sysadmin\"]",
roles: '["sysadmin"]',
isAdmin: true,
isAuthenticated: true,
},
},
queryStringParameters: {
fiscalYearEnd: 2023
fiscalYearEnd: 2023,
},
};
const varianceExportGET = require("../GET/index");
const result = await varianceExportGET.handler(event, null)
const varianceExportGET = require('../GET/index');
const result = await varianceExportGET.handler(event, null);

// Returns value below even with no job
// Update when invokable can be called
expect(result.body).toBe("{\"msg\":\"Variance report export job already running\"}")
expect(result.body).toBe('{"msg":"Variance report export job already running"}');
});
});
63 changes: 54 additions & 9 deletions arSam/handlers/export-variance/invokable/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const fs = require('fs');
const { VARIANCE_CSV_SCHEMA, VARIANCE_STATE_DICTIONARY } = require("/opt/constantsLayer");
const { VARIANCE_CSV_SCHEMA, VARIANCE_STATE_DICTIONARY, EXPORT_VARIANCE_CONFIG } = require("/opt/constantsLayer");
const { getParks,
TABLE_NAME,
dynamoClient,
Expand Down Expand Up @@ -234,16 +234,29 @@ function updateHighAccuracyJobState(state, index, total, size){
}
}

// used to flatten EXPORT_VARIANCE_CONFIG keys into an array
function flattenConfig(config) {
let flattenedKeys = [];
Object.values(config).forEach(category => {
Object.keys(category).forEach(key => {
flattenedKeys.push(key);
});
});
return flattenedKeys;
}

function formatRecords(records) {
for (const record of records) {
// list all variances as semicolon separated string so it can be parsed later
if (record.fields.length > 0) {
let fields = [];
// add each existing variance field to the record
if (record.fields && record.fields.length > 0) {
for (const field of record.fields) {
const percent = (parseFloat(field.percentageChange) * 100).toFixed(2);
fields.push(String(field.key + " " + percent + "%"));
// if the key matches an item in the array of EXPORT_VARIANCE_CONFIG, push it to the record
const flattenedConfig = flattenConfig(EXPORT_VARIANCE_CONFIG);
if (flattenedSchema.includes(field.key)) {
const percent = (parseFloat(field.percentageChange) * 100).toFixed(2);
record[field.key] = String(percent + "%");
}
}
record['fields'] = fields.join("; ");
}
const date = record.pk.split('::')[2];
record['year'] = date.slice(0, 4);
Expand All @@ -268,8 +281,39 @@ function createCSV(records) {
record.year || 'N/A',
record.month || 'N/A',
`"${record.notes || ''}"`,
record.fields || '',
record.resolved || ''
record.resolved || '',
record['peopleAdult'] || '',
record['peopleChild'] || '',
record['peopleFamily'] || '',
record['revenueFamily'] || '',
record['people'] || '',
record['grossCampingRevenue'] || '',
record['boatAttendanceNightsOnDock'] || '',
record['boatAttendanceNightsOnBouys'] || '',
record['boatAttendanceMiscellaneous'] || '',
record['boatRevenueGross'] || '',
record['peopleAndVehiclesTrail'] || '',
record['peopleAndVehiclesVehicle'] || '',
record['peopleAndVehiclesBus'] || '',
record['picnicRevenueShelter'] || '',
record['picnicShelterPeople'] || '',
record['picnicRevenueGross'] || '',
record['otherDayUsePeopleHotSprings'] || '',
record['otherDayUseRevenueHotSprings'] || '',
record['totalAttendanceParties'] || '',
record['revenueGrossCamping'] || '',
record['campingPartyNightsAttendanceStandard'] || '',
record['campingPartyNightsAttendanceSenior'] || '',
record['campingPartyNightsAttendanceSocial'] || '',
record['campingPartyNightsAttendanceLongStay'] || '',
record['campingPartyNightsRevenueGross'] || '',
record['secondCarsAttendanceStandard'] || '',
record['secondCarsAttendanceSenior'] || '',
record['secondCarsAttendanceSocial'] || '',
record['secondCarsRevenueGross'] || '',
record['otherRevenueGrossSani'] || '',
record['otherRevenueElectrical'] || '',
record['otherRevenueShower'] || ''
])
}
let csvData = '';
Expand Down Expand Up @@ -312,3 +356,4 @@ function convertMonth(monthNumber){
}

}

Loading

0 comments on commit 9264684

Please sign in to comment.