Added referrer attribution from request context (#15499)
closes TryGhost/Team#2007 - uses request context to add referrer source and medium for a new member - uses integration name as referrer medium if exists
This commit is contained in:
parent
8a6f082b14
commit
e3600d70ef
@ -35,7 +35,8 @@ class MemberAttributionServiceWrapper {
|
||||
this.service = new MemberAttributionService({
|
||||
models: {
|
||||
MemberCreatedEvent: models.MemberCreatedEvent,
|
||||
SubscriptionCreatedEvent: models.SubscriptionCreatedEvent
|
||||
SubscriptionCreatedEvent: models.SubscriptionCreatedEvent,
|
||||
Integration: models.Integration
|
||||
},
|
||||
attributionBuilder: this.attributionBuilder
|
||||
});
|
||||
|
@ -539,7 +539,15 @@ exports[`Members API Can add 1: [body] 1`] = `
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": null,
|
||||
"attribution": Object {
|
||||
"id": null,
|
||||
"referrer_medium": "Ghost Admin",
|
||||
"referrer_source": "Created manually",
|
||||
"referrer_url": null,
|
||||
"title": null,
|
||||
"type": "url",
|
||||
"url": null,
|
||||
},
|
||||
"avatar_image": null,
|
||||
"comped": false,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -569,7 +577,7 @@ exports[`Members API Can add 2: [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": "641",
|
||||
"content-length": "774",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"location": StringMatching /https\\?:\\\\/\\\\/\\.\\*\\?\\\\/members\\\\/\\[a-f0-9\\]\\{24\\}\\\\//,
|
||||
@ -582,7 +590,15 @@ exports[`Members API Can add a member that is not subscribed (old) 1: [body] 1`]
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": null,
|
||||
"attribution": Object {
|
||||
"id": null,
|
||||
"referrer_medium": "Ghost Admin",
|
||||
"referrer_source": "Created manually",
|
||||
"referrer_url": null,
|
||||
"title": null,
|
||||
"type": "url",
|
||||
"url": null,
|
||||
},
|
||||
"avatar_image": null,
|
||||
"comped": false,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -612,7 +628,7 @@ exports[`Members API Can add a member that is not subscribed (old) 2: [headers]
|
||||
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": "517",
|
||||
"content-length": "650",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"location": Any<String>,
|
||||
@ -652,7 +668,15 @@ Object {
|
||||
"subscribed": true,
|
||||
"subscriptions": Array [
|
||||
Object {
|
||||
"attribution": null,
|
||||
"attribution": Object {
|
||||
"id": null,
|
||||
"referrer_medium": null,
|
||||
"referrer_source": null,
|
||||
"referrer_url": null,
|
||||
"title": null,
|
||||
"type": "url",
|
||||
"url": null,
|
||||
},
|
||||
"cancel_at_period_end": false,
|
||||
"cancellation_reason": null,
|
||||
"current_period_end": Any<String>,
|
||||
@ -703,7 +727,7 @@ exports[`Members API Can add a subscription 2: [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": "2375",
|
||||
"content-length": "2485",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
@ -742,7 +766,15 @@ Object {
|
||||
"subscribed": true,
|
||||
"subscriptions": Array [
|
||||
Object {
|
||||
"attribution": null,
|
||||
"attribution": Object {
|
||||
"id": null,
|
||||
"referrer_medium": null,
|
||||
"referrer_source": null,
|
||||
"referrer_url": null,
|
||||
"title": null,
|
||||
"type": "url",
|
||||
"url": null,
|
||||
},
|
||||
"cancel_at_period_end": false,
|
||||
"cancellation_reason": null,
|
||||
"current_period_end": Any<String>,
|
||||
@ -793,7 +825,7 @@ exports[`Members API Can add a subscription 4: [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": "2375",
|
||||
"content-length": "2485",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
@ -805,7 +837,15 @@ exports[`Members API Can add and edit with custom newsletters 1: [body] 1`] = `
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": null,
|
||||
"attribution": Object {
|
||||
"id": null,
|
||||
"referrer_medium": "Ghost Admin",
|
||||
"referrer_source": "Created manually",
|
||||
"referrer_url": null,
|
||||
"title": null,
|
||||
"type": "url",
|
||||
"url": null,
|
||||
},
|
||||
"avatar_image": null,
|
||||
"comped": false,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -862,7 +902,7 @@ exports[`Members API Can add and edit with custom newsletters 2: [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": "1361",
|
||||
"content-length": "1494",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"location": StringMatching /https\\?:\\\\/\\\\/\\.\\*\\?\\\\/members\\\\/\\[a-f0-9\\]\\{24\\}\\\\//,
|
||||
@ -875,7 +915,15 @@ exports[`Members API Can add and edit with custom newsletters 3: [body] 1`] = `
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": null,
|
||||
"attribution": Object {
|
||||
"id": null,
|
||||
"referrer_medium": "Ghost Admin",
|
||||
"referrer_source": "Created manually",
|
||||
"referrer_url": null,
|
||||
"title": null,
|
||||
"type": "url",
|
||||
"url": null,
|
||||
},
|
||||
"avatar_image": null,
|
||||
"comped": false,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -932,7 +980,7 @@ exports[`Members API Can add and edit with custom newsletters 4: [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": "1360",
|
||||
"content-length": "1493",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
@ -944,7 +992,15 @@ exports[`Members API Can add and send a signup confirmation email (old) 1: [body
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": null,
|
||||
"attribution": Object {
|
||||
"id": null,
|
||||
"referrer_medium": "Ghost Admin",
|
||||
"referrer_source": "Created manually",
|
||||
"referrer_url": null,
|
||||
"title": null,
|
||||
"type": "url",
|
||||
"url": null,
|
||||
},
|
||||
"avatar_image": null,
|
||||
"comped": false,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -1027,7 +1083,7 @@ exports[`Members API Can add and send a signup confirmation email (old) 2: [head
|
||||
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": "1856",
|
||||
"content-length": "1989",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"location": Any<String>,
|
||||
@ -1050,7 +1106,15 @@ exports[`Members API Can add and send a signup confirmation email 1: [body] 1`]
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": null,
|
||||
"attribution": Object {
|
||||
"id": null,
|
||||
"referrer_medium": "Ghost Admin",
|
||||
"referrer_source": "Created manually",
|
||||
"referrer_url": null,
|
||||
"title": null,
|
||||
"type": "url",
|
||||
"url": null,
|
||||
},
|
||||
"avatar_image": null,
|
||||
"comped": false,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -1133,7 +1197,7 @@ exports[`Members API Can add and send a signup confirmation email 2: [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": "1851",
|
||||
"content-length": "1984",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"location": Any<String>,
|
||||
@ -1156,7 +1220,15 @@ exports[`Members API Can add complimentary subscription (out of date) 1: [body]
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": null,
|
||||
"attribution": Object {
|
||||
"id": null,
|
||||
"referrer_medium": "Ghost Admin",
|
||||
"referrer_source": "Created manually",
|
||||
"referrer_url": null,
|
||||
"title": null,
|
||||
"type": "url",
|
||||
"url": null,
|
||||
},
|
||||
"avatar_image": null,
|
||||
"comped": false,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -1186,7 +1258,7 @@ exports[`Members API Can add complimentary subscription (out of date) 2: [header
|
||||
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": "1119",
|
||||
"content-length": "1252",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"location": StringMatching /https\\?:\\\\/\\\\/\\.\\*\\?\\\\/members\\\\/\\[a-f0-9\\]\\{24\\}\\\\//,
|
||||
@ -1199,7 +1271,15 @@ exports[`Members API Can add complimentary subscription (out of date) 3: [body]
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": null,
|
||||
"attribution": Object {
|
||||
"id": null,
|
||||
"referrer_medium": "Ghost Admin",
|
||||
"referrer_source": "Created manually",
|
||||
"referrer_url": null,
|
||||
"title": null,
|
||||
"type": "url",
|
||||
"url": null,
|
||||
},
|
||||
"avatar_image": null,
|
||||
"comped": true,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -1246,7 +1326,7 @@ exports[`Members API Can add complimentary subscription (out of date) 4: [header
|
||||
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": "2655",
|
||||
"content-length": "2898",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
@ -1555,7 +1635,15 @@ exports[`Members API Can create a member with an existing complimentary subscrip
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": null,
|
||||
"attribution": Object {
|
||||
"id": null,
|
||||
"referrer_medium": "Ghost Admin",
|
||||
"referrer_source": "Created manually",
|
||||
"referrer_url": null,
|
||||
"title": null,
|
||||
"type": "url",
|
||||
"url": null,
|
||||
},
|
||||
"avatar_image": null,
|
||||
"comped": true,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -1629,7 +1717,7 @@ exports[`Members API Can create a member with an existing complimentary subscrip
|
||||
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": "2706",
|
||||
"content-length": "2949",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"location": StringMatching /https\\?:\\\\/\\\\/\\.\\*\\?\\\\/members\\\\/\\[a-f0-9\\]\\{24\\}\\\\//,
|
||||
@ -1642,7 +1730,15 @@ exports[`Members API Can create a member with an existing paid subscription 1: [
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": null,
|
||||
"attribution": Object {
|
||||
"id": null,
|
||||
"referrer_medium": "Ghost Admin",
|
||||
"referrer_source": "Created manually",
|
||||
"referrer_url": null,
|
||||
"title": null,
|
||||
"type": "url",
|
||||
"url": null,
|
||||
},
|
||||
"avatar_image": null,
|
||||
"comped": false,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -1699,7 +1795,7 @@ exports[`Members API Can create a member with an existing paid subscription 2: [
|
||||
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": "2692",
|
||||
"content-length": "2935",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"location": StringMatching /https\\?:\\\\/\\\\/\\.\\*\\?\\\\/members\\\\/\\[a-f0-9\\]\\{24\\}\\\\//,
|
||||
@ -1712,7 +1808,15 @@ exports[`Members API Can create a new member with a product (complimentary) 1: [
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": null,
|
||||
"attribution": Object {
|
||||
"id": null,
|
||||
"referrer_medium": "Ghost Admin",
|
||||
"referrer_source": "Created manually",
|
||||
"referrer_url": null,
|
||||
"title": null,
|
||||
"type": "url",
|
||||
"url": null,
|
||||
},
|
||||
"avatar_image": null,
|
||||
"comped": true,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -1786,7 +1890,7 @@ exports[`Members API Can create a new member with a product (complimentary) 2: [
|
||||
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": "2463",
|
||||
"content-length": "2596",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"location": StringMatching /https\\?:\\\\/\\\\/\\.\\*\\?\\\\/members\\\\/\\[a-f0-9\\]\\{24\\}\\\\//,
|
||||
@ -1809,7 +1913,15 @@ exports[`Members API Can destroy 1: [body] 1`] = `
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": null,
|
||||
"attribution": Object {
|
||||
"id": null,
|
||||
"referrer_medium": "Ghost Admin",
|
||||
"referrer_source": "Created manually",
|
||||
"referrer_url": null,
|
||||
"title": null,
|
||||
"type": "url",
|
||||
"url": null,
|
||||
},
|
||||
"avatar_image": null,
|
||||
"comped": false,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -1839,7 +1951,7 @@ exports[`Members API Can destroy 2: [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": "1826",
|
||||
"content-length": "1959",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"location": StringMatching /https\\?:\\\\/\\\\/\\.\\*\\?\\\\/members\\\\/\\[a-f0-9\\]\\{24\\}\\\\//,
|
||||
@ -1892,7 +2004,15 @@ exports[`Members API Can edit by id 1: [body] 1`] = `
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": null,
|
||||
"attribution": Object {
|
||||
"id": null,
|
||||
"referrer_medium": "Ghost Admin",
|
||||
"referrer_source": "Created manually",
|
||||
"referrer_url": null,
|
||||
"title": null,
|
||||
"type": "url",
|
||||
"url": null,
|
||||
},
|
||||
"avatar_image": null,
|
||||
"comped": false,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -1922,7 +2042,7 @@ exports[`Members API Can edit by id 2: [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": "1137",
|
||||
"content-length": "1270",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"location": StringMatching /https\\?:\\\\/\\\\/\\.\\*\\?\\\\/members\\\\/\\[a-f0-9\\]\\{24\\}\\\\//,
|
||||
@ -1935,7 +2055,15 @@ exports[`Members API Can edit by id 3: [body] 1`] = `
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": null,
|
||||
"attribution": Object {
|
||||
"id": null,
|
||||
"referrer_medium": "Ghost Admin",
|
||||
"referrer_source": "Created manually",
|
||||
"referrer_url": null,
|
||||
"title": null,
|
||||
"type": "url",
|
||||
"url": null,
|
||||
},
|
||||
"avatar_image": null,
|
||||
"comped": false,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -1965,7 +2093,7 @@ exports[`Members API Can edit by id 4: [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": "492",
|
||||
"content-length": "625",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
@ -3403,7 +3531,15 @@ exports[`Members API Can subscribe by setting (old) subscribed property to true
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": null,
|
||||
"attribution": Object {
|
||||
"id": null,
|
||||
"referrer_medium": "Ghost Admin",
|
||||
"referrer_source": "Created manually",
|
||||
"referrer_url": null,
|
||||
"title": null,
|
||||
"type": "url",
|
||||
"url": null,
|
||||
},
|
||||
"avatar_image": null,
|
||||
"comped": false,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -3433,7 +3569,7 @@ exports[`Members API Can subscribe by setting (old) subscribed property to true
|
||||
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": "499",
|
||||
"content-length": "632",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"location": StringMatching /https\\?:\\\\/\\\\/\\.\\*\\?\\\\/members\\\\/\\[a-f0-9\\]\\{24\\}\\\\//,
|
||||
@ -3446,7 +3582,15 @@ exports[`Members API Can subscribe by setting (old) subscribed property to true
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": null,
|
||||
"attribution": Object {
|
||||
"id": null,
|
||||
"referrer_medium": "Ghost Admin",
|
||||
"referrer_source": "Created manually",
|
||||
"referrer_url": null,
|
||||
"title": null,
|
||||
"type": "url",
|
||||
"url": null,
|
||||
},
|
||||
"avatar_image": null,
|
||||
"comped": false,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -3529,7 +3673,7 @@ exports[`Members API Can subscribe by setting (old) subscribed property to true
|
||||
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": "1840",
|
||||
"content-length": "1973",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
@ -3541,7 +3685,15 @@ exports[`Members API Can subscribe to a newsletter 1: [body] 1`] = `
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": null,
|
||||
"attribution": Object {
|
||||
"id": null,
|
||||
"referrer_medium": "Ghost Admin",
|
||||
"referrer_source": "Created manually",
|
||||
"referrer_url": null,
|
||||
"title": null,
|
||||
"type": "url",
|
||||
"url": null,
|
||||
},
|
||||
"avatar_image": null,
|
||||
"comped": false,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -3571,7 +3723,7 @@ exports[`Members API Can subscribe to a newsletter 2: [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": "1127",
|
||||
"content-length": "1260",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"location": StringMatching /https\\?:\\\\/\\\\/\\.\\*\\?\\\\/members\\\\/\\[a-f0-9\\]\\{24\\}\\\\//,
|
||||
@ -3584,7 +3736,15 @@ exports[`Members API Can subscribe to a newsletter 3: [body] 1`] = `
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": null,
|
||||
"attribution": Object {
|
||||
"id": null,
|
||||
"referrer_medium": "Ghost Admin",
|
||||
"referrer_source": "Created manually",
|
||||
"referrer_url": null,
|
||||
"title": null,
|
||||
"type": "url",
|
||||
"url": null,
|
||||
},
|
||||
"avatar_image": null,
|
||||
"comped": false,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -3614,7 +3774,7 @@ exports[`Members API Can subscribe to a newsletter 4: [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": "1183",
|
||||
"content-length": "1316",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
@ -3626,7 +3786,7 @@ 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": "4822",
|
||||
"content-length": "4978",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
@ -3638,7 +3798,15 @@ exports[`Members API Can unsubscribe by setting (old) subscribed property to fal
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": null,
|
||||
"attribution": Object {
|
||||
"id": null,
|
||||
"referrer_medium": "Ghost Admin",
|
||||
"referrer_source": "Created manually",
|
||||
"referrer_url": null,
|
||||
"title": null,
|
||||
"type": "url",
|
||||
"url": null,
|
||||
},
|
||||
"avatar_image": null,
|
||||
"comped": false,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -3695,7 +3863,7 @@ exports[`Members API Can unsubscribe by setting (old) subscribed property to fal
|
||||
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": "1145",
|
||||
"content-length": "1278",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"location": StringMatching /https\\?:\\\\/\\\\/\\.\\*\\?\\\\/members\\\\/\\[a-f0-9\\]\\{24\\}\\\\//,
|
||||
@ -3708,7 +3876,15 @@ exports[`Members API Can unsubscribe by setting (old) subscribed property to fal
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": null,
|
||||
"attribution": Object {
|
||||
"id": null,
|
||||
"referrer_medium": "Ghost Admin",
|
||||
"referrer_source": "Created manually",
|
||||
"referrer_url": null,
|
||||
"title": null,
|
||||
"type": "url",
|
||||
"url": null,
|
||||
},
|
||||
"avatar_image": null,
|
||||
"comped": false,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -3738,7 +3914,7 @@ exports[`Members API Can unsubscribe by setting (old) subscribed property to fal
|
||||
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": "504",
|
||||
"content-length": "637",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
@ -4075,7 +4251,15 @@ exports[`Members API Subscribes to default newsletters 1: [body] 1`] = `
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": null,
|
||||
"attribution": Object {
|
||||
"id": null,
|
||||
"referrer_medium": "Ghost Admin",
|
||||
"referrer_source": "Created manually",
|
||||
"referrer_url": null,
|
||||
"title": null,
|
||||
"type": "url",
|
||||
"url": null,
|
||||
},
|
||||
"avatar_image": null,
|
||||
"comped": false,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -4105,7 +4289,7 @@ exports[`Members API Subscribes to default newsletters 2: [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": "1827",
|
||||
"content-length": "1960",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"location": StringMatching /https\\?:\\\\/\\\\/\\.\\*\\?\\\\/members\\\\/\\[a-f0-9\\]\\{24\\}\\\\//,
|
||||
|
@ -4,15 +4,7 @@ exports[`Members API Member attribution Creates a SubscriptionCreatedEvent with
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": Object {
|
||||
"id": "1",
|
||||
"referrer_medium": null,
|
||||
"referrer_source": null,
|
||||
"referrer_url": null,
|
||||
"title": "Joe Bloggs",
|
||||
"type": "author",
|
||||
"url": "http://127.0.0.1:2369/author/joe-bloggs/",
|
||||
},
|
||||
"attribution": Any<Object>,
|
||||
"avatar_image": null,
|
||||
"comped": false,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -54,15 +46,7 @@ exports[`Members API Member attribution Creates a SubscriptionCreatedEvent with
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": Object {
|
||||
"id": null,
|
||||
"referrer_medium": null,
|
||||
"referrer_source": null,
|
||||
"referrer_url": null,
|
||||
"title": "/removed-blog-post/",
|
||||
"type": "url",
|
||||
"url": "http://127.0.0.1:2369/removed-blog-post/",
|
||||
},
|
||||
"attribution": Any<Object>,
|
||||
"avatar_image": null,
|
||||
"comped": false,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -104,7 +88,7 @@ exports[`Members API Member attribution Creates a SubscriptionCreatedEvent with
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": null,
|
||||
"attribution": Any<Object>,
|
||||
"avatar_image": null,
|
||||
"comped": false,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -134,7 +118,7 @@ exports[`Members API Member attribution Creates a SubscriptionCreatedEvent with
|
||||
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": "2611",
|
||||
"content-length": "2831",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
@ -146,15 +130,7 @@ exports[`Members API Member attribution Creates a SubscriptionCreatedEvent with
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": Object {
|
||||
"id": "618ba1ffbe2896088840a6e9",
|
||||
"referrer_medium": null,
|
||||
"referrer_source": null,
|
||||
"referrer_url": null,
|
||||
"title": "This is a static page",
|
||||
"type": "page",
|
||||
"url": "http://127.0.0.1:2369/static-page-test/",
|
||||
},
|
||||
"attribution": Any<Object>,
|
||||
"avatar_image": null,
|
||||
"comped": false,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -196,15 +172,7 @@ exports[`Members API Member attribution Creates a SubscriptionCreatedEvent with
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": Object {
|
||||
"id": "618ba1ffbe2896088840a6df",
|
||||
"referrer_medium": null,
|
||||
"referrer_source": null,
|
||||
"referrer_url": null,
|
||||
"title": "HTML Ipsum",
|
||||
"type": "post",
|
||||
"url": "http://127.0.0.1:2369/html-ipsum/",
|
||||
},
|
||||
"attribution": Any<Object>,
|
||||
"avatar_image": null,
|
||||
"comped": false,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -246,15 +214,7 @@ exports[`Members API Member attribution Creates a SubscriptionCreatedEvent with
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": Object {
|
||||
"id": "618ba1febe2896088840a6db",
|
||||
"referrer_medium": null,
|
||||
"referrer_source": null,
|
||||
"referrer_url": null,
|
||||
"title": "kitchen sink",
|
||||
"type": "tag",
|
||||
"url": "http://127.0.0.1:2369/tag/kitchen-sink/",
|
||||
},
|
||||
"attribution": Any<Object>,
|
||||
"avatar_image": null,
|
||||
"comped": false,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -296,15 +256,7 @@ exports[`Members API Member attribution Creates a SubscriptionCreatedEvent with
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": Object {
|
||||
"id": null,
|
||||
"referrer_medium": null,
|
||||
"referrer_source": null,
|
||||
"referrer_url": null,
|
||||
"title": "homepage",
|
||||
"type": "url",
|
||||
"url": "http://127.0.0.1:2369/",
|
||||
},
|
||||
"attribution": Any<Object>,
|
||||
"avatar_image": null,
|
||||
"comped": false,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -346,7 +298,7 @@ exports[`Members API Member attribution Creates a SubscriptionCreatedEvent witho
|
||||
Object {
|
||||
"members": Array [
|
||||
Object {
|
||||
"attribution": null,
|
||||
"attribution": Any<Object>,
|
||||
"avatar_image": null,
|
||||
"comped": false,
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
@ -376,7 +328,7 @@ exports[`Members API Member attribution Creates a SubscriptionCreatedEvent witho
|
||||
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": "2611",
|
||||
"content-length": "2831",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
@ -439,7 +391,7 @@ exports[`Members API Member attribution Returns subscription created attribution
|
||||
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": "14502",
|
||||
"content-length": "14722",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
|
@ -1663,6 +1663,7 @@ describe('Members API', function () {
|
||||
subscriptions: anyArray,
|
||||
labels: anyArray,
|
||||
tiers: anyArray,
|
||||
attribution: anyObject,
|
||||
newsletters: anyArray
|
||||
};
|
||||
|
||||
@ -1957,13 +1958,29 @@ describe('Members API', function () {
|
||||
|
||||
it('Creates a SubscriptionCreatedEvent without attribution', async function () {
|
||||
const attribution = undefined;
|
||||
await testWithAttribution(attribution, null);
|
||||
await testWithAttribution(attribution, {
|
||||
id: null,
|
||||
url: null,
|
||||
type: 'url',
|
||||
title: null,
|
||||
referrer_source: null,
|
||||
referrer_medium: null,
|
||||
referrer_url: null
|
||||
});
|
||||
});
|
||||
|
||||
it('Creates a SubscriptionCreatedEvent with empty attribution object', async function () {
|
||||
// Shouldn't happen, but to make sure we handle it
|
||||
const attribution = {};
|
||||
await testWithAttribution(attribution, null);
|
||||
await testWithAttribution(attribution, {
|
||||
id: null,
|
||||
url: null,
|
||||
type: 'url',
|
||||
title: null,
|
||||
referrer_source: null,
|
||||
referrer_medium: null,
|
||||
referrer_url: null
|
||||
});
|
||||
});
|
||||
|
||||
// Activity feed
|
||||
|
@ -14,6 +14,54 @@ class MemberAttributionService {
|
||||
this.attributionBuilder = attributionBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Object} context instance of ghost framework context object
|
||||
* @returns {Promise<import('./attribution').AttributionResource|null>}
|
||||
*/
|
||||
async getAttributionFromContext(context) {
|
||||
if (!context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const source = this._resolveContextSource(context);
|
||||
|
||||
// We consider only select internal context sources
|
||||
if (['import', 'api', 'admin'].includes(source)) {
|
||||
let attribution = {
|
||||
id: null,
|
||||
type: null,
|
||||
url: null,
|
||||
title: null,
|
||||
referrerUrl: null,
|
||||
referrerSource: null,
|
||||
referrerMedium: null
|
||||
};
|
||||
if (source === 'import') {
|
||||
attribution.referrerSource = 'Imported';
|
||||
attribution.referrerMedium = 'Member Importer';
|
||||
} else if (source === 'admin') {
|
||||
attribution.referrerSource = 'Created manually';
|
||||
attribution.referrerMedium = 'Ghost Admin';
|
||||
} else if (source === 'api') {
|
||||
attribution.referrerSource = 'Created via API';
|
||||
attribution.referrerMedium = 'Admin API';
|
||||
}
|
||||
|
||||
// If context has integration, set referrer medium as integration anme
|
||||
if (context?.integration?.id) {
|
||||
try {
|
||||
const integration = await this.models.Integration.findOne({id: context.integration.id});
|
||||
attribution.referrerSource = `Integration: ${integration?.get('name')}`;
|
||||
} catch (error) {
|
||||
// ignore error for integration not found
|
||||
}
|
||||
}
|
||||
return attribution;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import('./history').UrlHistoryArray} historyArray
|
||||
@ -63,10 +111,6 @@ class MemberAttributionService {
|
||||
* @returns {import('./attribution').AttributionResource|null}
|
||||
*/
|
||||
getEventAttribution(eventModel) {
|
||||
if (eventModel.get('attribution_type') === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const _attribution = this.attributionBuilder.build({
|
||||
id: eventModel.get('attribution_id'),
|
||||
url: eventModel.get('attribution_url'),
|
||||
@ -76,7 +120,7 @@ class MemberAttributionService {
|
||||
referrerUrl: eventModel.get('referrer_url')
|
||||
});
|
||||
|
||||
if (_attribution.type !== 'url') {
|
||||
if (_attribution.type && _attribution.type !== 'url') {
|
||||
// Find the right relation to use to fetch the resource
|
||||
const tryRelations = [
|
||||
eventModel.related('postAttribution'),
|
||||
@ -100,7 +144,7 @@ class MemberAttributionService {
|
||||
*/
|
||||
async getMemberCreatedAttribution(memberId) {
|
||||
const memberCreatedEvent = await this.models.MemberCreatedEvent.findOne({member_id: memberId}, {require: false, withRelated: []});
|
||||
if (!memberCreatedEvent || !memberCreatedEvent.get('attribution_type')) {
|
||||
if (!memberCreatedEvent) {
|
||||
return null;
|
||||
}
|
||||
const attribution = this.attributionBuilder.build({
|
||||
@ -121,7 +165,7 @@ class MemberAttributionService {
|
||||
*/
|
||||
async getSubscriptionCreatedAttribution(subscriptionId) {
|
||||
const subscriptionCreatedEvent = await this.models.SubscriptionCreatedEvent.findOne({subscription_id: subscriptionId}, {require: false, withRelated: []});
|
||||
if (!subscriptionCreatedEvent || !subscriptionCreatedEvent.get('attribution_type')) {
|
||||
if (!subscriptionCreatedEvent) {
|
||||
return null;
|
||||
}
|
||||
const attribution = this.attributionBuilder.build({
|
||||
@ -134,6 +178,30 @@ class MemberAttributionService {
|
||||
});
|
||||
return await attribution.fetchResource();
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps the framework context to source string
|
||||
* @param {Object} context instance of ghost framework context object
|
||||
* @returns {'import' | 'system' | 'api' | 'admin' | 'member'}
|
||||
* @private
|
||||
*/
|
||||
_resolveContextSource(context) {
|
||||
let source;
|
||||
|
||||
if (context.import || context.importer) {
|
||||
source = 'import';
|
||||
} else if (context.internal) {
|
||||
source = 'system';
|
||||
} else if (context.api_key) {
|
||||
source = 'api';
|
||||
} else if (context.user) {
|
||||
source = 'admin';
|
||||
} else {
|
||||
source = 'member';
|
||||
}
|
||||
|
||||
return source;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = MemberAttributionService;
|
||||
|
@ -10,16 +10,90 @@ describe('MemberAttributionService', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('getAttributionFromContext', function () {
|
||||
it('returns null if no context is provided', async function () {
|
||||
const service = new MemberAttributionService({});
|
||||
const attribution = await service.getAttributionFromContext();
|
||||
|
||||
should(attribution).be.null();
|
||||
});
|
||||
|
||||
it('returns attribution for importer context', async function () {
|
||||
const service = new MemberAttributionService({});
|
||||
const attribution = await service.getAttributionFromContext({importer: true});
|
||||
|
||||
should(attribution).containEql({referrerSource: 'Imported', referrerMedium: 'Member Importer'});
|
||||
});
|
||||
|
||||
it('returns attribution for admin context', async function () {
|
||||
const service = new MemberAttributionService({});
|
||||
const attribution = await service.getAttributionFromContext({user: 'abc'});
|
||||
|
||||
should(attribution).containEql({referrerSource: 'Created manually', referrerMedium: 'Ghost Admin'});
|
||||
});
|
||||
|
||||
it('returns attribution for api without integration context', async function () {
|
||||
const service = new MemberAttributionService({});
|
||||
const attribution = await service.getAttributionFromContext({
|
||||
api_key: 'abc'
|
||||
});
|
||||
|
||||
should(attribution).containEql({referrerSource: 'Created via API', referrerMedium: 'Admin API'});
|
||||
});
|
||||
|
||||
it('returns attribution for api with integration context', async function () {
|
||||
const service = new MemberAttributionService({
|
||||
models: {
|
||||
Integration: {
|
||||
findOne: () => {
|
||||
return {
|
||||
get: () => 'Test Integration'
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
const attribution = await service.getAttributionFromContext({
|
||||
api_key: 'abc',
|
||||
integration: {id: 'integration_1'}
|
||||
});
|
||||
|
||||
should(attribution).containEql({referrerSource: 'Integration: Test Integration', referrerMedium: 'Admin API'});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getEventAttribution', function () {
|
||||
it('returns null if attribution_type is null', function () {
|
||||
const service = new MemberAttributionService({});
|
||||
const service = new MemberAttributionService({
|
||||
attributionBuilder: {
|
||||
build(attribution) {
|
||||
return {
|
||||
...attribution,
|
||||
getResource() {
|
||||
return {
|
||||
...attribution,
|
||||
title: 'added'
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
const model = {
|
||||
id: 'event_id',
|
||||
get() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
should(service.getEventAttribution(model)).eql(null);
|
||||
should(service.getEventAttribution(model)).eql({
|
||||
id: null,
|
||||
url: null,
|
||||
title: 'added',
|
||||
type: null,
|
||||
referrerSource: null,
|
||||
referrerMedium: null,
|
||||
referrerUrl: null
|
||||
});
|
||||
});
|
||||
|
||||
it('returns url attribution types', function () {
|
||||
|
@ -205,7 +205,7 @@ module.exports = class MemberRepository {
|
||||
* @param {Object[]} [data.newsletters]
|
||||
* @param {Object} [data.stripeCustomer]
|
||||
* @param {string} [data.offerId]
|
||||
* @param {import('@tryghost/member-attribution/lib/history').Attribution} [data.attribution]
|
||||
* @param {import('@tryghost/member-attribution/lib/attribution').AttributionResource} [data.attribution]
|
||||
* @param {*} options
|
||||
* @returns
|
||||
*/
|
||||
@ -778,7 +778,7 @@ module.exports = class MemberRepository {
|
||||
* @param {String} data.id - member ID
|
||||
* @param {Object} data.subscription
|
||||
* @param {String} data.offerId
|
||||
* @param {import('@tryghost/member-attribution/lib/history').Attribution} data.attribution
|
||||
* @param {import('@tryghost/member-attribution/lib/attribution').AttributionResource} [data.attribution]
|
||||
* @param {*} options
|
||||
* @returns
|
||||
*/
|
||||
|
@ -174,7 +174,7 @@ module.exports = class MemberBREADService {
|
||||
async attachAttributionsToMember(member, subscriptionIdMap) {
|
||||
// Created attribution
|
||||
member.attribution = await this.memberAttributionService.getMemberCreatedAttribution(member.id);
|
||||
|
||||
|
||||
// Subscriptions attributions
|
||||
for (const subscription of member.subscriptions) {
|
||||
if (!subscription.id) {
|
||||
@ -254,6 +254,10 @@ module.exports = class MemberBREADService {
|
||||
let model;
|
||||
|
||||
try {
|
||||
const attribution = await this.memberAttributionService.getAttributionFromContext(options?.context);
|
||||
if (attribution) {
|
||||
data.attribution = attribution;
|
||||
}
|
||||
model = await this.memberRepository.create(data, options);
|
||||
} catch (error) {
|
||||
if (error.code && error.message.toLowerCase().indexOf('unique') !== -1) {
|
||||
|
Loading…
Reference in New Issue
Block a user