fixed tests

This commit is contained in:
Andris Reinman 2017-12-13 10:33:13 +02:00
parent bd1883d9cd
commit 7598ac2f17
6 changed files with 309 additions and 294 deletions

View file

@ -12,7 +12,8 @@ module.exports = function(grunt) {
options: { options: {
reporter: 'spec' 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']
} }
}, },

View file

@ -66,7 +66,9 @@ subject: test6
hello 6 hello 6
" "
mongo "$DBNAME" --eval "db.messages.updateOne({uid:1}, {\$set:{modseq: 100}})" > /dev/null mongo "$DBNAME" --eval "db.mailboxes.updateOne({_id: ObjectId('$INBOXID')}, {\$set:{modifyIndex: 5000, uidNext: 1000}})" > /dev/null
mongo "$DBNAME" --eval "db.messages.updateOne({uid:2}, {\$set:{modseq: 5000}})" > /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 # curl --silent "http://localhost:8080/users/$USERID/mailboxes/$INBOXID/messages" | jq

View file

@ -1046,7 +1046,7 @@ describe('IMAP Protocol integration tests', function() {
}, },
function(resp) { function(resp) {
resp = resp.toString(); 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) "/" "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) "/" "[Gmail]/Sent Mail"\r\n') >= 0).to.be.true;
expect(resp.indexOf('\r\n* LSUB (\\HasNoChildren) "/" "testfolder"\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) { function(resp) {
resp = resp.toString(); 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) "/" "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) "/" "[Gmail]/Sent Mail"\r\n') >= 0).to.be.true;
expect(resp.indexOf('\r\n* LSUB (\\HasNoChildren) "/" "testfolder"\r\n') >= 0).to.be.false; 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() { describe('EXPUNGE', function() {
it('should expunge messages', function(done) { // EXPUNGE is a NO OP with autoexpunge. We can still test as the result after applying Delete would be the same
let cmds = ['T1 LOGIN testuser pass', 'T2 SELECT INBOX', 'T3 STORE 2:* +FLAGS (\\Deleted)', 'T4 EXPUNGE', 'T6 LOGOUT']; 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( testClient(
{ {
@ -1108,8 +1109,9 @@ describe('IMAP Protocol integration tests', function() {
}); });
describe('UID EXPUNGE', function() { describe('UID EXPUNGE', function() {
it('should expunge messages', function(done) { // UID EXPUNGE is a NO OP with autoexpunge
let cmds = ['T1 LOGIN testuser pass', 'T2 SELECT INBOX', 'T3 STORE 1:* +FLAGS (\\Deleted)', 'T4 UID EXPUNGE 50', 'T5 LOGOUT']; 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( testClient(
{ {
@ -1130,7 +1132,7 @@ describe('IMAP Protocol integration tests', function() {
describe('FETCH command', function() { describe('FETCH command', function() {
it('should list by UID', function(done) { 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( testClient(
{ {
@ -1140,7 +1142,7 @@ describe('IMAP Protocol integration tests', function() {
}, },
function(resp) { function(resp) {
resp = resp.toString(); 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(resp.slice(/\n/).indexOf('* 3 FETCH (FLAGS (\\Seen))') >= 0).to.be.true; // FETCH FLAGS
expect(/^T3 OK/m.test(resp)).to.be.true; expect(/^T3 OK/m.test(resp)).to.be.true;
done(); done();
@ -1152,9 +1154,9 @@ describe('IMAP Protocol integration tests', function() {
let cmds = [ let cmds = [
'T1 LOGIN testuser pass', 'T1 LOGIN testuser pass',
'T2 SELECT INBOX', 'T2 SELECT INBOX',
'T3 UID FETCH 50 (FLAGS) (CHANGEDSINCE 1)', 'T3 UID FETCH 103 (FLAGS) (CHANGEDSINCE 1)',
'T4 FETCH 3 (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)', 'T6 FETCH 3 (FLAGS) (CHANGEDSINCE 10000)',
'T7 LOGOUT' 'T7 LOGOUT'
]; ];
@ -1167,8 +1169,8 @@ describe('IMAP Protocol integration tests', function() {
}, },
function(resp) { function(resp) {
resp = resp.toString(); 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) UID 103 MODSEQ (3))') >= 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) MODSEQ (3))') >= 0).to.be.true; // FETCH FLAGS
expect(resp.match(/^\* \d+ FETCH/gm).length).to.equal(2); expect(resp.match(/^\* \d+ FETCH/gm).length).to.equal(2);
expect(/^T3 OK/m.test(resp)).to.be.true; expect(/^T3 OK/m.test(resp)).to.be.true;
expect(/^T4 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 resp
.slice(/\n/) .slice(/\n/)
.indexOf( .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 ) >= 0
).to.be.true; ).to.be.true;
expect(/^T3 OK/m.test(resp)).to.be.true; expect(/^T3 OK/m.test(resp)).to.be.true;
@ -1249,7 +1251,7 @@ describe('IMAP Protocol integration tests', function() {
function(resp) { function(resp) {
resp = resp.toString(); 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; expect(/^T3 OK/m.test(resp)).to.be.true;
done(); done();
@ -1698,7 +1700,7 @@ describe('IMAP Protocol integration tests', function() {
resp = resp.toString(); resp = resp.toString();
expect(resp.match(/^\* SEARCH /gm).length).to.equal(2); expect(resp.match(/^\* SEARCH /gm).length).to.equal(2);
expect(/^\* SEARCH 1 4 5 6$/m.test(resp)).to.be.true; 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(/^T3 OK/m.test(resp)).to.be.true;
expect(/^T4 OK/m.test(resp)).to.be.true; expect(/^T4 OK/m.test(resp)).to.be.true;
done(); done();

View file

@ -21,122 +21,132 @@ function runClientMockup(options, callback) {
let callbackSent = false; let callbackSent = false;
let delay; let delay;
let socket = (options.secure ? tls : net).connect({ let socket = (options.secure ? tls : net).connect(
rejectUnauthorized: false, {
port, rejectUnauthorized: false,
host port,
}, () => { host
socket.on('close', () => { },
if (callbackSent) { () => {
return; socket.on('close', () => {
} if (callbackSent) {
callbackSent = true; return;
if (typeof callback === 'function') { }
return callback(Buffer.concat(responses)); callbackSent = true;
} if (typeof callback === 'function') {
}); return callback(Buffer.concat(responses));
}
});
let onData = function (chunk) { let onData = function(chunk) {
if (ignore_data) { 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())) {
return; return;
} }
ignore_data = true; responses.push(chunk);
if (debug) { if (debug) {
console.log('Initiated TLS connection'); console.log('S: ' + chunk.toString('binary').trim());
} }
socket.removeAllListeners('data'); if (!commands.length) {
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; 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)) { if (typeof command === 'string' && command.match(/^[a-z0-9]+ STARTTLS$/i)) {
let i = 0; // wait until server sends response to the STARTTLS command
let send = function () { if (!/STARTTLS completed/.test(Buffer.concat(responses).toString())) {
if (i >= command.length) { return;
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); 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);
}
);
} }

View file

@ -8,10 +8,7 @@
"test": "mongo --eval 'db.dropDatabase()' wildduck-test && redis-cli -n 13 flushdb && NODE_ENV=test grunt", "test": "mongo --eval 'db.dropDatabase()' wildduck-test && redis-cli -n 13 flushdb && NODE_ENV=test grunt",
"apidoc": "apidoc -i lib/api/ -o docs/" "apidoc": "apidoc -i lib/api/ -o docs/"
}, },
"keywords": [ "keywords": ["imap", "mail server"],
"imap",
"mail server"
],
"author": "Andris Reinman", "author": "Andris Reinman",
"license": "EUPL-1.1", "license": "EUPL-1.1",
"devDependencies": { "devDependencies": {

View file

@ -12,185 +12,188 @@ const URL = 'http://localhost:8080';
let userId = false; let userId = false;
frisby describe('API tests', function() {
.create('POST users') this.timeout(10000); // eslint-disable-line no-invalid-this
.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 frisby
.create('GET users/{id}') .create('POST users')
.get(URL + '/users/' + userId) .post(
.expectStatus(200) URL + '/users',
.afterJSON(response => { {
console.log(response); // eslint-disable-line username: 'testuser',
expect(response).to.exist; password: 'secretpass',
expect(response.success).to.be.true; address: 'testuser@example.com',
expect(response.id).to.equal(userId); name: 'test user'
expect(response.name).to.equal('test user'); },
}) { json: true }
.toss(); )
.expectStatus(200)
.afterJSON(response => {
expect(response).to.exist;
expect(response.success).to.be.true;
userId = response.id;
frisby frisby
.create('PUT users/{id}') .create('GET users/{id}')
.put( .get(URL + '/users/' + userId)
URL + '/users/' + userId, .expectStatus(200)
{ .afterJSON(response => {
name: 'user test' expect(response).to.exist;
}, expect(response.success).to.be.true;
{ json: true } expect(response.id).to.equal(userId);
) expect(response.name).to.equal('test user');
.expectStatus(200) })
.afterJSON(response => { .toss();
expect(response).to.exist;
expect(response.success).to.be.true;
})
.toss();
frisby frisby
.create('GET users/{id} updated name') .create('PUT users/{id}')
.get(URL + '/users/' + userId) .put(
.expectStatus(200) URL + '/users/' + userId,
.afterJSON(response => { {
expect(response).to.exist; name: 'user test'
expect(response.success).to.be.true; },
expect(response.id).to.equal(userId); { json: true }
expect(response.name).to.equal('user test'); )
}) .expectStatus(200)
.toss(); .afterJSON(response => {
expect(response).to.exist;
expect(response.success).to.be.true;
})
.toss();
frisby frisby
.create('GET users/{id}/addresses') .create('GET users/{id} updated name')
.get(URL + '/users/' + userId + '/addresses') .get(URL + '/users/' + userId)
.expectStatus(200) .expectStatus(200)
.afterJSON(response => { .afterJSON(response => {
expect(response).to.exist; expect(response).to.exist;
expect(response.success).to.be.true; expect(response.success).to.be.true;
expect(response.results.length).to.equal(1); expect(response.id).to.equal(userId);
expect(response.results[0].address).to.equal('testuser@example.com'); expect(response.name).to.equal('user test');
expect(response.results[0].main).to.be.true; })
}) .toss();
.toss();
frisby frisby
.create('POST users/{id}/addresses') .create('GET users/{id}/addresses')
.post( .get(URL + '/users/' + userId + '/addresses')
URL + '/users/' + userId + '/addresses', .expectStatus(200)
{ .afterJSON(response => {
address: 'alias1@example.com', expect(response).to.exist;
main: true expect(response.success).to.be.true;
}, expect(response.results.length).to.equal(1);
{ json: true } expect(response.results[0].address).to.equal('testuser@example.com');
) expect(response.results[0].main).to.be.true;
.expectStatus(200) })
.afterJSON(response => { .toss();
expect(response).to.exist;
expect(response.success).to.be.true;
})
.toss();
frisby frisby
.create('POST users/{id}/addresses') .create('POST users/{id}/addresses')
.post( .post(
URL + '/users/' + userId + '/addresses', URL + '/users/' + userId + '/addresses',
{ {
address: 'alias2@example.com' address: 'alias1@example.com',
}, main: true
{ json: true } },
) { json: true }
.expectStatus(200) )
.afterJSON(response => { .expectStatus(200)
expect(response).to.exist; .afterJSON(response => {
expect(response.success).to.be.true; expect(response).to.exist;
}) expect(response.success).to.be.true;
.toss(); })
.toss();
frisby frisby
.create('GET users/{id}/addresses updated listing') .create('POST users/{id}/addresses')
.get(URL + '/users/' + userId + '/addresses') .post(
.expectStatus(200) URL + '/users/' + userId + '/addresses',
.afterJSON(response => { {
expect(response).to.exist; address: 'alias2@example.com'
expect(response.success).to.be.true; },
expect(response.results.length).to.equal(3); { json: true }
response.results.sort((a, b) => a.id.localeCompare(b.id)); )
.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'); frisby
expect(response.results[0].main).to.be.false; .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[0].address).to.equal('testuser@example.com');
expect(response.results[1].main).to.be.true; expect(response.results[0].main).to.be.false;
expect(response.results[2].address).to.equal('alias2@example.com'); expect(response.results[1].address).to.equal('alias1@example.com');
expect(response.results[2].main).to.be.false; expect(response.results[1].main).to.be.true;
frisby expect(response.results[2].address).to.equal('alias2@example.com');
.create('DELETE users/{id}/addresses/{address}') expect(response.results[2].main).to.be.false;
.delete(URL + '/users/' + userId + '/addresses/' + response.results[2].id)
.expectStatus(200)
.afterJSON(response => {
expect(response).to.exist;
expect(response.success).to.be.true;
frisby frisby
.create('GET users/{id}/addresses after DELETE') .create('DELETE users/{id}/addresses/{address}')
.get(URL + '/users/' + userId + '/addresses') .delete(URL + '/users/' + userId + '/addresses/' + response.results[2].id)
.expectStatus(200) .expectStatus(200)
.afterJSON(response => { .afterJSON(response => {
expect(response).to.exist; expect(response).to.exist;
expect(response.success).to.be.true; expect(response.success).to.be.true;
expect(response.results.length).to.equal(2);
frisby frisby
.create('DELETE users/{id}') .create('GET users/{id}/addresses after DELETE')
.delete(URL + '/users/' + userId) .get(URL + '/users/' + userId + '/addresses')
.expectStatus(200) .expectStatus(200)
.afterJSON(response => { .afterJSON(response => {
expect(response).to.exist; expect(response).to.exist;
expect(response.success).to.be.true; expect(response.success).to.be.true;
}) expect(response.results.length).to.equal(2);
.toss();
})
.toss();
})
.toss();
})
.toss();
frisby frisby
.create('GET users/{id} updated address') .create('DELETE users/{id}')
.get(URL + '/users/' + userId) .delete(URL + '/users/' + userId)
.expectStatus(200) .expectStatus(200)
.afterJSON(response => { .afterJSON(response => {
expect(response).to.exist; expect(response).to.exist;
expect(response.success).to.be.true; expect(response.success).to.be.true;
expect(response.id).to.equal(userId); })
expect(response.address).to.equal('alias1@example.com'); .toss();
}) })
.toss(); .toss();
})
.toss();
})
.toss();
frisby frisby
.create('GET users/{id}/mailboxes') .create('GET users/{id} updated address')
.get(URL + '/users/' + userId + '/mailboxes') .get(URL + '/users/' + userId)
.expectStatus(200) .expectStatus(200)
.afterJSON(response => { .afterJSON(response => {
expect(response).to.exist; expect(response).to.exist;
expect(response.success).to.be.true; expect(response.success).to.be.true;
expect(response.results.length).to.be.gte(4); expect(response.id).to.equal(userId);
expect(response.results[0].path).to.equal('INBOX'); expect(response.address).to.equal('alias1@example.com');
}) })
.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();
});