Skip to content

Commit

Permalink
feat: CMS-2604 token resource
Browse files Browse the repository at this point in the history
  • Loading branch information
simon-scherzinger committed Feb 13, 2017
1 parent ee06973 commit fb404b0
Show file tree
Hide file tree
Showing 7 changed files with 621 additions and 2 deletions.
18 changes: 16 additions & 2 deletions src/resources/AccountResource.js
@@ -1,4 +1,6 @@
import Resource from './Resource';
import TokenList from './TokenList';
import { get } from '../helper';

/**
* Account resource class
Expand Down Expand Up @@ -189,8 +191,20 @@ export default class AccountResource extends Resource {
return this.getProperty('hasPendingEmail');
}

// todo change email
// todo password reset
/**
* Load the {@link TokenList} for this account
*
* @returns {Promise<TokenList>} Promise resolving the token list
*/
tokenList() {
return Promise.resolve()
.then(() => {
const request = this.newRequest().follow('ec:account/tokens');

return get(this.environment, request)
.then(([tokenList, traversal]) => new TokenList(tokenList, this.environment, traversal));
});
}
}

/**
Expand Down
22 changes: 22 additions & 0 deletions src/resources/TokenList.js
@@ -0,0 +1,22 @@
import ListResource from './ListResource';
import TokenResource from './TokenResource';

/**
* Token list class
*
* @class
*/
export default class TokenList extends ListResource {
/**
* Creates a new {@link TokenList}.
*
* @param {object} resource resource loaded from the API.
* @param {string} environment the environment this resource is associated to.
* @param {?object} traversal traversal from which traverson can continue.
*/
constructor(resource, environment, traversal) {
super(resource, environment, 'ec:account/token', traversal);
this.ListClass = TokenList;
this.ItemClass = TokenResource;
}
}
71 changes: 71 additions & 0 deletions src/resources/TokenResource.js
@@ -0,0 +1,71 @@
import Resource from './Resource';

/**
* TokenResource class
*
* @class
*/
export default class TokenResource extends Resource {
/**
* Whether or not this is the token which is used by the current session.
*
* @returns {boolean} whether or not this is the current token
*/
isCurrent() {
return this.getProperty('isCurrent');
}

/**
* Issued {@link Date} for this token.
*
* @returns {Date} issued date
*/
issued() {
return new Date(this.getProperty('issued'));
}

/**
* Valid until {@link Date} for this token.
*
* @returns {Date} valid until date
*/
validUntil() {
return new Date(this.getProperty('validUntil'));
}

/**
* Will return ipAddress property.
*
* @returns {string} the ipAddress.
*/
getIpAddress() {
return this.getProperty('ipAddress');
}

/**
* Will return ipAddressLocation property.
*
* @returns {string} the ipAddressLocation.
*/
getIpAddressLocation() {
return this.getProperty('ipAddressLocation');
}

/**
* Will return accessTokenID property.
*
* @returns {string} the token id.
*/
getAccessTokenID() {
return this.getProperty('accessTokenID');
}

/**
* Will return device property.
*
* @returns {object} the device property.
*/
getDevice() {
return this.getProperty('device');
}
}
7 changes: 7 additions & 0 deletions test/Account.test.js
Expand Up @@ -357,6 +357,13 @@ describe('Account Resource', () => {
it('should get all permissions', () => {
resource.getAllPermissions().should.have.property('length', 8);
});
it('should load TokenList', () => {
const stub = sinon.stub(helper, 'get');
stub.returns(resolver('token-list.json'));

return resource.tokenList().should.be.fulfilled
.and.notify(() => stub.restore());
});

const dateGetter = [
'created',
Expand Down
117 changes: 117 additions & 0 deletions test/TokenResource.test.js
@@ -0,0 +1,117 @@
/* eslint no-unused-expressions:0 */

const chai = require('chai');
const sinon = require('sinon');
const sinonChai = require('sinon-chai');
const fs = require('fs');

const TokenResource = require('../lib/resources/TokenResource').default;
const TokenList = require('../lib/resources/TokenList').default;
const Resource = require('../lib/resources/Resource').default;
const ListResource = require('../lib/resources/ListResource').default;

const should = chai.should();
chai.use(sinonChai);

function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}

describe('Token ListResource', () => {
let listJson;
let list;
before(() => {
return new Promise((resolve, reject) => {
fs.readFile(`${__dirname}/mocks/token-list.json`, 'utf-8', (err, res) => {
if (err) {
return reject(err);
}
return resolve(JSON.parse(res));
});
})
.then((json) => {
listJson = json;
});
});
beforeEach(() => {
list = new TokenList(listJson);
});
afterEach(() => {
list = null;
});
it('should be instance of ListResource', () => {
list.should.be.instanceOf(ListResource);
});
it('should be instance of TokenLisst', () => {
list.should.be.instanceOf(TokenList);
});
it('should have TokenResource items', () => {
list.getAllItems().forEach(item => item.should.be.instanceOf(TokenResource));
});
});

describe('Token Resource', () => {
let resourceJson;
let resource;
before(() => {
return new Promise((resolve, reject) => {
fs.readFile(`${__dirname}/mocks/token-single.json`, 'utf-8', (err, res) => {
if (err) {
return reject(err);
}
return resolve(JSON.parse(res));
});
})
.then((json) => {
resourceJson = json;
});
});
beforeEach(() => {
resource = new TokenResource(resourceJson);
});
afterEach(() => {
resource = null;
});
it('should be instance of Resource', () => {
resource.should.be.instanceOf(Resource);
});
it('should be instance of TokenResource', () => {
resource.should.be.instanceOf(TokenResource);
});
it('should return boolean on isCurrent', () => {
resource.isCurrent().should.be.false;
});

const dateGetter = [
'issued', 'validUntil',
];
dateGetter.forEach((name) => {
it(`should call resource.getProperty with ${name}`, () => {
const spy = sinon.spy(resource, 'getProperty');

const property = resource[name]();
spy.should.have.been.called.once;
spy.should.have.been.calledWith(name);
property.toISOString().should.be.equal(resource.getProperty(name));

spy.restore();
});
});

const getter = [
'ipAddress', 'ipAddressLocation',
'accessTokenID', 'device',
];
getter.forEach((name) => {
it(`should call resource.getProperty with ${name}`, () => {
const spy = sinon.spy(resource, 'getProperty');

const property = resource[`get${capitalizeFirstLetter(name)}`]();
spy.should.have.been.called.once;
spy.should.have.been.calledWith(name);
property.should.be.equal(resource.getProperty(name));

spy.restore();
});
});
});

0 comments on commit fb404b0

Please sign in to comment.