mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-20 22:42:53 -05:00
Added newsletter relation to subscribe events (#14585)
refs https://github.com/TryGhost/Team/issues/1478 **Changes** - Added the newsletter relation to subscribe events **Changes in `members-api`** - Compare: https://github.com/TryGhost/Members/compare/%40tryghost/members-api%406.0.0-alpha.0...%40tryghost/members-api%406.0.0 - Makes sure the newsletter relation is returned in the activity feed for susbcribe events (aka newsletter events). **Tests** - Added first test for activity feed to check if the newsletter relation is correctly fetched
This commit is contained in:
parent
d94859f2e5
commit
2cf76cb031
5 changed files with 222 additions and 9 deletions
|
@ -8,6 +8,10 @@ const MemberSubscribeEvent = ghostBookshelf.Model.extend({
|
||||||
return this.belongsTo('Member', 'member_id', 'id');
|
return this.belongsTo('Member', 'member_id', 'id');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
newsletter() {
|
||||||
|
return this.belongsTo('Newsletter', 'newsletter_id', 'id');
|
||||||
|
},
|
||||||
|
|
||||||
customQuery(qb, options) {
|
customQuery(qb, options) {
|
||||||
if (options.aggregateSubscriptionDeltas) {
|
if (options.aggregateSubscriptionDeltas) {
|
||||||
if (options.limit || options.filter) {
|
if (options.limit || options.filter) {
|
||||||
|
|
|
@ -84,7 +84,7 @@
|
||||||
"@tryghost/logging": "2.1.8",
|
"@tryghost/logging": "2.1.8",
|
||||||
"@tryghost/magic-link": "1.0.21",
|
"@tryghost/magic-link": "1.0.21",
|
||||||
"@tryghost/member-events": "0.4.1",
|
"@tryghost/member-events": "0.4.1",
|
||||||
"@tryghost/members-api": "6.0.0-alpha.0",
|
"@tryghost/members-api": "6.0.0",
|
||||||
"@tryghost/members-events-service": "0.3.3",
|
"@tryghost/members-events-service": "0.3.3",
|
||||||
"@tryghost/members-importer": "0.5.8",
|
"@tryghost/members-importer": "0.5.8",
|
||||||
"@tryghost/members-offers": "0.11.1",
|
"@tryghost/members-offers": "0.11.1",
|
||||||
|
|
|
@ -2289,6 +2289,148 @@ Object {
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`Members API Can subscribe to a newsletter 5: [body] 1`] = `
|
||||||
|
Object {
|
||||||
|
"events": Array [
|
||||||
|
Object {
|
||||||
|
"data": Object {
|
||||||
|
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||||
|
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||||
|
"member": Object {
|
||||||
|
"avatar_image": null,
|
||||||
|
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||||
|
"email": "member3change@test.com",
|
||||||
|
"email_count": 0,
|
||||||
|
"email_open_rate": null,
|
||||||
|
"email_opened_count": 0,
|
||||||
|
"geolocation": null,
|
||||||
|
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||||
|
"last_seen_at": null,
|
||||||
|
"name": "change me",
|
||||||
|
"note": null,
|
||||||
|
"status": "free",
|
||||||
|
"subscribed": true,
|
||||||
|
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||||
|
"uuid": "afd6010c-53ab-4e33-a1f0-600d942fa1ae",
|
||||||
|
},
|
||||||
|
"member_id": "6267babe96506b05ae3a6285",
|
||||||
|
"newsletter_id": "6267babd96506b05ae3a6050",
|
||||||
|
"source": "admin",
|
||||||
|
"subscribed": true,
|
||||||
|
},
|
||||||
|
"type": Any<String>,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"data": Object {
|
||||||
|
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||||
|
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||||
|
"member": Object {
|
||||||
|
"avatar_image": null,
|
||||||
|
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||||
|
"email": "member3change@test.com",
|
||||||
|
"email_count": 0,
|
||||||
|
"email_open_rate": null,
|
||||||
|
"email_opened_count": 0,
|
||||||
|
"geolocation": null,
|
||||||
|
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||||
|
"last_seen_at": null,
|
||||||
|
"name": "change me",
|
||||||
|
"note": null,
|
||||||
|
"status": "free",
|
||||||
|
"subscribed": true,
|
||||||
|
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||||
|
"uuid": "afd6010c-53ab-4e33-a1f0-600d942fa1ae",
|
||||||
|
},
|
||||||
|
"member_id": "6267babe96506b05ae3a6285",
|
||||||
|
"newsletter_id": "6267baba96506b05ae3a5db9",
|
||||||
|
"source": "admin",
|
||||||
|
"subscribed": true,
|
||||||
|
},
|
||||||
|
"type": Any<String>,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"data": Object {
|
||||||
|
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||||
|
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||||
|
"member": Object {
|
||||||
|
"avatar_image": null,
|
||||||
|
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||||
|
"email": "member3change@test.com",
|
||||||
|
"email_count": 0,
|
||||||
|
"email_open_rate": null,
|
||||||
|
"email_opened_count": 0,
|
||||||
|
"geolocation": null,
|
||||||
|
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||||
|
"last_seen_at": null,
|
||||||
|
"name": "change me",
|
||||||
|
"note": null,
|
||||||
|
"status": "free",
|
||||||
|
"subscribed": true,
|
||||||
|
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||||
|
"uuid": "afd6010c-53ab-4e33-a1f0-600d942fa1ae",
|
||||||
|
},
|
||||||
|
"member_id": "6267babe96506b05ae3a6285",
|
||||||
|
"newsletter_id": "6267babd96506b05ae3a6050",
|
||||||
|
"source": "admin",
|
||||||
|
"subscribed": false,
|
||||||
|
},
|
||||||
|
"type": Any<String>,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"data": Object {
|
||||||
|
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||||
|
"from_status": null,
|
||||||
|
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||||
|
"member": Object {
|
||||||
|
"avatar_image": null,
|
||||||
|
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||||
|
"email": "member3change@test.com",
|
||||||
|
"email_count": 0,
|
||||||
|
"email_open_rate": null,
|
||||||
|
"email_opened_count": 0,
|
||||||
|
"geolocation": null,
|
||||||
|
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||||
|
"last_seen_at": null,
|
||||||
|
"name": "change me",
|
||||||
|
"note": null,
|
||||||
|
"status": "free",
|
||||||
|
"subscribed": true,
|
||||||
|
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||||
|
"uuid": "afd6010c-53ab-4e33-a1f0-600d942fa1ae",
|
||||||
|
},
|
||||||
|
"member_id": "6267babe96506b05ae3a6285",
|
||||||
|
"to_status": "free",
|
||||||
|
},
|
||||||
|
"type": Any<String>,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Members API Can subscribe to a newsletter 5: [headers] 1`] = `
|
||||||
|
Object {
|
||||||
|
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||||
|
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||||
|
"content-length": "4398",
|
||||||
|
"content-type": "application/json; charset=utf-8",
|
||||||
|
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||||
|
"vary": "Origin, Accept-Encoding",
|
||||||
|
"x-powered-by": "Express",
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Members API Can subscribe to a newsletter 6: [headers] 1`] = `
|
||||||
|
Object {
|
||||||
|
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||||
|
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||||
|
"content-length": "2425",
|
||||||
|
"content-type": "application/json; charset=utf-8",
|
||||||
|
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||||
|
"vary": "Origin, Accept-Encoding",
|
||||||
|
"x-powered-by": "Express",
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`Members API Errors when fetching stats with unknown days param value 1: [body] 1`] = `
|
exports[`Members API Errors when fetching stats with unknown days param value 1: [body] 1`] = `
|
||||||
Object {
|
Object {
|
||||||
"errors": Array [
|
"errors": Array [
|
||||||
|
|
|
@ -117,6 +117,7 @@ describe('Members API', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
mockManager.mockLabsEnabled('multipleProducts');
|
mockManager.mockLabsEnabled('multipleProducts');
|
||||||
mockManager.mockLabsEnabled('multipleNewsletters');
|
mockManager.mockLabsEnabled('multipleNewsletters');
|
||||||
|
mockManager.mockLabsEnabled('membersActivityFeed');
|
||||||
mockManager.mockStripe();
|
mockManager.mockStripe();
|
||||||
mockManager.mockMail();
|
mockManager.mockMail();
|
||||||
});
|
});
|
||||||
|
@ -1190,6 +1191,7 @@ describe('Members API', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Can subscribe to a newsletter', async function () {
|
it('Can subscribe to a newsletter', async function () {
|
||||||
|
const clock = sinon.useFakeTimers(Date.now());
|
||||||
const memberToChange = {
|
const memberToChange = {
|
||||||
name: 'change me',
|
name: 'change me',
|
||||||
email: 'member3change@test.com',
|
email: 'member3change@test.com',
|
||||||
|
@ -1216,6 +1218,8 @@ describe('Members API', function () {
|
||||||
location: anyLocationFor('members')
|
location: anyLocationFor('members')
|
||||||
});
|
});
|
||||||
const newMember = body.members[0];
|
const newMember = body.members[0];
|
||||||
|
const before = new Date();
|
||||||
|
before.setMilliseconds(0);
|
||||||
|
|
||||||
await assertMemberEvents({
|
await assertMemberEvents({
|
||||||
eventType: 'MemberSubscribeEvent',
|
eventType: 'MemberSubscribeEvent',
|
||||||
|
@ -1223,9 +1227,16 @@ describe('Members API', function () {
|
||||||
asserts: [{
|
asserts: [{
|
||||||
subscribed: true,
|
subscribed: true,
|
||||||
source: 'admin',
|
source: 'admin',
|
||||||
newsletter_id: newsletters[0].id
|
newsletter_id: newsletters[0].id,
|
||||||
|
created_at: before
|
||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Wait 5 second sto guarantee event ordering
|
||||||
|
clock.tick(5000);
|
||||||
|
|
||||||
|
const after = new Date();
|
||||||
|
after.setMilliseconds(0);
|
||||||
|
|
||||||
await agent
|
await agent
|
||||||
.put(`/members/${newMember.id}/`)
|
.put(`/members/${newMember.id}/`)
|
||||||
|
@ -1245,18 +1256,74 @@ describe('Members API', function () {
|
||||||
{
|
{
|
||||||
subscribed: true,
|
subscribed: true,
|
||||||
source: 'admin',
|
source: 'admin',
|
||||||
newsletter_id: newsletters[0].id
|
newsletter_id: newsletters[0].id,
|
||||||
|
created_at: before
|
||||||
}, {
|
}, {
|
||||||
subscribed: true,
|
subscribed: true,
|
||||||
source: 'admin',
|
source: 'admin',
|
||||||
newsletter_id: newsletters[1].id
|
newsletter_id: newsletters[1].id,
|
||||||
|
created_at: after
|
||||||
}, {
|
}, {
|
||||||
subscribed: false,
|
subscribed: false,
|
||||||
source: 'admin',
|
source: 'admin',
|
||||||
newsletter_id: newsletters[0].id
|
newsletter_id: newsletters[0].id,
|
||||||
|
created_at: after
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
clock.tick(5000);
|
||||||
|
|
||||||
|
// Check activity feed
|
||||||
|
const {body: eventsBody} = await agent
|
||||||
|
.get(`/members/events?filter=data.member_id:${newMember.id}`)
|
||||||
|
.body({members: [memberChanged]})
|
||||||
|
.expectStatus(200)
|
||||||
|
.matchHeaderSnapshot({
|
||||||
|
etag: anyEtag
|
||||||
|
});
|
||||||
|
|
||||||
|
const events = eventsBody.events;
|
||||||
|
events.should.match([
|
||||||
|
{
|
||||||
|
type: 'newsletter_event',
|
||||||
|
data: {
|
||||||
|
subscribed: true,
|
||||||
|
source: 'admin',
|
||||||
|
newsletter_id: newsletters[1].id,
|
||||||
|
newsletter: {
|
||||||
|
id: newsletters[1].id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'newsletter_event',
|
||||||
|
data: {
|
||||||
|
subscribed: false,
|
||||||
|
source: 'admin',
|
||||||
|
newsletter_id: newsletters[0].id,
|
||||||
|
newsletter: {
|
||||||
|
id: newsletters[0].id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'newsletter_event',
|
||||||
|
data: {
|
||||||
|
subscribed: true,
|
||||||
|
source: 'admin',
|
||||||
|
newsletter_id: newsletters[0].id,
|
||||||
|
newsletter: {
|
||||||
|
id: newsletters[0].id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'signup_event'
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
clock.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Subscribes to default newsletters', async function () {
|
it('Subscribes to default newsletters', async function () {
|
||||||
|
|
|
@ -2150,10 +2150,10 @@
|
||||||
"@tryghost/domain-events" "^0.1.9"
|
"@tryghost/domain-events" "^0.1.9"
|
||||||
"@tryghost/member-events" "^0.4.1"
|
"@tryghost/member-events" "^0.4.1"
|
||||||
|
|
||||||
"@tryghost/members-api@6.0.0-alpha.0":
|
"@tryghost/members-api@6.0.0":
|
||||||
version "6.0.0-alpha.0"
|
version "6.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@tryghost/members-api/-/members-api-6.0.0-alpha.0.tgz#91f99cc7076c612ccb84d8b8dd6135246968b842"
|
resolved "https://registry.yarnpkg.com/@tryghost/members-api/-/members-api-6.0.0.tgz#935aee6298154176424c0574d73e290006d67221"
|
||||||
integrity sha512-qV7WEK7GZ3ejenIThj8+bSUa7ubKSN5iqB0LZXXFwihEWaySheZhNXhNJda6e1MiZwQYqQBH1TrVuv4hKfRwCA==
|
integrity sha512-fMsqb5Tuegw8DBhu9Hdwl/mldzIpZJgor63ub3P4TtRWlF5uNQIAaUi/w8AOQDmTSbkMm3YSXNkescPWBocdkw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@nexes/nql" "^0.6.0"
|
"@nexes/nql" "^0.6.0"
|
||||||
"@tryghost/debug" "^0.1.2"
|
"@tryghost/debug" "^0.1.2"
|
||||||
|
|
Loading…
Add table
Reference in a new issue