From 777a7fed78efbde9e9ce38c2e4faac6439614620 Mon Sep 17 00:00:00 2001 From: Austin Burdine Date: Mon, 23 Nov 2015 07:48:08 -0600 Subject: [PATCH] implement custom user adapter to pull users by slug closes #6095 - implements custom user adapter for the `/team/:slug/` route - abstracts slug-url behavior into a mixin (used in /settings/tags/ as well) - adds unit tests for both tag and user adapters --- app/adapters/tag.js | 17 ++------- app/adapters/user.js | 3 +- app/mixins/slug-url.js | 16 +++++++++ app/router.js | 2 +- app/routes/team/user.js | 17 +++------ tests/unit/adapters/tag-test.js | 62 ++++++++++++++++++++++++++++++++ tests/unit/adapters/user-test.js | 62 ++++++++++++++++++++++++++++++++ 7 files changed, 149 insertions(+), 30 deletions(-) create mode 100644 app/mixins/slug-url.js create mode 100644 tests/unit/adapters/tag-test.js create mode 100644 tests/unit/adapters/user-test.js diff --git a/app/adapters/tag.js b/app/adapters/tag.js index 86b6282dd..5dc33f7e8 100644 --- a/app/adapters/tag.js +++ b/app/adapters/tag.js @@ -1,17 +1,4 @@ import ApplicationAdapter from 'ghost/adapters/application'; -import Ember from 'ember'; +import SlugUrl from 'ghost/mixins/slug-url'; -const {isBlank} = Ember; - -export default ApplicationAdapter.extend({ - buildURL: function (_modelName, _id, _snapshot, _requestType, query) { - let url = this._super(...arguments); - - if (query && !isBlank(query.slug)) { - url += `slug/${query.slug}/`; - delete query.slug; - } - - return url; - } -}); +export default ApplicationAdapter.extend(SlugUrl); diff --git a/app/adapters/user.js b/app/adapters/user.js index fcc397c16..89f769ddb 100644 --- a/app/adapters/user.js +++ b/app/adapters/user.js @@ -1,6 +1,7 @@ import ApplicationAdapter from 'ghost/adapters/application'; +import SlugUrl from 'ghost/mixins/slug-url'; -export default ApplicationAdapter.extend({ +export default ApplicationAdapter.extend(SlugUrl, { find: function (store, type, id) { return this.findQuery(store, type, {id: id, status: 'all'}); }, diff --git a/app/mixins/slug-url.js b/app/mixins/slug-url.js new file mode 100644 index 000000000..8b6f460d9 --- /dev/null +++ b/app/mixins/slug-url.js @@ -0,0 +1,16 @@ +import Ember from 'ember'; + +const {isBlank} = Ember; + +export default Ember.Mixin.create({ + buildURL: function (_modelName, _id, _snapshot, _requestType, query) { + let url = this._super(...arguments); + + if (query && !isBlank(query.slug)) { + url += `slug/${query.slug}/`; + delete query.slug; + } + + return url; + } +}); diff --git a/app/router.js b/app/router.js index df3504b00..795c7fb5b 100644 --- a/app/router.js +++ b/app/router.js @@ -39,7 +39,7 @@ Router.map(function () { }); this.route('team', {path: '/team'}, function () { - this.route('user', {path: ':slug'}); + this.route('user', {path: ':user_slug'}); }); this.route('settings.general', {path: '/settings/general'}); diff --git a/app/routes/team/user.js b/app/routes/team/user.js index a18f6edaa..2944874fb 100644 --- a/app/routes/team/user.js +++ b/app/routes/team/user.js @@ -8,20 +8,11 @@ export default AuthenticatedRoute.extend(styleBody, CurrentUserSettings, { classNames: ['team-view-user'], model: function (params) { - var self = this; - // TODO: Make custom user adapter that uses /api/users/:slug endpoint - // return this.store.find('user', { slug: params.slug }); + return this.store.queryRecord('user', {slug: params.user_slug}); + }, - // Instead, get all the users and then find by slug - return this.store.findAll('user', {reload: true}).then(function (result) { - var user = result.findBy('slug', params.slug); - - if (!user) { - return self.transitionTo('error404', 'team/' + params.slug); - } - - return user; - }); + serialize: function (model) { + return {user_slug: model.get('slug')}; }, afterModel: function (user) { diff --git a/tests/unit/adapters/tag-test.js b/tests/unit/adapters/tag-test.js new file mode 100644 index 000000000..ddb13c8ac --- /dev/null +++ b/tests/unit/adapters/tag-test.js @@ -0,0 +1,62 @@ +/* jshint expr:true */ +import { expect } from 'chai'; +import { + describeModel, + it +} from 'ember-mocha'; +import Pretender from 'pretender'; + +describeModel('tag', 'Unit: Adapter: tag', { + needs: [ + 'service:ghost-paths', + 'service:session', + 'adapter:tag', + 'serializer:tag' + ] +}, function () { + let server; + + beforeEach(function () { + server = new Pretender(); + }); + + afterEach(function () { + server.shutdown(); + }); + + it('loads tags from regular endpoint when all are fetched', function (done) { + server.get('/ghost/api/v0.1/tags/', function () { + return [200, {'Content-Type': 'application/json'}, JSON.stringify({tags: [{ + id: 1, + name: 'Tag 1', + slug: 'tag-1' + }, { + id: 2, + name: 'Tag 2', + slug: 'tag-2' + }]})]; + }); + + this.store().findAll('tag', {reload: true}).then((tags) => { + expect(tags).to.be.ok; + expect(tags.objectAtContent(0).get('name')).to.equal('Tag 1'); + done(); + }); + }); + + it('loads tag from slug endpoint when single tag is queried and slug is passed in', function (done) { + server.get('/ghost/api/v0.1/tags/slug/tag-1/', function () { + return [200, {'Content-Type': 'application/json'}, JSON.stringify({tags: [{ + id: 1, + slug: 'tag-1', + name: 'Tag 1' + }]})]; + }); + + this.store().queryRecord('tag', {slug: 'tag-1'}).then((tag) => { + expect(tag).to.be.ok; + expect(tag.get('name')).to.equal('Tag 1'); + done(); + }); + }); +}); diff --git a/tests/unit/adapters/user-test.js b/tests/unit/adapters/user-test.js new file mode 100644 index 000000000..0463459fb --- /dev/null +++ b/tests/unit/adapters/user-test.js @@ -0,0 +1,62 @@ +/* jshint expr:true */ +import { expect } from 'chai'; +import { + describeModel, + it +} from 'ember-mocha'; +import Pretender from 'pretender'; + +describeModel('user', 'Unit: Adapter: user', { + needs: [ + 'service:ghost-paths', + 'service:session', + 'adapter:user', + 'serializer:user' + ] +}, function () { + let server; + + beforeEach(function () { + server = new Pretender(); + }); + + afterEach(function () { + server.shutdown(); + }); + + it('loads users from regular endpoint when all are fetched', function (done) { + server.get('/ghost/api/v0.1/users/', function () { + return [200, {'Content-Type': 'application/json'}, JSON.stringify({users: [{ + id: 1, + name: 'User 1', + slug: 'user-1' + }, { + id: 2, + name: 'User 2', + slug: 'user-2' + }]})]; + }); + + this.store().findAll('user', {reload: true}).then((users) => { + expect(users).to.be.ok; + expect(users.objectAtContent(0).get('name')).to.equal('User 1'); + done(); + }); + }); + + it('loads user from slug endpoint when single user is queried and slug is passed in', function (done) { + server.get('/ghost/api/v0.1/users/slug/user-1/', function () { + return [200, {'Content-Type': 'application/json'}, JSON.stringify({users: [{ + id: 1, + slug: 'user-1', + name: 'User 1' + }]})]; + }); + + this.store().queryRecord('user', {slug: 'user-1'}).then((user) => { + expect(user).to.be.ok; + expect(user.get('name')).to.equal('User 1'); + done(); + }); + }); +});