Skip to content

Commit

Permalink
Merge pull request responsible-ai-collaborative#2490 from clari182/fi…
Browse files Browse the repository at this point in the history
…x/refactor-submission-approved

Fix/refactor submission approved
  • Loading branch information
kepae authored Jan 8, 2024
2 parents ce13e0a + a4cec26 commit 5964151
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 131 deletions.
15 changes: 0 additions & 15 deletions site/gatsby-site/cypress/e2e/integration/apps/submitted.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,21 +171,6 @@ describe('Submitted reports', () => {
}
);

cy.conditionalIntercept(
'**/graphql',
(req) =>
req.body.operationName == 'UpsertSubscription' &&
req.body.variables?.query?.type === SUBSCRIPTION_TYPE.submissionPromoted,
'UpsertSubscriptionPromoted',
{
data: {
upsertOneSubscription: {
_id: 'dummyIncidentId',
},
},
}
);

cy.get('select[data-cy="promote-select"]').as('dropdown');

cy.get('@dropdown').select('Incident');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,22 @@ const pendingNotifications = [
type: SUBSCRIPTION_TYPE.submissionPromoted,
incident_id: 217,
processed: false,
userId: '63320ce63ec803072c9f5291',
},
{
_id: '63616f82d0db19c07d081401',
type: SUBSCRIPTION_TYPE.submissionPromoted,
incident_id: 218,
processed: false,
userId: '63320ce63ec803072c9f5291',
},
//Duplicated pending notification
{
_id: '63616f82d0db19c07d081402',
type: SUBSCRIPTION_TYPE.submissionPromoted,
incident_id: 218,
processed: false,
userId: '63320ce63ec803072c9f5291',
},
];

