Cleaned up "List Unsubscribe Header" GA feature flag (#20573)
no issue
- "List Unsubscribe Header" feature was added in Ghost release
[v5.74.0](https://github.com/TryGhost/Ghost/releases/tag/v5.74.0)
(commit: 69ee4a5
)
- [Project
details](https://www.notion.so/ghost/One-click-unsubscribe-from-gmail-2b5cdc81e49f462287e9894c9c368aad?pvs=4)
This commit is contained in:
parent
6bfba13937
commit
83b1603202
@ -2,7 +2,6 @@ const debug = require('@tryghost/debug')('services:routing:controllers:unsubscri
|
||||
const url = require('url');
|
||||
const members = require('../../../../server/services/members');
|
||||
const urlUtils = require('../../../../shared/url-utils');
|
||||
const labs = require('../../../../shared/labs');
|
||||
const logging = require('@tryghost/logging');
|
||||
|
||||
module.exports = async function unsubscribeController(req, res) {
|
||||
@ -15,7 +14,7 @@ module.exports = async function unsubscribeController(req, res) {
|
||||
return res.end('Email address not found.');
|
||||
}
|
||||
|
||||
if (req.method === 'POST' && labs.isSet('listUnsubscribeHeader')) {
|
||||
if (req.method === 'POST') {
|
||||
logging.info('[List-Unsubscribe] Received POST unsubscribe for ' + query.uuid + ', newsletter: ' + (query.newsletter ?? 'null') + ', comments: ' + (query.comments ?? 'false'));
|
||||
|
||||
// Do an actual unsubscribe
|
||||
|
@ -21,7 +21,6 @@ const GA_FEATURES = [
|
||||
'announcementBar',
|
||||
'signupForm',
|
||||
'recommendations',
|
||||
'listUnsubscribeHeader',
|
||||
'newEmailAddresses',
|
||||
'internalLinking'
|
||||
];
|
||||
|
@ -1155,7 +1155,7 @@ exports[`Settings API Edit Can edit a setting 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": "4530",
|
||||
"content-length": "4499",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
|
@ -9,7 +9,7 @@ const settingsCache = require('../../core/shared/settings-cache');
|
||||
const DomainEvents = require('@tryghost/domain-events');
|
||||
const {MemberPageViewEvent} = require('@tryghost/member-events');
|
||||
const models = require('../../core/server/models');
|
||||
const {mockManager, fixtureManager} = require('../utils/e2e-framework');
|
||||
const {fixtureManager} = require('../utils/e2e-framework');
|
||||
const DataGenerator = require('../utils/fixtures/data-generator');
|
||||
const members = require('../../core/server/services/members');
|
||||
|
||||
@ -266,14 +266,6 @@ describe('Front-end members behavior', function () {
|
||||
});
|
||||
|
||||
describe('Unsubscribe', function () {
|
||||
beforeEach(function () {
|
||||
mockManager.mockLabsEnabled('listUnsubscribeHeader');
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
mockManager.restore();
|
||||
});
|
||||
|
||||
it('should redirect with uuid and action param', async function () {
|
||||
await request.get('/unsubscribe/?uuid=XXX')
|
||||
.expect(302)
|
||||
|
@ -687,22 +687,17 @@ class EmailRenderer {
|
||||
getValue: (member) => {
|
||||
return this.getMemberStatusText(member);
|
||||
}
|
||||
},
|
||||
// List unsubscribe header to unsubcribe in one-click
|
||||
{
|
||||
id: 'list_unsubscribe',
|
||||
getValue: (member) => {
|
||||
return this.createUnsubscribeUrl(member.uuid, {newsletterUuid});
|
||||
},
|
||||
required: true // Used in email headers
|
||||
}
|
||||
];
|
||||
|
||||
if (this.#labs.isSet('listUnsubscribeHeader')) {
|
||||
baseDefinitions.push(
|
||||
{
|
||||
id: 'list_unsubscribe',
|
||||
getValue: (member) => {
|
||||
// Same URL
|
||||
return this.createUnsubscribeUrl(member.uuid, {newsletterUuid});
|
||||
},
|
||||
required: true // Used in email headers
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Now loop through all the definenitions to see which ones are actually used + to add fallbacks if needed
|
||||
const EMAIL_REPLACEMENT_REGEX = /%%\{(.*?)\}%%/g;
|
||||
const REPLACEMENT_STRING_REGEX = /^(?<recipientProperty>\w+?)(?:,? *(?:"|")(?<fallback>.*?)(?:"|"))?$/;
|
||||
|
@ -107,16 +107,19 @@ describe('Email renderer', function () {
|
||||
};
|
||||
});
|
||||
|
||||
it('returns an empty list of replacements if nothing is used', function () {
|
||||
it('returns the unsubscribe header replacement by default', function () {
|
||||
const html = 'Hello world';
|
||||
const replacements = emailRenderer.buildReplacementDefinitions({html, newsletterUuid: newsletter.get('uuid')});
|
||||
assert.equal(replacements.length, 0);
|
||||
assert.equal(replacements.length, 1);
|
||||
assert.equal(replacements[0].token.toString(), '/%%\\{list_unsubscribe\\}%%/g');
|
||||
assert.equal(replacements[0].id, 'list_unsubscribe');
|
||||
assert.equal(replacements[0].getValue(member), `http://example.com/subdirectory/unsubscribe/?uuid=myuuid&newsletter=newsletteruuid`);
|
||||
});
|
||||
|
||||
it('returns a replacement if it is used', function () {
|
||||
const html = 'Hello world %%{uuid}%%';
|
||||
const replacements = emailRenderer.buildReplacementDefinitions({html, newsletterUuid: newsletter.get('uuid')});
|
||||
assert.equal(replacements.length, 1);
|
||||
assert.equal(replacements.length, 2);
|
||||
assert.equal(replacements[0].token.toString(), '/%%\\{uuid\\}%%/g');
|
||||
assert.equal(replacements[0].id, 'uuid');
|
||||
assert.equal(replacements[0].getValue(member), 'myuuid');
|
||||
@ -125,7 +128,7 @@ describe('Email renderer', function () {
|
||||
it('returns a replacement only once if used multiple times', function () {
|
||||
const html = 'Hello world %%{uuid}%% And %%{uuid}%%';
|
||||
const replacements = emailRenderer.buildReplacementDefinitions({html, newsletterUuid: newsletter.get('uuid')});
|
||||
assert.equal(replacements.length, 1);
|
||||
assert.equal(replacements.length, 2);
|
||||
assert.equal(replacements[0].token.toString(), '/%%\\{uuid\\}%%/g');
|
||||
assert.equal(replacements[0].id, 'uuid');
|
||||
assert.equal(replacements[0].getValue(member), 'myuuid');
|
||||
@ -134,7 +137,7 @@ describe('Email renderer', function () {
|
||||
it('returns correct first name', function () {
|
||||
const html = 'Hello %%{first_name}%%,';
|
||||
const replacements = emailRenderer.buildReplacementDefinitions({html, newsletterUuid: newsletter.get('uuid')});
|
||||
assert.equal(replacements.length, 1);
|
||||
assert.equal(replacements.length, 2);
|
||||
assert.equal(replacements[0].token.toString(), '/%%\\{first_name\\}%%/g');
|
||||
assert.equal(replacements[0].id, 'first_name');
|
||||
assert.equal(replacements[0].getValue(member), 'Test');
|
||||
@ -143,26 +146,16 @@ describe('Email renderer', function () {
|
||||
it('returns correct unsubscribe url', function () {
|
||||
const html = 'Hello %%{unsubscribe_url}%%,';
|
||||
const replacements = emailRenderer.buildReplacementDefinitions({html, newsletterUuid: newsletter.get('uuid')});
|
||||
assert.equal(replacements.length, 1);
|
||||
assert.equal(replacements.length, 2);
|
||||
assert.equal(replacements[0].token.toString(), '/%%\\{unsubscribe_url\\}%%/g');
|
||||
assert.equal(replacements[0].id, 'unsubscribe_url');
|
||||
assert.equal(replacements[0].getValue(member), `http://example.com/subdirectory/unsubscribe/?uuid=myuuid&newsletter=newsletteruuid`);
|
||||
});
|
||||
|
||||
it('returns correct list-unsubscribe value', function () {
|
||||
labsEnabled = true;
|
||||
const html = 'Hello';
|
||||
const replacements = emailRenderer.buildReplacementDefinitions({html, newsletterUuid: newsletter.get('uuid')});
|
||||
assert.equal(replacements.length, 1);
|
||||
assert.equal(replacements[0].token.toString(), '/%%\\{list_unsubscribe\\}%%/g');
|
||||
assert.equal(replacements[0].id, 'list_unsubscribe');
|
||||
assert.equal(replacements[0].getValue(member), `http://example.com/subdirectory/unsubscribe/?uuid=myuuid&newsletter=newsletteruuid`);
|
||||
});
|
||||
|
||||
it('returns correct name', function () {
|
||||
const html = 'Hello %%{name}%%,';
|
||||
const replacements = emailRenderer.buildReplacementDefinitions({html, newsletterUuid: newsletter.get('uuid')});
|
||||
assert.equal(replacements.length, 1);
|
||||
assert.equal(replacements.length, 2);
|
||||
assert.equal(replacements[0].token.toString(), '/%%\\{name\\}%%/g');
|
||||
assert.equal(replacements[0].id, 'name');
|
||||
assert.equal(replacements[0].getValue(member), 'Test User');
|
||||
@ -172,7 +165,7 @@ describe('Email renderer', function () {
|
||||
member.name = '';
|
||||
const html = 'Hello %%{name_class}%%,';
|
||||
const replacements = emailRenderer.buildReplacementDefinitions({html, newsletterUuid: newsletter.get('uuid')});
|
||||
assert.equal(replacements.length, 1);
|
||||
assert.equal(replacements.length, 2);
|
||||
assert.equal(replacements[0].token.toString(), '/%%\\{name_class\\}%%/g');
|
||||
assert.equal(replacements[0].id, 'name_class');
|
||||
assert.equal(replacements[0].getValue(member), 'hidden');
|
||||
@ -181,7 +174,7 @@ describe('Email renderer', function () {
|
||||
it('returns empty class for available name', function () {
|
||||
const html = 'Hello %%{name_class}%%,';
|
||||
const replacements = emailRenderer.buildReplacementDefinitions({html, newsletterUuid: newsletter.get('uuid')});
|
||||
assert.equal(replacements.length, 1);
|
||||
assert.equal(replacements.length, 2);
|
||||
assert.equal(replacements[0].token.toString(), '/%%\\{name_class\\}%%/g');
|
||||
assert.equal(replacements[0].id, 'name_class');
|
||||
assert.equal(replacements[0].getValue(member), '');
|
||||
@ -190,7 +183,7 @@ describe('Email renderer', function () {
|
||||
it('returns correct email', function () {
|
||||
const html = 'Hello %%{email}%%,';
|
||||
const replacements = emailRenderer.buildReplacementDefinitions({html, newsletterUuid: newsletter.get('uuid')});
|
||||
assert.equal(replacements.length, 1);
|
||||
assert.equal(replacements.length, 2);
|
||||
assert.equal(replacements[0].token.toString(), '/%%\\{email\\}%%/g');
|
||||
assert.equal(replacements[0].id, 'email');
|
||||
assert.equal(replacements[0].getValue(member), 'test@example.com');
|
||||
@ -199,7 +192,7 @@ describe('Email renderer', function () {
|
||||
it('returns correct status', function () {
|
||||
const html = 'Hello %%{status}%%,';
|
||||
const replacements = emailRenderer.buildReplacementDefinitions({html, newsletterUuid: newsletter.get('uuid')});
|
||||
assert.equal(replacements.length, 1);
|
||||
assert.equal(replacements.length, 2);
|
||||
assert.equal(replacements[0].token.toString(), '/%%\\{status\\}%%/g');
|
||||
assert.equal(replacements[0].id, 'status');
|
||||
assert.equal(replacements[0].getValue(member), 'free');
|
||||
@ -209,7 +202,7 @@ describe('Email renderer', function () {
|
||||
member.status = 'comped';
|
||||
const html = 'Hello %%{status}%%,';
|
||||
const replacements = emailRenderer.buildReplacementDefinitions({html, newsletterUuid: newsletter.get('uuid')});
|
||||
assert.equal(replacements.length, 1);
|
||||
assert.equal(replacements.length, 2);
|
||||
assert.equal(replacements[0].token.toString(), '/%%\\{status\\}%%/g');
|
||||
assert.equal(replacements[0].id, 'status');
|
||||
assert.equal(replacements[0].getValue(member), 'complimentary');
|
||||
@ -227,7 +220,7 @@ describe('Email renderer', function () {
|
||||
];
|
||||
const html = 'Hello %%{status}%%,';
|
||||
const replacements = emailRenderer.buildReplacementDefinitions({html, newsletterUuid: newsletter.get('uuid')});
|
||||
assert.equal(replacements.length, 1);
|
||||
assert.equal(replacements.length, 2);
|
||||
assert.equal(replacements[0].token.toString(), '/%%\\{status\\}%%/g');
|
||||
assert.equal(replacements[0].id, 'status');
|
||||
assert.equal(replacements[0].getValue(member), 'trialing');
|
||||
@ -236,7 +229,7 @@ describe('Email renderer', function () {
|
||||
it('returns manage_account_url', function () {
|
||||
const html = 'Hello %%{manage_account_url}%%,';
|
||||
const replacements = emailRenderer.buildReplacementDefinitions({html, newsletterUuid: newsletter.get('uuid')});
|
||||
assert.equal(replacements.length, 1);
|
||||
assert.equal(replacements.length, 2);
|
||||
assert.equal(replacements[0].token.toString(), '/%%\\{manage_account_url\\}%%/g');
|
||||
assert.equal(replacements[0].id, 'manage_account_url');
|
||||
assert.equal(replacements[0].getValue(member), 'http://example.com/subdirectory/#/portal/account');
|
||||
@ -255,7 +248,7 @@ describe('Email renderer', function () {
|
||||
];
|
||||
|
||||
const replacements = emailRenderer.buildReplacementDefinitions({html, newsletterUuid: newsletter.get('uuid')});
|
||||
assert.equal(replacements.length, 1);
|
||||
assert.equal(replacements.length, 2);
|
||||
assert.equal(replacements[0].token.toString(), '/%%\\{status_text\\}%%/g');
|
||||
assert.equal(replacements[0].id, 'status_text');
|
||||
assert.equal(replacements[0].getValue(member), 'Your free trial ends on 13 March 2050, at which time you will be charged the regular price. You can always cancel before then.');
|
||||
@ -264,7 +257,7 @@ describe('Email renderer', function () {
|
||||
it('returns correct createdAt', function () {
|
||||
const html = 'Hello %%{created_at}%%,';
|
||||
const replacements = emailRenderer.buildReplacementDefinitions({html, newsletterUuid: newsletter.get('uuid')});
|
||||
assert.equal(replacements.length, 1);
|
||||
assert.equal(replacements.length, 2);
|
||||
assert.equal(replacements[0].token.toString(), '/%%\\{created_at\\}%%/g');
|
||||
assert.equal(replacements[0].id, 'created_at');
|
||||
assert.equal(replacements[0].getValue(member), '13 March 2023');
|
||||
@ -274,7 +267,7 @@ describe('Email renderer', function () {
|
||||
member.createdAt = null;
|
||||
const html = 'Hello %%{created_at}%%,';
|
||||
const replacements = emailRenderer.buildReplacementDefinitions({html, newsletterUuid: newsletter.get('uuid')});
|
||||
assert.equal(replacements.length, 1);
|
||||
assert.equal(replacements.length, 2);
|
||||
assert.equal(replacements[0].token.toString(), '/%%\\{created_at\\}%%/g');
|
||||
assert.equal(replacements[0].id, 'created_at');
|
||||
assert.equal(replacements[0].getValue(member), '');
|
||||
@ -283,7 +276,7 @@ describe('Email renderer', function () {
|
||||
it('supports fallback values', function () {
|
||||
const html = 'Hey %%{first_name, "there"}%%,';
|
||||
const replacements = emailRenderer.buildReplacementDefinitions({html, newsletterUuid: newsletter.get('uuid')});
|
||||
assert.equal(replacements.length, 1);
|
||||
assert.equal(replacements.length, 2);
|
||||
assert.equal(replacements[0].token.toString(), '/%%\\{first_name, (?:"|")there(?:"|")\\}%%/g');
|
||||
assert.equal(replacements[0].id, 'first_name_2');
|
||||
assert.equal(replacements[0].getValue(member), 'Test');
|
||||
@ -295,7 +288,7 @@ describe('Email renderer', function () {
|
||||
it('supports combination of multiple fallback values', function () {
|
||||
const html = 'Hey %%{first_name, "there"}%%, %%{first_name, "member"}%% %%{first_name}%% %%{first_name, "there"}%%';
|
||||
const replacements = emailRenderer.buildReplacementDefinitions({html, newsletterUuid: newsletter.get('uuid')});
|
||||
assert.equal(replacements.length, 3);
|
||||
assert.equal(replacements.length, 4);
|
||||
assert.equal(replacements[0].token.toString(), '/%%\\{first_name, (?:"|")there(?:"|")\\}%%/g');
|
||||
assert.equal(replacements[0].id, 'first_name_2');
|
||||
assert.equal(replacements[0].getValue(member), 'Test');
|
||||
|
Loading…
Reference in New Issue
Block a user