7e27d3f3e8
fixes https://github.com/TryGhost/Team/issues/3331 This adds attribution tracking to the signup form. It sends a newly created url history when sending the signup API call, this url history will get translated to a proper attribution and saved on the backend. We send a history with only a single item that contains the referrer source, medium and path of the Embed form. This also makes some changes to the E2E tests so that the tests run in an https environment instead of about:blank.
310 lines
9.9 KiB
JavaScript
310 lines
9.9 KiB
JavaScript
// Switch these lines once there are useful utils
|
|
// const testUtils = require('./utils');
|
|
require('./utils');
|
|
const UrlTranslator = require('../lib/UrlTranslator');
|
|
|
|
const models = {
|
|
Post: {
|
|
findOne({id}) {
|
|
if (id === 'invalid') {
|
|
return null;
|
|
}
|
|
return {id: 'post_id', get: () => 'Title'};
|
|
}
|
|
},
|
|
User: {
|
|
findOne({id}) {
|
|
if (id === 'invalid') {
|
|
return null;
|
|
}
|
|
return {id: 'user_id', get: () => 'Title'};
|
|
}
|
|
},
|
|
Tag: {
|
|
findOne({id}) {
|
|
if (id === 'invalid') {
|
|
return null;
|
|
}
|
|
return {id: 'tag_id', get: () => 'Title'};
|
|
}
|
|
}
|
|
};
|
|
|
|
describe('UrlTranslator', function () {
|
|
describe('Constructor', function () {
|
|
it('doesn\'t throw', function () {
|
|
new UrlTranslator({});
|
|
});
|
|
});
|
|
|
|
describe('getResourceDetails', function () {
|
|
let translator;
|
|
before(function () {
|
|
translator = new UrlTranslator({
|
|
urlUtils: {
|
|
relativeToAbsolute: (t) => {
|
|
return 'https://absolute' + t;
|
|
},
|
|
absoluteToRelative: (t) => {
|
|
return t.replace('https://absolute/with-subdirectory', '').replace('https://absolute', '');
|
|
}
|
|
},
|
|
urlService: {
|
|
getUrlByResourceId: (id) => {
|
|
return '/path/' + id;
|
|
},
|
|
getResource: (path) => {
|
|
switch (path) {
|
|
case '/path/post': return {
|
|
config: {type: 'posts'},
|
|
data: {id: 'post'}
|
|
};
|
|
case '/path/tag': return {
|
|
config: {type: 'tags'},
|
|
data: {id: 'tag'}
|
|
};
|
|
case '/path/page': return {
|
|
config: {type: 'pages'},
|
|
data: {id: 'page'}
|
|
};
|
|
case '/path/author': return {
|
|
config: {type: 'authors'},
|
|
data: {id: 'author'}
|
|
};
|
|
}
|
|
}
|
|
},
|
|
models
|
|
});
|
|
});
|
|
|
|
it('skips items without path and type', async function () {
|
|
should(await translator.getResourceDetails({time: 123})).eql(null);
|
|
});
|
|
|
|
it('returns posts for explicit items', async function () {
|
|
should(await translator.getResourceDetails({id: 'my-post', type: 'post', time: 123})).eql({
|
|
type: 'post',
|
|
id: 'my-post',
|
|
url: '/path/my-post'
|
|
});
|
|
});
|
|
|
|
it('returns null if explicit resource not found', async function () {
|
|
should(await translator.getResourceDetails({id: 'invalid', type: 'post', time: 123})).eql(null);
|
|
});
|
|
|
|
it('returns null for invalid item', async function () {
|
|
should(await translator.getResourceDetails({time: 123})).eql(null);
|
|
});
|
|
|
|
it('returns url type if no path not matching a resource', async function () {
|
|
should(await translator.getResourceDetails({path: '/test', time: 123})).eql({
|
|
type: 'url',
|
|
id: null,
|
|
url: '/test'
|
|
});
|
|
});
|
|
|
|
it('strips subdirectory for url types', async function () {
|
|
should(await translator.getResourceDetails({path: '/with-subdirectory/test', time: 123})).eql({
|
|
type: 'url',
|
|
id: null,
|
|
url: '/test'
|
|
});
|
|
});
|
|
|
|
it('returns post type if matching resource', async function () {
|
|
should(await translator.getResourceDetails({path: '/with-subdirectory/path/post', time: 123})).eql({
|
|
type: 'post',
|
|
id: 'post',
|
|
url: '/path/post'
|
|
});
|
|
});
|
|
|
|
it('returns page type if matching resource', async function () {
|
|
should(await translator.getResourceDetails({path: '/with-subdirectory/path/page', time: 123})).eql({
|
|
type: 'page',
|
|
id: 'page',
|
|
url: '/path/page'
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('getUrlTitle', function () {
|
|
let translator;
|
|
before(function () {
|
|
translator = new UrlTranslator({});
|
|
});
|
|
|
|
it('returns homepage', function () {
|
|
should(translator.getUrlTitle('/')).eql('homepage');
|
|
});
|
|
|
|
it('returns url', function () {
|
|
should(translator.getUrlTitle('/url')).eql('/url');
|
|
});
|
|
});
|
|
|
|
describe('getTypeAndIdFromPath', function () {
|
|
let translator;
|
|
before(function () {
|
|
translator = new UrlTranslator({
|
|
urlService: {
|
|
getResource: (path) => {
|
|
switch (path) {
|
|
case '/post': return {
|
|
config: {type: 'posts'},
|
|
data: {id: 'post'}
|
|
};
|
|
case '/tag': return {
|
|
config: {type: 'tags'},
|
|
data: {id: 'tag'}
|
|
};
|
|
case '/page': return {
|
|
config: {type: 'pages'},
|
|
data: {id: 'page'}
|
|
};
|
|
case '/author': return {
|
|
config: {type: 'authors'},
|
|
data: {id: 'author'}
|
|
};
|
|
}
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
it('returns posts', function () {
|
|
should(translator.getTypeAndIdFromPath('/post')).eql({
|
|
type: 'post',
|
|
id: 'post'
|
|
});
|
|
});
|
|
|
|
it('returns pages', function () {
|
|
should(translator.getTypeAndIdFromPath('/page')).eql({
|
|
type: 'page',
|
|
id: 'page'
|
|
});
|
|
});
|
|
|
|
it('returns authors', function () {
|
|
should(translator.getTypeAndIdFromPath('/author')).eql({
|
|
type: 'author',
|
|
id: 'author'
|
|
});
|
|
});
|
|
|
|
it('returns tags', function () {
|
|
should(translator.getTypeAndIdFromPath('/tag')).eql({
|
|
type: 'tag',
|
|
id: 'tag'
|
|
});
|
|
});
|
|
|
|
it('returns undefined', function () {
|
|
should(translator.getTypeAndIdFromPath('/other')).eql(undefined);
|
|
});
|
|
});
|
|
|
|
describe('getResourceById', function () {
|
|
let translator;
|
|
before(function () {
|
|
translator = new UrlTranslator({
|
|
urlService: {
|
|
getUrlByResourceId: () => {
|
|
return '/path';
|
|
}
|
|
},
|
|
models
|
|
});
|
|
});
|
|
|
|
it('returns for post', async function () {
|
|
should(await translator.getResourceById('id', 'post')).match({
|
|
id: 'post_id'
|
|
});
|
|
});
|
|
|
|
it('returns for page', async function () {
|
|
should(await translator.getResourceById('id', 'page')).match({
|
|
id: 'post_id'
|
|
});
|
|
});
|
|
|
|
it('returns for tag', async function () {
|
|
should(await translator.getResourceById('id', 'tag')).match({
|
|
id: 'tag_id'
|
|
});
|
|
});
|
|
|
|
it('returns for user', async function () {
|
|
should(await translator.getResourceById('id', 'author')).match({
|
|
id: 'user_id'
|
|
});
|
|
});
|
|
|
|
it('returns for invalid', async function () {
|
|
should(await translator.getResourceById('id', 'invalid')).eql(null);
|
|
});
|
|
|
|
it('returns null for not found post', async function () {
|
|
should(await translator.getResourceById('invalid', 'post')).eql(null);
|
|
});
|
|
|
|
it('returns null for not found page', async function () {
|
|
should(await translator.getResourceById('invalid', 'page')).eql(null);
|
|
});
|
|
|
|
it('returns null for not found author', async function () {
|
|
should(await translator.getResourceById('invalid', 'author')).eql(null);
|
|
});
|
|
|
|
it('returns null for not found tag', async function () {
|
|
should(await translator.getResourceById('invalid', 'tag')).eql(null);
|
|
});
|
|
});
|
|
|
|
describe('relativeToAbsolute', function () {
|
|
let translator;
|
|
before(function () {
|
|
translator = new UrlTranslator({
|
|
urlUtils: {
|
|
relativeToAbsolute: (t) => {
|
|
return 'absolute/' + t;
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
it('passes relativeToAbsolute to urlUtils', async function () {
|
|
should(translator.relativeToAbsolute('relative')).eql('absolute/relative');
|
|
});
|
|
});
|
|
|
|
describe('stripSubdirectoryFromPath', function () {
|
|
let translator;
|
|
before(function () {
|
|
translator = new UrlTranslator({
|
|
urlUtils: {
|
|
relativeToAbsolute: (t) => {
|
|
return 'absolute' + t;
|
|
},
|
|
absoluteToRelative: (t) => {
|
|
const prefix = 'absolute/dir/';
|
|
if (t.startsWith(prefix)) {
|
|
return t.substring(prefix.length - 1);
|
|
}
|
|
return t;
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
it('passes calls to urlUtils', async function () {
|
|
should(translator.stripSubdirectoryFromPath('/dir/relative')).eql('/relative');
|
|
});
|
|
});
|
|
});
|