From 3a7108c9752a4aca56ab8d949df7cb89a380a980 Mon Sep 17 00:00:00 2001 From: Kevin Ansfield Date: Fri, 20 Jul 2018 11:57:53 +0100 Subject: [PATCH] Use `filter` instead of `status` and `staticPages` params for post queries (#1025) no issue - `staticPages` API param is deprecated in favour of using the `filter` param - switched `status` query to param to the `filter` param as well for consistency --- app/components/gh-search-input.js | 2 +- app/routes/editor/edit.js | 2 +- app/routes/posts.js | 22 +++++----- mirage/config/posts.js | 68 +++++++++++++++++++++++-------- tests/acceptance/content-test.js | 32 +++++++-------- 5 files changed, 81 insertions(+), 45 deletions(-) diff --git a/app/components/gh-search-input.js b/app/components/gh-search-input.js index be36fed87..6ca818ce9 100644 --- a/app/components/gh-search-input.js +++ b/app/components/gh-search-input.js @@ -128,7 +128,7 @@ export default Component.extend({ _loadPosts() { let store = this.get('store'); let postsUrl = `${store.adapterFor('post').urlForQuery({}, 'post')}/`; - let postsQuery = {fields: 'id,title,page', limit: 'all', status: 'all', staticPages: 'all'}; + let postsQuery = {fields: 'id,title,page', limit: 'all', status: 'all', filter: 'page:[true,false]'}; let content = this.get('content'); return this.get('ajax').request(postsUrl, {data: postsQuery}).then((posts) => { diff --git a/app/routes/editor/edit.js b/app/routes/editor/edit.js index f39bfa88c..c3980e3ef 100644 --- a/app/routes/editor/edit.js +++ b/app/routes/editor/edit.js @@ -17,7 +17,7 @@ export default AuthenticatedRoute.extend({ let query = { id: params.post_id, status: 'all', - staticPages: 'all', + filter: 'page:[true,false]', formats: 'mobiledoc,plaintext' }; diff --git a/app/routes/posts.js b/app/routes/posts.js index 5a110d03e..012201bdc 100644 --- a/app/routes/posts.js +++ b/app/routes/posts.js @@ -34,13 +34,15 @@ export default AuthenticatedRoute.extend({ model(params) { return this.get('session.user').then((user) => { - let queryParams = this._typeParams(params.type); + let queryParams = {}; let filterParams = {tag: params.tag}; let paginationParams = { perPageParam: 'limit', totalPagesParam: 'meta.pagination.pages' }; + assign(filterParams, this._getTypeFilters(params.type)); + if (params.type === 'featured') { filterParams.featured = true; } @@ -51,7 +53,7 @@ export default AuthenticatedRoute.extend({ } else if (user.get('isContributor')) { // Contributors can only view their own draft posts filterParams.authors = user.get('slug'); - queryParams.status = 'draft'; + filterParams.status = 'draft'; } else if (params.author) { filterParams.authors = params.author; } @@ -108,31 +110,31 @@ export default AuthenticatedRoute.extend({ } }, - _typeParams(type) { - let status = 'all'; - let staticPages = 'all'; + _getTypeFilters(type) { + let status = '[draft,scheduled,published]'; + let page = '[true,false]'; switch (type) { case 'draft': status = 'draft'; - staticPages = false; + page = false; break; case 'published': status = 'published'; - staticPages = false; + page = false; break; case 'scheduled': status = 'scheduled'; - staticPages = false; + page = false; break; case 'page': - staticPages = true; + page = true; break; } return { status, - staticPages + page }; }, diff --git a/mirage/config/posts.js b/mirage/config/posts.js index de3bf3448..f87628762 100644 --- a/mirage/config/posts.js +++ b/mirage/config/posts.js @@ -1,9 +1,41 @@ import moment from 'moment'; import {Response} from 'ember-cli-mirage'; import {dasherize} from '@ember/string'; -import {isBlank} from '@ember/utils'; +import {isArray} from '@ember/array'; +import {isBlank, isEmpty} from '@ember/utils'; import {paginateModelCollection} from '../utils'; +function normalizeBooleanParams(arr) { + if (!isArray(arr)) { + return arr; + } + + return arr.map((i) => { + if (i === 'true') { + return true; + } else if (i === 'false') { + return false; + } else { + return i; + } + }); +} + +// TODO: use GQL to parse filter string? +function extractFilterParam(param, filter) { + let filterRegex = new RegExp(`${param}:(.*?)(?:\\+|$)`); + let match; + + let [, result] = filter.match(filterRegex) || []; + if (result.startsWith('[')) { + match = result.replace(/^\[|\]$/g, '').split(','); + } else if (result) { + match = [result]; + } + + return normalizeBooleanParams(match); +} + export default function mockPosts(server) { server.post('/posts', function ({posts, users}) { let attrs = this.normalizedRequestAttrs(); @@ -25,26 +57,30 @@ export default function mockPosts(server) { return posts.create(attrs); }); - // TODO: handle author filter + // TODO: handle authors filter server.get('/posts/', function ({posts}, {queryParams}) { - let page = +queryParams.page || 1; - let limit = +queryParams.limit || 15; - let {status, staticPages} = queryParams; - let query = {}; + let {filter, page, limit} = queryParams; - if (status && status !== 'all') { - query.status = status; - } + page = +page || 1; + limit = +limit || 15; - if (staticPages === 'false') { - query.page = false; - } + let statusFilter = extractFilterParam('status', filter); + let pageFilter = extractFilterParam('page', filter); - if (staticPages === 'true') { - query.page = true; - } + let collection = posts.all().filter((post) => { + let matchesStatus = true; + let matchesPage = true; - let collection = posts.where(query); + if (!isEmpty(statusFilter)) { + matchesStatus = statusFilter.includes(post.status); + } + + if (!isEmpty(pageFilter)) { + matchesPage = pageFilter.includes(post.page); + } + + return matchesStatus && matchesPage; + }); return paginateModelCollection('posts', collection, page, limit); }); diff --git a/tests/acceptance/content-test.js b/tests/acceptance/content-test.js index 4665c7d77..1e1686587 100644 --- a/tests/acceptance/content-test.js +++ b/tests/acceptance/content-test.js @@ -46,7 +46,6 @@ describe('Acceptance: Content', function () { it('displays and filters posts', async function () { await visit('/'); - // Not checking request here as it won't be the last request made // Displays all posts + pages expect(find('[data-test-post-id]').length, 'all posts count').to.equal(5); @@ -56,8 +55,8 @@ describe('Acceptance: Content', function () { // API request is correct let [lastRequest] = server.pretender.handledRequests.slice(-1); - expect(lastRequest.queryParams.status, '"drafts" request status param').to.equal('draft'); - expect(lastRequest.queryParams.staticPages, '"drafts" request staticPages param').to.equal('false'); + expect(lastRequest.queryParams.filter, '"drafts" request status filter').to.have.string('status:draft'); + expect(lastRequest.queryParams.filter, '"drafts" request page filter').to.have.string('page:false'); // Displays draft post expect(find('[data-test-post-id]').length, 'drafts count').to.equal(1); expect(find(`[data-test-post-id="${draftPost.id}"]`), 'draft post').to.exist; @@ -67,8 +66,8 @@ describe('Acceptance: Content', function () { // API request is correct [lastRequest] = server.pretender.handledRequests.slice(-1); - expect(lastRequest.queryParams.status, '"published" request status param').to.equal('published'); - expect(lastRequest.queryParams.staticPages, '"published" request staticPages param').to.equal('false'); + expect(lastRequest.queryParams.filter, '"published" request status filter').to.have.string('status:published'); + expect(lastRequest.queryParams.filter, '"published" request page filter').to.have.string('page:false'); // Displays three published posts + pages expect(find('[data-test-post-id]').length, 'published count').to.equal(2); expect(find(`[data-test-post-id="${publishedPost.id}"]`), 'admin published post').to.exist; @@ -79,8 +78,8 @@ describe('Acceptance: Content', function () { // API request is correct [lastRequest] = server.pretender.handledRequests.slice(-1); - expect(lastRequest.queryParams.status, '"scheduled" request status param').to.equal('scheduled'); - expect(lastRequest.queryParams.staticPages, '"scheduled" request staticPages param').to.equal('false'); + expect(lastRequest.queryParams.filter, '"scheduled" request status filter').to.have.string('status:scheduled'); + expect(lastRequest.queryParams.filter, '"scheduled" request page filter').to.have.string('page:false'); // Displays scheduled post expect(find('[data-test-post-id]').length, 'scheduled count').to.equal(1); expect(find(`[data-test-post-id="${scheduledPost.id}"]`), 'scheduled post').to.exist; @@ -90,8 +89,8 @@ describe('Acceptance: Content', function () { // API request is correct [lastRequest] = server.pretender.handledRequests.slice(-1); - expect(lastRequest.queryParams.status, '"pages" request status param').to.equal('all'); - expect(lastRequest.queryParams.staticPages, '"pages" request staticPages param').to.equal('true'); + expect(lastRequest.queryParams.filter, '"pages" request status filter').to.have.string('status:[draft,scheduled,published]'); + expect(lastRequest.queryParams.filter, '"pages" request page filter').to.have.string('page:true'); // Displays page expect(find('[data-test-post-id]').length, 'pages count').to.equal(1); expect(find(`[data-test-post-id="${publishedPage.id}"]`), 'page post').to.exist; @@ -101,18 +100,17 @@ describe('Acceptance: Content', function () { // API request is correct [lastRequest] = server.pretender.handledRequests.slice(-1); - expect(lastRequest.queryParams.status, '"all" request status param').to.equal('all'); - expect(lastRequest.queryParams.staticPages, '"all" request staticPages param').to.equal('all'); + expect(lastRequest.queryParams.filter, '"all" request status filter').to.have.string('status:[draft,scheduled,published]'); + expect(lastRequest.queryParams.filter, '"all" request page filter').to.have.string('page:[true,false]'); // show all posts by editor await selectChoose('[data-test-author-select]', editor.name); // API request is correct [lastRequest] = server.pretender.handledRequests.slice(-1); - expect(lastRequest.queryParams.status, '"all" request status param').to.equal('all'); - expect(lastRequest.queryParams.staticPages, '"all" request staticPages param').to.equal('all'); - expect(lastRequest.queryParams.filter, '"editor" request filter param') - .to.equal(`authors:${editor.slug}`); + expect(lastRequest.queryParams.filter, '"editor" request status filter').to.have.string('status:[draft,scheduled,published]'); + expect(lastRequest.queryParams.filter, '"editor" request page filter').to.have.string('page:[true,false]'); + expect(lastRequest.queryParams.filter, '"editor" request filter param').to.have.string(`authors:${editor.slug}`); // Displays editor post // TODO: implement "filter" param support and fix mirage post->author association @@ -151,7 +149,7 @@ describe('Acceptance: Content', function () { // API request includes author filter let [lastRequest] = server.pretender.handledRequests.slice(-1); - expect(lastRequest.queryParams.filter).to.equal(`authors:${author.slug}`); + expect(lastRequest.queryParams.filter).to.have.string(`authors:${author.slug}`); // only author's post is shown expect(find('[data-test-post-id]').length, 'post count').to.equal(1); @@ -189,7 +187,7 @@ describe('Acceptance: Content', function () { // API request includes author filter let [lastRequest] = server.pretender.handledRequests.slice(-1); - expect(lastRequest.queryParams.filter).to.equal(`authors:${contributor.slug}`); + expect(lastRequest.queryParams.filter).to.have.string(`authors:${contributor.slug}`); // only contributor's post is shown expect(find('[data-test-post-id]').length, 'post count').to.equal(1);