diff --git a/admin/index.js b/admin/index.js index 19baa9a..700eb70 100644 --- a/admin/index.js +++ b/admin/index.js @@ -44,6 +44,9 @@ function AccountAdmin (options) { return getUsername(state) }, signIn: function (options) { + // include defaults to account.profile, but admins have neither + options.include = '' + return signIn(state, options) .then(function (session) { diff --git a/lib/fetch.js b/lib/fetch.js index 3a3c631..d747635 100644 --- a/lib/fetch.js +++ b/lib/fetch.js @@ -16,9 +16,10 @@ function fetch (state, path) { return Promise.reject(error) } return internals.fetchProperties({ - url: state.url + '/session/account', + url: state.url + '/session/account?include=profile', sessionId: get(state, 'account.session.id'), - path: path + path: path, + include: 'profile' }) .then(function (properties) { diff --git a/lib/sign-in.js b/lib/sign-in.js index d9816f5..7ddd35c 100644 --- a/lib/sign-in.js +++ b/lib/sign-in.js @@ -16,6 +16,10 @@ function signIn (state, options) { return Promise.reject(new Error('options.username and options.password is required')) } + if (!options.hasOwnProperty('include')) { + options.include = 'account.profile' + } + var preHooks = [] // note: the `pre:signin` & `post:signin` events are not considered public // APIs and might change in future without notice @@ -30,7 +34,7 @@ function signIn (state, options) { .then(function () { return internals.request({ - url: state.url + '/session', + url: sessionUrl(state, options), method: 'PUT', body: internals.serialise('session', options) }) @@ -38,7 +42,7 @@ function signIn (state, options) { .then(function (response) { var data = internals.deserialise(response.body, { - include: 'account' + include: 'account.profile' }) // admins don’t have an account @@ -65,6 +69,10 @@ function signIn (state, options) { state.account.id = data.account.id } + if (data.account.profile) { + state.account.profile = data.account.profile + } + internals.saveAccount({ cacheKey: state.cacheKey, account: state.account @@ -90,3 +98,11 @@ function signIn (state, options) { }) }) } + +function sessionUrl (state, options) { + if (options.include) { + return state.url + '/session?include=' + options.include + } + + return state.url + '/session' +} diff --git a/test/fixtures/fetch-profile.json b/test/fixtures/fetch-profile.json index 0059eb5..4715da9 100644 --- a/test/fixtures/fetch-profile.json +++ b/test/fixtures/fetch-profile.json @@ -6,8 +6,8 @@ "id": "abc123-profile", "type": "profile", "attributes": { - "fullName": "Docs Chicken", - "favoriteClothing": "Hoodie" + "fullName": "Docs Chicken", + "favoriteClothing": "Hoodie" } } } diff --git a/test/fixtures/fetch.json b/test/fixtures/fetch.json index 1a4078b..ddfb483 100644 --- a/test/fixtures/fetch.json +++ b/test/fixtures/fetch.json @@ -19,5 +19,15 @@ } } } - } + }, + "included": [ + { + "id": "abc4567-profile", + "type": "profile", + "attributes": { + "fullName": "Docs Chicken", + "favoriteClothing": "Hoodie" + } + } + ] } diff --git a/test/fixtures/signin.json b/test/fixtures/signin.json index ee2127e..6749aa6 100644 --- a/test/fixtures/signin.json +++ b/test/fixtures/signin.json @@ -35,6 +35,14 @@ } } } + }, + { + "id": "abc4567-profile", + "type": "profile", + "attributes": { + "fullName": "Docs Chicken", + "favoriteClothing": "Hoodie" + } } ] } diff --git a/test/integration/api-test.js b/test/integration/api-test.js index 5f13b19..c33ea2e 100644 --- a/test/integration/api-test.js +++ b/test/integration/api-test.js @@ -15,7 +15,7 @@ test('account.signIn() with invalid credentials', function (t) { }) nock('http://localhost:3000') - .put('/session') + .put('/session?include=account.profile') .reply(401, sessionUnauthorizedResponse) account.signIn({ diff --git a/test/integration/cachekey-test.js b/test/integration/cachekey-test.js index 1ed0484..a75f6de 100644 --- a/test/integration/cachekey-test.js +++ b/test/integration/cachekey-test.js @@ -13,7 +13,7 @@ test('new Account(options) defaults to "account" cacheKey', function (t) { }) nock('http://localhost:3000') - .put('/session') + .put('/session?include=account.profile') .reply(201, JSON.stringify(signInResponse)) return account.signIn({ diff --git a/test/integration/destroy-test.js b/test/integration/destroy-test.js index b3a831b..d4bc920 100644 --- a/test/integration/destroy-test.js +++ b/test/integration/destroy-test.js @@ -23,7 +23,7 @@ test('destroy account', function (t) { }) nock(baseURL) - .put('/session') + .put('/session?include=account.profile') .reply(201, signInResponse) .delete('/session/account') .reply(204) @@ -46,13 +46,15 @@ test('destroy account', function (t) { t.deepEqual(signOutHandler.lastCall.arg, { id: 'abc4567', username: 'chicken@docs.com', - session: { id: 'sessionid123' } + session: { id: 'sessionid123' }, + profile: { favoriteClothing: 'Hoodie', fullName: 'Docs Chicken' } }, '"signout" event emitted with account object') t.deepEqual(destroyHandler.lastCall.arg, { id: 'abc4567', username: 'chicken@docs.com', - session: { id: 'sessionid123' } + session: { id: 'sessionid123' }, + profile: { favoriteClothing: 'Hoodie', fullName: 'Docs Chicken' } }, '"destroy" event emitted with account object') t.is(signOutHandler.callCount, 1, '"signout" event emitted once') diff --git a/test/integration/events-test.js b/test/integration/events-test.js index 2207fbf..c6421cf 100644 --- a/test/integration/events-test.js +++ b/test/integration/events-test.js @@ -24,7 +24,7 @@ test('events', function (t) { nock(baseURL) .put('/session/account') .reply(201, signUpResponse) - .put('/session').thrice() + .put('/session?include=account.profile').thrice() .reply(201, signInResponse) .patch('/session/account') .reply(201, updateResponse) @@ -71,7 +71,8 @@ test('events', function (t) { t.deepEqual(signInHandler.lastCall.arg, { id: 'abc4567', username: 'chicken@docs.com', - session: { id: 'sessionid123' } + session: { id: 'sessionid123' }, + profile: { favoriteClothing: 'Hoodie', fullName: 'Docs Chicken' } }, '"signin" event emitted with account object') return account.update({username: updateResponse.data.attributes.username}) @@ -86,7 +87,8 @@ test('events', function (t) { t.deepEqual(updateHandler.lastCall.arg, { id: 'abc4567', username: 'newchicken@docs.com', - session: { id: 'sessionid123' } + session: { id: 'sessionid123' }, + profile: { favoriteClothing: 'Hoodie', fullName: 'Docs Chicken' } }, '"update" event emitted with account object') return account.signOut() @@ -96,7 +98,8 @@ test('events', function (t) { t.deepEqual(signOutHandler.lastCall.arg, { id: 'abc4567', username: 'newchicken@docs.com', - session: { id: 'sessionid123' } + session: { id: 'sessionid123' }, + profile: { favoriteClothing: 'Hoodie', fullName: 'Docs Chicken' } }, '"signout" event emitted with account object') t.is(signUpHandler.callCount, 1, '"signup" event emitted once') diff --git a/test/integration/fetch-url-test.js b/test/integration/fetch-url-test.js index 7ac76dd..0b58555 100644 --- a/test/integration/fetch-url-test.js +++ b/test/integration/fetch-url-test.js @@ -21,7 +21,7 @@ test('account.fetch() and account.profil.fetch()', function (t) { }) var apiMock = nock('http://localhost:3000') - .get('/session/account') + .get('/session/account?include=profile') .reply(200, require('../fixtures/fetch.json')) .get('/session/account/profile') .reply(200, require('../fixtures/fetch-profile.json')) @@ -29,7 +29,14 @@ test('account.fetch() and account.profil.fetch()', function (t) { account.fetch() .then(function (accountProperties) { - t.same(accountProperties, {id: 'abc4567', username: 'john-doe'}) + t.same(accountProperties, { + id: 'abc4567', + username: 'john-doe', + profile: { + fullName: 'Docs Chicken', + favoriteClothing: 'Hoodie' + } + }) return account.profile.fetch() }) diff --git a/test/integration/hooks-test.js b/test/integration/hooks-test.js index 6732e60..1c13605 100644 --- a/test/integration/hooks-test.js +++ b/test/integration/hooks-test.js @@ -19,7 +19,7 @@ test('sign in with pre & post hooks', function (t) { t.plan(2) nock(baseURL) - .put('/session') + .put('/session?include=account.profile') .reply(201, signInResponse) var callOrder = [] @@ -94,7 +94,7 @@ test('sign in with throw in post hook', function (t) { t.plan(2) nock(baseURL) - .put('/session') + .put('/session?include=account.profile') .reply(201, signInResponse) var account = new Account({ diff --git a/test/integration/sign-in-test.js b/test/integration/sign-in-test.js index 109cadb..dec86bf 100644 --- a/test/integration/sign-in-test.js +++ b/test/integration/sign-in-test.js @@ -16,7 +16,7 @@ var options = { test('sign in', function (t) { store.clear() - t.plan(11) + t.plan(12) var account = new Account({ url: baseURL, @@ -24,7 +24,7 @@ test('sign in', function (t) { }) nock(baseURL) - .put('/session') + .put('/session?include=account.profile') .reply(201, signInResponse) .delete('/session') @@ -43,6 +43,10 @@ test('sign in', function (t) { username: 'chicken@docs.com', session: { id: 'sessionid123' + }, + profile: { + fullName: 'Docs Chicken', + favoriteClothing: 'Hoodie' } }, 'stores account with id with session') t.deepEqual(account.get(), { @@ -50,6 +54,10 @@ test('sign in', function (t) { username: 'chicken@docs.com', session: { id: 'sessionid123' + }, + profile: { + fullName: 'Docs Chicken', + favoriteClothing: 'Hoodie' } }, '.get() returns account with session') @@ -60,6 +68,7 @@ test('sign in', function (t) { t.pass('signes out') t.is(signOutResult.username, 'chicken@docs.com') + t.is(signOutResult.profile.fullName, 'Docs Chicken') var storeAccount = store.getObject('account') diff --git a/test/integration/unauthenticate-test.js b/test/integration/unauthenticate-test.js index 4e1a96e..d430095 100644 --- a/test/integration/unauthenticate-test.js +++ b/test/integration/unauthenticate-test.js @@ -25,7 +25,7 @@ test('unauthenticate state within account.fetch()', function (t) { }) nock('http://example.de') - .get('/session/account') + .get('/session/account?include=profile') .reply(401, errorMessage) var account = new Account({url: 'http://example.de'}) diff --git a/test/integration/update-account-test.js b/test/integration/update-account-test.js index 0a3c094..94d08ef 100644 --- a/test/integration/update-account-test.js +++ b/test/integration/update-account-test.js @@ -29,7 +29,7 @@ test('sign in and change username', function (t) { }) nock(baseURL) - .put('/session', function (body) { + .put('/session?include=account.profile', function (body) { return body.data.attributes.password === 'secret' }) .reply(201, signInResponse) @@ -40,7 +40,7 @@ test('sign in and change username', function (t) { return true }) .reply(200, updateResponse) - .put('/session', function (body) { + .put('/session?include=account.profile', function (body) { return body.data.attributes.password === 'newsecret' }) .thrice() diff --git a/test/integration/update-profile-test.js b/test/integration/update-profile-test.js index ca8b75c..b545693 100644 --- a/test/integration/update-profile-test.js +++ b/test/integration/update-profile-test.js @@ -26,7 +26,7 @@ test('sign in and change username', function (t) { }) nock(baseURL) - .put('/session', function (body) { + .put('/session?include=account.profile', function (body) { return body.data.attributes.password === 'secret' }) .reply(201, signInResponse) diff --git a/test/unit/fetch-test.js b/test/unit/fetch-test.js index 94b4479..c0b954a 100644 --- a/test/unit/fetch-test.js +++ b/test/unit/fetch-test.js @@ -17,9 +17,10 @@ test('fetch', function (t) { }, 'path') t.deepEqual(internals.fetchProperties.lastCall.arg, { - url: 'http://example.com/session/account', + url: 'http://example.com/session/account?include=profile', sessionId: 'abc4567', - path: 'path' + path: 'path', + include: 'profile' }, 'calls fetchProperties with account url') simple.restore() @@ -52,9 +53,10 @@ test('fetch with undefined path', function (t) { }) t.deepEqual(internals.fetchProperties.lastCall.arg, { - url: 'http://example.com/session/account', + url: 'http://example.com/session/account?include=profile', sessionId: 'abc45678', - path: undefined + path: undefined, + include: 'profile' }, 'calls fetchProperties with account url and non-string path') simple.restore() diff --git a/test/unit/sign-in-test.js b/test/unit/sign-in-test.js index 1618383..6fdb7b3 100644 --- a/test/unit/sign-in-test.js +++ b/test/unit/sign-in-test.js @@ -67,7 +67,7 @@ test('successful account.signIn(options)', function (t) { .then(function (accountProperties) { t.deepEqual(signIn.internals.request.lastCall.arg, { method: 'PUT', - url: 'http://example.com/session', + url: 'http://example.com/session?include=account.profile', body: 'serialised' }) t.deepEqual(signIn.internals.deserialise.lastCall.arg, 'response body') diff --git a/test/unit/sign-out-test.js b/test/unit/sign-out-test.js index 79e1dc7..c1251de 100644 --- a/test/unit/sign-out-test.js +++ b/test/unit/sign-out-test.js @@ -4,7 +4,7 @@ var test = require('tape') var signOut = require('../../lib/sign-out') test('signOut()', function (t) { - t.plan(3) + t.plan(4) simple.mock(signOut.internals, 'request').resolveWith({ statusCode: 204, @@ -19,7 +19,10 @@ test('signOut()', function (t) { session: { id: 'abc4567' }, - username: 'pat' + username: 'pat', + profile: { + foo: 'bar' + } }, emitter: { emit: simple.stub() @@ -41,6 +44,7 @@ test('signOut()', function (t) { }) t.is(state.account, undefined, 'unsets account') + t.is(result.profile.foo, 'bar', 'resolves with .profile') simple.restore() }) diff --git a/utils/fetch-properties.js b/utils/fetch-properties.js index d284ee1..4e9d7be 100644 --- a/utils/fetch-properties.js +++ b/utils/fetch-properties.js @@ -14,7 +14,7 @@ function fetchProperties (options) { }) .then(function (response) { - var data = deserialise(response.body) + var data = deserialise(response.body, options) return getProperties(data, options.path) })