Skip to content

Commit

Permalink
feat: CMS-2579 password reset
Browse files Browse the repository at this point in the history
  • Loading branch information
simon-scherzinger committed Feb 3, 2017
1 parent af639c5 commit 58d6793
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 11 deletions.
15 changes: 14 additions & 1 deletion src/Accounts.js
@@ -1,5 +1,5 @@
import Core from './Core';
import { get, post, getUrl, superagentFormPost, optionsToQuery } from './helper';
import { get, post, getUrl, getEmpty, superagentFormPost, optionsToQuery } from './helper';
import AccountList from './resources/AccountList';
import AccountResource from './resources/AccountResource';
import TokenStoreFactory from './TokenStore';
Expand Down Expand Up @@ -213,5 +213,18 @@ export default class Accounts extends Core {
}

resetPassword(email) {
if (!email) {
throw new Error('email must be defined');
}
if (!this.clientID) {
throw new Error('clientID must be set with Account#setClientID(clientID: string)');
}

const request = this.newRequest().follow('ec:auth/assword-reset').withTemplateParameters({
clientID: this.clientID,
email,
});

return getEmpty(this.environment, request);
}
}
42 changes: 37 additions & 5 deletions src/helper.js
Expand Up @@ -15,8 +15,8 @@ import { stores } from './TokenStore';
* @param {function} callback the callback which should be wrapped.
* @returns {function} function whichs wraps the given callback.
*/
function handlerCallback(callback) {
return function callbackWrapper(err, res, traversal) {
function jsonHandler(callback) {
return function jsonHandler(err, res, traversal) {
if (err) {
return callback(err);
}
Expand All @@ -29,6 +29,31 @@ function handlerCallback(callback) {
};
}

/**
* Creates a callback which wraps a traverson repsonse from `get`, `post`, `put`, `delete` and
* handles http status codes.
* The callback will only handle status codes 200-299 as success. All
* other codes are handled as errors.
*
* @access private
*
* @param {function} callback the callback which should be wrapped.
* @returns {function} function whichs wraps the given callback.
*/
function unparsedHandler(callback) {
return function unparsedHandler(err, res, traversal) {
if (err) {
return callback(err);
}

if (res.statusCode >= 200 && res.statusCode < 300) {
return callback(null, [res.body, traversal]);
}

return callback(new Error(res.body));
};
}

/**
* Generic Promise wrapper for traverson functions.
*
Expand Down Expand Up @@ -62,11 +87,13 @@ function traversonWrapper(func, environment, t, body) {

if (func === 'getUrl') {
t[func](cb);
} else if (func === 'getEmpty') {
t.get(unparsedHandler(cb));
} else if (func === 'post' || func === 'put') {
t.addRequestOptions({ headers: { 'Content-Type': 'application/json' } })
t[func](body, handlerCallback(cb));
t.addRequestOptions({ headers: { 'Content-Type': 'application/json' } });
t[func](body, jsonHandler(cb));
} else {
t[func](handlerCallback(cb));
t[func](jsonHandler(cb));
}
});
}
Expand All @@ -90,6 +117,11 @@ export function get(environment, t) {
return traversonWrapper('get', environment, t);
}

export function getEmpty(environment, t) {
return traversonWrapper('getEmpty', environment, t)
.then(() => Promise.resolve());
}

/**
* Wraps a {@link
* https://github.com/basti1302/traverson traverson} getUrl request with a {@link Promise}
Expand Down
27 changes: 23 additions & 4 deletions test/Account.test.js
Expand Up @@ -48,10 +48,6 @@ describe('Accounts class', () => {
const throws = () => new Accounts().setClientID('notrest');
throws.should.throw(Error);
});
it('should throw with undefiend token', () => {
const throws = () => new Accounts().setToken();
throws.should.throw(Error);
});
it('should return list on list', () => {
const accounts = new Accounts('live');
const stub = sinon.stub(helper, 'get');
Expand Down Expand Up @@ -176,6 +172,29 @@ describe('Accounts class', () => {
const throws = () => new Accounts().signup('someone@example.com', 'supersecure');
throws.should.throw(Error);
});
it('should reset password', () => {
const accounts = new Accounts();
accounts.setClientID('rest');
const stub = sinon.stub(helper, 'getEmpty');
stub.returns(Promise.resolve());

return accounts.resetPassword('someone@entrecode.de')
.then(() => {
stub.restore();
})
.catch((err) => {
stub.restore();
throw err;
});
});
it('should throw on undefined email', () => {
const throws = () => new Accounts().resetPassword();
throws.should.throw(Error);
});
it('should throw on undefiend clientID', () => {
const throws = () => new Accounts().resetPassword('someone@entrecode.de');
throws.should.throw(Error);
});
});

describe('Account ListResource', () => {
Expand Down
33 changes: 33 additions & 0 deletions test/Core.test.js
Expand Up @@ -172,6 +172,39 @@ describe('Network Helper', () => {
});
});
});
describe('getEmpty', () => {
it('should be resolved', () => {
nock('https://datamanager.entrecode.de')
.get('/').reply(204);

return helper.getEmpty('live', traversal).should.be.eventually.resolved;
});
it('should be rejected', () => {
nock('https://datamanager.entrecode.de')
.get('/').reply(404, 'mocked error');

return helper.getEmpty('live', traversal)
.then(() => {
throw new Error('unexpectedly resolved');
})
.catch((err) => {
err.should.have.property('message', 'mocked error');
});
});
it('should fire error event', () => {
nock('https://datamanager.entrecode.de')
.get('/').replyWithError('mocked error');

return helper.getEmpty('live', traversal)
.then(() => {
throw new Error('unexpectedly resolved');
})
.catch((err) => {
err.should.have.property('message', 'mocked error');
spy.should.be.called.once;
});
});
});
describe('post', () => {
it('should be resolved', () => {
nock('https://datamanager.entrecode.de')
Expand Down
4 changes: 3 additions & 1 deletion typings/Accounts.d.ts
Expand Up @@ -20,7 +20,9 @@ export declare class Accounts extends Core {

emailAvailable(email: string): Promise<boolean>;

signup(email: string, password: string, invite: string): Promise<string>
signup(email: string, password: string, invite: string): Promise<string>;

resetPassword(email: string): Promise<undefined>;
}

interface tokenResponse {
Expand Down

0 comments on commit 58d6793

Please sign in to comment.