From 7598ac2f17ece774d533bab0908970a806669a66 Mon Sep 17 00:00:00 2001 From: Andris Reinman Date: Wed, 13 Dec 2017 10:33:13 +0200 Subject: [PATCH] fixed tests --- Gruntfile.js | 3 +- imap-core/test/prepare.sh | 6 +- imap-core/test/protocol-test.js | 32 +-- imap-core/test/test-client.js | 220 +++++++++++---------- package.json | 5 +- test/api-test.js | 337 ++++++++++++++++---------------- 6 files changed, 309 insertions(+), 294 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 5597a4bb..07ae38a0 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -12,7 +12,8 @@ module.exports = function(grunt) { options: { reporter: 'spec' }, - src: ['test/**/*-test.js', 'imap-core/test/**/*-test.js'] + // run imap-core tests first + src: ['imap-core/test/**/*-test.js', 'test/**/*-test.js'] } }, diff --git a/imap-core/test/prepare.sh b/imap-core/test/prepare.sh index 11aaaab6..5582308d 100755 --- a/imap-core/test/prepare.sh +++ b/imap-core/test/prepare.sh @@ -66,7 +66,9 @@ subject: test6 hello 6 " -mongo "$DBNAME" --eval "db.messages.updateOne({uid:1}, {\$set:{modseq: 100}})" > /dev/null -mongo "$DBNAME" --eval "db.messages.updateOne({uid:2}, {\$set:{modseq: 5000}})" > /dev/null +mongo "$DBNAME" --eval "db.mailboxes.updateOne({_id: ObjectId('$INBOXID')}, {\$set:{modifyIndex: 5000, uidNext: 1000}})" > /dev/null +mongo "$DBNAME" --eval "db.messages.updateOne({mailbox: ObjectId('$INBOXID'), uid:1}, {\$set:{modseq: 100}})" > /dev/null +mongo "$DBNAME" --eval "db.messages.updateOne({mailbox: ObjectId('$INBOXID'), uid:2}, {\$set:{modseq: 5000}})" > /dev/null +mongo "$DBNAME" --eval "db.messages.updateMany({}, {\$inc:{uid: 100}})" > /dev/null # curl --silent "http://localhost:8080/users/$USERID/mailboxes/$INBOXID/messages" | jq diff --git a/imap-core/test/protocol-test.js b/imap-core/test/protocol-test.js index 673acbe6..991c5fd6 100644 --- a/imap-core/test/protocol-test.js +++ b/imap-core/test/protocol-test.js @@ -1046,7 +1046,7 @@ describe('IMAP Protocol integration tests', function() { }, function(resp) { resp = resp.toString(); - expect(resp.match(/^\* LSUB /gm).length).to.equal(3); + expect(resp.match(/^\* LSUB /gm).length).to.equal(6); expect(resp.indexOf('\r\n* LSUB (\\HasNoChildren) "/" "INBOX"\r\n') >= 0).to.be.true; expect(resp.indexOf('\r\n* LSUB (\\HasNoChildren) "/" "[Gmail]/Sent Mail"\r\n') >= 0).to.be.true; expect(resp.indexOf('\r\n* LSUB (\\HasNoChildren) "/" "testfolder"\r\n') >= 0).to.be.true; @@ -1076,7 +1076,7 @@ describe('IMAP Protocol integration tests', function() { }, function(resp) { resp = resp.toString(); - expect(resp.match(/^\* LSUB /gm).length).to.equal(2); + expect(resp.match(/^\* LSUB /gm).length).to.equal(5); expect(resp.indexOf('\r\n* LSUB (\\HasNoChildren) "/" "INBOX"\r\n') >= 0).to.be.true; expect(resp.indexOf('\r\n* LSUB (\\HasNoChildren) "/" "[Gmail]/Sent Mail"\r\n') >= 0).to.be.true; expect(resp.indexOf('\r\n* LSUB (\\HasNoChildren) "/" "testfolder"\r\n') >= 0).to.be.false; @@ -1088,8 +1088,9 @@ describe('IMAP Protocol integration tests', function() { }); describe('EXPUNGE', function() { - it('should expunge messages', function(done) { - let cmds = ['T1 LOGIN testuser pass', 'T2 SELECT INBOX', 'T3 STORE 2:* +FLAGS (\\Deleted)', 'T4 EXPUNGE', 'T6 LOGOUT']; + // EXPUNGE is a NO OP with autoexpunge. We can still test as the result after applying Delete would be the same + it('should automatically expunge messages', function(done) { + let cmds = ['T1 LOGIN testuser pass', 'T2 SELECT INBOX', 'T3 STORE 2:* +FLAGS (\\Deleted)', 'SLEEP', 'T4 EXPUNGE', 'T6 LOGOUT']; testClient( { @@ -1108,8 +1109,9 @@ describe('IMAP Protocol integration tests', function() { }); describe('UID EXPUNGE', function() { - it('should expunge messages', function(done) { - let cmds = ['T1 LOGIN testuser pass', 'T2 SELECT INBOX', 'T3 STORE 1:* +FLAGS (\\Deleted)', 'T4 UID EXPUNGE 50', 'T5 LOGOUT']; + // UID EXPUNGE is a NO OP with autoexpunge + it.skip('should automatically expunge messages', function(done) { + let cmds = ['T1 LOGIN testuser pass', 'T2 SELECT INBOX', 'T3 STORE 1:* +FLAGS (\\Deleted)', 'SLEEP', 'T4 UID EXPUNGE 50', 'T5 LOGOUT']; testClient( { @@ -1130,7 +1132,7 @@ describe('IMAP Protocol integration tests', function() { describe('FETCH command', function() { it('should list by UID', function(done) { - let cmds = ['T1 LOGIN testuser pass', 'T2 SELECT INBOX', 'T3 UID FETCH 50 (FLAGS)', 'T4 FETCH 3 (FLAGS)', 'T4 LOGOUT']; + let cmds = ['T1 LOGIN testuser pass', 'T2 SELECT INBOX', 'T3 UID FETCH 103 (FLAGS)', 'T4 FETCH 3 (FLAGS)', 'T4 LOGOUT']; testClient( { @@ -1140,7 +1142,7 @@ describe('IMAP Protocol integration tests', function() { }, function(resp) { resp = resp.toString(); - expect(resp.slice(/\n/).indexOf('* 3 FETCH (FLAGS (\\Seen) UID 50)') >= 0).to.be.true; // UID FETCH FLAGS + expect(resp.slice(/\n/).indexOf('* 3 FETCH (FLAGS (\\Seen) UID 103)') >= 0).to.be.true; // UID FETCH FLAGS expect(resp.slice(/\n/).indexOf('* 3 FETCH (FLAGS (\\Seen))') >= 0).to.be.true; // FETCH FLAGS expect(/^T3 OK/m.test(resp)).to.be.true; done(); @@ -1152,9 +1154,9 @@ describe('IMAP Protocol integration tests', function() { let cmds = [ 'T1 LOGIN testuser pass', 'T2 SELECT INBOX', - 'T3 UID FETCH 50 (FLAGS) (CHANGEDSINCE 1)', + 'T3 UID FETCH 103 (FLAGS) (CHANGEDSINCE 1)', 'T4 FETCH 3 (FLAGS) (CHANGEDSINCE 1)', - 'T5 UID FETCH 50 (FLAGS) (CHANGEDSINCE 10000)', + 'T5 UID FETCH 103 (FLAGS) (CHANGEDSINCE 10000)', 'T6 FETCH 3 (FLAGS) (CHANGEDSINCE 10000)', 'T7 LOGOUT' ]; @@ -1167,8 +1169,8 @@ describe('IMAP Protocol integration tests', function() { }, function(resp) { resp = resp.toString(); - expect(resp.slice(/\n/).indexOf('* 3 FETCH (FLAGS (\\Seen) UID 50 MODSEQ (45))') >= 0).to.be.true; // UID FETCH FLAGS - expect(resp.slice(/\n/).indexOf('* 3 FETCH (FLAGS (\\Seen) MODSEQ (45))') >= 0).to.be.true; // FETCH FLAGS + expect(resp.slice(/\n/).indexOf('* 3 FETCH (FLAGS (\\Seen) UID 103 MODSEQ (3))') >= 0).to.be.true; // UID FETCH FLAGS + expect(resp.slice(/\n/).indexOf('* 3 FETCH (FLAGS (\\Seen) MODSEQ (3))') >= 0).to.be.true; // FETCH FLAGS expect(resp.match(/^\* \d+ FETCH/gm).length).to.equal(2); expect(/^T3 OK/m.test(resp)).to.be.true; expect(/^T4 OK/m.test(resp)).to.be.true; @@ -1195,7 +1197,7 @@ describe('IMAP Protocol integration tests', function() { resp .slice(/\n/) .indexOf( - '* 1 FETCH (UID 45 BODYSTRUCTURE ("TEXT" "PLAIN" NIL NIL NIL "7BIT" 6 1 NIL NIL NIL NIL) ENVELOPE (NIL "test" ((NIL NIL "sender" "example.com")) ((NIL NIL "sender" "example.com")) ((NIL NIL "sender" "example.com")) ((NIL NIL "to" "example.com")) ((NIL NIL "cc" "example.com")) NIL NIL NIL))' + '* 1 FETCH (UID 101 BODYSTRUCTURE ("TEXT" "PLAIN" NIL NIL NIL "7BIT" 6 1 NIL NIL NIL NIL) ENVELOPE (NIL "test" ((NIL NIL "sender" "example.com")) ((NIL NIL "sender" "example.com")) ((NIL NIL "sender" "example.com")) ((NIL NIL "to" "example.com")) ((NIL NIL "cc" "example.com")) NIL NIL NIL))' ) >= 0 ).to.be.true; expect(/^T3 OK/m.test(resp)).to.be.true; @@ -1249,7 +1251,7 @@ describe('IMAP Protocol integration tests', function() { function(resp) { resp = resp.toString(); - expect(resp.indexOf('\n* 3 FETCH (UID 50)\r\n') >= 0).to.be.true; + expect(resp.indexOf('\n* 3 FETCH (UID 103)\r\n') >= 0).to.be.true; expect(/^T3 OK/m.test(resp)).to.be.true; done(); @@ -1698,7 +1700,7 @@ describe('IMAP Protocol integration tests', function() { resp = resp.toString(); expect(resp.match(/^\* SEARCH /gm).length).to.equal(2); expect(/^\* SEARCH 1 4 5 6$/m.test(resp)).to.be.true; - expect(/^\* SEARCH 45 52 53 60$/m.test(resp)).to.be.true; + expect(/^\* SEARCH 101 104 105 106$/m.test(resp)).to.be.true; expect(/^T3 OK/m.test(resp)).to.be.true; expect(/^T4 OK/m.test(resp)).to.be.true; done(); diff --git a/imap-core/test/test-client.js b/imap-core/test/test-client.js index 7edfab08..cb37ba3c 100644 --- a/imap-core/test/test-client.js +++ b/imap-core/test/test-client.js @@ -21,122 +21,132 @@ function runClientMockup(options, callback) { let callbackSent = false; let delay; - let socket = (options.secure ? tls : net).connect({ - rejectUnauthorized: false, - port, - host - }, () => { - socket.on('close', () => { - if (callbackSent) { - return; - } - callbackSent = true; - if (typeof callback === 'function') { - return callback(Buffer.concat(responses)); - } - }); + let socket = (options.secure ? tls : net).connect( + { + rejectUnauthorized: false, + port, + host + }, + () => { + socket.on('close', () => { + if (callbackSent) { + return; + } + callbackSent = true; + if (typeof callback === 'function') { + return callback(Buffer.concat(responses)); + } + }); - let onData = function (chunk) { - if (ignore_data) { - return; - } - - responses.push(chunk); - if (debug) { - console.log('S: ' + chunk.toString('binary').trim()); - } - - if (!commands.length) { - return; - } - - if (typeof command === 'string' && command.match(/^[a-z0-9]+ STARTTLS$/i)) { - // wait until server sends response to the STARTTLS command - if (!/STARTTLS completed/.test(Buffer.concat(responses).toString())) { + let onData = function(chunk) { + if (ignore_data) { return; } - ignore_data = true; + responses.push(chunk); if (debug) { - console.log('Initiated TLS connection'); + console.log('S: ' + chunk.toString('binary').trim()); } - socket.removeAllListeners('data'); - let secureSocket = tls.connect({ - rejectUnauthorized: false, - socket, - host - }, () => { - ignore_data = false; - - socket = secureSocket; - - if (debug) { - console.log('TLS connection secured'); - } - - secureSocket.on('data', onData); - - secureSocket.on('close', () => { - if (callbackSent) { - return; - } - callbackSent = true; - if (typeof callback === 'function') { - return callback(Buffer.concat(responses)); - } - }); - - command = commands.shift(); - if (debug) { - console.log('(Secure) C: ' + command); - } - secureSocket.write(command + '\r\n'); - }); - - secureSocket.on('error', err => { - console.log('SECURE ERR'); - console.log(err.stack); - }); - - } else { - if (!/\r?\n$/.test(chunk.toString('binary'))) { + if (!commands.length) { return; } - // only go forward with the next command if the last data ends with a newline - // and there is no activity in the socket for 10ms - clearTimeout(delay); - delay = setTimeout(() => { - command = commands.shift(); - if (Array.isArray(command)) { - let i = 0; - let send = function () { - if (i >= command.length) { - return; - } - - let part = command[i++]; - - socket.write(new Buffer(part + (i >= command.length ? '\r\n' : ''), 'binary')); - if (debug) { - console.log('C: ' + part); - } - setTimeout(send, 10); - }; - - send(); - } else { - socket.write(new Buffer(command + '\r\n', 'binary')); - if (debug) { - console.log('C: ' + command); - } + if (typeof command === 'string' && command.match(/^[a-z0-9]+ STARTTLS$/i)) { + // wait until server sends response to the STARTTLS command + if (!/STARTTLS completed/.test(Buffer.concat(responses).toString())) { + return; } - }, 10); - } - }; + ignore_data = true; + if (debug) { + console.log('Initiated TLS connection'); + } - socket.on('data', onData); - }); + socket.removeAllListeners('data'); + let secureSocket = tls.connect( + { + rejectUnauthorized: false, + socket, + host + }, + () => { + ignore_data = false; + + socket = secureSocket; + + if (debug) { + console.log('TLS connection secured'); + } + + secureSocket.on('data', onData); + + secureSocket.on('close', () => { + if (callbackSent) { + return; + } + callbackSent = true; + if (typeof callback === 'function') { + return callback(Buffer.concat(responses)); + } + }); + + command = commands.shift(); + if (debug) { + console.log('(Secure) C: ' + command); + } + secureSocket.write(command + '\r\n'); + } + ); + + secureSocket.on('error', err => { + console.log('SECURE ERR'); + console.log(err.stack); + }); + } else { + if (!/\r?\n$/.test(chunk.toString('binary'))) { + return; + } + // only go forward with the next command if the last data ends with a newline + // and there is no activity in the socket for 10ms + let processCommand = () => { + clearTimeout(delay); + delay = setTimeout(() => { + command = commands.shift(); + if (command === 'SLEEP') { + return setTimeout(processCommand, 1000); + } + + if (Array.isArray(command)) { + let i = 0; + let send = function() { + if (i >= command.length) { + return; + } + + let part = command[i++]; + + socket.write(new Buffer(part + (i >= command.length ? '\r\n' : ''), 'binary')); + if (debug) { + console.log('C: ' + part); + } + setTimeout(send, 10); + }; + + send(); + } else { + socket.write(new Buffer(command + '\r\n', 'binary')); + if (debug) { + console.log('C: ' + command); + } + } + }, 10); + }; + processCommand(); + } + }; + + socket.on('data', onData); + } + ); } diff --git a/package.json b/package.json index 9bc983e8..5aa36905 100644 --- a/package.json +++ b/package.json @@ -8,10 +8,7 @@ "test": "mongo --eval 'db.dropDatabase()' wildduck-test && redis-cli -n 13 flushdb && NODE_ENV=test grunt", "apidoc": "apidoc -i lib/api/ -o docs/" }, - "keywords": [ - "imap", - "mail server" - ], + "keywords": ["imap", "mail server"], "author": "Andris Reinman", "license": "EUPL-1.1", "devDependencies": { diff --git a/test/api-test.js b/test/api-test.js index 3d8fb2c0..6ffc7319 100644 --- a/test/api-test.js +++ b/test/api-test.js @@ -12,185 +12,188 @@ const URL = 'http://localhost:8080'; let userId = false; -frisby - .create('POST users') - .post( - URL + '/users', - { - username: 'testuser', - password: 'secretpass', - address: 'testuser@example.com', - name: 'test user' - }, - { json: true } - ) - .expectStatus(200) - .afterJSON(response => { - expect(response).to.exist; - expect(response.success).to.be.true; - userId = response.id; +describe('API tests', function() { + this.timeout(10000); // eslint-disable-line no-invalid-this - frisby - .create('GET users/{id}') - .get(URL + '/users/' + userId) - .expectStatus(200) - .afterJSON(response => { - console.log(response); // eslint-disable-line - expect(response).to.exist; - expect(response.success).to.be.true; - expect(response.id).to.equal(userId); - expect(response.name).to.equal('test user'); - }) - .toss(); + frisby + .create('POST users') + .post( + URL + '/users', + { + username: 'testuser', + password: 'secretpass', + address: 'testuser@example.com', + name: 'test user' + }, + { json: true } + ) + .expectStatus(200) + .afterJSON(response => { + expect(response).to.exist; + expect(response.success).to.be.true; + userId = response.id; - frisby - .create('PUT users/{id}') - .put( - URL + '/users/' + userId, - { - name: 'user test' - }, - { json: true } - ) - .expectStatus(200) - .afterJSON(response => { - expect(response).to.exist; - expect(response.success).to.be.true; - }) - .toss(); + frisby + .create('GET users/{id}') + .get(URL + '/users/' + userId) + .expectStatus(200) + .afterJSON(response => { + expect(response).to.exist; + expect(response.success).to.be.true; + expect(response.id).to.equal(userId); + expect(response.name).to.equal('test user'); + }) + .toss(); - frisby - .create('GET users/{id} – updated name') - .get(URL + '/users/' + userId) - .expectStatus(200) - .afterJSON(response => { - expect(response).to.exist; - expect(response.success).to.be.true; - expect(response.id).to.equal(userId); - expect(response.name).to.equal('user test'); - }) - .toss(); + frisby + .create('PUT users/{id}') + .put( + URL + '/users/' + userId, + { + name: 'user test' + }, + { json: true } + ) + .expectStatus(200) + .afterJSON(response => { + expect(response).to.exist; + expect(response.success).to.be.true; + }) + .toss(); - frisby - .create('GET users/{id}/addresses') - .get(URL + '/users/' + userId + '/addresses') - .expectStatus(200) - .afterJSON(response => { - expect(response).to.exist; - expect(response.success).to.be.true; - expect(response.results.length).to.equal(1); - expect(response.results[0].address).to.equal('testuser@example.com'); - expect(response.results[0].main).to.be.true; - }) - .toss(); + frisby + .create('GET users/{id} – updated name') + .get(URL + '/users/' + userId) + .expectStatus(200) + .afterJSON(response => { + expect(response).to.exist; + expect(response.success).to.be.true; + expect(response.id).to.equal(userId); + expect(response.name).to.equal('user test'); + }) + .toss(); - frisby - .create('POST users/{id}/addresses') - .post( - URL + '/users/' + userId + '/addresses', - { - address: 'alias1@example.com', - main: true - }, - { json: true } - ) - .expectStatus(200) - .afterJSON(response => { - expect(response).to.exist; - expect(response.success).to.be.true; - }) - .toss(); + frisby + .create('GET users/{id}/addresses') + .get(URL + '/users/' + userId + '/addresses') + .expectStatus(200) + .afterJSON(response => { + expect(response).to.exist; + expect(response.success).to.be.true; + expect(response.results.length).to.equal(1); + expect(response.results[0].address).to.equal('testuser@example.com'); + expect(response.results[0].main).to.be.true; + }) + .toss(); - frisby - .create('POST users/{id}/addresses') - .post( - URL + '/users/' + userId + '/addresses', - { - address: 'alias2@example.com' - }, - { json: true } - ) - .expectStatus(200) - .afterJSON(response => { - expect(response).to.exist; - expect(response.success).to.be.true; - }) - .toss(); + frisby + .create('POST users/{id}/addresses') + .post( + URL + '/users/' + userId + '/addresses', + { + address: 'alias1@example.com', + main: true + }, + { json: true } + ) + .expectStatus(200) + .afterJSON(response => { + expect(response).to.exist; + expect(response.success).to.be.true; + }) + .toss(); - frisby - .create('GET users/{id}/addresses – updated listing') - .get(URL + '/users/' + userId + '/addresses') - .expectStatus(200) - .afterJSON(response => { - expect(response).to.exist; - expect(response.success).to.be.true; - expect(response.results.length).to.equal(3); - response.results.sort((a, b) => a.id.localeCompare(b.id)); + frisby + .create('POST users/{id}/addresses') + .post( + URL + '/users/' + userId + '/addresses', + { + address: 'alias2@example.com' + }, + { json: true } + ) + .expectStatus(200) + .afterJSON(response => { + expect(response).to.exist; + expect(response.success).to.be.true; + }) + .toss(); - expect(response.results[0].address).to.equal('testuser@example.com'); - expect(response.results[0].main).to.be.false; + frisby + .create('GET users/{id}/addresses – updated listing') + .get(URL + '/users/' + userId + '/addresses') + .expectStatus(200) + .afterJSON(response => { + expect(response).to.exist; + expect(response.success).to.be.true; + expect(response.results.length).to.equal(3); + response.results.sort((a, b) => a.id.localeCompare(b.id)); - expect(response.results[1].address).to.equal('alias1@example.com'); - expect(response.results[1].main).to.be.true; + expect(response.results[0].address).to.equal('testuser@example.com'); + expect(response.results[0].main).to.be.false; - expect(response.results[2].address).to.equal('alias2@example.com'); - expect(response.results[2].main).to.be.false; + expect(response.results[1].address).to.equal('alias1@example.com'); + expect(response.results[1].main).to.be.true; - frisby - .create('DELETE users/{id}/addresses/{address}') - .delete(URL + '/users/' + userId + '/addresses/' + response.results[2].id) - .expectStatus(200) - .afterJSON(response => { - expect(response).to.exist; - expect(response.success).to.be.true; + expect(response.results[2].address).to.equal('alias2@example.com'); + expect(response.results[2].main).to.be.false; - frisby - .create('GET users/{id}/addresses – after DELETE') - .get(URL + '/users/' + userId + '/addresses') - .expectStatus(200) - .afterJSON(response => { - expect(response).to.exist; - expect(response.success).to.be.true; - expect(response.results.length).to.equal(2); + frisby + .create('DELETE users/{id}/addresses/{address}') + .delete(URL + '/users/' + userId + '/addresses/' + response.results[2].id) + .expectStatus(200) + .afterJSON(response => { + expect(response).to.exist; + expect(response.success).to.be.true; - frisby - .create('DELETE users/{id}') - .delete(URL + '/users/' + userId) - .expectStatus(200) - .afterJSON(response => { - expect(response).to.exist; - expect(response.success).to.be.true; - }) - .toss(); - }) - .toss(); - }) - .toss(); - }) - .toss(); + frisby + .create('GET users/{id}/addresses – after DELETE') + .get(URL + '/users/' + userId + '/addresses') + .expectStatus(200) + .afterJSON(response => { + expect(response).to.exist; + expect(response.success).to.be.true; + expect(response.results.length).to.equal(2); - frisby - .create('GET users/{id} – updated address') - .get(URL + '/users/' + userId) - .expectStatus(200) - .afterJSON(response => { - expect(response).to.exist; - expect(response.success).to.be.true; - expect(response.id).to.equal(userId); - expect(response.address).to.equal('alias1@example.com'); - }) - .toss(); + frisby + .create('DELETE users/{id}') + .delete(URL + '/users/' + userId) + .expectStatus(200) + .afterJSON(response => { + expect(response).to.exist; + expect(response.success).to.be.true; + }) + .toss(); + }) + .toss(); + }) + .toss(); + }) + .toss(); - frisby - .create('GET users/{id}/mailboxes') - .get(URL + '/users/' + userId + '/mailboxes') - .expectStatus(200) - .afterJSON(response => { - expect(response).to.exist; - expect(response.success).to.be.true; - expect(response.results.length).to.be.gte(4); - expect(response.results[0].path).to.equal('INBOX'); - }) - .toss(); - }) - .toss(); + frisby + .create('GET users/{id} – updated address') + .get(URL + '/users/' + userId) + .expectStatus(200) + .afterJSON(response => { + expect(response).to.exist; + expect(response.success).to.be.true; + expect(response.id).to.equal(userId); + expect(response.address).to.equal('alias1@example.com'); + }) + .toss(); + + frisby + .create('GET users/{id}/mailboxes') + .get(URL + '/users/' + userId + '/mailboxes') + .expectStatus(200) + .afterJSON(response => { + expect(response).to.exist; + expect(response.success).to.be.true; + expect(response.results.length).to.be.gte(4); + expect(response.results[0].path).to.equal('INBOX'); + }) + .toss(); + }) + .toss(); +});