Refactor code and add test for threading

This commit is contained in:
Jackie Luo 2016-06-27 14:52:05 -07:00
parent 94cd088dd7
commit 179f24449b
5 changed files with 173 additions and 14 deletions

View file

@ -9,9 +9,9 @@ global.Promise = require('bluebird');
const MessageAttributes = ['body', 'processed']
const MessageProcessorVersion = 1;
function runPipeline(accountId, message) {
function runPipeline({db, accountId, message}) {
return processors.reduce((prevPromise, processor) => (
prevPromise.then((msg) => processor({message: msg, accountId}))
prevPromise.then((msg) => processor({db, accountId, message: msg}))
), Promise.resolve(message))
}
@ -24,9 +24,10 @@ function saveMessage(message) {
function processMessage({messageId, accountId}) {
DatabaseConnector.forAccount(accountId)
.then(({Message}) =>
.then((db) => {
const {Message} = db
Message.find({where: {id: messageId}}).then((message) =>
runPipeline(accountId, message)
runPipeline({db, accountId, message})
.then((processedMessage) => saveMessage(processedMessage))
.catch((err) =>
console.error(`MessageProcessor Failed: ${err}`)
@ -35,7 +36,7 @@ function processMessage({messageId, accountId}) {
.catch((err) =>
console.error(`MessageProcessor: Couldn't find message id ${messageId} in accountId: ${accountId}: ${err}`)
)
)
})
}
module.exports = {

View file

@ -50,13 +50,15 @@ function findCorrespondingThread({message, threads}) {
function removeBccParticipants({message, match}) {
const matchBcc = match.bcc ? match.bcc : []
const messageBcc = message.bcc ? message.bcc : []
let matchEmails = match.participants.filter((participant) => {
const matchParticipants = [...match.from, ...match.to, ...match.cc, ...match.bcc]
const messageParticipants = [...message.from, ...message.to, ...message.cc, ...message.bcc]
let matchEmails = matchParticipants.filter((participant) => {
return matchBcc.find(bcc => bcc === participant)
})
matchEmails.map((email) => {
return email[1]
})
let messageEmails = message.participants.filter((participant) => {
let messageEmails = messageParticipants.filter((participant) => {
return messageBcc.find(bcc => bcc === participant)
})
messageEmails.map((email) => {
@ -125,7 +127,6 @@ function matchThread({db, accountId, message}) {
return thread
}
return Thread.create({
subject: message.subject,
cleanedSubject: cleanSubject(message.subject),
})
})
@ -138,7 +139,6 @@ function matchThread({db, accountId, message}) {
return thread
}
return Thread.create({
subject: message.subject,
cleanedSubject: cleanSubject(message.subject),
})
})
@ -148,15 +148,21 @@ function addMessageToThread({db, accountId, message}) {
const {Thread} = db
// Check for Gmail's own thread ID
if (message.headers['X-GM-THRID']) {
return Thread.find({where: {threadId: message.headers['X-GM-THRID']}})
const thread = Thread.find({where: {threadId: message.headers['X-GM-THRID']}})
if (thread) {
return thread
}
return Thread.create({
cleanedSubject: cleanSubject(message.subject),
threadId: message.headers['X-GM-THRID'],
})
}
return matchThread({db, accountId, message})
.then((thread) => (thread))
}
function processMessage({message, accountId}) {
return DatabaseConnector.forAccount(accountId)
.then((db) => addMessageToThread({db, accountId, message}))
function processMessage({db, accountId, message}) {
return addMessageToThread({db, accountId, message})
.then((thread) => {
thread.addMessage(message)
message.setThread(thread)

View file

@ -0,0 +1,94 @@
export const message = {
id: 1,
subject: "Loved your work and interests",
body: "<head></head><body>Hi Jackie,<div><div>While browsing Nylas&nbsp;themes, I stumbled upon your website and looked at your work.&nbsp;</div><div>Great work on projects, nice to see your multidisciplinary interests :)</div><div><div><br></div><!-- <signature> -->Thanks,&nbsp;<div>Sagar Sutar</div><div>thesagarsutar.me</div><!-- </signature> --></div></div><img class=\"n1-open\" width=\"0\" height=\"0\" style=\"border:0; width:0; height:0;\" src=\"https://link.nylas.com/open/8w734mdm7q9ivpc0cnq3ousy3/local-7b7d5479-575c?r=amFja2llaGx1b0BnbWFpbC5jb20=\"></body>",
headers: {
"Delivered-To": "jackiehluo@gmail.com",
"Received": `by 10.107.182.215 with SMTP id g206csp311103iof;
Fri, 17 Jun 2016 09:38:45 -0700 (PDT)`,
"X-Received": `by 10.66.16.133 with SMTP id g5mr1799805pad.145.1466181525915;
Fri, 17 Jun 2016 09:38:45 -0700 (PDT)`,
"Return-Path": "<sagy26.1991@gmail.com>",
"Received": `from mail-pf0-f174.google.com (mail-pf0-f174.google.com.
[209.85.192.174])
by mx.google.com with ESMTPS id n6si15649421pav.242.2016.06.17.09.38.45
for <jackiehluo@gmail.com>
(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
Fri, 17 Jun 2016 09:38:45 -0700 (PDT)`,
"Received-SPF": `pass (google.com: domain of sagy26.1991@gmail.com
designates 209.85.192.174 as permitted sender) client-ip=209.85.192.174;`,
"Authentication-Results": `mx.google.com;
spf=pass (google.com: domain of sagy26.1991@gmail.com designates
209.85.192.174 as permitted sender) smtp.mailfrom=sagy26.1991@gmail.com`,
"Received": `by mail-pf0-f174.google.com with SMTP id i123so25772868pfg.0
for <jackiehluo@gmail.com>; Fri, 17 Jun 2016 09:38:45 -0700 (PDT)`,
"X-Google-DKIM-Signature": `v=1; a=rsa-sha256; c=relaxed/relaxed;
d=1e100.net; s=20130820;
h=x-gm-message-state:date:user-agent:message-id:to:from:subject
:mime-version;
bh=to3fCB9g4R6V18kpAAKSAlUeTC+N0rg4JckFbiaILA4=;
b=WfI5viTYPjviUur9Bd2rJQfpHxIm2xYRdxrN64bJGuX0TQlb7p8bDvCBNNhY3mTXJx
lsQzRX9RA4FMuDk0oz0mpviWtkpkZsDeyjpSmA+ONcPgdyPAezzPDvSWRzMZY21fiHxS
hr4I5AeFKesGcbvwtJu+S0fMGhdveC8E35oTA010Xfave6Xd55qGXy7hW+4xCfvIesy4
01oOaXWDmLHqixKO3SXwmGCcDzqn/IKXhB7UXkF0efSTwh8yid6v9iXdW+ovJ2qg9peI
HSnPIilYk8SaKoPdGDgYZykfUIgNrSugtK/vvGG2aN+9lhURxPfzhniWdNqdsgR7G4E7
7XqA==`,
"X-Gm-Message-State": "ALyK8tIf7XyYaylyVf0qjzh8rhYz3rj/VQYaNLDjVq5ESH19ioJIgW7o9FbghP+wFYrBuw==",
"X-Received": `by 10.98.111.138 with SMTP id k132mr3246291pfc.105.1466181525186;
Fri, 17 Jun 2016 09:38:45 -0700 (PDT)`,
"Return-Path": "<sagy26.1991@gmail.com>",
"Received": `from [127.0.0.1] (ec2-52-36-99-221.us-west-2.compute.amazonaws.com. [52.36.99.221])
by smtp.gmail.com with ESMTPSA id d69sm64179062pfj.31.2016.06.17.09.38.44
for <jackiehluo@gmail.com>
(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
Fri, 17 Jun 2016 09:38:44 -0700 (PDT)`,
"Date": "Fri, 17 Jun 2016 09:38:44 -0700 (PDT)",
"User-Agent": "NylasMailer/0.4",
"Message-Id": "<82y7eq1ipmadaxwcy6kr072bw-2147483647@mailer.nylas.com>",
"X-Inbox-Id": "82y7eq1ipmadaxwcy6kr072bw-2147483647",
},
from: [{
name: "Sagar Sutar",
email: "<sagar_s@nid.edu>",
}],
to: [{
name: "jackiehluo@gmail.com",
email: "<jackiehluo@gmail.com>",
}],
cc: [],
bcc: [],
messageId: "<82y7eq1ipmadaxwcy6kr072bw-2147483647@mailer.nylas.com>",
snippet: "Hi Jackie, While browsing Nylas themes, I stumbled upon your website and looked at your work. Great ",
setThread: (thread) => {
message.thread = thread.id
},
}
export const reply = {
id: 2,
subject: "Re: Loved your work and interests",
body: "<head></head><body>Sagar,<div><div><br></div><div>Aw, glad to hear it! Thanks for getting in touch!</div><br><!-- <signature> -->Jackie Luo<div>Software Engineer, Nylas</div><br><!-- </signature> --></div><div class=\"gmail_quote\">On Jun 17 2016, at 9:38 am, Sagar Sutar &lt;sagar_s@nid.edu&gt; wrote:<br><blockquote class=\"gmail_quote\" style=\"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;\">Hi Jackie,<div><div>While browsing Nylas&nbsp;themes, I stumbled upon your website and looked at your work.&nbsp;</div><div>Great work on projects, nice to see your multidisciplinary interests :)</div><div><div><br></div>Thanks,&nbsp;<div>Sagar Sutar</div><div>thesagarsutar.me</div></div></div><img width=\"0\" height=\"0\" style=\"border:0; width:0; height:0;\" src=\"https://link.nylas.com/open/8w734mdm7q9ivpc0cnq3ousy3/local-7b7d5479-575c?r=amFja2llaGx1b0BnbWFpbC5jb20=\"></blockquote></div></body>",
headers: {
"Date": "Fri, 17 Jun 2016 18:20:47 +0000",
"References": "<82y7eq1ipmadaxwcy6kr072bw-2147483647@mailer.nylas.com>",
"In-Reply-To": "<82y7eq1ipmadaxwcy6kr072bw-2147483647@mailer.nylas.com>",
"User-Agent": "NylasMailer/0.4",
"Message-Id": "<cq08iqwatp00kai4qnff7zbaj-2147483647@mailer.nylas.com>",
"X-Inbox-Id": "cq08iqwatp00kai4qnff7zbaj-2147483647",
},
from: [{
name: "Jackie Luo",
email: "<jackiehluo@gmail.com>",
}],
to: [{
name: "Sagar Sutar",
email: "<sagar_s@nid.edu>",
}],
cc: [],
bcc: [],
messageId: "<cq08iqwatp00kai4qnff7zbaj-2147483647@mailer.nylas.com>",
snippet: "Sagar, Aw, glad to hear it! Thanks for getting in touch! Jackie Luo Software Engineer, Nylas",
setThread: (thread) => {
reply.thread = thread.id
},
}

View file

@ -0,0 +1,58 @@
const path = require('path')
const fs = require('fs')
const {DatabaseConnector} = require('nylas-core')
const {processMessage} = require('../processors/threading')
const BASE_PATH = path.join(__dirname, 'fixtures')
it('adds the message to the thread', (done) => {
const {message, reply} = require(`${BASE_PATH}/thread`)
const accountId = 'a-1'
const mockDb = {
Thread: {
findAll: () => {
return Promise.resolve([
{
id: 1,
cleanedSubject: "Loved your work and interests",
messages: [message],
}])
},
find: () => {
return Promise.resolve(null)
},
create: (thread) => {
thread.id = 1
thread.addMessage = (message) => {
if (thread.messages) {
thread.messages.push(message.id)
} else {
thread.messages = [message.id]
}
}
return Promise.resolve(thread)
}
},
Message: {
findAll: () => {
return Promise.resolve([message, reply])
},
find: () => {
return Promise.resolve(reply)
},
create: (message) => {
message.setThread = (thread) => {
console.log("setting")
message.thread = thread.id
}
return Promise.resolve(message)
}
}
}
processMessage({db: mockDb, message: reply, accountId}).then((processed) => {
expect(processed.thread).toBe(1)
done()
})
})

View file

@ -63,7 +63,7 @@ class SyncProcessManager {
client.setAsync(key, Date.now()).then(() =>
client.expireAsync(key, HEARTBEAT_EXPIRES)
).then(() =>
console.log("ProcessManager: ")
console.log("ProcessManager: 💘")
)
}