"use strict"; const Promise = require("bluebird"); const tap = require("tap"); const pEvent = require("p-event"); const IMAP = require("../.."); const lines = require("../lines"); const createMockServer = require("../mock-server"); const fetch = require("../fetch"); tap.test("fetch-with-uid", (test) => { return testFetch(test, true, false); }); tap.test("fetch-without-uid", (test) => { return testFetch(test, false, false); }); tap.test("fetch-with-body", (test) => { return testFetch(test, true, true); }); function testFetch(test, withUID, withBody) { let steps = [{ expected: 'A0 CAPABILITY', response: lines([ '* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA CHILDREN', 'A0 OK Thats all she wrote!', ]), }, { expected: 'A1 LOGIN "foo" "bar"', response: lines([ '* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA CHILDREN UIDPLUS MOVE', 'A1 OK authenticated (Success)', ]), }, { expected: 'A2 NAMESPACE', response: lines([ '* NAMESPACE (("" "/")) NIL NIL', 'A2 OK Success', ]), }, { expected: 'A3 LIST "" ""', response: lines([ '* LIST (\\Noselect) "/" "/"', 'A3 OK Success', ]), }, { expected: 'A4 EXAMINE "INBOX"', response: lines([ '* FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)', '* OK [PERMANENTFLAGS ()] Flags permitted.', '* OK [UIDVALIDITY 2] UIDs valid.', '* 685 EXISTS', '* 0 RECENT', '* OK [UIDNEXT 4422] Predicted next UID.', 'A4 OK [READ-ONLY] INBOX selected. (Success)', ]), }, { expected: (withBody) ? 'A5 FETCH 1 (UID FLAGS INTERNALDATE BODY.PEEK[TEXT])' : 'A5 FETCH 1 (UID FLAGS INTERNALDATE)', response: lines([ '* 1 FETCH (UID 1)', `* 1 FETCH (INTERNALDATE "05-Sep-2004 00:38:03 +0000"${(withUID) ? " UID 1000" : ""})`, (withBody) ? '* 1 FETCH (BODY[TEXT] "IMAP is terrible")' : null, '* 1 FETCH (FLAGS (\\Seen))', 'A5 OK Success', ]), }, { expected: "A6 LOGOUT", response: lines([ '* BYE LOGOUT Requested', 'A6 OK good day (Success)', ]), }]; return Promise.try(() => { let continuationWasSent; return createMockServer({ steps: steps, test: test, // NOTE: Anything handled here is not matched against steps, nor is the counter incremented handle: function (line) { if (line === "IDLE IDLE") { continuationWasSent = true; return Promise.delay(100).then(() => { return lines([ "+ idling" ]); }); } else if (line === "DONE") { test.ok(continuationWasSent, "DONE seen before continuation sent"); continuationWasSent = false; return lines([ "IDLE ok" ]); } } }); }).then(({ server, port, finalize }) => { const client = new IMAP({ user: "foo", password: "bar", host: "127.0.0.1", port: port, keepalive: false }); Promise.promisifyAll(client, { multiArgs: true }); client.connect(); return Promise.try(() => { return pEvent(client, "ready"); }).then(() => { server.close(); // Stop listening for new clients return client.openBoxAsync("INBOX", true); }).then(() => { return fetch( client, (withBody) ? [ 1, { bodies: [ "TEXT" ] } ] : [ 1 ] ); }).tap(() => { client.end(); return pEvent(client, "end"); }).then(({ attributeResults, bodyInfoResults, bodies }) => { finalize(); test.same(attributeResults, [{ uid: 1, date: new Date('05-Sep-2004 00:38:03 +0000'), flags: [ '\\Seen' ] }]); if (withBody) { test.same(bodies, [ Buffer.from('IMAP is terrible') ]); test.same(bodyInfoResults, [{ seqno: 1, which: 'TEXT', size: 16 }]); } }); }); }