mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-11-11 01:54:40 +08:00
[local-sync] Add specs for message parsing
Summary: This commit also fixes snippets for HTML-only messages to strip out HTML tags, and makes us preserve whitespace for plaintext emails by displaying them in <pre class="nylas-plaintext"> tags, and makes us log messages that fail to parse at all to a tempdir. The only issue I found with using <pre> tags for plaintext email was that some lines may trigger scrolling, so there is an associated commit (D3484) that changes the CSS for <pre class="nylas-plaintext"> to wrap lines. In the future, we can add regression tests to this test suite whenever we fix parsing bugs. Test Plan: unit tests included Reviewers: bengotow Reviewed By: bengotow Differential Revision: https://phab.nylas.com/D3483
This commit is contained in:
parent
c3bd3dc297
commit
a23c68092e
12 changed files with 36 additions and 10 deletions
|
@ -23,7 +23,8 @@
|
|||
"sqlite3": "https://github.com/bengotow/node-sqlite3/archive/bengotow/usleep-v3.1.4.tar.gz",
|
||||
"striptags": "2.1.1",
|
||||
"underscore": "1.8.3",
|
||||
"utf7": "1.0.2",
|
||||
"utf7": "^1.0.2",
|
||||
"striptags": "2.1.1",
|
||||
"vision": "4.1.0"
|
||||
},
|
||||
"scripts": {
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"imapMessage": {},
|
||||
"desiredParts": {},
|
||||
"result": {}
|
||||
}
|
File diff suppressed because one or more lines are too long
1
packages/local-sync/spec/fixtures/MessageFactory/parseFromImap/eff-plaintext-no-mime.json
vendored
Normal file
1
packages/local-sync/spec/fixtures/MessageFactory/parseFromImap/eff-plaintext-no-mime.json
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -26,10 +26,17 @@ describe('MessageFactory', function MessageFactorySpecs() {
|
|||
forEachJSONFixture('MessageFactory/parseFromImap', (filename, json) => {
|
||||
it(`should correctly build message properties for ${filename}`, () => {
|
||||
const {imapMessage, desiredParts, result} = json;
|
||||
// requiring these to match makes it overly arduous to generate test
|
||||
// cases from real accounts
|
||||
const excludeKeys = new Set(['id', 'accountId', 'folderId', 'folder', 'labels']);
|
||||
|
||||
waitsForPromise(async () => {
|
||||
const actual = await parseFromImap(imapMessage, desiredParts, this.options);
|
||||
expect(actual).toEqual(result)
|
||||
for (const key of Object.keys(result)) {
|
||||
if (!excludeKeys.has(key)) {
|
||||
expect(actual[key]).toEqual(result[key]);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
})
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
const _ = require('underscore');
|
||||
const os = require('os');
|
||||
const fs = require('fs');
|
||||
const mkdirp = require('mkdirp');
|
||||
|
||||
const {PromiseUtils, IMAPConnection} = require('isomorphic-core');
|
||||
const {Capabilities} = IMAPConnection;
|
||||
|
@ -265,6 +268,11 @@ class FetchMessagesInFolder {
|
|||
imapMessage,
|
||||
desiredParts,
|
||||
}, `FetchMessagesInFolder: Could not build message`)
|
||||
const outJSON = JSON.stringify({'imapMessage': imapMessage, 'desiredParts': desiredParts, 'result': {}});
|
||||
const outDir = path.join(os.tmpdir(), "k2-parse-errors", this._folder.name)
|
||||
const outFile = path.join(outDir, imapMessage.attributes.uid.toString());
|
||||
mkdirp.sync(outDir);
|
||||
fs.writeFileSync(outFile, outJSON);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
const utf7 = require('utf7').imap;
|
||||
const mimelib = require('mimelib');
|
||||
const QuotedPrintable = require('quoted-printable');
|
||||
const {Imap} = require('isomorphic-core')
|
||||
const {Imap} = require('isomorphic-core');
|
||||
const mkdirp = require('mkdirp');
|
||||
const striptags = require('striptags');
|
||||
|
||||
const SNIPPET_SIZE = 100
|
||||
|
||||
|
@ -59,6 +61,13 @@ async function parseFromImap(imapMessage, desiredParts, {db, accountId, folder})
|
|||
subject: parsedHeaders.subject[0],
|
||||
}
|
||||
|
||||
// preserve whitespacing on plaintext emails -- has the side effect of monospacing, but
|
||||
// that seems OK and perhaps sometimes even desired (for e.g. ascii art, alignment)
|
||||
if (!body['text/html'] && body['text/plain']) {
|
||||
values.body = `<pre class="nylas-plaintext">${values.body}</pre>`;
|
||||
}
|
||||
|
||||
// TODO: strip quoted text from snippets also
|
||||
if (values.snippet) {
|
||||
// trim and clean snippet which is alreay present (from values plaintext)
|
||||
values.snippet = values.snippet.replace(/[\n\r]/g, ' ').replace(/\s\s+/g, ' ')
|
||||
|
@ -68,8 +77,7 @@ async function parseFromImap(imapMessage, desiredParts, {db, accountId, folder})
|
|||
}
|
||||
} else if (values.body) {
|
||||
// create snippet from body, which is most likely html
|
||||
// TODO: Fanciness
|
||||
values.snippet = values.body.substr(0, Math.min(values.body.length, SNIPPET_SIZE));
|
||||
values.snippet = striptags(values.body).trim().substr(0, Math.min(values.body.length, SNIPPET_SIZE));
|
||||
}
|
||||
|
||||
values.folder = folder
|
||||
|
|
Loading…
Reference in a new issue