Skip to content
This repository was archived by the owner on Mar 11, 2022. It is now read-only.

Commit ab21b46

Browse files
authored
Merge pull request #396 from cloudant/error-on-cookie-auth-failure-tests
Update tests to expect an error on cookie authentication failure.
2 parents 062f48b + 164c57c commit ab21b46

File tree

7 files changed

+88
-1116
lines changed

7 files changed

+88
-1116
lines changed

test/client.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright © 2017, 2018 IBM Corp. All rights reserved.
1+
// Copyright © 2017, 2019 IBM Corp. All rights reserved.
22
//
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
@@ -227,23 +227,23 @@ describe('CloudantClient', function() {
227227

228228
describe('Error Handling', function() {
229229
it('Propagate request error: Invalid protocol.', function(done) {
230-
var cloudantClient = new Client();
230+
var cloudantClient = new Client({ plugins: [] });
231231
cloudantClient.request('abc://localhost:5984', function(err) {
232232
assert.equal(err.message, 'Invalid protocol: abc:');
233233
done();
234234
});
235235
});
236236

237237
it('Propagate request error: Base URL must be type string.', function(done) {
238-
var cloudantClient = new Client();
238+
var cloudantClient = new Client({ plugins: [] });
239239
cloudantClient.request({ baseUrl: 123, url: '/_all_dbs' }, function(err) {
240240
assert.equal(err.message, 'options.baseUrl must be a string');
241241
done();
242242
});
243243
});
244244

245245
it('Propagate request error: `unix://` URL scheme is no longer supported.', function(done) {
246-
var cloudantClient = new Client();
246+
var cloudantClient = new Client({ plugins: [] });
247247
cloudantClient.request('unix://abc', function(err) {
248248
assert.equal(
249249
err.message,
@@ -294,8 +294,8 @@ describe('CloudantClient', function() {
294294
.get(DBNAME)
295295
.reply(200, {doc_count: 1});
296296

297-
var cloudantClient = new Client();
298-
assert.equal(cloudantClient._plugins.length, 1);
297+
var cloudantClient = new Client({ plugins: [] });
298+
assert.equal(cloudantClient._plugins.length, 0);
299299

300300
var options = {
301301
url: SERVER + DBNAME,

test/legacy/api.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,8 @@ describe('#db Initialization', function() {
7373

7474
var mocks = nock(SERVER)
7575
.post('/_session')
76+
.times(3)
7677
.replyWithError({code: 'ECONNRESET', message: 'socket hang up'})
77-
.get('/')
78-
.replyWithError({code: 'ECONNRESET', message: 'socket hang up'});
7978

8079
Cloudant({username: ME, password: PASSWORD, url: SERVER}, function(er, cloudant, body) {
8180
er.should.be.an.Object;

test/legacy/plugin.js

Lines changed: 54 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright © 2015, 2018 IBM Corp. All rights reserved.
1+
// Copyright © 2015, 2019 IBM Corp. All rights reserved.
22
//
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
@@ -170,142 +170,6 @@ describe('promises #db', function() {
170170
});
171171
});
172172

173-
describe('cookieauth plugin #db', function() {
174-
before(onBefore);
175-
after(onAfter);
176-
177-
it('should return a promise', function(done) {
178-
var mocks = nock(SERVER)
179-
.post('/_session').reply(200, { ok: true })
180-
.get('/' + dbName).reply(200, { ok: true });
181-
var cloudant = Cloudant({plugins: 'cookieauth', url: SERVER, username: ME, password: PASSWORD});
182-
var db = cloudant.db.use(dbName);
183-
var p = db.info().then(function(data) {
184-
data.should.be.an.Object;
185-
// check that we use all the nocked API calls
186-
mocks.done();
187-
done();
188-
});
189-
assert.equal(p instanceof Promise, true);
190-
});
191-
192-
it('should authenticate before attempting API call', function(done) {
193-
var mocks = nock(SERVER)
194-
.post('/_session', {name: ME, password: PASSWORD}).reply(200, { ok: true, info: {}, userCtx: { name: ME, roles: ['_admin'] } })
195-
.get('/' + dbName + '/mydoc').reply(200, { _id: 'mydoc', _rev: '1-123', ok: true });
196-
var cloudant = Cloudant({plugins: 'cookieauth', url: SERVER, username: ME, password: PASSWORD});
197-
var db = cloudant.db.use(dbName);
198-
var p = db.get('mydoc', function(err, data) {
199-
assert.equal(err, null);
200-
data.should.be.an.Object;
201-
data.should.have.property._id;
202-
data.should.have.property._rev;
203-
data.should.have.property.ok;
204-
205-
// check that we use all the nocked API calls
206-
mocks.done();
207-
done();
208-
});
209-
});
210-
211-
it('should fail with incorrect authentication', function(done) {
212-
var mocks = nock(SERVER)
213-
.post('/_session', {name: ME, password: 'wrongpassword'})
214-
.reply(401, {error: 'unauthorized', reason: 'Name or password is incorrect.'})
215-
.get('/' + dbName + '/mydoc')
216-
.reply(401, {error: 'unauthorized', reason: 'Name or password is incorrect.'});
217-
var cloudant = Cloudant({plugins: 'cookieauth', url: SERVER, username: ME, password: 'wrongpassword'});
218-
var db = cloudant.db.use(dbName);
219-
var p = db.get('mydoc', function(err, data) {
220-
assert.equal(data, null);
221-
err.should.be.an.Object;
222-
err.should.have.property.error;
223-
err.should.have.property.reason;
224-
225-
// check that we use all the nocked API calls
226-
mocks.done();
227-
done();
228-
});
229-
});
230-
231-
it('should only authenticate once', function(done) {
232-
var mocks = nock(SERVER)
233-
.post('/_session', {name: ME, password: PASSWORD}).reply(200, { ok: true, info: {}, userCtx: { name: ME, roles: ['_admin'] } }, { 'Set-Cookie': 'AuthSession=xyz; Version=1; Path=/; HttpOnly' })
234-
.get('/' + dbName + '/mydoc').reply(200, { _id: 'mydoc', _rev: '1-123', ok: true })
235-
.get('/' + dbName + '/mydoc').reply(200, { _id: 'mydoc', _rev: '1-123', ok: true });
236-
var cloudant = Cloudant({plugins: 'cookieauth', url: SERVER, username: ME, password: PASSWORD});
237-
var db = cloudant.db.use(dbName);
238-
var p = db.get('mydoc', function(err, data) {
239-
assert.equal(err, null);
240-
data.should.be.an.Object;
241-
data.should.have.property._id;
242-
data.should.have.property._rev;
243-
data.should.have.property.ok;
244-
245-
db.get('mydoc', function(err, data) {
246-
assert.equal(err, null);
247-
data.should.be.an.Object;
248-
data.should.have.property._id;
249-
data.should.have.property._rev;
250-
data.should.have.property.ok;
251-
252-
// check that we use all the nocked API calls
253-
mocks.done();
254-
done();
255-
});
256-
});
257-
});
258-
259-
it('should not authenticate without credentials', function(done) {
260-
var mocks = nock(SERVER)
261-
.get('/' + dbName + '/mydoc').reply(401, { error: 'unauthorized', reason: '_reader access is required for this request' });
262-
var cloudant = Cloudant({plugins: 'cookieauth', url: SERVER});
263-
var db = cloudant.db.use(dbName);
264-
var p = db.get('mydoc', function(err, data) {
265-
assert.equal(data, null);
266-
err.should.be.an.Object;
267-
err.should.have.property.error;
268-
err.should.have.property.reason;
269-
270-
// check that we use all the nocked API calls
271-
mocks.done();
272-
done();
273-
});
274-
});
275-
276-
it('should work with asynchronous instantiation', function(done) {
277-
if (process.env.NOCK_OFF) {
278-
this.skip();
279-
}
280-
var mocks = nock(SERVER)
281-
.post('/_session', {name: ME, password: PASSWORD})
282-
.reply(401, {error: 'unauthorized', reason: 'Name or password is incorrect.'})
283-
.get('/')
284-
.reply(200, {couchdb: 'Welcome', version: '1.0.2', cloudant_build: '2488'});
285-
var cloudant = Cloudant({plugins: 'cookieauth', url: SERVER, username: ME, password: PASSWORD}, function(err, cloudant, data) {
286-
cloudant.should.be.an.Object;
287-
data.should.be.an.Object.have.a.property('couchdb');
288-
mocks.done();
289-
done();
290-
});
291-
});
292-
293-
it('should work with asynchronous instantiation with no credentials', function(done) {
294-
if (process.env.NOCK_OFF) {
295-
this.skip();
296-
}
297-
var mocks = nock(SERVER)
298-
.get('/')
299-
.reply(200, { couchdb: 'Welcome', version: '1.0.2', cloudant_build: '2488' });
300-
var cloudant = Cloudant({plugins: 'cookieauth', url: SERVER}, function(err, cloudant, data) {
301-
cloudant.should.be.an.Object;
302-
data.should.be.an.Object.have.a.property('couchdb');
303-
mocks.done();
304-
done();
305-
});
306-
});
307-
});
308-
309173
describe('custom plugin #db', function() {
310174
before(onBefore);
311175
after(onAfter);
@@ -357,35 +221,71 @@ describe('custom plugin #db', function() {
357221
done();
358222
});
359223
});
224+
});
360225

361-
it('should allow custom plugins using asynchronous instantiation with invalid credentials', function(done) {
362-
const badPass = 'bAD%%Pa$$w0rd123';
226+
describe('cookieauth plugin #db', function() {
227+
before(onBefore);
228+
after(onAfter);
363229

230+
it('should return a promise', function(done) {
364231
var mocks = nock(SERVER)
365-
.post('/_session', { name: ME, password: badPass })
366-
.reply(401, { error: 'unauthorized', reason: 'Name or password is incorrect.' })
367-
.get('/')
368-
.reply(401, { error: 'unauthorized', reason: 'Name or password is incorrect.' });
369-
370-
Cloudant({ plugins: defaultPlugin, url: SERVER, username: ME, password: badPass }, function(err, nano) {
371-
assert.equal(err.error, 'unauthorized');
372-
assert.equal(nano, null);
232+
.post('/_session').reply(200, { ok: true })
233+
.get('/' + dbName).reply(200, { ok: true });
234+
var cloudant = Cloudant({plugins: 'cookieauth', url: SERVER, username: ME, password: PASSWORD});
235+
var db = cloudant.db.use(dbName);
236+
var p = db.info().then(function(data) {
237+
data.should.be.an.Object;
238+
// check that we use all the nocked API calls
373239
mocks.done();
374240
done();
375241
});
242+
assert.equal(p instanceof Promise, true);
376243
});
377244

378-
it('should allow custom plugins using asynchronous instantiation with no credentials', function(done) {
245+
it('should authenticate before attempting API call', function(done) {
379246
var mocks = nock(SERVER)
380-
.get('/')
381-
.reply(200, { couchdb: 'Welcome' });
382-
383-
Cloudant({ plugins: defaultPlugin, url: SERVER }, function(err, nano, pong) {
247+
.post('/_session', {name: ME, password: PASSWORD}).reply(200, { ok: true, info: {}, userCtx: { name: ME, roles: ['_admin'] } })
248+
.get('/' + dbName + '/mydoc').reply(200, { _id: 'mydoc', _rev: '1-123', ok: true });
249+
var cloudant = Cloudant({plugins: 'cookieauth', url: SERVER, username: ME, password: PASSWORD});
250+
var db = cloudant.db.use(dbName);
251+
var p = db.get('mydoc', function(err, data) {
384252
assert.equal(err, null);
385-
assert.notEqual(nano, null);
386-
assert.equal(pong.couchdb, 'Welcome');
253+
data.should.be.an.Object;
254+
data.should.have.property._id;
255+
data.should.have.property._rev;
256+
data.should.have.property.ok;
257+
258+
// check that we use all the nocked API calls
387259
mocks.done();
388260
done();
389261
});
390262
});
263+
264+
it('should only authenticate once', function(done) {
265+
var mocks = nock(SERVER)
266+
.post('/_session', {name: ME, password: PASSWORD}).reply(200, { ok: true, info: {}, userCtx: { name: ME, roles: ['_admin'] } }, { 'Set-Cookie': 'AuthSession=xyz; Version=1; Path=/; HttpOnly' })
267+
.get('/' + dbName + '/mydoc').reply(200, { _id: 'mydoc', _rev: '1-123', ok: true })
268+
.get('/' + dbName + '/mydoc').reply(200, { _id: 'mydoc', _rev: '1-123', ok: true });
269+
var cloudant = Cloudant({plugins: 'cookieauth', url: SERVER, username: ME, password: PASSWORD});
270+
var db = cloudant.db.use(dbName);
271+
var p = db.get('mydoc', function(err, data) {
272+
assert.equal(err, null);
273+
data.should.be.an.Object;
274+
data.should.have.property._id;
275+
data.should.have.property._rev;
276+
data.should.have.property.ok;
277+
278+
db.get('mydoc', function(err, data) {
279+
assert.equal(err, null);
280+
data.should.be.an.Object;
281+
data.should.have.property._id;
282+
data.should.have.property._rev;
283+
data.should.have.property.ok;
284+
285+
// check that we use all the nocked API calls
286+
mocks.done();
287+
done();
288+
});
289+
});
290+
});
391291
});

test/legacy/readme-examples.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ var ME = process.env.cloudant_username || 'nodejs';
3434
var PASSWORD = process.env.cloudant_password || 'sjedon';
3535
var SERVER = process.env.SERVER_URL || 'https://' + ME + '.cloudant.com';
3636

37+
const MOCK_COOKIE = 'AuthSession=Y2xbZWr0bQlpcc19ZQN8OeU4OWFCNYcZOxgdhy-QRDp4i6JQrfkForX5OU5P';
38+
const MOCK_SET_COOKIE_HEADER = { 'set-cookie': `${MOCK_COOKIE}; Version=1; Max-Age=86400; Path=/; HttpOnly` };
39+
3740
var real_require = require;
3841
require = function(module) {
3942
return (module == '@cloudant/cloudant')
@@ -129,7 +132,7 @@ if (SERVER.endsWith('.cloudant.com')) {
129132
});
130133
before(function() {
131134
mocks = nock(SERVER)
132-
.post('/_session').reply(200, {XXXXX: 'YYYYYYYYYY', ok: true, userCtx: {name: 'jhs', roles: []}})
135+
.post('/_session').reply(200, {ok: true}, MOCK_SET_COOKIE_HEADER)
133136
.get('/').reply(200, {couchdb: 'Welcome', version: '1.0.2', cloudant_build: '2488'})
134137
.get('/animaldb/dog').reply(404, {error: 'not_found', reason: 'missing'});
135138
});
@@ -166,8 +169,8 @@ if (SERVER.endsWith('.cloudant.com')) {
166169
this.skip();
167170
}
168171
mocks = nock(SERVER)
169-
.post('/_session').reply(200, {ok:true})
170-
.get('/').reply(200, {couchdb: 'Welcome!!!!!', version: '1.0.2', cloudant_build: '2488'});
172+
.post('/_session').reply(200, {ok: true}, MOCK_SET_COOKIE_HEADER)
173+
.get('/').reply(200, {couchdb: 'Welcome', version: '1.0.2', cloudant_build: '2488'});
171174
});
172175

173176
it('Example 1', function(done) {
@@ -515,7 +518,7 @@ if (SERVER.endsWith('.cloudant.com')) {
515518
});
516519
before(function(done) {
517520
mocks = nock(SERVER)
518-
.post('/_session').reply(200, { ok: true, name: ME, roles: [] }, {'set-cookie': ['AuthSession=bm9kZWpzOjU1RTA1NDdEOsUsoq9lykQCEBhwTpIyEbgmYpvX; Version=1; Expires=Sat, 29 Aug 2015 12:30:53 GMT; Max-Age=86400; Path=/; HttpOnly; Secure']})
521+
.post('/_session').reply(200, {ok: true}, MOCK_SET_COOKIE_HEADER)
519522
.put(`/${alice}`).reply(200, { ok: true })
520523
.post(`/${alice}`).reply(200, { ok: true, id: '72e0367f3e195340e239948164bbb7e7', rev: '1-feb5539029f4fc50dc3f827b164a2088' })
521524
.get('/_session').reply(200, {ok: true, userCtx: {name: ME, roles: ['_admin', '_reader', '_writer']}})

0 commit comments

Comments
 (0)