Expand Down Expand Up @@ -73,9 +76,7 @@ describe('Process New Promotions Pending Notifications', () => {

const sendEmailCallArgs = sendEmailCalls[i].args[1];

const userIds = subscriptions
.filter((s) => s.incident_id === pendingNotification.incident_id)
.map((subscription) => subscription.userId);
const userIds = pendingNotifications.map((n) => n.userId);

const incident = incidents.find((i) => i.incident_id == pendingNotification.incident_id);

Expand Down Expand Up @@ -107,43 +108,32 @@ describe('Process New Promotions Pending Notifications', () => {
});

it('New Promotions - Should send pending submissions promoted notifications', () => {
const { notificationsCollection, subscriptionsCollection, incidentsCollection } =
stubEverything({
subscriptionType: SUBSCRIPTION_TYPE.submissionPromoted,
pendingNotifications,
subscriptions,
});
const { notificationsCollection, incidentsCollection } = stubEverything({
subscriptionType: SUBSCRIPTION_TYPE.submissionPromoted,
pendingNotifications,
subscriptions,
});

cy.wrap(processNotifications()).then(() => {
expect(notificationsCollection.find.getCall(3).args[0]).to.deep.equal({
processed: false,
type: SUBSCRIPTION_TYPE.submissionPromoted,
});

for (const subscription of subscriptions) {
for (const notification of pendingNotifications) {
expect(global.context.functions.execute).to.be.calledWith('getUser', {
userId: subscription.userId,
userId: notification.userId,
});
}

for (let i = 0; i < uniquePendingNotifications.length; i++) {
const pendingNotification = uniquePendingNotifications[i];

expect(
subscriptionsCollection.find.getCall(i).args[0],
'Get subscriptions for Incident'
).to.deep.equal({
type: SUBSCRIPTION_TYPE.submissionPromoted,
incident_id: pendingNotification.incident_id,
});

expect(incidentsCollection.findOne.getCall(i).args[0], 'Find incident').to.deep.equal({
incident_id: pendingNotification.incident_id,
});

const userIds = subscriptions
.filter((s) => s.incident_id === pendingNotification.incident_id)
.map((subscription) => subscription.userId);
const userIds = pendingNotifications.map((n) => n.userId);

const incident = incidents.find((i) => i.incident_id == pendingNotification.incident_id);

Expand Down Expand Up @@ -176,7 +166,7 @@ describe('Process New Promotions Pending Notifications', () => {
});

it('New Promotions - Should mark pending notifications as processed if there are no subscribers', () => {
const { notificationsCollection, subscriptionsCollection } = stubEverything({
const { notificationsCollection } = stubEverything({
subscriptionType: SUBSCRIPTION_TYPE.submissionPromoted,
pendingNotifications,
subscriptions: [],
Expand All @@ -203,16 +193,9 @@ describe('Process New Promotions Pending Notifications', () => {
type: SUBSCRIPTION_TYPE.submissionPromoted,
});

expect(global.context.functions.execute).not.to.be.called;

for (let i = 0; i < uniquePendingNotifications.length; i++) {
const pendingNotification = uniquePendingNotifications[i];

expect(subscriptionsCollection.find.getCall(i).args[0]).to.deep.equal({
type: SUBSCRIPTION_TYPE.submissionPromoted,
incident_id: pendingNotification.incident_id,
});

expect(notificationsCollection.updateOne.getCall(i).args[0]).to.deep.equal({
_id: pendingNotification._id,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,11 @@ describe('Functions', () => {
modifiedBy: submission.user,
});

expect(subscriptionsCollection.insertOne.firstCall.args[0]).to.deep.equal({
expect(notificationsCollection.insertOne.firstCall.args[0]).to.deep.equal({
type: SUBSCRIPTION_TYPE.submissionPromoted,
incident_id: 2,
userId: 'user1',
processed: false,
});
});
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
{}
{
"userId": {
"ref": "#/relationship/mongodb-atlas/customData/users",
"source_key": "userId",
"foreign_key": "userId",
"is_list": false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
},
"type": {
"bsonType": "string"
},
"userId": {
"bsonType": "string"
}
},
"title": "notification"
Expand Down
143 changes: 65 additions & 78 deletions site/realm/functions/processNotifications.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,54 +240,54 @@ exports = async function () {
if (!uniqueNotifications.some(n => n.incident_id === pendingNotification.incident_id && n.type === pendingNotification.type)) {
uniqueNotifications.push(pendingNotification);

try {
const subscriptionsToIncidentUpdates = await subscriptionsCollection.find({
type: 'incident',
incident_id: pendingNotification.incident_id
}).toArray();
try {
const subscriptionsToIncidentUpdates = await subscriptionsCollection.find({
type: 'incident',
incident_id: pendingNotification.incident_id
}).toArray();

// Process subscriptions to Incident updates
if (subscriptionsToIncidentUpdates.length > 0) {
// Process subscriptions to Incident updates
if (subscriptionsToIncidentUpdates.length > 0) {

const userIds = subscriptionsToIncidentUpdates.map((subscription) => subscription.userId);
const userIds = subscriptionsToIncidentUpdates.map((subscription) => subscription.userId);

const uniqueUserIds = [...new Set(userIds)];
const uniqueUserIds = [...new Set(userIds)];

const recipients = await getRecipients(uniqueUserIds);
const recipients = await getRecipients(uniqueUserIds);

const incident = await incidentsCollection.findOne({ incident_id: pendingNotification.incident_id });
const incident = await incidentsCollection.findOne({ incident_id: pendingNotification.incident_id });

const newReportNumber = pendingNotification.report_number;
const newReportNumber = pendingNotification.report_number;

const newReport = newReportNumber ? await reportsCollection.findOne({ report_number: newReportNumber }) : null;
const newReport = newReportNumber ? await reportsCollection.findOne({ report_number: newReportNumber }) : null;

//Send email notification
const sendEmailParams = {
recipients,
subject: 'Incident {{incidentId}} was updated',
dynamicData: {
incidentId: `${incident.incident_id}`,
incidentTitle: incident.title,
incidentUrl: `https://incidentdatabase.ai/cite/${incident.incident_id}`,
reportUrl: `https://incidentdatabase.ai/cite/${incident.incident_id}#r${newReportNumber}`,
reportTitle: newReportNumber ? newReport.title : '',
reportAuthor: newReportNumber && newReport.authors[0] ? newReport.authors[0] : '',
},
// Template value from function name sufix from "site/realm/functions/config.json"
templateId: newReportNumber ? 'NewReportAddedToAnIncident' : 'IncidentUpdate',
};
//Send email notification
const sendEmailParams = {
recipients,
subject: 'Incident {{incidentId}} was updated',
dynamicData: {
incidentId: `${incident.incident_id}`,
incidentTitle: incident.title,
incidentUrl: `https://incidentdatabase.ai/cite/${incident.incident_id}`,
reportUrl: `https://incidentdatabase.ai/cite/${incident.incident_id}#r${newReportNumber}`,
reportTitle: newReportNumber ? newReport.title : '',
reportAuthor: newReportNumber && newReport.authors[0] ? newReport.authors[0] : '',
},
// Template value from function name sufix from "site/realm/functions/config.json"
templateId: newReportNumber ? 'NewReportAddedToAnIncident' : 'IncidentUpdate',
};

await context.functions.execute('sendEmail', sendEmailParams);
await context.functions.execute('sendEmail', sendEmailParams);

console.log(`Incident ${incident.incident_id} updates: Pending notification was processed.`);
}
} catch (error) {
// If there is an error sending the email > Mark the notification as not processed
await markNotificationsAsNotProcessed(notificationsCollection, [pendingNotification]);
console.log(`Incident ${incident.incident_id} updates: Pending notification was processed.`);
}
} catch (error) {
// If there is an error sending the email > Mark the notification as not processed
await markNotificationsAsNotProcessed(notificationsCollection, [pendingNotification]);

error.message = `[Process Pending Notifications: Incidents Updates]: ${error.message}`;
context.functions.execute('logRollbar', { error });
}
error.message = `[Process Pending Notifications: Incidents Updates]: ${error.message}`;
context.functions.execute('logRollbar', { error });
}
}
}
}
Expand All @@ -299,7 +299,6 @@ exports = async function () {
context.functions.execute('logRollbar', { error });
}


// Notifications to New Promotions
try {

Expand All @@ -310,63 +309,51 @@ exports = async function () {

result += pendingNotificationsToNewPromotions.length;

const userIds = pendingNotificationsToNewPromotions.map((subscription) => subscription.userId);

const uniqueUserIds = [...new Set(userIds)];

const recipients = await getRecipients(uniqueUserIds);

let uniqueNotifications = [];

for (const pendingNotification of pendingNotificationsToNewPromotions) {

// Mark the notification as processed before sending the email
await markNotificationsAsProcessed(notificationsCollection, [pendingNotification]);

// Process each Incident only once
if (!uniqueNotifications.includes(pendingNotification.incident_id)) {
uniqueNotifications.push(pendingNotification.incident_id);

// Finds all subscriptions to New Promotions for this Incident
const subscriptionsToNewPromotions = await subscriptionsCollection.find({
type: 'submission-promoted',
incident_id: pendingNotification.incident_id
}).toArray();

// Process subscriptions to New Incidents
if (subscriptionsToNewPromotions.length > 0) {

const userIds = subscriptionsToNewPromotions.map((subscription) => subscription.userId);

const uniqueUserIds = [...new Set(userIds)];

const recipients = await getRecipients(uniqueUserIds);

try {
const incident = await incidentsCollection.findOne({ incident_id: pendingNotification.incident_id });

//Send email notification
const sendEmailParams = {
recipients,
subject: 'Your submission has been approved!',
dynamicData: {
incidentId: `${incident.incident_id}`,
incidentTitle: incident.title,
incidentUrl: `https://incidentdatabase.ai/cite/${incident.incident_id}`,
incidentDescription: incident.description,
incidentDate: incident.date,
},
templateId: 'SubmissionApproved' // Template value from function name sufix from "site/realm/functions/config.json"
};
try {
const incident = await incidentsCollection.findOne({ incident_id: pendingNotification.incident_id });

await context.functions.execute('sendEmail', sendEmailParams);
//Send email notification
const sendEmailParams = {
recipients,
subject: 'Your submission has been approved!',
dynamicData: {
incidentId: `${incident.incident_id}`,
incidentTitle: incident.title,
incidentUrl: `https://incidentdatabase.ai/cite/${incident.incident_id}`,
incidentDescription: incident.description,
incidentDate: incident.date,
},
templateId: 'SubmissionApproved' // Template value from function name sufix from "site/realm/functions/config.json"
};

console.log(`Promoted notification for incident ${incident.incident_id} was processed.`);
await context.functions.execute('sendEmail', sendEmailParams);

} catch (error) {
// If there is an error sending the email > Mark the notification as not processed
await markNotificationsAsNotProcessed(notificationsCollection, [pendingNotification]);
} catch (error) {
// If there is an error sending the email > Mark the notification as not processed
await markNotificationsAsNotProcessed(notificationsCollection, [pendingNotification]);

error.message = `[Process Pending Notifications: Submission Promoted]: ${error.message}`;
context.functions.execute('logRollbar', { error });
}
error.message = `[Process Pending Notifications: Submission Promoted]: ${error.message}`;
context.functions.execute('logRollbar', { error });
}
}
}

console.log(`New Promotions: ${pendingNotificationsToNewPromotions.length} pending notifications were processed.`);
}
else {
Expand Down
8 changes: 2 additions & 6 deletions site/realm/functions/promoteSubmissionToReport.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,12 @@ exports = async (input) => {
await incidents.insertOne({ ...newIncident, incident_id: BSON.Int32(newIncident.incident_id) });

if (submission.user) {
await subscriptionsCollection.insertOne({
type: 'submission-promoted',
incident_id: BSON.Int32(newIncident.incident_id),
userId: submission.user
});

await notificationsCollection.insertOne({
type: 'submission-promoted',
incident_id: BSON.Int32(newIncident.incident_id),
processed: false
processed: false,
userId: submission.user
});
}

Expand Down

0 comments on commit 5964151

Please sign in to comment.