From 748a8e0d0f858e5a5d877d06eae7d82ab706c4fd Mon Sep 17 00:00:00 2001 From: Kevin Ansfield Date: Tue, 8 Dec 2020 12:43:48 +0000 Subject: [PATCH] Added `email_open_rate` order option to members API (#12462) refs https://github.com/TryGhost/Ghost/issues/12421 - add `orderRawQuery` function to members model so that we can ensure members with an open rate are ordered before members without an open rate no matter the order direction chosen - added `email_open_rate` to members in the test fixtures to allow testing of order --- core/server/models/member.js | 8 ++++ .../api/canary/admin/members_spec.js | 46 +++++++++++++++++++ test/utils/fixtures/data-generator.js | 6 ++- 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/core/server/models/member.js b/core/server/models/member.js index f39bfb803f..e1b707ffcd 100644 --- a/core/server/models/member.js +++ b/core/server/models/member.js @@ -227,6 +227,14 @@ const Member = ghostBookshelf.Model.extend({ } }, + orderRawQuery(field, direction) { + if (field === 'email_open_rate') { + return { + orderByRaw: `members.email_open_rate IS NOT NULL DESC, members.email_open_rate ${direction}` + }; + } + }, + toJSON(unfilteredOptions) { const options = Member.filterOptions(unfilteredOptions, 'toJSON'); const attrs = ghostBookshelf.Model.prototype.toJSON.call(this, options); diff --git a/test/regression/api/canary/admin/members_spec.js b/test/regression/api/canary/admin/members_spec.js index ea43314e17..290b22392b 100644 --- a/test/regression/api/canary/admin/members_spec.js +++ b/test/regression/api/canary/admin/members_spec.js @@ -30,6 +30,52 @@ describe('Members API', function () { }); }); + it('Can order by email_open_rate', async function () { + await request + .get(localUtils.API.getApiQuery('members/?order=email_open_rate%20desc')) + .set('Origin', config.get('url')) + .expect('Content-Type', /json/) + .expect('Cache-Control', testUtils.cacheRules.private) + .expect(200) + .then((res) => { + should.not.exist(res.headers['x-cache-invalidate']); + const jsonResponse = res.body; + should.exist(jsonResponse.members); + localUtils.API.checkResponse(jsonResponse, 'members'); + jsonResponse.members.should.have.length(4); + + jsonResponse.members[0].email.should.equal('paid@test.com'); + jsonResponse.members[0].email_open_rate.should.equal(80); + jsonResponse.members[1].email.should.equal('member2@test.com'); + jsonResponse.members[1].email_open_rate.should.equal(50); + jsonResponse.members[2].email.should.equal('member1@test.com'); + should.equal(null, jsonResponse.members[2].email_open_rate); + jsonResponse.members[3].email.should.equal('trialing@test.com'); + should.equal(null, jsonResponse.members[3].email_open_rate); + }); + + await request + .get(localUtils.API.getApiQuery('members/?order=email_open_rate%20asc')) + .set('Origin', config.get('url')) + .expect('Content-Type', /json/) + .expect('Cache-Control', testUtils.cacheRules.private) + .expect(200) + .then((res) => { + const jsonResponse = res.body; + localUtils.API.checkResponse(jsonResponse, 'members'); + jsonResponse.members.should.have.length(4); + + jsonResponse.members[0].email.should.equal('member2@test.com'); + jsonResponse.members[0].email_open_rate.should.equal(50); + jsonResponse.members[1].email.should.equal('paid@test.com'); + jsonResponse.members[1].email_open_rate.should.equal(80); + jsonResponse.members[2].email.should.equal('member1@test.com'); + should.equal(null, jsonResponse.members[2].email_open_rate); + jsonResponse.members[3].email.should.equal('trialing@test.com'); + should.equal(null, jsonResponse.members[3].email_open_rate); + }); + }); + it('Can search by case-insensitive name', function () { return request .get(localUtils.API.getApiQuery('members/?search=egg')) diff --git a/test/utils/fixtures/data-generator.js b/test/utils/fixtures/data-generator.js index fc35f126d0..f1e06c8beb 100644 --- a/test/utils/fixtures/data-generator.js +++ b/test/utils/fixtures/data-generator.js @@ -314,12 +314,14 @@ DataGenerator.Content = { }, { id: ObjectId.generate(), - email: 'member2@test.com' + email: 'member2@test.com', + email_open_rate: 50 }, { id: ObjectId.generate(), email: 'paid@test.com', - name: 'Egon Spengler' + name: 'Egon Spengler', + email_open_rate: 80 }, { id: ObjectId.generate(),