/* eslint-disable no-regex-spaces */
const should = require('should');
const sinon = require('sinon');
const _ = require('lodash');
const moment = require('moment');
const testUtils = require('../../utils');
const testUrlUtils = require('../../utils/urlUtils');
const configUtils = require('../../utils/configUtils');
const themeService = require('../../../core/frontend/services/themes');
const models = require('../../../core/server/models');
const imageLib = require('../../../core/server/lib/image');
const routing = require('../../../core/frontend/services/routing');
const urlService = require('../../../core/frontend/services/url');
const helpers = require('../../../core/frontend/helpers');
const proxy = require('../../../core/frontend/services/proxy');
const settingsCache = proxy.settingsCache;
describe('{{ghost_head}} helper', function () {
let posts = [];
let tags = [];
let authors = [];
let users = [];
const makeFixtures = () => {
const {createPost, createUser, createTag} = testUtils.DataGenerator.forKnex;
/** TAGS - used for tag pages */
tags.push(createTag({
meta_description: 'tag meta description',
name: 'tagtitle',
meta_title: 'tag meta title',
feature_image: '/content/images/tag-image.png'
}));
tags.push(createTag({
meta_description: '',
description: 'tag description',
name: 'tagtitle',
meta_title: '',
feature_image: '/content/images/tag-image.png'
}));
tags.push(createTag({
description: '',
meta_description: '',
name: 'tagtitle',
meta_title: '',
feature_image: '/content/images/tag-image.png'
}));
tags.push(createTag({
meta_description: 'tag meta description',
title: 'tagtitle',
meta_title: 'tag meta title',
feature_image: '/content/images/tag-image.png'
}));
/** USERS - used for author PAGES */
users.push(createUser({
name: 'Author name',
slug: 'AuthorName',
bio: 'Author bio',
profile_image: '/content/images/test-author-image.png',
cover_image: '/content/images/author-cover-image.png',
website: 'http://authorwebsite.com',
facebook: 'testuser',
twitter: '@testuser'
}));
users.push(createUser({
name: 'Author name',
slug: 'AuthorName1',
bio: 'Author bio',
profile_image: '/content/images/test-author-image.png',
cover_image: '/content/images/author-cover-image.png',
website: 'http://authorwebsite.com'
}));
/** AUTHORS - related to posts */
authors.push(createUser({// Author 0
profile_image: '/content/images/test-author-image.png',
website: 'http://authorwebsite.com',
facebook: 'testuser',
twitter: '@testuser'
}));
authors.push(createUser({// Author 1
name: 'Author name',
slug: 'author2',
profile_image: '/content/images/test-author-image.png',
website: 'http://authorwebsite.com',
bio: 'Author bio',
facebook: 'testuser',
twitter: '@testuser'
}));
authors.push(createUser({// Author 2
name: 'Author name',
slug: 'author3',
profile_image: '/content/images/test-author-image.png',
website: 'http://authorwebsite.com',
facebook: 'testuser',
twitter: '@testuser',
bio: 'Author bio'
}));
authors.push(createUser({// Author 3
name: 'Author name',
url: 'http://testauthorurl.com',
slug: 'author4',
profile_image: '/content/images/test-author-image.png',
website: 'http://authorwebsite.com',
facebook: 'testuser',
twitter: '@testuser'
}));
authors.push(createUser({// Author 4
name: 'Author name'
}));
authors.push(createUser({// Author 5
name: 'Author name',
url: 'http://testauthorurl.com',
slug: 'author8',
profile_image: null,
website: 'http://authorwebsite.com',
facebook: 'testuser',
twitter: '@testuser'
}));
/** POSTS */
posts.push(createPost({// Post 0
meta_description: 'all about our site',
title: 'About',
feature_image: '/content/images/test-image-about.png',
page: true,
authors: [authors[0]],
primary_author: authors[0]
}));
posts.push(createPost({// Post 1
meta_description: 'all about our site',
title: 'About',
feature_image: '/content/images/test-image-about.png',
og_image: '/content/images/test-og-image.png',
og_title: 'Custom Facebook title',
og_description: 'Custom Facebook description',
twitter_image: '/content/images/test-twitter-image.png',
twitter_title: 'Custom Twitter title',
twitter_description: 'Custom Twitter description',
page: true,
authors: [authors[0]],
primary_author: authors[0]
}));
posts.push(createPost({// Post 2
meta_description: 'site description',
title: 'Welcome to Ghost',
feature_image: '/content/images/test-image.png',
og_title: 'Custom Facebook title',
og_description: 'Custom Facebook description',
twitter_image: '/content/images/test-twitter-image.png',
published_at: moment('2008-05-31T19:18:15').toDate(),
updated_at: moment('2014-10-06T15:23:54').toDate(),
tags: [
createTag({name: 'tag1'}),
createTag({name: 'tag2'}),
createTag({name: 'tag3'})
],
authors: [authors[1]],
primary_author: authors[1]
}));
posts.push(createPost({// Post 3
meta_description: 'site description',
custom_excerpt: 'post custom excerpt',
title: 'Welcome to Ghost',
feature_image: '/content/images/test-image.png',
og_image: '/content/images/test-facebook-image.png',
twitter_image: '/content/images/test-twitter-image.png',
twitter_title: 'Custom Twitter title',
tags: [
createTag({name: 'tag1'}),
createTag({name: 'tag2'}),
createTag({name: 'tag3'})
],
authors: [
authors[2]
],
primary_author: authors[2]
}));
posts.push(createPost({// Post 4
title: 'Welcome to Ghost',
mobiledoc: testUtils.DataGenerator.markdownToMobiledoc('This is a short post'),
authors: [
authors[3]
],
primary_author: authors[3]
}));
posts.push(createPost({// Post 5
meta_description: 'site description',
title: 'Welcome to Ghost',
feature_image: '/content/images/test-image.png',
og_image: '/content/images/test-facebook-image.png',
og_title: 'Custom Facebook title',
twitter_image: '/content/images/test-twitter-image.png',
twitter_title: 'Custom Twitter title',
tags: [
createTag({name: 'tag1'}),
createTag({name: 'tag2'}),
createTag({name: 'tag3'})
],
authors: [
authors[3]
],
primary_author: authors[3]
}));
posts.push(createPost({// Post 6
meta_description: 'site "test" description',
title: 'title',
meta_title: 'Welcome to Ghost "test"',
feature_image: '/content/images/test-image.png',
tags: [
createTag({name: 'tag1'}),
createTag({name: 'tag2'}),
createTag({name: 'tag3'})
],
authors: [
authors[3]
],
primary_author: authors[3]
}));
posts.push(createPost({// Post 7
meta_description: 'site description',
title: 'Welcome to Ghost',
feature_image: '/content/images/test-image.png',
tags: [],
authors: [
authors[3]
],
primary_author: authors[3]
}));
posts.push(createPost({// Post 8
meta_description: 'site description',
title: 'Welcome to Ghost',
feature_image: null,
tags: [
createTag({name: 'tag1'}),
createTag({name: 'tag2'}),
createTag({name: 'tag3'})
],
authors: [
authors[5]
],
primary_author: authors[5]
}));
posts.push(createPost({// Post 9
title: 'Welcome to Ghost',
mobiledoc: testUtils.DataGenerator.markdownToMobiledoc('This is a short post'),
tags: [
createTag({name: 'tag1'}),
createTag({name: 'tag2'}),
createTag({name: 'tag3'})
],
authors: [
authors[4]
],
primary_author: authors[4]
}));
};
before(function () {
// @TODO: remove when visibility is refactored out of models
models.init();
});
beforeEach(function () {
sinon.stub(urlService, 'getUrlByResourceId').returns('https://mysite.com/fakeauthor/');
// @TODO: this is a LOT of mocking :/
sinon.stub(routing.registry, 'getRssUrl').returns('http://localhost:65530/rss/');
sinon.stub(imageLib.imageSize, 'getImageSizeFromUrl').resolves();
sinon.stub(themeService, 'getActive').returns({
engine: () => 'v2'
});
sinon.stub(settingsCache, 'get');
settingsCache.get.withArgs('title').returns('Ghost');
settingsCache.get.withArgs('description').returns('site description');
settingsCache.get.withArgs('cover_image').returns('/content/images/site-cover.png');
settingsCache.get.withArgs('amp').returns(true);
makeFixtures();
});
afterEach(function () {
sinon.restore();
configUtils.restore();
});
describe('without Code Injection', function () {
let sandbox;
beforeEach(function () {
sandbox = sinon.createSandbox();
testUrlUtils.stubUrlUtils({url: 'http://localhost:65530/'}, sandbox);
});
afterEach(function () {
sandbox.restore();
});
it('returns meta tag string on paginated index page without structured data and schema', function (done) {
// @TODO: later we can extend this fn with an `meta` object e.g. locals.meta
helpers.ghost_head(testUtils.createHbsResponse({
locals: {
relativeUrl: '/page/2/',
context: ['paged', 'index'],
safeVersion: '0.3'
}
})).then(function (rendered) {
should.exist(rendered);
rendered.string.should.match(//);
rendered.string.should.match(//);
rendered.string.should.match(//);
rendered.string.should.not.match(//);
done();
}).catch(done);
});
it('returns structured data on first index page', function (done) {
helpers.ghost_head(testUtils.createHbsResponse({
locals: {
relativeUrl: '/',
context: ['home', 'index'],
safeVersion: '0.3'
}
})).then(function (rendered) {
should.exist(rendered);
rendered.string.should.match(//);
rendered.string.should.match(//);
rendered.string.should.match(//);
rendered.string.should.match(//);
rendered.string.should.match(//);
rendered.string.should.match(//);
rendered.string.should.match(//);
rendered.string.should.match(//);
rendered.string.should.match(//);
rendered.string.should.match(//);
rendered.string.should.match(//);
rendered.string.should.match(//);
rendered.string.should.match(//);
rendered.string.should.match(//);
rendered.string.should.match(//);
rendered.string.should.match(//);
rendered.string.should.match(/