mirror of https://github.com/TryGhost/Ghost.git
1568 lines
92 KiB
JavaScript
1568 lines
92 KiB
JavaScript
const should = require('should'),
|
|
sinon = require('sinon'),
|
|
_ = require('lodash'),
|
|
moment = require('moment'),
|
|
testUtils = require('../../utils'),
|
|
configUtils = require('../../utils/configUtils'),
|
|
models = require('../../../server/models'),
|
|
routing = require('../../../server/services/routing'),
|
|
helpers = require('../../../server/helpers'),
|
|
proxy = require('../../../server/helpers/proxy'),
|
|
settingsCache = proxy.settingsCache,
|
|
sandbox = sinon.sandbox.create();
|
|
|
|
/**
|
|
* @TODO: this is not a full unit test. it's a half integration test, because we don't mock "getMetaData"!!
|
|
* either move to integration tests or rewrite!!!
|
|
*/
|
|
describe('{{ghost_head}} helper', function () {
|
|
let posts = [], tags = [], users = [];
|
|
|
|
before(function () {
|
|
testUtils.integrationTesting.defaultMocks(sandbox);
|
|
});
|
|
|
|
before(testUtils.teardown);
|
|
before(testUtils.setup('users:roles', 'posts'));
|
|
|
|
before(function () {
|
|
models.init();
|
|
|
|
sandbox.stub(routing.registry, 'getRssUrl').returns('http://localhost:65530/rss/');
|
|
|
|
settingsCache.get.withArgs('title').returns('Ghost');
|
|
settingsCache.get.withArgs('description').returns('blog description');
|
|
settingsCache.get.withArgs('cover_image').returns('/content/images/blog-cover.png');
|
|
settingsCache.get.withArgs('amp').returns(true);
|
|
|
|
return models.Post.add(testUtils.DataGenerator.forKnex.createPost({
|
|
meta_description: 'all about our blog',
|
|
title: 'About',
|
|
feature_image: '/content/images/test-image-about.png',
|
|
page: true,
|
|
authors: [testUtils.DataGenerator.forKnex.createUser({
|
|
profile_image: '/content/images/test-author-image.png',
|
|
website: 'http://authorwebsite.com',
|
|
facebook: 'testuser',
|
|
twitter: '@testuser',
|
|
})]
|
|
}), {withRelated: ['authors']}).then(function (post) {
|
|
posts.push(post.toJSON());
|
|
|
|
return models.Post.add(testUtils.DataGenerator.forKnex.createPost({
|
|
meta_description: 'all about our blog',
|
|
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: [testUtils.DataGenerator.forKnex.createUser({
|
|
profile_image: '/content/images/test-author-image.png',
|
|
website: 'http://authorwebsite.com',
|
|
facebook: 'testuser',
|
|
twitter: '@testuser'
|
|
})]
|
|
}), {withRelated: ['authors']});
|
|
}).then(function (post) {
|
|
posts.push(post.toJSON());
|
|
|
|
return models.Post.add(testUtils.DataGenerator.forKnex.createPost({
|
|
meta_description: 'blog 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: [
|
|
testUtils.DataGenerator.forKnex.createTag({name: 'tag1'}),
|
|
testUtils.DataGenerator.forKnex.createTag({name: 'tag2'}),
|
|
testUtils.DataGenerator.forKnex.createTag({name: 'tag3'})
|
|
],
|
|
authors: [testUtils.DataGenerator.forKnex.createUser({
|
|
name: 'Author name',
|
|
slug: 'author2',
|
|
profile_image: '/content/images/test-author-image.png',
|
|
website: 'http://authorwebsite.com',
|
|
bio: 'Author bio',
|
|
facebook: 'testuser',
|
|
twitter: '@testuser'
|
|
})]
|
|
}), {withRelated: ['authors', 'tags']});
|
|
}).then(function (post) {
|
|
posts.push(post.toJSON());
|
|
|
|
return models.Post.add(testUtils.DataGenerator.forKnex.createPost({
|
|
meta_description: 'blog 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: [
|
|
testUtils.DataGenerator.forKnex.createTag({name: 'tag1'}),
|
|
testUtils.DataGenerator.forKnex.createTag({name: 'tag2'}),
|
|
testUtils.DataGenerator.forKnex.createTag({name: 'tag3'})
|
|
],
|
|
authors: [
|
|
testUtils.DataGenerator.forKnex.createUser({
|
|
name: 'Author name',
|
|
url: 'http://testauthorurl.com',
|
|
slug: 'author3',
|
|
profile_image: '/content/images/test-author-image.png',
|
|
website: 'http://authorwebsite.com',
|
|
facebook: 'testuser',
|
|
twitter: '@testuser',
|
|
bio: 'Author bio'
|
|
})
|
|
]
|
|
}), {withRelated: ['authors', 'tags']});
|
|
}).then(function (post) {
|
|
posts.push(post.toJSON());
|
|
|
|
return models.Post.add(testUtils.DataGenerator.forKnex.createPost({
|
|
title: 'Welcome to Ghost',
|
|
mobiledoc: testUtils.DataGenerator.markdownToMobiledoc('This is a short post'),
|
|
authors: [
|
|
testUtils.DataGenerator.forKnex.createUser({
|
|
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'
|
|
})
|
|
]
|
|
}), {withRelated: ['authors', 'tags']});
|
|
}).then(function (post) {
|
|
posts.push(post.toJSON());
|
|
|
|
return models.Post.add(testUtils.DataGenerator.forKnex.createPost({
|
|
meta_description: 'blog 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: [
|
|
testUtils.DataGenerator.forKnex.createTag({name: 'tag1'}),
|
|
testUtils.DataGenerator.forKnex.createTag({name: 'tag2'}),
|
|
testUtils.DataGenerator.forKnex.createTag({name: 'tag3'})
|
|
],
|
|
authors: [
|
|
testUtils.DataGenerator.forKnex.createUser({
|
|
name: 'Author name',
|
|
url: 'http://testauthorurl.com',
|
|
slug: 'author5',
|
|
profile_image: '/content/images/test-author-image.png',
|
|
website: 'http://authorwebsite.com',
|
|
facebook: 'testuser',
|
|
twitter: '@testuser'
|
|
})
|
|
]
|
|
}), {withRelated: ['authors', 'tags']});
|
|
}).then(function (post) {
|
|
posts.push(post.toJSON());
|
|
|
|
return models.Post.add(testUtils.DataGenerator.forKnex.createPost({
|
|
meta_description: 'blog "test" description',
|
|
title: 'title',
|
|
meta_title: 'Welcome to Ghost "test"',
|
|
feature_image: '/content/images/test-image.png',
|
|
tags: [
|
|
testUtils.DataGenerator.forKnex.createTag({name: 'tag1'}),
|
|
testUtils.DataGenerator.forKnex.createTag({name: 'tag2'}),
|
|
testUtils.DataGenerator.forKnex.createTag({name: 'tag3'})
|
|
],
|
|
authors: [
|
|
testUtils.DataGenerator.forKnex.createUser({
|
|
name: 'Author name',
|
|
url: 'http://testauthorurl.com',
|
|
slug: 'author6',
|
|
profile_image: '/content/images/test-author-image.png',
|
|
website: 'http://authorwebsite.com',
|
|
facebook: 'testuser',
|
|
twitter: '@testuser'
|
|
})
|
|
]
|
|
}), {withRelated: ['authors', 'tags']});
|
|
}).then(function (post) {
|
|
posts.push(post.toJSON());
|
|
|
|
return models.Post.add(testUtils.DataGenerator.forKnex.createPost({
|
|
meta_description: 'blog description',
|
|
title: 'Welcome to Ghost',
|
|
feature_image: '/content/images/test-image.png',
|
|
tags: [],
|
|
authors: [
|
|
testUtils.DataGenerator.forKnex.createUser({
|
|
name: 'Author name',
|
|
url: 'http://testauthorurl.com',
|
|
slug: 'author7',
|
|
profile_image: '/content/images/test-author-image.png',
|
|
website: 'http://authorwebsite.com',
|
|
facebook: 'testuser',
|
|
twitter: '@testuser'
|
|
})
|
|
]
|
|
}), {withRelated: ['authors', 'tags']});
|
|
}).then(function (post) {
|
|
posts.push(post.toJSON());
|
|
|
|
return models.Post.add(testUtils.DataGenerator.forKnex.createPost({
|
|
meta_description: 'blog description',
|
|
title: 'Welcome to Ghost',
|
|
feature_image: null,
|
|
tags: [
|
|
testUtils.DataGenerator.forKnex.createTag({name: 'tag1'}),
|
|
testUtils.DataGenerator.forKnex.createTag({name: 'tag2'}),
|
|
testUtils.DataGenerator.forKnex.createTag({name: 'tag3'})
|
|
],
|
|
authors: [
|
|
testUtils.DataGenerator.forKnex.createUser({
|
|
name: 'Author name',
|
|
url: 'http://testauthorurl.com',
|
|
slug: 'author8',
|
|
profile_image: null,
|
|
website: 'http://authorwebsite.com',
|
|
facebook: 'testuser',
|
|
twitter: '@testuser'
|
|
})
|
|
]
|
|
}), {withRelated: ['authors', 'tags']});
|
|
}).then(function (post) {
|
|
posts.push(post.toJSON());
|
|
|
|
return models.Post.add(testUtils.DataGenerator.forKnex.createPost({
|
|
title: 'Welcome to Ghost',
|
|
mobiledoc: testUtils.DataGenerator.markdownToMobiledoc('This is a short post'),
|
|
tags: [
|
|
testUtils.DataGenerator.forKnex.createTag({name: 'tag1'}),
|
|
testUtils.DataGenerator.forKnex.createTag({name: 'tag2'}),
|
|
testUtils.DataGenerator.forKnex.createTag({name: 'tag3'})
|
|
],
|
|
authors: [
|
|
testUtils.DataGenerator.forKnex.createUser({
|
|
name: 'Author name'
|
|
})
|
|
]
|
|
}), {withRelated: ['authors', 'tags']});
|
|
}).then(function (post) {
|
|
posts.push(post.toJSON());
|
|
|
|
return models.Tag.add(testUtils.DataGenerator.forKnex.createTag({
|
|
meta_description: 'tag meta description',
|
|
name: 'tagtitle',
|
|
meta_title: 'tag meta title',
|
|
feature_image: '/content/images/tag-image.png'
|
|
}));
|
|
}).then(function (tag) {
|
|
tags.push(tag.toJSON());
|
|
|
|
return models.Tag.add(testUtils.DataGenerator.forKnex.createTag({
|
|
meta_description: '',
|
|
description: 'tag description',
|
|
name: 'tagtitle',
|
|
meta_title: '',
|
|
feature_image: '/content/images/tag-image.png'
|
|
}));
|
|
}).then(function (tag) {
|
|
tags.push(tag.toJSON());
|
|
|
|
return models.Tag.add(testUtils.DataGenerator.forKnex.createTag({
|
|
meta_description: '',
|
|
name: 'tagtitle',
|
|
meta_title: '',
|
|
feature_image: '/content/images/tag-image.png'
|
|
}));
|
|
}).then(function (tag) {
|
|
tags.push(tag.toJSON());
|
|
|
|
return models.Tag.add(testUtils.DataGenerator.forKnex.createTag({
|
|
meta_description: 'tag meta description',
|
|
title: 'tagtitle',
|
|
meta_title: 'tag meta title',
|
|
feature_image: '/content/images/tag-image.png'
|
|
}));
|
|
}).then(function (tag) {
|
|
tags.push(tag.toJSON());
|
|
|
|
return models.User.add(testUtils.DataGenerator.forKnex.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'
|
|
}));
|
|
}).then(function (user) {
|
|
users.push(user.toJSON());
|
|
|
|
return models.User.add(testUtils.DataGenerator.forKnex.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'
|
|
}));
|
|
}).then(function (user) {
|
|
users.push(user.toJSON());
|
|
}).finally(function () {
|
|
return testUtils.integrationTesting.urlService.init();
|
|
});
|
|
});
|
|
|
|
after(function () {
|
|
testUtils.integrationTesting.urlService.resetGenerators();
|
|
sandbox.restore();
|
|
configUtils.restore();
|
|
});
|
|
|
|
describe('without Code Injection', function () {
|
|
before(function () {
|
|
configUtils.set('url', 'http://localhost:65530/');
|
|
});
|
|
|
|
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(/<link rel="shortcut icon" href="\/favicon.ico" type="image\/x-icon" \/>/);
|
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/localhost:65530\/page\/2\/" \/>/);
|
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/localhost:65530\/rss\/" \/>/);
|
|
rendered.string.should.not.match(/<meta name="description"/);
|
|
rendered.string.should.not.match(/<meta property="og/);
|
|
rendered.string.should.not.match(/<script type=\"application\/ld\+json\">/);
|
|
|
|
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(/<link rel="shortcut icon" href="\/favicon.ico" type="image\/x-icon" \/>/);
|
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/localhost:65530\/" \/>/);
|
|
rendered.string.should.match(/<meta name="referrer" content="no-referrer-when-downgrade" \/>/);
|
|
rendered.string.should.match(/<meta name="description" content="blog description" \/>/);
|
|
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
|
rendered.string.should.match(/<meta property="og:type" content="website" \/>/);
|
|
rendered.string.should.match(/<meta property="og:title" content="Ghost" \/>/);
|
|
rendered.string.should.match(/<meta property="og:description" content="blog description" \/>/);
|
|
rendered.string.should.match(/<meta property="og:url" content="http:\/\/localhost:65530\/" \/>/);
|
|
rendered.string.should.match(/<meta property="og:image" content="http:\/\/localhost:65530\/content\/images\/blog-cover.png" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:card" content="summary_large_image" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:title" content="Ghost" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:description" content="blog description" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:url" content="http:\/\/localhost:65530\/" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:image" content="http:\/\/localhost:65530\/content\/images\/blog-cover.png" \/>/);
|
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/localhost:65530\/rss\/" \/>/);
|
|
rendered.string.should.match(/<script type=\"application\/ld\+json\">/);
|
|
rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
|
|
rendered.string.should.match(/"@type": "WebSite"/);
|
|
rendered.string.should.match(/"publisher": {\n "@type": "Organization",\n "name": "Ghost",/);
|
|
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/"/);
|
|
rendered.string.should.match(/"image": "http:\/\/localhost:65530\/content\/images\/blog-cover.png"/);
|
|
rendered.string.should.match(/"description": "blog description"/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('returns structured data on static page', function (done) {
|
|
var renderObject = {
|
|
post: posts[0]
|
|
};
|
|
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: renderObject,
|
|
locals: {
|
|
relativeUrl: '/about/',
|
|
context: ['page'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/favicon.ico" type="image\/x-icon" \/>/);
|
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/localhost:65530\/about\/" \/>/);
|
|
rendered.string.should.match(/<meta name="referrer" content="no-referrer-when-downgrade" \/>/);
|
|
rendered.string.should.match(/<meta name="description" content="all about our blog" \/>/);
|
|
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
|
rendered.string.should.match(/<meta property="og:type" content="website" \/>/);
|
|
rendered.string.should.match(/<meta property="og:title" content="About" \/>/);
|
|
rendered.string.should.match(/<meta property="og:description" content="all about our blog" \/>/);
|
|
rendered.string.should.match(/<meta property="og:url" content="http:\/\/localhost:65530\/about\/" \/>/);
|
|
rendered.string.should.match(/<meta property="og:image" content="http:\/\/localhost:65530\/content\/images\/test-image-about.png" \/>/);
|
|
rendered.string.should.match(/<meta property="article:author" content="https:\/\/www.facebook.com\/testuser" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:card" content="summary_large_image" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:title" content="About" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:creator" content="@testuser" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:description" content="all about our blog" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:url" content="http:\/\/localhost:65530\/about\/" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:image" content="http:\/\/localhost:65530\/content\/images\/test-image-about.png" \/>/);
|
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/localhost:65530\/rss\/" \/>/);
|
|
rendered.string.should.match(/<script type=\"application\/ld\+json\">/);
|
|
rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
|
|
rendered.string.should.match(/"@type": "Article"/);
|
|
rendered.string.should.match(/"publisher": {/);
|
|
rendered.string.should.match(/"@type": "Organization"/);
|
|
rendered.string.should.match(/"name": "Ghost"/);
|
|
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/about\/"/);
|
|
rendered.string.should.match(/"sameAs": \[\n "http:\/\/authorwebsite.com",\n "https:\/\/www.facebook.com\/testuser",\n "https:\/\/twitter.com\/testuser"\n \]/);
|
|
rendered.string.should.match(/"image": "http:\/\/localhost:65530\/content\/images\/test-image-about.png"/);
|
|
rendered.string.should.match(/"image\": \"http:\/\/localhost:65530\/content\/images\/test-author-image.png\"/);
|
|
rendered.string.should.match(/"description": "all about our blog"/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('returns structured data on static page with custom post structured data', function (done) {
|
|
var renderObject = {
|
|
post: posts[1]
|
|
};
|
|
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: renderObject,
|
|
locals: {
|
|
relativeUrl: '/about/',
|
|
context: ['page'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/favicon.ico" type="image\/x-icon" \/>/);
|
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/localhost:65530\/about\/" \/>/);
|
|
rendered.string.should.match(/<meta name="referrer" content="no-referrer-when-downgrade" \/>/);
|
|
rendered.string.should.match(/<meta name="description" content="all about our blog" \/>/);
|
|
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
|
rendered.string.should.match(/<meta property="og:type" content="website" \/>/);
|
|
rendered.string.should.match(/<meta property="og:title" content="Custom Facebook title" \/>/);
|
|
rendered.string.should.match(/<meta property="og:description" content="Custom Facebook description" \/>/);
|
|
rendered.string.should.match(/<meta property="og:url" content="http:\/\/localhost:65530\/about\/" \/>/);
|
|
rendered.string.should.match(/<meta property="og:image" content="http:\/\/localhost:65530\/content\/images\/test-og-image.png" \/>/);
|
|
rendered.string.should.match(/<meta property="article:author" content="https:\/\/www.facebook.com\/testuser" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:card" content="summary_large_image" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:title" content="Custom Twitter title" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:creator" content="@testuser" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:description" content="Custom Twitter description" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:url" content="http:\/\/localhost:65530\/about\/" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:image" content="http:\/\/localhost:65530\/content\/images\/test-twitter-image.png" \/>/);
|
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/localhost:65530\/rss\/" \/>/);
|
|
rendered.string.should.match(/<script type=\"application\/ld\+json\">/);
|
|
rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
|
|
rendered.string.should.match(/"@type": "Article"/);
|
|
rendered.string.should.match(/"publisher": {/);
|
|
rendered.string.should.match(/"@type": "Organization"/);
|
|
rendered.string.should.match(/"name": "Ghost"/);
|
|
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/about\/"/);
|
|
rendered.string.should.match(/"sameAs": \[\n "http:\/\/authorwebsite.com",\n "https:\/\/www.facebook.com\/testuser",\n "https:\/\/twitter.com\/testuser"\n \]/);
|
|
rendered.string.should.match(/"image": "http:\/\/localhost:65530\/content\/images\/test-image-about.png"/);
|
|
rendered.string.should.match(/"image\": \"http:\/\/localhost:65530\/content\/images\/test-author-image.png\"/);
|
|
rendered.string.should.match(/"description": "all about our blog"/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('returns structured data on post page with author image and post cover image', function (done) {
|
|
var renderObject = {
|
|
post: posts[2]
|
|
}, postBk = _.cloneDeep(renderObject.post);
|
|
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: renderObject,
|
|
locals: {
|
|
relativeUrl: '/post/',
|
|
context: ['post'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
var re1 = new RegExp('<meta property="article:published_time" content="' + new Date(renderObject.post.published_at).toISOString()),
|
|
re2 = new RegExp('<meta property="article:modified_time" content="' + new Date(renderObject.post.updated_at).toISOString()),
|
|
re3 = new RegExp('"datePublished": "' + new Date(renderObject.post.published_at).toISOString()),
|
|
re4 = new RegExp('"dateModified": "' + new Date(renderObject.post.updated_at).toISOString());
|
|
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/favicon.ico" type="image\/x-icon" \/>/);
|
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/localhost:65530\/post\/" \/>/);
|
|
rendered.string.should.match(/<link rel="amphtml" href="http:\/\/localhost:65530\/post\/amp\/" \/>/);
|
|
rendered.string.should.match(/<meta name="description" content="blog description" \/>/);
|
|
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
|
rendered.string.should.match(/<meta property="og:type" content="article" \/>/);
|
|
rendered.string.should.match(/<meta property="og:title" content="Custom Facebook title" \/>/);
|
|
rendered.string.should.match(/<meta property="og:description" content="Custom Facebook description" \/>/);
|
|
rendered.string.should.match(/<meta property="og:url" content="http:\/\/localhost:65530\/post\/" \/>/);
|
|
rendered.string.should.match(/<meta property="og:image" content="http:\/\/localhost:65530\/content\/images\/test-image.png" \/>/);
|
|
rendered.string.should.match(re1);
|
|
rendered.string.should.match(re2);
|
|
rendered.string.should.match(/<meta property="article:tag" content="tag1" \/>/);
|
|
rendered.string.should.match(/<meta property="article:tag" content="tag2" \/>/);
|
|
rendered.string.should.match(/<meta property="article:tag" content="tag3" \/>/);
|
|
rendered.string.should.match(/<meta property="article:author" content="https:\/\/www.facebook.com\/testuser" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:title" content="Welcome to Ghost" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:description" content="blog description" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:url" content="http:\/\/localhost:65530\/post\/" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:image" content="http:\/\/localhost:65530\/content\/images\/test-twitter-image.png" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:creator" content="@testuser" \/>/);
|
|
rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
|
|
rendered.string.should.match(/"@type": "Article"/);
|
|
rendered.string.should.match(/"publisher": {/);
|
|
rendered.string.should.match(/"@type": "Organization"/);
|
|
rendered.string.should.match(/"name": "Ghost"/);
|
|
rendered.string.should.match(/"author": {/);
|
|
rendered.string.should.match(/"@type": "Person"/);
|
|
rendered.string.should.match(/"name": "Author name"/);
|
|
rendered.string.should.match(/"image\": \"http:\/\/localhost:65530\/content\/images\/test-author-image.png\"/);
|
|
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/author\/author2\/"/);
|
|
rendered.string.should.match(/"sameAs": \[\n "http:\/\/authorwebsite.com",\n "https:\/\/www.facebook.com\/testuser",\n "https:\/\/twitter.com\/testuser"\n \]/);
|
|
rendered.string.should.not.match(/"description": "Author bio"/);
|
|
rendered.string.should.match(/"headline": "Welcome to Ghost"/);
|
|
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/post\/"/);
|
|
rendered.string.should.match(re3);
|
|
rendered.string.should.match(re4);
|
|
rendered.string.should.match(/"image": "http:\/\/localhost:65530\/content\/images\/test-image.png"/);
|
|
rendered.string.should.match(/"keywords": "tag1, tag2, tag3"/);
|
|
rendered.string.should.match(/"description": "blog description"/);
|
|
rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
|
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/localhost:65530\/rss\/" \/>/);
|
|
|
|
renderObject.post.should.eql(postBk);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('returns structured data on post page with custom excerpt for description and meta description', function (done) {
|
|
var renderObject = {
|
|
post: posts[3]
|
|
}, postBk = _.cloneDeep(renderObject.post);
|
|
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: renderObject,
|
|
locals: {
|
|
relativeUrl: '/post/',
|
|
context: ['post'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/favicon.ico" type="image\/x-icon" \/>/);
|
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/localhost:65530\/post\/" \/>/);
|
|
rendered.string.should.match(/<link rel="amphtml" href="http:\/\/localhost:65530\/post\/amp\/" \/>/);
|
|
rendered.string.should.match(/<meta name="description" content="blog description" \/>/);
|
|
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
|
rendered.string.should.match(/<meta property="og:type" content="article" \/>/);
|
|
rendered.string.should.match(/<meta property="og:title" content="Welcome to Ghost" \/>/);
|
|
rendered.string.should.match(/<meta property="og:description" content="post custom excerpt" \/>/);
|
|
rendered.string.should.match(/<meta property="og:url" content="http:\/\/localhost:65530\/post\/" \/>/);
|
|
rendered.string.should.match(/<meta property="og:image" content="http:\/\/localhost:65530\/content\/images\/test-facebook-image.png" \/>/);
|
|
rendered.string.should.match(/<meta property="article:tag" content="tag1" \/>/);
|
|
rendered.string.should.match(/<meta property="article:tag" content="tag2" \/>/);
|
|
rendered.string.should.match(/<meta property="article:tag" content="tag3" \/>/);
|
|
rendered.string.should.match(/<meta property="article:author" content="https:\/\/www.facebook.com\/testuser" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:title" content="Custom Twitter title" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:description" content="post custom excerpt" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:url" content="http:\/\/localhost:65530\/post\/" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:image" content="http:\/\/localhost:65530\/content\/images\/test-twitter-image.png" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:creator" content="@testuser" \/>/);
|
|
rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
|
|
rendered.string.should.match(/"@type": "Article"/);
|
|
rendered.string.should.match(/"publisher": {/);
|
|
rendered.string.should.match(/"@type": "Organization"/);
|
|
rendered.string.should.match(/"name": "Ghost"/);
|
|
rendered.string.should.match(/"author": {/);
|
|
rendered.string.should.match(/"@type": "Person"/);
|
|
rendered.string.should.match(/"name": "Author name"/);
|
|
rendered.string.should.match(/"image\": \"http:\/\/localhost:65530\/content\/images\/test-author-image.png\"/);
|
|
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/author\/author3\/"/);
|
|
rendered.string.should.match(/"sameAs": \[\n "http:\/\/authorwebsite.com",\n "https:\/\/www.facebook.com\/testuser",\n "https:\/\/twitter.com\/testuser"\n \]/);
|
|
rendered.string.should.not.match(/"description": "Author bio"/);
|
|
rendered.string.should.match(/"headline": "Welcome to Ghost"/);
|
|
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/post\/"/);
|
|
rendered.string.should.match(/"image": "http:\/\/localhost:65530\/content\/images\/test-image.png"/);
|
|
rendered.string.should.match(/"keywords": "tag1, tag2, tag3"/);
|
|
rendered.string.should.match(/"description": "post custom excerpt"/);
|
|
rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
|
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/localhost:65530\/rss\/" \/>/);
|
|
|
|
renderObject.post.should.eql(postBk);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('returns structured data on post page with fall back excerpt if no meta description provided', function (done) {
|
|
var renderObject = {
|
|
post: posts[4]
|
|
}, postBk = _.cloneDeep(renderObject.post);
|
|
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: renderObject,
|
|
locals: {
|
|
relativeUrl: '/post/',
|
|
context: ['post'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/favicon.ico" type="image\/x-icon" \/>/);
|
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/localhost:65530\/post\/" \/>/);
|
|
rendered.string.should.match(/<link rel="amphtml" href="http:\/\/localhost:65530\/post\/amp\/" \/>/);
|
|
rendered.string.should.not.match(/<meta name="description" content="blog description" \/>/);
|
|
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
|
rendered.string.should.match(/<meta property="og:type" content="article" \/>/);
|
|
rendered.string.should.match(/<meta property="og:title" content="Welcome to Ghost" \/>/);
|
|
rendered.string.should.match(/<meta property="og:description" content="This is a short post" \/>/);
|
|
rendered.string.should.match(/<meta property="og:url" content="http:\/\/localhost:65530\/post\/" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:title" content="Welcome to Ghost" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:description" content="This is a short post" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:url" content="http:\/\/localhost:65530\/post\/" \/>/);
|
|
rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
|
|
rendered.string.should.match(/"@type": "Article"/);
|
|
rendered.string.should.match(/"publisher": {/);
|
|
rendered.string.should.match(/"@type": "Organization"/);
|
|
rendered.string.should.match(/"name": "Ghost"/);
|
|
rendered.string.should.match(/"author": {/);
|
|
rendered.string.should.match(/"@type": "Person"/);
|
|
rendered.string.should.match(/"name": "Author name"/);
|
|
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/author\/author4\/"/);
|
|
rendered.string.should.not.match(/"description": "Author bio"/);
|
|
rendered.string.should.match(/"headline": "Welcome to Ghost"/);
|
|
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/post\/"/);
|
|
rendered.string.should.match(/"description": "This is a short post"/);
|
|
rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
|
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/localhost:65530\/rss\/" \/>/);
|
|
|
|
renderObject.post.should.eql(postBk);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('returns structured data on AMP post page with author image and post cover image', function (done) {
|
|
var renderObject = {
|
|
post: posts[5]
|
|
}, postBk = _.cloneDeep(renderObject.post);
|
|
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: renderObject,
|
|
locals: {
|
|
relativeUrl: '/post/amp/',
|
|
context: ['amp', 'post'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/favicon.ico" type="image\/x-icon" \/>/);
|
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/localhost:65530\/post\/" \/>/);
|
|
rendered.string.should.not.match(/<link rel="amphtml" href="http:\/\/localhost:65530\/post\/amp\/" \/>/);
|
|
rendered.string.should.match(/<meta name="description" content="blog description" \/>/);
|
|
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
|
rendered.string.should.match(/<meta property="og:type" content="article" \/>/);
|
|
rendered.string.should.match(/<meta property="og:title" content="Custom Facebook title" \/>/);
|
|
rendered.string.should.match(/<meta property="og:description" content="blog description" \/>/);
|
|
rendered.string.should.match(/<meta property="og:url" content="http:\/\/localhost:65530\/post\/" \/>/);
|
|
rendered.string.should.match(/<meta property="og:image" content="http:\/\/localhost:65530\/content\/images\/test-facebook-image.png" \/>/);
|
|
rendered.string.should.match(/<meta property="article:tag" content="tag1" \/>/);
|
|
rendered.string.should.match(/<meta property="article:tag" content="tag2" \/>/);
|
|
rendered.string.should.match(/<meta property="article:tag" content="tag3" \/>/);
|
|
rendered.string.should.match(/<meta property="article:author" content="https:\/\/www.facebook.com\/testuser" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:title" content="Custom Twitter title" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:description" content="blog description" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:url" content="http:\/\/localhost:65530\/post\/" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:image" content="http:\/\/localhost:65530\/content\/images\/test-twitter-image.png" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:creator" content="@testuser" \/>/);
|
|
rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
|
|
rendered.string.should.match(/"@type": "Article"/);
|
|
rendered.string.should.match(/"publisher": {/);
|
|
rendered.string.should.match(/"@type": "Organization"/);
|
|
rendered.string.should.match(/"name": "Ghost"/);
|
|
rendered.string.should.match(/"author": {/);
|
|
rendered.string.should.match(/"@type": "Person"/);
|
|
rendered.string.should.match(/"name": "Author name"/);
|
|
rendered.string.should.match(/"image\": \"http:\/\/localhost:65530\/content\/images\/test-author-image.png\"/);
|
|
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/author\/author5\/"/);
|
|
rendered.string.should.match(/"sameAs": \[\n "http:\/\/authorwebsite.com",\n "https:\/\/www.facebook.com\/testuser",\n "https:\/\/twitter.com\/testuser"\n \]/);
|
|
rendered.string.should.not.match(/"description": "Author bio"/);
|
|
rendered.string.should.match(/"headline": "Welcome to Ghost"/);
|
|
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/post\/"/);
|
|
rendered.string.should.match(/"image": "http:\/\/localhost:65530\/content\/images\/test-image.png"/);
|
|
rendered.string.should.match(/"keywords": "tag1, tag2, tag3"/);
|
|
rendered.string.should.match(/"description": "blog description"/);
|
|
rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
|
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/localhost:65530\/rss\/" \/>/);
|
|
|
|
renderObject.post.should.eql(postBk);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('returns structured data if metaTitle and metaDescription have double quotes', function (done) {
|
|
var renderObject = {
|
|
post: posts[6]
|
|
};
|
|
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: renderObject,
|
|
locals: {
|
|
relativeUrl: '/post/',
|
|
context: ['post'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/favicon.ico" type="image\/x-icon" \/>/);
|
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/localhost:65530\/post\/" \/>/);
|
|
rendered.string.should.match(/<link rel="amphtml" href="http:\/\/localhost:65530\/post\/amp\/" \/>/);
|
|
rendered.string.should.match(/<meta name="description" content="blog "test" description" \/>/);
|
|
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
|
rendered.string.should.match(/<meta property="og:type" content="article" \/>/);
|
|
rendered.string.should.match(/<meta property="og:title" content="Welcome to Ghost "test"" \/>/);
|
|
rendered.string.should.match(/<meta property="og:description" content="blog "test" description" \/>/);
|
|
rendered.string.should.match(/<meta property="og:url" content="http:\/\/localhost:65530\/post\/" \/>/);
|
|
rendered.string.should.match(/<meta property="og:image" content="http:\/\/localhost:65530\/content\/images\/test-image.png" \/>/);
|
|
rendered.string.should.match(/<meta property="article:author" content="https:\/\/www.facebook.com\/testuser" \/>/);
|
|
rendered.string.should.match(/<meta property="article:tag" content="tag1" \/>/);
|
|
rendered.string.should.match(/<meta property="article:tag" content="tag2" \/>/);
|
|
rendered.string.should.match(/<meta property="article:tag" content="tag3" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:card" content="summary_large_image" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:title" content="Welcome to Ghost "test"" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:description" content="blog "test" description" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:url" content="http:\/\/localhost:65530\/post\/" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:creator" content="@testuser" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:image" content="http:\/\/localhost:65530\/content\/images\/test-image.png" \/>/);
|
|
rendered.string.should.match(/<script type=\"application\/ld\+json\">/);
|
|
rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
|
|
rendered.string.should.match(/"@type": "Article"/);
|
|
rendered.string.should.match(/"publisher": {/);
|
|
rendered.string.should.match(/"@type": "Organization"/);
|
|
rendered.string.should.match(/"name": "Ghost"/);
|
|
rendered.string.should.match(/"author": {/);
|
|
rendered.string.should.match(/"@type": "Person"/);
|
|
rendered.string.should.match(/"name": "Author name"/);
|
|
rendered.string.should.match(/"image\": \"http:\/\/localhost:65530\/content\/images\/test-author-image.png\"/);
|
|
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/author\/author6\/"/);
|
|
rendered.string.should.match(/"sameAs": \[\n "http:\/\/authorwebsite.com",\n "https:\/\/www.facebook.com\/testuser",\n "https:\/\/twitter.com\/testuser"\n \]/);
|
|
rendered.string.should.match(/"headline": "Welcome to Ghost "test""/);
|
|
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/post\/"/);
|
|
rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
|
|
rendered.string.should.match(/"image": "http:\/\/localhost:65530\/content\/images\/test-image.png"/);
|
|
rendered.string.should.match(/"keywords": "tag1, tag2, tag3"/);
|
|
rendered.string.should.match(/"description": "blog "test" description"/);
|
|
rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
|
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/localhost:65530\/rss\/" \/>/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('returns structured data without tags if there are no tags', function (done) {
|
|
var renderObject = {
|
|
post: posts[7]
|
|
};
|
|
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: renderObject,
|
|
locals: {
|
|
relativeUrl: '/post/',
|
|
context: ['post'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/favicon.ico" type="image\/x-icon" \/>/);
|
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/localhost:65530\/post\/" \/>/);
|
|
rendered.string.should.match(/<link rel="amphtml" href="http:\/\/localhost:65530\/post\/amp\/" \/>/);
|
|
rendered.string.should.match(/<meta name="description" content="blog description" \/>/);
|
|
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
|
rendered.string.should.match(/<meta property="og:type" content="article" \/>/);
|
|
rendered.string.should.match(/<meta property="og:title" content="Welcome to Ghost" \/>/);
|
|
rendered.string.should.match(/<meta property="og:description" content="blog description" \/>/);
|
|
rendered.string.should.match(/<meta property="og:url" content="http:\/\/localhost:65530\/post\/" \/>/);
|
|
rendered.string.should.match(/<meta property="og:image" content="http:\/\/localhost:65530\/content\/images\/test-image.png" \/>/);
|
|
rendered.string.should.match(/<meta property="article:author" content="https:\/\/www.facebook.com\/testuser" \/>/);
|
|
rendered.string.should.not.match(/<meta property="article:tag"/);
|
|
rendered.string.should.match(/<meta name="twitter:card" content="summary_large_image" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:title" content="Welcome to Ghost" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:description" content="blog description" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:url" content="http:\/\/localhost:65530\/post\/" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:image" content="http:\/\/localhost:65530\/content\/images\/test-image.png" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:creator" content="@testuser" \/>/);
|
|
rendered.string.should.match(/<script type=\"application\/ld\+json\">/);
|
|
rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
|
|
rendered.string.should.match(/"@type": "Article"/);
|
|
rendered.string.should.match(/"publisher": {/);
|
|
rendered.string.should.match(/"@type": "Organization"/);
|
|
rendered.string.should.match(/"author": {/);
|
|
rendered.string.should.match(/"@type": "Person"/);
|
|
rendered.string.should.match(/"name": "Author name"/);
|
|
rendered.string.should.match(/"image\": \"http:\/\/localhost:65530\/content\/images\/test-author-image.png\"/);
|
|
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/author\/author7\/"/);
|
|
rendered.string.should.match(/"sameAs": \[\n "http:\/\/authorwebsite.com",\n "https:\/\/www.facebook.com\/testuser",\n "https:\/\/twitter.com\/testuser"\n \]/);
|
|
rendered.string.should.match(/"headline": "Welcome to Ghost"/);
|
|
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/post\/"/);
|
|
rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
|
|
rendered.string.should.match(/"image": "http:\/\/localhost:65530\/content\/images\/test-image.png"/);
|
|
rendered.string.should.not.match(/"keywords":/);
|
|
rendered.string.should.match(/"description": "blog description"/);
|
|
rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
|
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/localhost:65530\/rss\/" \/>/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('returns structured data on post page with null author image and post cover image', function (done) {
|
|
var renderObject = {
|
|
post: posts[8]
|
|
};
|
|
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: renderObject,
|
|
locals: {
|
|
relativeUrl: '/post/',
|
|
context: ['post'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/favicon.ico" type="image\/x-icon" \/>/);
|
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/localhost:65530\/post\/" \/>/);
|
|
rendered.string.should.match(/<link rel="amphtml" href="http:\/\/localhost:65530\/post\/amp\/" \/>/);
|
|
rendered.string.should.match(/<meta name="description" content="blog description" \/>/);
|
|
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
|
rendered.string.should.match(/<meta property="og:type" content="article" \/>/);
|
|
rendered.string.should.match(/<meta property="og:title" content="Welcome to Ghost" \/>/);
|
|
rendered.string.should.match(/<meta property="og:description" content="blog description" \/>/);
|
|
rendered.string.should.match(/<meta property="og:url" content="http:\/\/localhost:65530\/post\/" \/>/);
|
|
rendered.string.should.match(/<meta property="article:author" content="https:\/\/www.facebook.com\/testuser" \/>/);
|
|
rendered.string.should.not.match(/<meta property="og:image"/);
|
|
rendered.string.should.match(/<meta property="article:tag" content="tag1" \/>/);
|
|
rendered.string.should.match(/<meta property="article:tag" content="tag2" \/>/);
|
|
rendered.string.should.match(/<meta property="article:tag" content="tag3" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:card" content="summary" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:title" content="Welcome to Ghost" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:description" content="blog description" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:url" content="http:\/\/localhost:65530\/post\/" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:creator" content="@testuser" \/>/);
|
|
rendered.string.should.not.match(/<meta name="twitter:image"/);
|
|
rendered.string.should.match(/<script type=\"application\/ld\+json\">/);
|
|
rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
|
|
rendered.string.should.match(/"@type": "Article"/);
|
|
rendered.string.should.match(/"publisher": {/);
|
|
rendered.string.should.match(/"@type": "Organization"/);
|
|
rendered.string.should.match(/"name": "Ghost"/);
|
|
rendered.string.should.match(/"author": {/);
|
|
rendered.string.should.match(/"@type": "Person"/);
|
|
rendered.string.should.match(/"name": "Author name"/);
|
|
rendered.string.should.not.match(/"image\"/);
|
|
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/author\/author8\/"/);
|
|
rendered.string.should.match(/"sameAs": \[\n "http:\/\/authorwebsite.com",\n "https:\/\/www.facebook.com\/testuser",\n "https:\/\/twitter.com\/testuser"\n \]/);
|
|
rendered.string.should.match(/"headline": "Welcome to Ghost"/);
|
|
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/post\/"/);
|
|
rendered.string.should.match(/"keywords": "tag1, tag2, tag3"/);
|
|
rendered.string.should.match(/"description": "blog description"/);
|
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/localhost:65530\/rss\/" \/>/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('returns twitter and facebook descriptions even if no meta description available', function (done) {
|
|
var renderObject = {
|
|
post: posts[9]
|
|
};
|
|
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: renderObject,
|
|
locals: {
|
|
relativeUrl: '/post/',
|
|
context: ['post'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.not.match(/<meta name="description" /);
|
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/favicon.ico" type="image\/x-icon" \/>/);
|
|
rendered.string.should.match(/<link rel="amphtml" href="http:\/\/localhost:65530\/post\/amp\/" \/>/);
|
|
rendered.string.should.match(/<meta property="og:description" content="This is a short post" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:description" content="This is a short post" \/>/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('returns canonical URL', function (done) {
|
|
var renderObject = {
|
|
post: posts[9]
|
|
};
|
|
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: renderObject,
|
|
locals: {
|
|
relativeUrl: '/about/',
|
|
context: ['page'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/favicon.ico" type="image\/x-icon" \/>/);
|
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/localhost:65530\/about\/" \/>/);
|
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/localhost:65530\/rss\/" \/>/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('returns next & prev URL correctly for middle page', function (done) {
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: {
|
|
pagination: {total: 4, page: 3, next: 4, prev: 2}
|
|
},
|
|
locals: {
|
|
relativeUrl: '/page/3/',
|
|
context: ['paged', 'index'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/favicon.ico" type="image\/x-icon" \/>/);
|
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/localhost:65530\/page\/3\/" \/>/);
|
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
|
rendered.string.should.match(/<link rel="prev" href="http:\/\/localhost:65530\/page\/2\/" \/>/);
|
|
rendered.string.should.match(/<link rel="next" href="http:\/\/localhost:65530\/page\/4\/" \/>/);
|
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/localhost:65530\/rss\/" \/>/);
|
|
rendered.string.should.not.match(/<meta property="og/);
|
|
rendered.string.should.not.match(/<script type=\"application\/ld\+json\">/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('returns next & prev URL correctly for second page', function (done) {
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: {
|
|
pagination: {total: 3, page: 2, next: 3, prev: 1}
|
|
},
|
|
locals: {
|
|
relativeUrl: '/page/2/',
|
|
context: ['paged', 'index'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/favicon.ico" type="image\/x-icon" \/>/);
|
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/localhost:65530\/page\/2\/" \/>/);
|
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
|
rendered.string.should.match(/<link rel="prev" href="http:\/\/localhost:65530\/" \/>/);
|
|
rendered.string.should.match(/<link rel="next" href="http:\/\/localhost:65530\/page\/3\/" \/>/);
|
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/localhost:65530\/rss\/" \/>/);
|
|
rendered.string.should.not.match(/<meta property="og/);
|
|
rendered.string.should.not.match(/<meta name="description" /);
|
|
rendered.string.should.not.match(/<script type=\"application\/ld\+json\">/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('returns structured data and schema first tag page with meta description and meta title', function (done) {
|
|
var renderObject = {
|
|
tag: tags[0]
|
|
};
|
|
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: renderObject,
|
|
locals: {
|
|
relativeUrl: '/tag/tagtitle/',
|
|
context: ['tag'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/favicon.ico" type="image\/x-icon" \/>/);
|
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/localhost:65530\/tag\/tagtitle\/" \/>/);
|
|
rendered.string.should.match(/<meta name="description" content="tag meta description" \/>/);
|
|
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
|
rendered.string.should.match(/<meta property="og:type" content="website" \/>/);
|
|
rendered.string.should.match(/<meta property="og:title" content="tag meta title" \/>/);
|
|
rendered.string.should.match(/<meta property="og:description" content="tag meta description" \/>/);
|
|
rendered.string.should.match(/<meta property="og:url" content="http:\/\/localhost:65530\/tag\/tagtitle\/" \/>/);
|
|
rendered.string.should.match(/<meta property="og:image" content="http:\/\/localhost:65530\/content\/images\/tag-image.png" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:card" content="summary_large_image" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:title" content="tag meta title" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:description" content="tag meta description" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:url" content="http:\/\/localhost:65530\/tag\/tagtitle\/" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:image" content="http:\/\/localhost:65530\/content\/images\/tag-image.png" \/>/);
|
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/localhost:65530\/rss\/" \/>/);
|
|
rendered.string.should.match(/<script type=\"application\/ld\+json\">/);
|
|
rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
|
|
rendered.string.should.match(/"@type": "Series"/);
|
|
rendered.string.should.match(/"publisher": {\n "@type": "Organization",\n "name": "Ghost",/);
|
|
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/tag\/tagtitle\/"/);
|
|
rendered.string.should.match(/"image": "http:\/\/localhost:65530\/content\/images\/tag-image.png"/);
|
|
rendered.string.should.match(/"name": "tagtitle"/);
|
|
rendered.string.should.match(/"description": "tag meta description"/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('tag first page without meta data if no meta title and meta description, but model description provided', function (done) {
|
|
var renderObject = {
|
|
tag: tags[1]
|
|
};
|
|
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: renderObject,
|
|
locals: {
|
|
relativeUrl: '/tag/tagtitle/',
|
|
context: ['tag'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/favicon.ico" type="image\/x-icon" \/>/);
|
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/localhost:65530\/tag\/tagtitle\/" \/>/);
|
|
rendered.string.should.not.match(/<meta name="description"/);
|
|
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
|
rendered.string.should.match(/<meta property="og:type" content="website" \/>/);
|
|
rendered.string.should.match(/<meta property="og:title" content="tagtitle - Ghost" \/>/);
|
|
rendered.string.should.not.match(/<meta property="og:description"/);
|
|
rendered.string.should.match(/<meta property="og:url" content="http:\/\/localhost:65530\/tag\/tagtitle\/" \/>/);
|
|
rendered.string.should.match(/<meta property="og:image" content="http:\/\/localhost:65530\/content\/images\/tag-image.png" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:card" content="summary_large_image" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:title" content="tagtitle - Ghost" \/>/);
|
|
rendered.string.should.not.match(/<meta name="twitter:description"/);
|
|
rendered.string.should.match(/<meta name="twitter:url" content="http:\/\/localhost:65530\/tag\/tagtitle\/" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:image" content="http:\/\/localhost:65530\/content\/images\/tag-image.png" \/>/);
|
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/localhost:65530\/rss\/" \/>/);
|
|
rendered.string.should.match(/<script type=\"application\/ld\+json\">/);
|
|
rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
|
|
rendered.string.should.match(/"@type": "Series"/);
|
|
rendered.string.should.match(/"publisher": {\n "@type": "Organization",\n "name": "Ghost",/);
|
|
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/tag\/tagtitle\/"/);
|
|
rendered.string.should.match(/"image": "http:\/\/localhost:65530\/content\/images\/tag-image.png"/);
|
|
rendered.string.should.match(/"name": "tagtitle"/);
|
|
rendered.string.should.not.match(/"description":/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('tag first page without meta and model description returns no description fields', function (done) {
|
|
var renderObject = {
|
|
tag: tags[2]
|
|
};
|
|
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: renderObject,
|
|
locals: {
|
|
relativeUrl: '/tag/tagtitle/',
|
|
context: ['tag'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/favicon.ico" type="image\/x-icon" \/>/);
|
|
rendered.string.should.not.match(/<meta name="description"/);
|
|
rendered.string.should.not.match(/<meta property="og:description"/);
|
|
rendered.string.should.not.match(/<meta name="twitter:description"/);
|
|
rendered.string.should.not.match(/"description":/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('does not return structured data on paginated tag pages', function (done) {
|
|
var renderObject = {
|
|
tag: tags[3]
|
|
};
|
|
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: renderObject,
|
|
locals: {
|
|
relativeUrl: '/tag/tagtitle/page/2/',
|
|
context: ['paged', 'tag'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/favicon.ico" type="image\/x-icon" \/>/);
|
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/localhost:65530\/tag\/tagtitle\/page\/2\/" \/>/);
|
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
|
rendered.string.should.not.match(/<meta name="description" content="tag meta description" \/>/);
|
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/localhost:65530\/rss\/" \/>/);
|
|
rendered.string.should.not.match(/<meta property="og/);
|
|
rendered.string.should.not.match(/<script type=\"application\/ld\+json\">/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('returns structured data and schema on first author page with cover image', function (done) {
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: {author: users[0]},
|
|
locals: {
|
|
// @TODO: WHY?
|
|
relativeUrl: '/author/authorname/',
|
|
context: ['author'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/favicon.ico" type="image\/x-icon" \/>/);
|
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/localhost:65530\/author\/authorname\/" \/>/);
|
|
rendered.string.should.not.match(/<meta name="description"/);
|
|
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
|
rendered.string.should.match(/<meta property="og:type" content="profile" \/>/);
|
|
rendered.string.should.not.match(/<meta property="og:description"/);
|
|
rendered.string.should.match(/<meta property="og:url" content="http:\/\/localhost:65530\/author\/authorname\/" \/>/);
|
|
rendered.string.should.match(/<meta property="og:image" content="http:\/\/localhost:65530\/content\/images\/author-cover-image.png" \/>/);
|
|
rendered.string.should.match(/<meta property="article:author" content="https:\/\/www.facebook.com\/testuser\" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:card" content="summary_large_image" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:title" content="Author name - Ghost" \/>/);
|
|
rendered.string.should.not.match(/<meta name="twitter:description"/);
|
|
rendered.string.should.match(/<meta name="twitter:url" content="http:\/\/localhost:65530\/author\/authorname\/" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:creator" content="@testuser" \/>/);
|
|
rendered.string.should.match(/<meta name="twitter:image" content="http:\/\/localhost:65530\/content\/images\/author-cover-image.png" \/>/);
|
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/localhost:65530\/rss\/" \/>/);
|
|
rendered.string.should.match(/<script type=\"application\/ld\+json\">/);
|
|
rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
|
|
rendered.string.should.match(/"@type": "Person"/);
|
|
rendered.string.should.match(/"sameAs": \[\n "http:\/\/authorwebsite.com",\n "https:\/\/www.facebook.com\/testuser",\n "https:\/\/twitter.com\/testuser"\n \]/);
|
|
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/author\/authorname\/"/);
|
|
rendered.string.should.match(/"image": "http:\/\/localhost:65530\/content\/images\/author-cover-image.png"/);
|
|
rendered.string.should.match(/"name": "Author name"/);
|
|
rendered.string.should.not.match(/"description":/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('does not return structured data on paginated author pages', function (done) {
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: {author: users[1]},
|
|
locals: {
|
|
// @TODO: WHY?
|
|
relativeUrl: '/author/authorname1/page/2/',
|
|
context: ['paged', 'author'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/favicon.ico" type="image\/x-icon" \/>/);
|
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/localhost:65530\/author\/authorname1\/page\/2\/" \/>/);
|
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/localhost:65530\/rss\/" \/>/);
|
|
rendered.string.should.not.match(/<meta name="description" /);
|
|
rendered.string.should.not.match(/<meta property="og/);
|
|
rendered.string.should.not.match(/<script type=\"application\/ld\+json\">/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('returns meta tag string even if safeVersion is invalid', function (done) {
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
locals: {
|
|
context: [],
|
|
safeVersion: '0.9'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/favicon.ico" type="image\/x-icon" \/>/);
|
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.9" \/>/);
|
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/localhost:65530\/rss\/" \/>/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('outputs structured data but not schema for custom collection', function (done) {
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
locals: {
|
|
relativeUrl: '/featured/',
|
|
context: ['featured'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/favicon.ico" type="image\/x-icon" \/>/);
|
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/localhost:65530\/featured\/" \/>/);
|
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/localhost:65530\/rss\/" \/>/);
|
|
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
|
rendered.string.should.match(/<meta property="og:type" content="website" \/>/);
|
|
rendered.string.should.match(/<meta property="og:title" content="Ghost" \/>/);
|
|
rendered.string.should.match(/<meta property="og:url" content="http:\/\/localhost:65530\/featured\/" \/>/);
|
|
|
|
rendered.string.should.not.match(/<script type=\"application\/ld\+json\">/);
|
|
rendered.string.should.not.match(/<meta name="description" /);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
describe('with /blog subdirectory', function () {
|
|
before(function () {
|
|
settingsCache.get.withArgs('icon').returns('/content/images/favicon.png');
|
|
|
|
configUtils.set({
|
|
url: 'http://localhost:65530/blog/'
|
|
});
|
|
|
|
routing.registry.getRssUrl.returns('http://localhost:65530/blog/rss/');
|
|
});
|
|
|
|
after(function () {
|
|
routing.registry.getRssUrl.returns('http://localhost:65530/rss/');
|
|
});
|
|
|
|
it('returns correct rss url with subdirectory', function (done) {
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
locals: {
|
|
context: ['paged', 'index'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/blog\/favicon.png" type="image\/png" \/>/);
|
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/localhost:65530\/blog\/" \/>/);
|
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/localhost:65530\/blog\/rss\/" \/>/);
|
|
rendered.string.should.not.match(/<meta name="description" /);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('with changed origin in config file', function () {
|
|
before(function () {
|
|
settingsCache.get.withArgs('icon').returns('/content/images/favicon.png');
|
|
|
|
configUtils.set({
|
|
url: 'http://localhost:65530/blog/',
|
|
referrerPolicy: 'origin'
|
|
});
|
|
});
|
|
|
|
it('contains the changed origin', function (done) {
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
locals: {
|
|
context: ['paged', 'index'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/blog\/favicon.png" type="image\/png" \/>/);
|
|
rendered.string.should.match(/<meta name="referrer" content="origin" \/>/);
|
|
rendered.string.should.not.match(/<meta name="description" /);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
});
|
|
|
|
describe('with useStructuredData is set to false in config file', function () {
|
|
before(function () {
|
|
settingsCache.get.withArgs('icon').returns('/content/images/favicon.png');
|
|
|
|
configUtils.set({
|
|
url: 'http://localhost:65530/',
|
|
privacy: {
|
|
useStructuredData: false
|
|
}
|
|
});
|
|
});
|
|
|
|
it('does not return structured data', function (done) {
|
|
var renderObject = {
|
|
post: posts[2]
|
|
};
|
|
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: renderObject,
|
|
locals: {
|
|
relativeUrl: '/post/',
|
|
context: ['post'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/favicon.png" type="image\/png" \/>/);
|
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/localhost:65530\/post\/" \/>/);
|
|
rendered.string.should.match(/<link rel="amphtml" href="http:\/\/localhost:65530\/post\/amp\/" \/>/);
|
|
rendered.string.should.match(/<meta name="description" content="blog description" \/>/);
|
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/localhost:65530\/rss\/" \/>/);
|
|
rendered.string.should.not.match(/<meta property="og/);
|
|
rendered.string.should.not.match(/<script type=\"application\/ld\+json\">/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
});
|
|
|
|
describe('with Code Injection', function () {
|
|
before(function () {
|
|
settingsCache.get.withArgs('icon').returns('/content/images/favicon.png');
|
|
settingsCache.get.withArgs('ghost_head').returns('<style>body {background: red;}</style>');
|
|
|
|
configUtils.set({
|
|
url: 'http://localhost:65530/'
|
|
});
|
|
});
|
|
|
|
it('returns meta tag plus injected code', function (done) {
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: {
|
|
post: false
|
|
},
|
|
locals: {
|
|
context: ['paged', 'index'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/favicon.png" type="image\/png" \/>/);
|
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/localhost:65530\/" \/>/);
|
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/localhost:65530\/rss\/" \/>/);
|
|
rendered.string.should.match(/<style>body {background: red;}<\/style>/);
|
|
|
|
// No default meta desc in paged context
|
|
rendered.string.should.not.match(/<meta name="description" \/>/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('outputs post codeinjection as well', function (done) {
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: {
|
|
post: {
|
|
codeinjection_head: 'post-codeinjection'
|
|
}
|
|
},
|
|
locals: {
|
|
context: ['paged', 'index'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<style>body {background: red;}<\/style>/);
|
|
rendered.string.should.match(/post-codeinjection/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('handles post codeinjection being empty', function (done) {
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: {
|
|
post: {
|
|
codeinjection_head: ''
|
|
}
|
|
},
|
|
locals: {
|
|
context: ['paged', 'index'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<style>body {background: red;}<\/style>/);
|
|
rendered.string.should.not.match(/post-codeinjection/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('handles post codeinjection being null', function (done) {
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: {
|
|
post: {
|
|
codeinjection_head: null
|
|
}
|
|
},
|
|
locals: {
|
|
context: ['paged', 'index'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<style>body {background: red;}<\/style>/);
|
|
rendered.string.should.not.match(/post-codeinjection/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('returns meta tag without injected code for amp context', function (done) {
|
|
var renderObject = {
|
|
post: posts[1]
|
|
};
|
|
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: renderObject,
|
|
locals: {
|
|
context: ['amp', 'post'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/favicon.png" type="image\/png" \/>/);
|
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/localhost:65530\/" \/>/);
|
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/localhost:65530\/rss\/" \/>/);
|
|
rendered.string.should.not.match(/<style>body {background: red;}<\/style>/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
});
|
|
|
|
describe('with Ajax Helper', function () {
|
|
before(function () {
|
|
configUtils.set({
|
|
url: 'http://localhost:65530/'
|
|
});
|
|
});
|
|
|
|
it('renders script tag with src', function (done) {
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: {
|
|
post: false
|
|
},
|
|
locals: {
|
|
context: ['paged', 'index'],
|
|
safeVersion: '0.3',
|
|
client: testUtils.DataGenerator.forKnex.createClient()
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<script src="\/public\/ghost-sdk\.js\?v=/);
|
|
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('renders script tag with init correctly', function (done) {
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: {
|
|
post: false
|
|
},
|
|
locals: {
|
|
context: ['paged', 'index'],
|
|
safeVersion: '0.3',
|
|
client: testUtils.DataGenerator.forKnex.createClient()
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.match(/<script src="/);
|
|
rendered.string.should.match(/ghost\.init\(\{/);
|
|
rendered.string.should.match(/\tclientId: "/);
|
|
rendered.string.should.match(/\tclientSecret: "/);
|
|
rendered.string.should.match(/}\);\n/);
|
|
rendered.string.should.match(/\n<\/script>/);
|
|
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('does not render script tag with for amp context', function (done) {
|
|
var renderObject = {
|
|
post: posts[1]
|
|
};
|
|
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: renderObject,
|
|
locals: {
|
|
context: ['amp', 'post'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.not.match(/<script src="/);
|
|
rendered.string.should.not.match(/ghost\.init\(\{/);
|
|
rendered.string.should.not.match(/\tclientId: "/);
|
|
rendered.string.should.not.match(/\tclientSecret: "/);
|
|
rendered.string.should.not.match(/}\);\n/);
|
|
rendered.string.should.not.match(/\n<\/script>/);
|
|
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('amp is disabled', function () {
|
|
before(function () {
|
|
configUtils.set({
|
|
url: 'http://localhost:65530/'
|
|
});
|
|
|
|
settingsCache.get.withArgs('amp').returns(false);
|
|
});
|
|
|
|
it('does not contain amphtml link', function (done) {
|
|
var renderObject = {
|
|
post: posts[1]
|
|
};
|
|
|
|
helpers.ghost_head(testUtils.createHbsResponse({
|
|
renderObject: renderObject,
|
|
locals: {
|
|
relativeUrl: '/post/',
|
|
context: ['post'],
|
|
safeVersion: '0.3'
|
|
}
|
|
})).then(function (rendered) {
|
|
should.exist(rendered);
|
|
rendered.string.should.not.match(/<link rel="amphtml"/);
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
});
|
|
});
|