Skip to content

Commit

Permalink
feat: CMS-2580 changeEmail request
Browse files Browse the repository at this point in the history
  • Loading branch information
simon-scherzinger committed Feb 6, 2017
1 parent 58d6793 commit c77f28f
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 3 deletions.
40 changes: 37 additions & 3 deletions src/Accounts.js
@@ -1,5 +1,13 @@
import Core from './Core';
import { get, post, getUrl, getEmpty, superagentFormPost, optionsToQuery } from './helper';
import {
get,
post,
getUrl,
getEmpty,
postEmpty,
superagentFormPost,
optionsToQuery,
} from './helper';
import AccountList from './resources/AccountList';
import AccountResource from './resources/AccountResource';
import TokenStoreFactory from './TokenStore';
Expand Down Expand Up @@ -31,7 +39,7 @@ export default class Accounts extends Core {
}

super(urls[environment || 'live']);
this.environment = environment;
this.environment = environment || 'live';
this.tokenStore = TokenStoreFactory(environment || 'live');
}

Expand Down Expand Up @@ -212,6 +220,12 @@ export default class Accounts extends Core {
});
}

/**
* Start a password reset.
*
* @param {string} email email of the account
* @returns {Promise} Promise resolving on success.
*/
resetPassword(email) {
if (!email) {
throw new Error('email must be defined');
Expand All @@ -220,11 +234,31 @@ export default class Accounts extends Core {
throw new Error('clientID must be set with Account#setClientID(clientID: string)');
}

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

return getEmpty(this.environment, request);
}

/**
* Change the logged in account to the given new email address.
*
* @param {string} email the new email
* @returns {Promise} Promise resolving on success.
*/
changeEmail(email) {
if (!email) {
throw new Error('email must be defined');
}

if (!this.tokenStore.has()) {
throw new Error('not logged in.');
}

const request = this.newRequest().follow('ec:auth/change-email');

return postEmpty(this.environment, request, { email });
}
}
38 changes: 38 additions & 0 deletions src/helper.js
Expand Up @@ -89,6 +89,8 @@ function traversonWrapper(func, environment, t, body) {
t[func](cb);
} else if (func === 'getEmpty') {
t.get(unparsedHandler(cb));
} else if (func === 'postEmpty') {
t.post(body, unparsedHandler(cb));
} else if (func === 'post' || func === 'put') {
t.addRequestOptions({ headers: { 'Content-Type': 'application/json' } });
t[func](body, jsonHandler(cb));
Expand Down Expand Up @@ -117,11 +119,47 @@ export function get(environment, t) {
return traversonWrapper('get', environment, t);
}

/**
* Wraps a {@link
* https://github.com/basti1302/traverson traverson} get request with a {@link Promise}
* Parameter t must be a {@link
* https://github.com/basti1302/traverson/blob/master/api.markdown#request-builder
* traverson request builder}.
* Only http status codes >200 <=299 will resolve, all others will
* reject.
*
* @access private
*
* @param {string} environment environment from which a token should be used
* @param {object} t request builder
* @returns {Promise} resolves to undefined.
*/
export function getEmpty(environment, t) {
return traversonWrapper('getEmpty', environment, t)
.then(() => Promise.resolve());
}

/**
* Wraps a {@link
* https://github.com/basti1302/traverson traverson} get request with a {@link Promise}
* Parameter t must be a {@link
* https://github.com/basti1302/traverson/blob/master/api.markdown#request-builder
* traverson request builder}.
* Only http status codes >200 <=299 will resolve, all others will
* reject.
*
* @access private
*
* @param {string} environment environment from which a token should be used
* @param {object} t request builder
* @param {object} body the request body
* @returns {Promise} resolves to undefined.
*/
export function postEmpty(environment, t, body) {
return traversonWrapper('postEmpty', environment, t, body)
.then(() => Promise.resolve());
}

/**
* Wraps a {@link
* https://github.com/basti1302/traverson traverson} getUrl request with a {@link Promise}
Expand Down
27 changes: 27 additions & 0 deletions test/Account.test.js
Expand Up @@ -195,6 +195,33 @@ describe('Accounts class', () => {
const throws = () => new Accounts().resetPassword('someone@entrecode.de');
throws.should.throw(Error);
});
it('should change email', () => {
const accounts = new Accounts();
accounts.setToken('eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJlbnRyZWNvZGVUZXN0IiwiaWF0IjoxNDg1NzgzNTg4LCJleHAiOjQ2NDE0NTcxODgsImF1ZCI6IlRlc3QiLCJzdWIiOiJ0ZXN0QGVudHJlY29kZS5kZSJ9.Vhrq5GR2hNz-RoAhdlnIIWHelPciBPCemEa74s7cXn8');
const stub = sinon.stub(helper, 'postEmpty');
stub.returns(Promise.resolve());

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

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

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

return helper.postEmpty('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')
.post('/').replyWithError('mocked error');

return helper.postEmpty('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
2 changes: 2 additions & 0 deletions typings/Accounts.d.ts
Expand Up @@ -23,6 +23,8 @@ export declare class Accounts extends Core {
signup(email: string, password: string, invite: string): Promise<string>;

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

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

interface tokenResponse {
Expand Down

0 comments on commit c77f28f

Please sign in to comment.