edgegrid-updated-log4js
Version:
Authentication handler for the Akamai OPEN EdgeGrid Authentication scheme in Node.js
302 lines (254 loc) • 9.41 kB
JavaScript
// Copyright 2014 Akamai Technologies, Inc. All Rights Reserved
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
var assert = require('assert'),
nock = require('nock'),
path = require('path'),
Api = require('../../src/api');
describe('Api', function() {
beforeEach(function() {
this.api = new Api(
'clientToken',
'clientSecret',
'accessToken',
'base.com'
);
});
describe('.config', function() {
it('reports the client token', function() {
assert.equal(this.api.config.client_token, 'clientToken');
});
it('reports the client secret', function() {
assert.equal(this.api.config.client_secret, 'clientSecret');
});
it('reports the access token', function() {
assert.equal(this.api.config.access_token, 'accessToken');
});
it('reports the API host', function() {
assert.equal(this.api.config.host, 'https://base.com');
});
describe('when it is instantiated with an API host that already contains the protocol', function() {
it('it does not double declare the protocol', function() {
this.api = new Api(
'clientToken',
'clientSecret',
'accessToken',
'https://base.com'
);
assert.equal(this.api.config.host, 'https://base.com');
});
});
describe('when it is instantiated with an object', function() {
beforeEach(function() {
this.api = new Api({
path: path.resolve(__dirname, '../test_edgerc'),
section: 'section'
});
});
it('reports the client token from the edgerc associated with the specified section', function() {
assert.equal(this.api.config.client_token, 'sectionClientToken');
});
it('reports the client secret from the edgerc associated with the specified section', function() {
assert.equal(this.api.config.client_secret, 'sectionClientSecret');
});
it('reports the access token from the edgerc associated with the specified section', function() {
assert.equal(this.api.config.access_token, 'sectionAccessToken');
});
it('reports the API host from the edgerc associated with the specified section', function() {
assert.equal(this.api.config.host, 'https://sectionexample.luna.akamaiapis.net');
});
describe('when it is instantiated with an object that does not specfy a section', function() {
beforeEach(function() {
this.api = new Api({
path: path.resolve(__dirname, '../test_edgerc')
});
});
it('reports the client token from the edgerc associated with the default section', function() {
assert.equal(this.api.config.client_token, 'clientToken');
});
it('reports the client secret from the edgerc associated with the default section', function() {
assert.equal(this.api.config.client_secret, 'clientSecret');
});
it('reports the access token from the edgerc associated with the default section', function() {
assert.equal(this.api.config.access_token, 'accessToken');
});
it('reports the API host from the edgerc associated with the default section', function() {
assert.equal(this.api.config.host, 'https://example.luna.akamaiapis.net');
});
});
describe('when it is instantiated with an object that does not specify a path nor a section', function() {
it('throws the appropriate error', function() {
assert.throws(
function() {
return new Api({});
},
/No edgerc path/
);
});
});
describe('when it is instantiated with an object that specifies an inadequate path', function() {
it('throws the appropriate error', function() {
assert.throws(
function() {
return new Api({
path: ''
});
},
/No edgerc path/
);
});
});
});
});
describe('when it is not instantiated with valid credentials', function() {
it('throws the appropriate error', function() {
assert.throws(
function() {
return new Api();
},
/Insufficient Akamai credentials/
);
});
});
describe('#auth', function() {
it('should be chainable', function(){
assert.deepEqual(this.api, this.api.auth({ path: '/foo' }));
});
describe('when minimal request options are passed', function() {
beforeEach(function() {
this.api.auth({
path: '/foo'
});
});
it('adds an Authorization header to the request it is passed', function() {
assert.equal(typeof this.api.request.headers.Authorization === 'string', true);
});
it('ensures a default Content-Type of application/json', function() {
assert.equal(this.api.request.headers['Content-Type'], 'application/json');
});
it('ensures a default GET method', function() {
assert.equal(this.api.request.method, 'GET');
});
it('ensures a default empty body', function() {
assert.equal(this.api.request.body, '');
});
it('ensures a url is properly declared', function() {
assert.equal(this.api.request.url, 'https://base.com/foo');
});
});
describe('when more specific request options are passed', function() {
beforeEach(function() {
this.api.auth({
path: '/foo',
method: 'POST',
body: {
foo: 'bar'
},
somethingArbitrary: 'someValue'
});
});
it('adds an Authorization header to the request it is passed', function() {
assert.equal(typeof this.api.request.headers.Authorization === 'string', true);
});
it('ensures a default Content-Type of application/json', function() {
assert.equal(this.api.request.headers['Content-Type'], 'application/json');
});
it('uses the specified POST method', function() {
assert.equal(this.api.request.method, 'POST');
});
it('uses the specified body parsed as a JSON string', function() {
console.log("BODY: ", this.api.request.body);
assert.equal(this.api.request.body, '{"foo":"bar"}');
});
it('extends the default request options with any others specified', function() {
assert.equal(this.api.request.somethingArbitrary, 'someValue');
});
});
});
describe('#send', function() {
it('should be chainable', function(){
assert.deepEqual(this.api, this.api.auth({ path: '/foo' }).send());
});
describe('when authentication is done with a simple options object specifying only a path', function() {
beforeEach(function() {
nock('https://base.com')
.get('/foo')
.reply(200, {
foo: 'bar'
});
});
it('sends the HTTP GET request created by #auth', function(done) {
this.api.auth({
path: '/foo'
});
this.api.send(function(err, resp, body) {
assert.equal(JSON.parse(body).foo, 'bar');
done();
});
});
});
describe('when authentication is done with a more complex options object specifying only a path', function() {
beforeEach(function() {
nock('https://base.com')
.post('/foo')
.reply(200, {
foo: 'bar'
});
});
it('sends the HTTP created by #auth', function(done) {
this.api.auth({
path: '/foo',
method: 'POST'
});
this.api.send(function(err, resp, body) {
assert.equal(JSON.parse(body).foo, 'bar');
done();
});
});
});
describe('when the initial request redirects', function() {
it('correctly follows the redirect and re-signs the request', function(done) {
nock('https://base.com')
.get('/foo')
.reply(302, undefined, {
'Location': 'https://base.com/bar'
})
.get('/bar')
.reply(200, {
bar: 'bim'
});
this.api.auth({
path: '/foo',
});
this.api.send(function(err, resp, body) {
assert.equal(JSON.parse(body).bar, 'bim');
done();
});
});
});
describe('when the initial request fails', function() {
it('correctly handles the error in the callback', function(done) {
nock('https://base.com')
.get('/foo')
.replyWithError('something awful happened');
this.api.auth({
path: '/foo',
});
this.api.send(function (data) {
assert.equal(data.message, 'something awful happened');
done();
});
});
});
});
});