diff --git a/lib/Parser.js b/lib/Parser.js index 5e2b020..7fb40ea 100644 --- a/lib/Parser.js +++ b/lib/Parser.js @@ -91,10 +91,10 @@ class Parser { /** * Parses an email body and converts it to Fragments. * @param {string} text the input text to parse - * @returns {Email} the parsed email, or null if not parseable + * @returns {Email} the parsed email */ parse(text) { - if (typeof(text) !== "string") return null; + if (typeof(text) !== "string") return new Email([]); var fragments = []; @@ -104,7 +104,7 @@ class Parser { for (var exp of this._quoteHeadersRegex) { var matches = text.match(exp); if (matches && matches.length >= 2) { - text = text.replace(matches[1], matches[1].replace('\n', ' ')); + text = text.replace(matches[1], matches[1].replace(/\n/g, ' ')); } } @@ -181,10 +181,10 @@ class Parser { * @private */ _isFragmentLine(fragment, line, isQuoted) { - if (fragment.isQuoted === isQuoted)return true; + if (fragment.isQuoted === isQuoted) return true; if (fragment.isQuoted) { - return this._isQuoteHeader(line) && fragment.lines.length === 0; + return this._isQuoteHeader(line) || line.length === 0; } return false; @@ -197,7 +197,7 @@ class Parser { * @private */ _isSignature(text) { - return this._signatureRegex.test(text); + return this._signatureRegex.test(esrever.reverse(text)); } /** @@ -217,7 +217,7 @@ class Parser { * @private */ _isQuoteHeader(text) { - return _.filter(this._quoteHeadersRegex, exp => exp.test(text)).length > 0; + return _.filter(this._quoteHeadersRegex, exp => exp.test(esrever.reverse(text))).length > 0; } } diff --git a/package.json b/package.json index ae5c3b2..6a1a055 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "lib/" ], "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "mocha test/*Test.js" }, "dependencies": { "esrever": "^0.2.0", diff --git a/test/ModuleTest.js b/test/ModuleTest.js index 6cf75a2..5dadfaf 100644 --- a/test/ModuleTest.js +++ b/test/ModuleTest.js @@ -28,49 +28,49 @@ describe('index.js', function () { var fixture = util.getFixture('email_iphone.txt'); var email = replyParser(fixture, true); - assert.equal(email, 'Here is another email', 'Visible text is incorrect'); + assert.equal(email, 'Here is another email\n', 'Visible text is incorrect'); }); it('should process sent from Blackberry messages', function () { var fixture = util.getFixture('email_blackberry.txt'); var email = replyParser(fixture, true); - assert.equal(email, 'Here is another email', 'Visible text is incorrect'); + assert.equal(email, 'Here is another email\n', 'Visible text is incorrect'); }); it('should process sent from multiword device messages', function () { var fixture = util.getFixture('email_multi_word_sent_from_my_mobile_device.txt'); var email = replyParser(fixture, true); - assert.equal(email, 'Here is another email', 'Visible text is incorrect'); + assert.equal(email, 'Here is another email\n', 'Visible text is incorrect'); }); it('should process sent from not a signature message', function () { var fixture = util.getFixture('email_sent_from_my_not_signature.txt'); var email = replyParser(fixture, true); - assert.equal(email, 'Here is another email\n\nSent from my desk, is much easier then my mobile phone.', 'Visible text is incorrect'); + assert.equal(email, 'Here is another email\n\nSent from my desk, is much easier then my mobile phone.\n', 'Visible text is incorrect'); }); it('should find just the top part of an Outlook message', function () { var fixture = util.getFixture('email_2_1.txt'); var email = replyParser(fixture, true); - assert.equal(email, 'Outlook with a reply', 'Visible text is incorrect'); + assert.equal(email, 'Outlook with a reply\n\n', 'Visible text is incorrect'); }); it('should retain bullets', function () { var fixture = util.getFixture('email_bullets.txt'); var email = replyParser(fixture, true); - assert.equal(email, 'test 2 this should list second\n\nand have spaces\n\nand retain this formatting\n\n\n - how about bullets\n - and another', 'Visible text is incorrect'); + assert.equal(email, 'test 2 this should list second\n\nand have spaces\n\nand retain this formatting\n\n\n - how about bullets\n - and another\n\n', 'Visible text is incorrect'); }); it('should parse unquoted reply', function () { var fixture = util.getFixture('email_unquoted_reply.txt'); var email = replyParser(fixture, true); - assert.equal(email, 'This is my reply.', 'Visible text is incorrect'); + assert.equal(email, 'This is my reply.\n', 'Visible text is incorrect'); }); it('should preserve newlines in email threads', function () { @@ -78,7 +78,7 @@ describe('index.js', function () { var email = replyParser(fixture); var expectedText = - "On Nov 21, 2014, at 10:18, John Doe wrote:\n" + + "On Nov 21, 2014, at 10:18, John Doe wrote:\n\n" + "> Ok. Thanks.\n" + ">\n" + "> On Nov 21, 2014, at 9:26, Jim Beam wrote:\n" + @@ -93,7 +93,7 @@ describe('index.js', function () { ">> --\n" + ">> Jim Beam – Acme Corp\n" + ">>\n" + - ">\n"; + ">"; assert.equal(email.getFragments()[1].getContent(), expectedText, 'Second fragment is incorrect'); }); @@ -106,21 +106,21 @@ describe('index.js', function () { "Hi,\n" + "You can list the keys for the bucket and call delete for each. Or if you\n" + "put the keys (and kept track of them in your test) you can delete them\n" + - "one at a time (without incurring the cost of calling list first.)\n" + - "Something like:\n" + + "one at a time (without incurring the cost of calling list first.)\n\n" + + "Something like:\n\n" + " String bucket = \"my_bucket\";\n" + " BucketResponse bucketResponse = riakClient.listBucket(bucket);\n" + - " RiakBucketInfo bucketInfo = bucketResponse.getBucketInfo();\n" + + " RiakBucketInfo bucketInfo = bucketResponse.getBucketInfo();\n\n" + " for(String key : bucketInfo.getKeys()) {\n" + " riakClient.delete(bucket, key);\n" + - " }\n" + - "would do it.\n" + - "See also\n" + - "http://wiki.basho.com/REST-API.html#Bucket-operations\n" + - "which says\n" + + " }\n\n\n" + + "would do it.\n\n" + + "See also\n\n" + + "http://wiki.basho.com/REST-API.html#Bucket-operations\n\n" + + "which says\n\n" + "\"At the moment there is no straightforward way to delete an entire\n" + "Bucket. There is, however, an open ticket for the feature. To delete all\n" + - "the keys in a bucket, you’ll need to delete them all individually.\"\n"; + "the keys in a bucket, you’ll need to delete them all individually.\""; assert.equal(email.getVisibleText(), expectedText, 'Did not get expected visible body'); }); @@ -133,21 +133,21 @@ describe('index.js', function () { "Hi,\n" + "You can list the keys for the bucket and call delete for each. Or if you\n" + "put the keys (and kept track of them in your test) you can delete them\n" + - "one at a time (without incurring the cost of calling list first.)\n" + - "Something like:\n" + + "one at a time (without incurring the cost of calling list first.)\n\n" + + "Something like:\n\n" + " String bucket = \"my_bucket\";\n" + " BucketResponse bucketResponse = riakClient.listBucket(bucket);\n" + - " RiakBucketInfo bucketInfo = bucketResponse.getBucketInfo();\n" + + " RiakBucketInfo bucketInfo = bucketResponse.getBucketInfo();\n\n" + " for(String key : bucketInfo.getKeys()) {\n" + " riakClient.delete(bucket, key);\n" + - " }\n" + - "would do it.\n" + - "See also\n" + - "http://wiki.basho.com/REST-API.html#Bucket-operations\n" + - "which says\n" + + " }\n\n\n" + + "would do it.\n\n" + + "See also\n\n" + + "http://wiki.basho.com/REST-API.html#Bucket-operations\n\n" + + "which says\n\n" + "\"At the moment there is no straightforward way to delete an entire\n" + "Bucket. There is, however, an open ticket for the feature. To delete all\n" + - "the keys in a bucket, you’ll need to delete them all individually.\"\n"; + "the keys in a bucket, you’ll need to delete them all individually.\""; assert.equal(email, expectedText, 'Did not get expected visible body'); }); diff --git a/test/ParserTest.js b/test/ParserTest.js index af9906e..9e14ce2 100644 --- a/test/ParserTest.js +++ b/test/ParserTest.js @@ -59,7 +59,7 @@ describe('the Parser', function () { "Hi folks\n\n" + "What is the best way to clear a Riak bucket of all key, values after\n" + "running a test?\n" + - "I am currently using the Java HTTP API.\n\n"; + "I am currently using the Java HTTP API.\n"; var fragSignature = "_______________________________________________\n" + "riak-users mailing list\n" + @@ -283,7 +283,7 @@ describe('the Parser', function () { var fragments = email.getFragments(); var visibleFragments = _.filter(fragments, f => !f.isHidden()); - var visibleText = visibleFragments.join('\n'); + var visibleText = _.map(visibleFragments, f => f.getContent()).join('\n'); assert.equal(email.getVisibleText(), visibleText, "Visible text doesn't match"); }); @@ -330,7 +330,7 @@ describe('the Parser', function () { it('should read email with correct signature with whitespace', function () { var parser = new Parser(); - var fixture = util.getFixture("correct_sig.txt").replace('--', '-- '); // we add the space here so that IDEs don't remove it accidentally + var fixture = util.getFixture("correct_sig.txt").replace(/--/g, '-- '); // we add the space here so that IDEs don't remove it accidentally var email = parser.parse(fixture); var fragments = email.getFragments(); @@ -350,7 +350,7 @@ describe('the Parser', function () { it('should read email with correct signature with no empty line above it and whitespace', function () { var parser = new Parser(); - var fixture = util.getFixture("sig_no_empty_line.txt").replace('--', '-- '); // we add the space here so that IDEs don't remove it accidentally + var fixture = util.getFixture("correct_sig.txt").replace(/--/g, '-- '); // we add the space here so that IDEs don't remove it accidentally var email = parser.parse(fixture); var fragments = email.getFragments(); @@ -384,7 +384,7 @@ describe('the Parser', function () { var fixture = util.getFixture("email_custom_quote_header.txt"); var email = parser.parse(fixture); - assert.equal(email.getVisibleText(), "Thank you!", "Visible text is incorrect"); + assert.equal(email.getVisibleText(), "Thank you!\n", "Visible text is incorrect"); }); it('should use custom quote header regex when given (second)', function () { @@ -396,13 +396,13 @@ describe('the Parser', function () { assert.equal(fragments.length, 2, 'Wrong number of fragments'); - assert.equal(email.getVisibleText(), "Thank you very much", "Visible text is incorrect"); + assert.equal(email.getVisibleText(), "Thank you very much.\n\n\n", "Visible text is incorrect"); assert.equal(fragments[1].isHidden(), true, "Second fragment should be hidden"); assert.equal(fragments[1].isQuoted(), true, "Second fragment should be quoted"); }); it('should use custom quote header regex when given (third)', function () { - var regex = [/^(De : [\S\s]+ [\S\s]+someone@yahoo[\S\s]fr\.com[\S\s]+)/m]; + var regex = [/^(De : .+ .+someone@yahoo\.fr[\S\s]+)/m]; var parser = new Parser(null, null, regex); var fixture = util.getFixture("email_customer_quote_header_3.txt"); var email = parser.parse(fixture); @@ -412,7 +412,7 @@ describe('the Parser', function () { var visibleText = "bonjour,\n" + "je n'ai pas eu de retour sur ma précision..\n" + - "merci d'avance"; + "merci d'avance\n"; assert.equal(email.getVisibleText(), visibleText, "Visible text is incorrect"); assert.equal(fragments[1].isHidden(), true, "Second fragment should be hidden"); @@ -425,7 +425,7 @@ describe('the Parser', function () { var fixture = util.getFixture("email_with_date_headers.txt").replace('[DATE]', format); var email = parser.parse(fixture); - assert.equal(email.getVisibleText(), "Thank you very much", "Visible text is incorrect"); + assert.equal(email.getVisibleText(), "Thank you very much.\n", "Visible text is incorrect"); }); } diff --git a/test/fixtures/email_customer_quote_header_3.txt b/test/fixtures/email_customer_quote_header_3.txt index af0d637..e918609 100644 --- a/test/fixtures/email_customer_quote_header_3.txt +++ b/test/fixtures/email_customer_quote_header_3.txt @@ -2,7 +2,7 @@ bonjour, je n'ai pas eu de retour sur ma précision.. merci d'avance - De : Someone Somewhere +De : Someone Somewhere À : mycompany Envoyé le : Mercredi 30 novembre 2016 10h30 Objet : Re: Vous avez reçu une réponse à votre question !