From b017520db402b6e9504900bc28b0d3cd15e6b81f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fassot?= Date: Thu, 25 Oct 2018 16:22:15 +0200 Subject: [PATCH] :sparkles: Import votes from JSON (#39) * Add import votes (not tested) * Finalise import votes function see #38 * forgot something * Fixed CircleCi import It still won't work until compute-stats and this branch are merged into master * Fixed import calling sendEmailToManager See #38 * Add some comments over the new field of vote * Forgot to remove a console.info * Fix review ! * Fix linting * fix review --- functions/src/cast-vote.ts | 2 + functions/src/config.ts | 7 ++++ functions/src/import-votes.ts | 56 ++++++++++++++++++++++++++ functions/src/index.ts | 4 ++ functions/src/send-email-to-manager.ts | 4 ++ 5 files changed, 73 insertions(+) create mode 100644 functions/src/import-votes.ts diff --git a/functions/src/cast-vote.ts b/functions/src/cast-vote.ts index ab5a024f..0e649c62 100644 --- a/functions/src/cast-vote.ts +++ b/functions/src/cast-vote.ts @@ -19,6 +19,7 @@ export interface Vote extends Employee { value: string; campaign: string; recordedAt: firestore.Timestamp; + voteFromUi?: boolean; //States if votes comes from Ui. If not, sendEmailToManager will abort } export const castVote = functions.https.onCall( @@ -66,6 +67,7 @@ export const castVote = functions.https.onCall( campaign: campaign.id, recordedAt: firestore.Timestamp.fromDate(voteDate), value: payload.vote, + voteFromUi: true, ...employee }; diff --git a/functions/src/config.ts b/functions/src/config.ts index 29dca52e..f56850f8 100644 --- a/functions/src/config.ts +++ b/functions/src/config.ts @@ -134,6 +134,12 @@ export interface DailyAlibeezImportConfig { export interface CollectStatsConfig { enabled: Flag; } + +export interface ImportVotesConfig { + enabled: Flag; + key: string; +} + export interface ComputeStatisticsConfigs { enabled: Flag; key: string; @@ -145,6 +151,7 @@ export interface FeaturesConfig { daily_alibeez_import: DailyAlibeezImportConfig; collect_stats: CollectStatsConfig; compute_statistics: ComputeStatisticsConfigs; + import_votes: ImportVotesConfig; } export interface AlibeezConfig { diff --git a/functions/src/import-votes.ts b/functions/src/import-votes.ts new file mode 100644 index 00000000..5d3f7528 --- /dev/null +++ b/functions/src/import-votes.ts @@ -0,0 +1,56 @@ +import * as functions from "firebase-functions"; +import * as firebase from "firebase-admin"; + +import { Config } from "./config"; +import { Vote } from "./cast-vote"; + +const config = functions.config() as Config; +const importVotesConfigs = config.features.import_votes; +const db = firebase.firestore(); + +const fromJSONtoVote = supposedlyValidVotes => { + if (!supposedlyValidVotes.votes) return []; + const validVotes: Vote[] = supposedlyValidVotes.votes.filter( + supposedlyValidVote => + supposedlyValidVote.value && + supposedlyValidVote.campaign && + supposedlyValidVote.agency + ); + return validVotes; +}; + +export const importVotes = functions.https.onRequest( + async (req: functions.Request, res: functions.Response) => { + if (!importVotesConfigs.enabled) { + console.info("Feature import votes disabled, aborting"); + return; + } + const authorizationHeader = req.get("Authorization") || ""; + const keyIsCorrect = + authorizationHeader === `Bearer ${importVotesConfigs.key}`; + if (!keyIsCorrect) { + console.error("Passed the wrong auth key, aborting"); + res.sendStatus(403); + return; + } + let validVotes: Vote[] = []; + if (req.body) { + validVotes = fromJSONtoVote(req.body); + } else { + console.error("votesData is null, aborting"); + res.sendStatus(422); + return; + } + const voteBatch = db.batch(); + for (const validVote of validVotes) { + voteBatch.create(db.collection("vote").doc(), validVote); + } + voteBatch + .commit() + .then(() => res.sendStatus(200)) + .catch(e => { + console.error(e); + res.sendStatus(500); + }); + } +); diff --git a/functions/src/index.ts b/functions/src/index.ts index 065a685f..214efbcd 100644 --- a/functions/src/index.ts +++ b/functions/src/index.ts @@ -22,6 +22,10 @@ export { getCampaign } from "./get-campaign"; export { castVote } from "./cast-vote"; +export { updateStats } from "./update-stats"; + +export { importVotes } from "./import-votes"; + export { updateStatsOnVote } from "./update-stats"; export { computeStatistics } from "./compute-statistics"; diff --git a/functions/src/send-email-to-manager.ts b/functions/src/send-email-to-manager.ts index 271afd63..0be5e409 100644 --- a/functions/src/send-email-to-manager.ts +++ b/functions/src/send-email-to-manager.ts @@ -24,6 +24,10 @@ export const sendEmailToManager = functions.firestore } const vote = voteSnapshot.data()! as Vote; + if (!vote.voteFromUi) { + console.info("Vote doesn't come from Ui, aborting..."); + return; + } const employeeSnapshot = await db .collection("employees")