Skip to content

Commit

Permalink
Wrapping async store methods + adding deprecations + cleaning up tests
Browse files Browse the repository at this point in the history
  • Loading branch information
rmachielse committed Nov 20, 2015
1 parent a11b7ef commit 1911837
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 94 deletions.
84 changes: 47 additions & 37 deletions addon/internal-session.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,66 +44,76 @@ export default Ember.ObjectProxy.extend(Ember.Evented, {

restore() {
return new Ember.RSVP.Promise((resolve, reject) => {
let restored = this.store.restore();
if (typeof restored === 'undefined' || typeof restored.then === 'undefined') {
restored = Ember.RSVP.Promise.resolve(restored || {});
}
restored.then((restoredContent) => {
this._callStoreAsync('restore').then((restoredContent) => {
let { authenticator } = (restoredContent.authenticated || {});
if (!!authenticator) {
delete restoredContent.authenticated.authenticator;
this.container.lookup(authenticator).restore(restoredContent.authenticated).then((content) => {
this.set('content', restoredContent);
this._setup(authenticator, content);
resolve();
this._setup(authenticator, content).then(resolve, reject);
}, () => {
Ember.Logger.debug(`The authenticator "${authenticator}" rejected to restore the session - invalidating…`);
this.set('content', restoredContent);
this._clear();
reject();
this._clear().then(resolve, reject);
});
} else {
delete (restoredContent || {}).authenticated;
this.set('content', restoredContent);
this._clear();
reject();
this._clear().then(resolve, reject);
}
}, () => {
this._clear();
reject();
this._clear().then(resolve, reject);
});
});
},

_callStoreAsync(method, ...params) {
let result = this.store[method].apply(this.store, params);
if (typeof result === 'undefined' || typeof result.then === 'undefined') {
Ember.deprecate(`Ember Simple Auth: Synchronous stores have been deprecated. Make sure your custom store's ${method} method returns a promise.`, false);
return Ember.RSVP.Promise.resolve(result || {});
} else {
return result;
}
},

_setup(authenticator, authenticatedContent, trigger) {
trigger = !!trigger && !this.get('isAuthenticated');
this.beginPropertyChanges();
this.setProperties({
isAuthenticated: true,
authenticator
return new Ember.RSVP.Promise((resolve, reject) => {
trigger = !!trigger && !this.get('isAuthenticated');
this.beginPropertyChanges();
this.setProperties({
isAuthenticated: true,
authenticator
});
Ember.set(this.content, 'authenticated', authenticatedContent);
this._bindToAuthenticatorEvents();
this._updateStore().then(() => {
this.endPropertyChanges();
if (trigger) {
this.trigger('authenticationSucceeded');
}
resolve();
}, reject);
});
Ember.set(this.content, 'authenticated', authenticatedContent);
this._bindToAuthenticatorEvents();
this._updateStore();
this.endPropertyChanges();
if (trigger) {
this.trigger('authenticationSucceeded');
}
},

_clear(trigger) {
trigger = !!trigger && this.get('isAuthenticated');
this.beginPropertyChanges();
this.setProperties({
isAuthenticated: false,
authenticator: null
return new Ember.RSVP.Promise((resolve, reject) => {
trigger = !!trigger && this.get('isAuthenticated');
this.beginPropertyChanges();
this.setProperties({
isAuthenticated: false,
authenticator: null
});
Ember.set(this.content, 'authenticated', {});
this._updateStore().then(() => {
this.endPropertyChanges();
if (trigger) {
this.trigger('invalidationSucceeded');
}
resolve();
}, reject);
});
Ember.set(this.content, 'authenticated', {});
this._updateStore();
this.endPropertyChanges();
if (trigger) {
this.trigger('invalidationSucceeded');
}
},

setUnknownProperty(key, value) {
Expand All @@ -118,7 +128,7 @@ export default Ember.ObjectProxy.extend(Ember.Evented, {
if (!Ember.isEmpty(this.authenticator)) {
Ember.set(data, 'authenticated', Ember.merge({ authenticator: this.authenticator }, data.authenticated || {}));
}
this.store.persist(data);
return this._callStoreAsync('persist', data);
},

_bindToAuthenticatorEvents() {
Expand Down
66 changes: 31 additions & 35 deletions tests/unit/internal-session-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { expect } from 'chai';
import sinon from 'sinon';
import InternalSession from 'ember-simple-auth/internal-session';
import EphemeralStore from 'ember-simple-auth/session-stores/ephemeral';
import Authenticator from 'ember-simple-auth/authenticators/base';
import Authenticator from 'ember-simple-auth/authenticators/test';

describe('InternalSession', () => {
let session;
Expand Down Expand Up @@ -138,37 +138,34 @@ describe('InternalSession', () => {
});
});

it('stores the data the authenticator resolves with in its authenticated section', (done) => {
store.persist({ authenticated: { authenticator: 'authenticator' } }).then(() => {
session.restore().then(() => {
store.restore().then((properties) => {
it('stores the data the authenticator resolves with in its authenticated section', () => {
return store.persist({ authenticated: { authenticator: 'authenticator' } }).then(() => {
return session.restore().then(() => {
return store.restore().then((properties) => {
delete properties.authenticator;

expect(session.get('authenticated')).to.eql({ some: 'property', authenticator: 'authenticator' });
done();
});
});
});
});

it('persists its content in the store', (done) => {
store.persist({ authenticated: { authenticator: 'authenticator' }, someOther: 'property' }).then(() => {
session.restore().then(() => {
store.restore().then((properties) => {
it('persists its content in the store', () => {
return store.persist({ authenticated: { authenticator: 'authenticator' }, someOther: 'property' }).then(() => {
return session.restore().then(() => {
return store.restore().then((properties) => {
delete properties.authenticator;

expect(properties).to.eql({ authenticated: { some: 'property', authenticator: 'authenticator' }, someOther: 'property' });
done();
});
});
});
});

it('persists the authenticator factory in the store', (done) => {
session.restore().then(() => {
store.restore().then((properties) => {
it('persists the authenticator factory in the store', () => {
return session.restore().then(() => {
return store.restore().then((properties) => {
expect(properties.authenticated.authenticator).to.eql('authenticator');
done();
});
});
});
Expand Down Expand Up @@ -205,6 +202,8 @@ describe('InternalSession', () => {
describe('when the store resolves restoration', function() {
beforeEach(() => {
sinon.stub(store, 'restore').returns({ authenticated: { authenticator: 'authenticator' } });
sinon.stub(store, 'persist').returns();
sinon.stub(store, 'clear').returns();
});

it('is authenticated', () => {
Expand All @@ -217,6 +216,8 @@ describe('InternalSession', () => {
describe('when the store rejects restoration', function() {
beforeEach(() => {
sinon.stub(store, 'restore').returns({});
sinon.stub(store, 'persist').returns();
sinon.stub(store, 'clear').returns();
});

it('is not authenticated', () => {
Expand Down Expand Up @@ -253,22 +254,20 @@ describe('InternalSession', () => {
});
});

it('persists its content in the store', (done) => {
session.authenticate('authenticator').then(() => {
store.restore().then((properties) => {
it('persists its content in the store', () => {
return session.authenticate('authenticator').then(() => {
return store.restore().then((properties) => {
delete properties.authenticator;

expect(properties).to.eql({ authenticated: { some: 'property', authenticator: 'authenticator' } });
done();
});
});
});

it('persists the authenticator factory in the store', (done) => {
session.authenticate('authenticator').then(() => {
store.restore().then((properties) => {
it('persists the authenticator factory in the store', () => {
return session.authenticate('authenticator').then(() => {
return store.restore().then((properties) => {
expect(properties.authenticated.authenticator).to.eql('authenticator');
done();
});
});
});
Expand Down Expand Up @@ -313,14 +312,13 @@ describe('InternalSession', () => {
});
});

it('updates the store', (done) => {
it('updates the store', () => {
sinon.stub(authenticator, 'authenticate').returns(Ember.RSVP.reject('error auth'));
session.set('content', { some: 'property', authenticated: { some: 'other property' } });

session.authenticate('authenticator').catch(() => {
store.restore().then((properties) => {
return session.authenticate('authenticator').catch(() => {
return store.restore().then((properties) => {
expect(properties).to.eql({ some: 'property', authenticated: {} });
done();
});
});
});
Expand Down Expand Up @@ -368,13 +366,12 @@ describe('InternalSession', () => {
});
});

it('updates the store', (done) => {
it('updates the store', () => {
session.set('content', { some: 'property', authenticated: { some: 'other property' } });

session.invalidate().then(() => {
store.restore().then((properties) => {
return session.invalidate().then(() => {
return store.restore().then((properties) => {
expect(properties).to.eql({ some: 'property', authenticated: {} });
done();
});
});
});
Expand Down Expand Up @@ -414,13 +411,12 @@ describe('InternalSession', () => {
});
});

it('does not update the store', (done) => {
it('does not update the store', () => {
sinon.stub(authenticator, 'invalidate').returns(Ember.RSVP.reject('error'));

session.invalidate().catch(() => {
store.restore().then((properties) => {
return session.invalidate().catch(() => {
return store.restore().then((properties) => {
expect(properties).to.eql({ authenticated: { some: 'property', authenticator: 'authenticator' } });
done();
});
});
});
Expand Down
39 changes: 17 additions & 22 deletions tests/unit/session-stores/shared/store-behavior.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,19 @@ export default function(options) {
});

describe('#persist', () => {
it('persists an object', (done) => {
store.persist({ key: 'value' }).then(() => {
store.restore().then((restoredContent) => {
it('persists an object', () => {
return store.persist({ key: 'value' }).then(() => {
return store.restore().then((restoredContent) => {
expect(restoredContent).to.eql({ key: 'value' });
done();
});
});
});

it('overrides existing data', (done) => {
store.persist({ key1: 'value1' }).then(() => {
store.persist({ key2: 'value2' }).then(() => {
store.restore().then((restoredContent) => {
it('overrides existing data', () => {
return store.persist({ key1: 'value1' }).then(() => {
return store.persist({ key2: 'value2' }).then(() => {
return store.restore().then((restoredContent) => {
expect(restoredContent).to.eql({ key2: 'value2' });
done();
});
});
});
Expand All @@ -48,11 +46,10 @@ export default function(options) {

describe('#restore', () => {
describe('when the store is empty', () => {
it('returns an empty object', (done) => {
store.clear().then(() => {
store.restore().then((restoredContent) => {
it('returns an empty object', () => {
return store.clear().then(() => {
return store.restore().then((restoredContent) => {
expect(restoredContent).to.eql({});
done();
});
});
});
Expand All @@ -69,26 +66,24 @@ export default function(options) {
});
});

it('returns a copy of the stored data', (done) => {
store.restore().then((data) => {
it('returns a copy of the stored data', () => {
return store.restore().then((data) => {
data.key1 = 'another value!';

store.restore().then((restoredContent) => {
return store.restore().then((restoredContent) => {
expect(restoredContent).to.eql({ key1: 'value1', key2: 'value2' });
done();
});
});
});
});
});

describe('#clear', () => {
it('empties the store', (done) => {
store.persist({ key1: 'value1', key2: 'value2' }).then(() => {
store.clear().then(() => {
store.restore().then((restoredContent) => {
it('empties the store', () => {
return store.persist({ key1: 'value1', key2: 'value2' }).then(() => {
return store.clear().then(() => {
return store.restore().then((restoredContent) => {
expect(restoredContent).to.eql({});
done();
});
});
});
Expand Down

0 comments on commit 1911837

Please sign in to comment.