mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-03 23:00:14 -05:00
✨ Favicon URI (#7700)
closes #7688 - Use `/favicon.ico` and `/favicon.png` in blog app. Depending on type of storage (custom upload = local file storage), serves either from storage adapter with `read()` method or reads the bytes via `fs`. - Redirects requests for `favicon.ico` to `favicon.png` if custom `png` icon is uploaded and vice versa. - Redirect requests for `favicon.png` to `favicon.ico` if default icon is used (in `core/shared`). - Changes the `{{asset}}` helper for favicon to not serve from theme assets anymore. It will either be served the custom blog-icon or the default one. - The `{{@blog.icon}}` helper renders the url of the **uploaded** blog icon. It won't render the default icon.
This commit is contained in:
parent
584bd15b76
commit
d2f2888da0
12 changed files with 377 additions and 66 deletions
|
@ -67,9 +67,7 @@ updateConfigCache = function () {
|
||||||
config.set('theme:timezone', (settingsCache.activeTimezone && settingsCache.activeTimezone.value) || config.get('theme').timezone);
|
config.set('theme:timezone', (settingsCache.activeTimezone && settingsCache.activeTimezone.value) || config.get('theme').timezone);
|
||||||
config.set('theme:url', globalUtils.url.urlFor('home', true));
|
config.set('theme:url', globalUtils.url.urlFor('home', true));
|
||||||
config.set('theme:amp', (settingsCache.amp && settingsCache.amp.value === 'true'));
|
config.set('theme:amp', (settingsCache.amp && settingsCache.amp.value === 'true'));
|
||||||
config.set('theme:icon', (settingsCache.icon && settingsCache.icon.value) ?
|
config.set('theme:icon', settingsCache.icon && settingsCache.icon.value);
|
||||||
{type: 'upload', url: (settingsCache.icon && settingsCache.icon.value)} :
|
|
||||||
{type: 'default', url: config.get('theme:icon')});
|
|
||||||
|
|
||||||
_.each(labsValue, function (value, key) {
|
_.each(labsValue, function (value, key) {
|
||||||
config.set('labs:' + key, value);
|
config.set('labs:' + key, value);
|
||||||
|
|
|
@ -20,7 +20,8 @@ var debug = require('debug')('ghost:blog'),
|
||||||
prettyURLs = require('../middleware/pretty-urls'),
|
prettyURLs = require('../middleware/pretty-urls'),
|
||||||
serveSharedFile = require('../middleware/serve-shared-file'),
|
serveSharedFile = require('../middleware/serve-shared-file'),
|
||||||
staticTheme = require('../middleware/static-theme'),
|
staticTheme = require('../middleware/static-theme'),
|
||||||
themeHandler = require('../middleware/theme-handler');
|
themeHandler = require('../middleware/theme-handler'),
|
||||||
|
serveFavicon = require('../middleware/serve-favicon');
|
||||||
|
|
||||||
module.exports = function setupBlogApp() {
|
module.exports = function setupBlogApp() {
|
||||||
debug('Blog setup start');
|
debug('Blog setup start');
|
||||||
|
@ -41,7 +42,7 @@ module.exports = function setupBlogApp() {
|
||||||
// Static content/assets
|
// Static content/assets
|
||||||
// @TODO make sure all of these have a local 404 error handler
|
// @TODO make sure all of these have a local 404 error handler
|
||||||
// Favicon
|
// Favicon
|
||||||
blogApp.use(serveSharedFile('favicon.ico', 'image/x-icon', utils.ONE_DAY_S));
|
blogApp.use(serveFavicon());
|
||||||
// Ghost-Url
|
// Ghost-Url
|
||||||
blogApp.use(serveSharedFile('shared/ghost-url.js', 'application/javascript', utils.ONE_HOUR_S));
|
blogApp.use(serveSharedFile('shared/ghost-url.js', 'application/javascript', utils.ONE_HOUR_S));
|
||||||
blogApp.use(serveSharedFile('shared/ghost-url.min.js', 'application/javascript', utils.ONE_HOUR_S));
|
blogApp.use(serveSharedFile('shared/ghost-url.min.js', 'application/javascript', utils.ONE_HOUR_S));
|
||||||
|
|
|
@ -64,11 +64,7 @@
|
||||||
"publishAPostBySchedulerToleranceInMinutes": 2
|
"publishAPostBySchedulerToleranceInMinutes": 2
|
||||||
},
|
},
|
||||||
"theme": {
|
"theme": {
|
||||||
"timezone": "Etc/UTC",
|
"timezone": "Etc/UTC"
|
||||||
"icon": {
|
|
||||||
"type": "default",
|
|
||||||
"url": "core/shared/favicon.ico"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"maintenance": {
|
"maintenance": {
|
||||||
"enabled": false
|
"enabled": false
|
||||||
|
|
|
@ -6,14 +6,22 @@ function getAssetUrl(path, isAdmin, minify) {
|
||||||
|
|
||||||
output += utils.url.urlJoin(utils.url.getSubdir(), '/');
|
output += utils.url.urlJoin(utils.url.getSubdir(), '/');
|
||||||
|
|
||||||
if (!path.match(/^favicon\.ico$/) && !path.match(/^shared/) && !path.match(/^asset/)) {
|
if (!path.match(/^favicon\.(ico|png)$/) && !path.match(/^shared/) && !path.match(/^asset/)) {
|
||||||
if (isAdmin) {
|
if (isAdmin) {
|
||||||
output = utils.url.urlJoin(output, 'ghost/');
|
output = utils.url.urlJoin(output, 'ghost/');
|
||||||
}
|
}
|
||||||
|
|
||||||
output = utils.url.urlJoin(output, 'assets/');
|
output = utils.url.urlJoin(output, 'assets/');
|
||||||
}
|
}
|
||||||
|
// Serve either uploaded favicon or default
|
||||||
|
// for favicon, we don't care anymore about the `/` leading slash, as don't support theme favicons
|
||||||
|
if (path.match(/\/?favicon\.(ico|png)$/)) {
|
||||||
|
if (isAdmin) {
|
||||||
|
output = utils.url.urlJoin(utils.url.getSubdir(), '/favicon.ico');
|
||||||
|
} else {
|
||||||
|
output = config.get('theme:icon') ? utils.url.urlJoin(utils.url.getSubdir(), utils.url.urlFor('image', {image: config.get('theme:icon')})) : utils.url.urlJoin(utils.url.getSubdir(), '/favicon.ico');
|
||||||
|
}
|
||||||
|
}
|
||||||
// Get rid of any leading slash on the path
|
// Get rid of any leading slash on the path
|
||||||
path = path.replace(/^\//, '');
|
path = path.replace(/^\//, '');
|
||||||
|
|
||||||
|
@ -22,9 +30,10 @@ function getAssetUrl(path, isAdmin, minify) {
|
||||||
path = path.replace(/\.([^\.]*)$/, '.min.$1');
|
path = path.replace(/\.([^\.]*)$/, '.min.$1');
|
||||||
}
|
}
|
||||||
|
|
||||||
output += path;
|
if (!path.match(/^favicon\.(ico|png)$/)) {
|
||||||
|
// we don't want to concat the path with our favicon url
|
||||||
|
output += path;
|
||||||
|
|
||||||
if (!path.match(/^favicon\.ico$/)) {
|
|
||||||
if (!config.get('assetHash')) {
|
if (!config.get('assetHash')) {
|
||||||
config.set('assetHash', utils.generateAssetHash());
|
config.set('assetHash', utils.generateAssetHash());
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ var getMetaData = require('../data/meta'),
|
||||||
config = require('../config'),
|
config = require('../config'),
|
||||||
Promise = require('bluebird'),
|
Promise = require('bluebird'),
|
||||||
labs = require('../utils/labs'),
|
labs = require('../utils/labs'),
|
||||||
|
utils = require('../utils'),
|
||||||
api = require('../api');
|
api = require('../api');
|
||||||
|
|
||||||
function getClient() {
|
function getClient() {
|
||||||
|
@ -86,7 +87,10 @@ function ghost_head(options) {
|
||||||
fetch = {
|
fetch = {
|
||||||
metaData: getMetaData(this, options.data.root),
|
metaData: getMetaData(this, options.data.root),
|
||||||
client: getClient()
|
client: getClient()
|
||||||
};
|
},
|
||||||
|
// CASE: blog icon is not set in config, we serve the default
|
||||||
|
iconType = !config.get('theme:icon') ? 'x-icon' : config.get('theme:icon').match(/\/favicon\.ico$/i) ? 'x-icon' : 'png',
|
||||||
|
favicon = !config.get('theme:icon') ? '/favicon.ico' : utils.url.urlFor('image', {image: config.get('theme:icon')}, true);
|
||||||
|
|
||||||
return Promise.props(fetch).then(function (response) {
|
return Promise.props(fetch).then(function (response) {
|
||||||
client = response.client;
|
client = response.client;
|
||||||
|
@ -94,6 +98,7 @@ function ghost_head(options) {
|
||||||
|
|
||||||
if (context) {
|
if (context) {
|
||||||
// head is our main array that holds our meta data
|
// head is our main array that holds our meta data
|
||||||
|
head.push('<link rel="shortcut icon" href="' + favicon + '" type="' + iconType + '" />');
|
||||||
head.push('<link rel="canonical" href="' +
|
head.push('<link rel="canonical" href="' +
|
||||||
escapeExpression(metaData.canonicalUrl) + '" />');
|
escapeExpression(metaData.canonicalUrl) + '" />');
|
||||||
head.push('<meta name="referrer" content="' + referrerPolicy + '" />');
|
head.push('<meta name="referrer" content="' + referrerPolicy + '" />');
|
||||||
|
|
88
core/server/middleware/serve-favicon.js
Normal file
88
core/server/middleware/serve-favicon.js
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
var fs = require('fs'),
|
||||||
|
path = require('path'),
|
||||||
|
storage = require('../storage'),
|
||||||
|
config = require('../config'),
|
||||||
|
utils = require('../utils'),
|
||||||
|
crypto = require('crypto'),
|
||||||
|
buildContentResponse,
|
||||||
|
content;
|
||||||
|
|
||||||
|
buildContentResponse = function buildContentResponse(ext, buf) {
|
||||||
|
content = {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'image/' + ext,
|
||||||
|
'Content-Length': buf.length,
|
||||||
|
ETag: '"' + crypto.createHash('md5').update(buf, 'utf8').digest('hex') + '"',
|
||||||
|
'Cache-Control': 'public, max-age=' + utils.ONE_DAY_S
|
||||||
|
},
|
||||||
|
body: buf
|
||||||
|
};
|
||||||
|
|
||||||
|
return content;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ### serveFavicon Middleware
|
||||||
|
// Handles requests to favicon.png and favicon.ico
|
||||||
|
function serveFavicon() {
|
||||||
|
var iconType,
|
||||||
|
filePath;
|
||||||
|
|
||||||
|
return function serveFavicon(req, res, next) {
|
||||||
|
if (req.path.match(/^\/favicon\.(ico|png)/i)) {
|
||||||
|
// CASE: favicon is default
|
||||||
|
// confusing: if you upload an icon, it's same logic as storing images
|
||||||
|
// we store as /content/images, because this is the url path images get requested via the browser
|
||||||
|
// we are using an express route to skip /content/images and the result is a image path
|
||||||
|
// based on config.getContentPath('images') + req.path
|
||||||
|
// in this case we don't use path rewrite, that's why we have to make it manually
|
||||||
|
filePath = config.get('theme:icon').replace(/\/content\/images\//, '');
|
||||||
|
|
||||||
|
var originalExtension = path.extname(filePath).toLowerCase(),
|
||||||
|
requestedExtension = path.extname(req.path).toLowerCase();
|
||||||
|
|
||||||
|
// CASE: custom favicon exists, load it from local file storage
|
||||||
|
if (config.get('theme:icon')) {
|
||||||
|
// depends on the uploaded icon extension
|
||||||
|
if (originalExtension !== requestedExtension) {
|
||||||
|
return res.redirect(302, '/favicon' + originalExtension);
|
||||||
|
}
|
||||||
|
|
||||||
|
storage.getStorage().read({path: filePath}).then(function readFile(buf, err) {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
iconType = config.get('theme:icon').match(/\/favicon\.ico$/i) ? 'x-icon' : 'png';
|
||||||
|
|
||||||
|
content = buildContentResponse(iconType, buf);
|
||||||
|
|
||||||
|
res.writeHead(200, content.headers);
|
||||||
|
res.end(content.body);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
filePath = 'core/shared/favicon.ico';
|
||||||
|
originalExtension = path.extname(filePath).toLowerCase();
|
||||||
|
|
||||||
|
// CASE: always redirect to .ico for default icon
|
||||||
|
if (originalExtension !== requestedExtension) {
|
||||||
|
return res.redirect(302, '/favicon.ico');
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.readFile(filePath, function readFile(err, buf) {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
content = buildContentResponse('x-icon', buf);
|
||||||
|
|
||||||
|
res.writeHead(200, content.headers);
|
||||||
|
res.end(content.body);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = serveFavicon;
|
|
@ -37,10 +37,7 @@ describe('Config', function () {
|
||||||
logo: 'casper',
|
logo: 'casper',
|
||||||
cover: 'casper',
|
cover: 'casper',
|
||||||
timezone: 'Etc/UTC',
|
timezone: 'Etc/UTC',
|
||||||
icon: {
|
icon: 'core/shared/favicon.ico'
|
||||||
type: 'default',
|
|
||||||
url: 'core/shared/favicon.ico'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -61,10 +58,7 @@ describe('Config', function () {
|
||||||
themeConfig.should.have.property('logo', 'casper');
|
themeConfig.should.have.property('logo', 'casper');
|
||||||
themeConfig.should.have.property('cover', 'casper');
|
themeConfig.should.have.property('cover', 'casper');
|
||||||
themeConfig.should.have.property('timezone', 'Etc/UTC');
|
themeConfig.should.have.property('timezone', 'Etc/UTC');
|
||||||
themeConfig.should.have.property('icon', {
|
themeConfig.should.have.property('icon', 'core/shared/favicon.ico');
|
||||||
type: 'default',
|
|
||||||
url: 'core/shared/favicon.ico'
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -93,43 +87,6 @@ describe('Config', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Favicon default', function () {
|
|
||||||
it('should use uploaded blog icon', function () {
|
|
||||||
var themeConfig = config.get('theme');
|
|
||||||
|
|
||||||
// Check values are as we expect
|
|
||||||
themeConfig.should.have.property('icon', {
|
|
||||||
type: 'default',
|
|
||||||
url: 'core/shared/favicon.ico'
|
|
||||||
});
|
|
||||||
|
|
||||||
configUtils.set({
|
|
||||||
theme: {
|
|
||||||
icon: {
|
|
||||||
type: 'upload',
|
|
||||||
url: 'content/images/favicon.ico'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
config.get('theme').should.have.property('icon', {
|
|
||||||
type: 'upload',
|
|
||||||
url: 'content/images/favicon.ico'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should set theme object with default favicon', function () {
|
|
||||||
var themeConfig = configUtils.defaultConfig;
|
|
||||||
|
|
||||||
// Check values are as we expect
|
|
||||||
themeConfig.should.have.property('theme');
|
|
||||||
themeConfig.theme.should.have.property('icon', {
|
|
||||||
type: 'default',
|
|
||||||
url: 'core/shared/favicon.ico'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Index', function () {
|
describe('Index', function () {
|
||||||
it('should have exactly the right keys', function () {
|
it('should have exactly the right keys', function () {
|
||||||
var pathConfig = config.get('paths');
|
var pathConfig = config.get('paths');
|
||||||
|
|
|
@ -78,7 +78,6 @@ describe('getImageDimensions', function () {
|
||||||
getImageDimensions.__set__('getCachedImageSizeFromUrl', sizeOfStub);
|
getImageDimensions.__set__('getCachedImageSizeFromUrl', sizeOfStub);
|
||||||
|
|
||||||
getImageDimensions(metaData).then(function (result) {
|
getImageDimensions(metaData).then(function (result) {
|
||||||
console.log('result:', result);
|
|
||||||
should.exist(result);
|
should.exist(result);
|
||||||
sizeOfStub.calledWith(metaData.coverImage.url).should.be.true();
|
sizeOfStub.calledWith(metaData.coverImage.url).should.be.true();
|
||||||
sizeOfStub.calledWith(metaData.authorImage.url).should.be.true();
|
sizeOfStub.calledWith(metaData.authorImage.url).should.be.true();
|
||||||
|
|
175
core/test/unit/middleware/serve-favicon_spec.js
Normal file
175
core/test/unit/middleware/serve-favicon_spec.js
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
var sinon = require('sinon'),
|
||||||
|
should = require('should'),
|
||||||
|
express = require('express'),
|
||||||
|
serveFavicon = require('../../../server/middleware/serve-favicon'),
|
||||||
|
configUtils = require('../../utils/configUtils'),
|
||||||
|
path = require('path'),
|
||||||
|
sandbox = sinon.sandbox.create();
|
||||||
|
|
||||||
|
should.equal(true, true);
|
||||||
|
|
||||||
|
describe('Serve Favicon', function () {
|
||||||
|
var req, res, next, blogApp;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
req = sinon.spy();
|
||||||
|
res = sinon.spy();
|
||||||
|
next = sinon.spy();
|
||||||
|
blogApp = express();
|
||||||
|
req.app = blogApp;
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
sandbox.restore();
|
||||||
|
configUtils.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('serveFavicon', function () {
|
||||||
|
it('should return a middleware', function () {
|
||||||
|
var middleware = serveFavicon();
|
||||||
|
|
||||||
|
middleware.should.be.a.Function();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should skip if the request does NOT match the file', function () {
|
||||||
|
var middleware = serveFavicon();
|
||||||
|
req.path = '/robots.txt';
|
||||||
|
middleware(req, res, next);
|
||||||
|
next.called.should.be.true();
|
||||||
|
});
|
||||||
|
describe('serves', function () {
|
||||||
|
it('custom uploaded favicon.png', function (done) {
|
||||||
|
var middleware = serveFavicon();
|
||||||
|
req.path = '/favicon.png';
|
||||||
|
configUtils.set('paths:contentPath', path.join(__dirname, '../../../test/utils/fixtures/'));
|
||||||
|
|
||||||
|
configUtils.set({
|
||||||
|
theme: {
|
||||||
|
icon: 'favicon.png'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
res = {
|
||||||
|
writeHead: function (statusCode) {
|
||||||
|
statusCode.should.eql(200);
|
||||||
|
},
|
||||||
|
end: function (body) {
|
||||||
|
body.length.should.eql(6792);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
middleware(req, res, next);
|
||||||
|
});
|
||||||
|
it('custom uploaded favicon.ico', function (done) {
|
||||||
|
var middleware = serveFavicon();
|
||||||
|
req.path = '/favicon.ico';
|
||||||
|
configUtils.set('paths:contentPath', path.join(__dirname, '../../../test/utils/fixtures/'));
|
||||||
|
|
||||||
|
configUtils.set({
|
||||||
|
theme: {
|
||||||
|
icon: 'favicon.ico'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
res = {
|
||||||
|
writeHead: function (statusCode) {
|
||||||
|
statusCode.should.eql(200);
|
||||||
|
},
|
||||||
|
end: function (body) {
|
||||||
|
body.length.should.eql(15086);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
middleware(req, res, next);
|
||||||
|
});
|
||||||
|
it('default favicon.ico', function (done) {
|
||||||
|
var middleware = serveFavicon();
|
||||||
|
req.path = '/favicon.ico';
|
||||||
|
configUtils.set('paths:corePath', path.join(__dirname, '../../../test/utils/fixtures/'));
|
||||||
|
|
||||||
|
configUtils.set({
|
||||||
|
theme: {
|
||||||
|
icon: ''
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
res = {
|
||||||
|
writeHead: function (statusCode) {
|
||||||
|
statusCode.should.eql(200);
|
||||||
|
},
|
||||||
|
end: function (body) {
|
||||||
|
body.length.should.eql(15086);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
middleware(req, res, next);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('redirects', function () {
|
||||||
|
it('to custom favicon.ico when favicon.png is requested', function (done) {
|
||||||
|
var middleware = serveFavicon();
|
||||||
|
req.path = '/favicon.png';
|
||||||
|
configUtils.set('paths:contentPath', path.join(__dirname, '../../../test/utils/fixtures/'));
|
||||||
|
|
||||||
|
configUtils.set({
|
||||||
|
theme: {
|
||||||
|
icon: 'favicon.ico'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
res = {
|
||||||
|
redirect: function (statusCode) {
|
||||||
|
statusCode.should.eql(302);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
middleware(req, res, next);
|
||||||
|
});
|
||||||
|
it('to custom favicon.png when favicon.ico is requested', function (done) {
|
||||||
|
var middleware = serveFavicon();
|
||||||
|
req.path = '/favicon.ico';
|
||||||
|
configUtils.set('paths:contentPath', path.join(__dirname, '../../../test/utils/fixtures/'));
|
||||||
|
|
||||||
|
configUtils.set({
|
||||||
|
theme: {
|
||||||
|
icon: 'favicon.png'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
res = {
|
||||||
|
redirect: function (statusCode) {
|
||||||
|
statusCode.should.eql(302);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
middleware(req, res, next);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('to favicon.ico when favicon.png is requested', function (done) {
|
||||||
|
var middleware = serveFavicon();
|
||||||
|
req.path = '/favicon.png';
|
||||||
|
configUtils.set('paths:corePath', path.join(__dirname, '../../../test/utils/fixtures/'));
|
||||||
|
|
||||||
|
configUtils.set({
|
||||||
|
theme: {
|
||||||
|
icon: ''
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
res = {
|
||||||
|
redirect: function (statusCode) {
|
||||||
|
statusCode.should.eql(302);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
middleware(req, res, next);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -36,7 +36,33 @@ describe('{{asset}} helper', function () {
|
||||||
String(rendered).should.equal('/favicon.ico');
|
String(rendered).should.equal('/favicon.ico');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('handles custom favicon correctly', function () {
|
||||||
|
configUtils.set('theme:icon', '/content/images/favicon.png');
|
||||||
|
// with ghost set and png
|
||||||
|
rendered = helpers.asset('favicon.png', {hash: {ghost: 'true'}});
|
||||||
|
should.exist(rendered);
|
||||||
|
String(rendered).should.equal('/favicon.ico');
|
||||||
|
|
||||||
|
// without ghost set and png
|
||||||
|
rendered = helpers.asset('favicon.png');
|
||||||
|
should.exist(rendered);
|
||||||
|
String(rendered).should.equal('/content/images/favicon.png');
|
||||||
|
|
||||||
|
configUtils.set('theme:icon', '/content/images/favicon.ico');
|
||||||
|
|
||||||
|
// with ghost set and ico
|
||||||
|
rendered = helpers.asset('favicon.ico', {hash: {ghost: 'true'}});
|
||||||
|
should.exist(rendered);
|
||||||
|
String(rendered).should.equal('/favicon.ico');
|
||||||
|
|
||||||
|
// without ghost set and ico
|
||||||
|
rendered = helpers.asset('favicon.ico');
|
||||||
|
should.exist(rendered);
|
||||||
|
String(rendered).should.equal('/content/images/favicon.ico');
|
||||||
|
});
|
||||||
|
|
||||||
it('handles shared assets correctly', function () {
|
it('handles shared assets correctly', function () {
|
||||||
|
configUtils.set('theme:icon', '');
|
||||||
// with ghost set
|
// with ghost set
|
||||||
rendered = helpers.asset('shared/asset.js', {hash: {ghost: 'true'}});
|
rendered = helpers.asset('shared/asset.js', {hash: {ghost: 'true'}});
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
|
@ -80,6 +106,31 @@ describe('{{asset}} helper', function () {
|
||||||
String(rendered).should.equal('/blog/favicon.ico');
|
String(rendered).should.equal('/blog/favicon.ico');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('handles custom favicon correctly', function () {
|
||||||
|
configUtils.set('theme:icon', '/content/images/favicon.png');
|
||||||
|
// with ghost set and png
|
||||||
|
rendered = helpers.asset('favicon.png', {hash: {ghost: 'true'}});
|
||||||
|
should.exist(rendered);
|
||||||
|
String(rendered).should.equal('/blog/favicon.ico');
|
||||||
|
|
||||||
|
// without ghost set and png
|
||||||
|
rendered = helpers.asset('favicon.png');
|
||||||
|
should.exist(rendered);
|
||||||
|
String(rendered).should.equal('/blog/content/images/favicon.png');
|
||||||
|
|
||||||
|
configUtils.set('theme:icon', '/content/images/favicon.ico');
|
||||||
|
|
||||||
|
// with ghost set and ico
|
||||||
|
rendered = helpers.asset('favicon.ico', {hash: {ghost: 'true'}});
|
||||||
|
should.exist(rendered);
|
||||||
|
String(rendered).should.equal('/blog/favicon.ico');
|
||||||
|
|
||||||
|
// without ghost set and ico
|
||||||
|
rendered = helpers.asset('favicon.ico');
|
||||||
|
should.exist(rendered);
|
||||||
|
String(rendered).should.equal('/blog/content/images/favicon.ico');
|
||||||
|
});
|
||||||
|
|
||||||
it('handles shared assets correctly', function () {
|
it('handles shared assets correctly', function () {
|
||||||
// with ghost set
|
// with ghost set
|
||||||
rendered = helpers.asset('shared/asset.js', {hash: {ghost: 'true'}});
|
rendered = helpers.asset('shared/asset.js', {hash: {ghost: 'true'}});
|
||||||
|
@ -105,5 +156,7 @@ describe('{{asset}} helper', function () {
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
String(rendered).should.equal('/blog/assets/js/asset.js?v=abc');
|
String(rendered).should.equal('/blog/assets/js/asset.js?v=abc');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
configUtils.restore();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -53,7 +53,8 @@ describe('{{ghost_head}} helper', function () {
|
||||||
title: 'Ghost',
|
title: 'Ghost',
|
||||||
description: 'blog description',
|
description: 'blog description',
|
||||||
cover: '/content/images/blog-cover.png',
|
cover: '/content/images/blog-cover.png',
|
||||||
amp: true
|
amp: true,
|
||||||
|
icon: 'core/shared/favicon.ico'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -68,6 +69,7 @@ describe('{{ghost_head}} helper', function () {
|
||||||
{data: {root: {context: ['paged', 'index']}}}
|
{data: {root: {context: ['paged', 'index']}}}
|
||||||
).then(function (rendered) {
|
).then(function (rendered) {
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
|
rendered.string.should.match(/<link rel="shortcut icon" href="core\/shared\/favicon.ico" type="x-icon" \/>/);
|
||||||
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/page\/2\/" \/>/);
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/page\/2\/" \/>/);
|
||||||
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
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:\/\/testurl.com\/rss\/" \/>/);
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/testurl.com\/rss\/" \/>/);
|
||||||
|
@ -84,6 +86,7 @@ describe('{{ghost_head}} helper', function () {
|
||||||
{data: {root: {context: ['home', 'index']}}}
|
{data: {root: {context: ['home', 'index']}}}
|
||||||
).then(function (rendered) {
|
).then(function (rendered) {
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
|
rendered.string.should.match(/<link rel="shortcut icon" href="core\/shared\/favicon.ico" type="x-icon" \/>/);
|
||||||
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/" \/>/);
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/" \/>/);
|
||||||
rendered.string.should.match(/<meta name="referrer" content="no-referrer-when-downgrade" \/>/);
|
rendered.string.should.match(/<meta name="referrer" content="no-referrer-when-downgrade" \/>/);
|
||||||
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
||||||
|
@ -136,6 +139,7 @@ describe('{{ghost_head}} helper', function () {
|
||||||
{data: {root: {context: ['page']}}}
|
{data: {root: {context: ['page']}}}
|
||||||
).then(function (rendered) {
|
).then(function (rendered) {
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
|
rendered.string.should.match(/<link rel="shortcut icon" href="core\/shared\/favicon.ico" type="x-icon" \/>/);
|
||||||
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/about\/" \/>/);
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/about\/" \/>/);
|
||||||
rendered.string.should.match(/<meta name="referrer" content="no-referrer-when-downgrade" \/>/);
|
rendered.string.should.match(/<meta name="referrer" content="no-referrer-when-downgrade" \/>/);
|
||||||
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
||||||
|
@ -182,6 +186,7 @@ describe('{{ghost_head}} helper', function () {
|
||||||
{data: {root: {context: ['tag']}}}
|
{data: {root: {context: ['tag']}}}
|
||||||
).then(function (rendered) {
|
).then(function (rendered) {
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
|
rendered.string.should.match(/<link rel="shortcut icon" href="core\/shared\/favicon.ico" type="x-icon" \/>/);
|
||||||
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/tag\/tagtitle\/" \/>/);
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/tag\/tagtitle\/" \/>/);
|
||||||
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
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:type" content="website" \/>/);
|
||||||
|
@ -223,6 +228,7 @@ describe('{{ghost_head}} helper', function () {
|
||||||
{data: {root: {context: ['tag']}}}
|
{data: {root: {context: ['tag']}}}
|
||||||
).then(function (rendered) {
|
).then(function (rendered) {
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
|
rendered.string.should.match(/<link rel="shortcut icon" href="core\/shared\/favicon.ico" type="x-icon" \/>/);
|
||||||
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/tag\/tagtitle\/" \/>/);
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/tag\/tagtitle\/" \/>/);
|
||||||
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
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:type" content="website" \/>/);
|
||||||
|
@ -263,6 +269,7 @@ describe('{{ghost_head}} helper', function () {
|
||||||
{data: {root: {context: ['tag']}}}
|
{data: {root: {context: ['tag']}}}
|
||||||
).then(function (rendered) {
|
).then(function (rendered) {
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
|
rendered.string.should.match(/<link rel="shortcut icon" href="core\/shared\/favicon.ico" type="x-icon" \/>/);
|
||||||
rendered.string.should.not.match(/<meta property="og:description" \/>/);
|
rendered.string.should.not.match(/<meta property="og:description" \/>/);
|
||||||
rendered.string.should.not.match(/<meta name="twitter:description"\/>/);
|
rendered.string.should.not.match(/<meta name="twitter:description"\/>/);
|
||||||
rendered.string.should.not.match(/"description":/);
|
rendered.string.should.not.match(/"description":/);
|
||||||
|
@ -284,6 +291,7 @@ describe('{{ghost_head}} helper', function () {
|
||||||
{data: {root: {context: ['tag']}}}
|
{data: {root: {context: ['tag']}}}
|
||||||
).then(function (rendered) {
|
).then(function (rendered) {
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
|
rendered.string.should.match(/<link rel="shortcut icon" href="core\/shared\/favicon.ico" type="x-icon" \/>/);
|
||||||
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/tag\/tagtitle\/page\/2\/" \/>/);
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/tag\/tagtitle\/page\/2\/" \/>/);
|
||||||
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
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:\/\/testurl.com\/rss\/" \/>/);
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/testurl.com\/rss\/" \/>/);
|
||||||
|
@ -311,6 +319,7 @@ describe('{{ghost_head}} helper', function () {
|
||||||
{data: {root: {context: ['author']}}}
|
{data: {root: {context: ['author']}}}
|
||||||
).then(function (rendered) {
|
).then(function (rendered) {
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
|
rendered.string.should.match(/<link rel="shortcut icon" href="core\/shared\/favicon.ico" type="x-icon" \/>/);
|
||||||
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/author\/AuthorName\/" \/>/);
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/author\/AuthorName\/" \/>/);
|
||||||
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
||||||
rendered.string.should.match(/<meta property="og:type" content="profile" \/>/);
|
rendered.string.should.match(/<meta property="og:type" content="profile" \/>/);
|
||||||
|
@ -356,6 +365,7 @@ describe('{{ghost_head}} helper', function () {
|
||||||
{data: {root: {context: ['paged', 'author']}}}
|
{data: {root: {context: ['paged', 'author']}}}
|
||||||
).then(function (rendered) {
|
).then(function (rendered) {
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
|
rendered.string.should.match(/<link rel="shortcut icon" href="core\/shared\/favicon.ico" type="x-icon" \/>/);
|
||||||
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/author\/AuthorName\/page\/2\/" \/>/);
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/author\/AuthorName\/page\/2\/" \/>/);
|
||||||
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
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:\/\/testurl.com\/rss\/" \/>/);
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/testurl.com\/rss\/" \/>/);
|
||||||
|
@ -372,6 +382,7 @@ describe('{{ghost_head}} helper', function () {
|
||||||
{data: {root: {context: []}}}
|
{data: {root: {context: []}}}
|
||||||
).then(function (rendered) {
|
).then(function (rendered) {
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
|
rendered.string.should.match(/<link rel="shortcut icon" href="core\/shared\/favicon.ico" type="x-icon" \/>/);
|
||||||
rendered.string.should.match(/<meta name="generator" content="Ghost 0.9" \/>/);
|
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:\/\/testurl.com\/rss\/" \/>/);
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/testurl.com\/rss\/" \/>/);
|
||||||
|
|
||||||
|
@ -409,6 +420,7 @@ describe('{{ghost_head}} helper', function () {
|
||||||
re4 = new RegExp('"dateModified": "' + post.updated_at);
|
re4 = new RegExp('"dateModified": "' + post.updated_at);
|
||||||
|
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
|
rendered.string.should.match(/<link rel="shortcut icon" href="core\/shared\/favicon.ico" type="x-icon" \/>/);
|
||||||
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/post\/" \/>/);
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/post\/" \/>/);
|
||||||
rendered.string.should.match(/<link rel="amphtml" href="http:\/\/testurl.com\/post\/amp\/" \/>/);
|
rendered.string.should.match(/<link rel="amphtml" href="http:\/\/testurl.com\/post\/amp\/" \/>/);
|
||||||
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
||||||
|
@ -487,6 +499,7 @@ describe('{{ghost_head}} helper', function () {
|
||||||
re4 = new RegExp('"dateModified": "' + post.updated_at);
|
re4 = new RegExp('"dateModified": "' + post.updated_at);
|
||||||
|
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
|
rendered.string.should.match(/<link rel="shortcut icon" href="core\/shared\/favicon.ico" type="x-icon" \/>/);
|
||||||
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/post\/" \/>/);
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/post\/" \/>/);
|
||||||
rendered.string.should.not.match(/<link rel="amphtml" href="http:\/\/testurl.com\/post\/amp\/" \/>/);
|
rendered.string.should.not.match(/<link rel="amphtml" href="http:\/\/testurl.com\/post\/amp\/" \/>/);
|
||||||
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
||||||
|
@ -565,6 +578,7 @@ describe('{{ghost_head}} helper', function () {
|
||||||
re4 = new RegExp('"dateModified": "' + post.updated_at);
|
re4 = new RegExp('"dateModified": "' + post.updated_at);
|
||||||
|
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
|
rendered.string.should.match(/<link rel="shortcut icon" href="core\/shared\/favicon.ico" type="x-icon" \/>/);
|
||||||
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/post\/" \/>/);
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/post\/" \/>/);
|
||||||
rendered.string.should.match(/<link rel="amphtml" href="http:\/\/testurl.com\/post\/amp\/" \/>/);
|
rendered.string.should.match(/<link rel="amphtml" href="http:\/\/testurl.com\/post\/amp\/" \/>/);
|
||||||
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
||||||
|
@ -641,6 +655,7 @@ describe('{{ghost_head}} helper', function () {
|
||||||
re4 = new RegExp('"dateModified": "' + post.updated_at);
|
re4 = new RegExp('"dateModified": "' + post.updated_at);
|
||||||
|
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
|
rendered.string.should.match(/<link rel="shortcut icon" href="core\/shared\/favicon.ico" type="x-icon" \/>/);
|
||||||
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/post\/" \/>/);
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/post\/" \/>/);
|
||||||
rendered.string.should.match(/<link rel="amphtml" href="http:\/\/testurl.com\/post\/amp\/" \/>/);
|
rendered.string.should.match(/<link rel="amphtml" href="http:\/\/testurl.com\/post\/amp\/" \/>/);
|
||||||
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
||||||
|
@ -715,6 +730,7 @@ describe('{{ghost_head}} helper', function () {
|
||||||
re4 = new RegExp('"dateModified": "' + post.updated_at);
|
re4 = new RegExp('"dateModified": "' + post.updated_at);
|
||||||
|
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
|
rendered.string.should.match(/<link rel="shortcut icon" href="core\/shared\/favicon.ico" type="x-icon" \/>/);
|
||||||
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/post\/" \/>/);
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/post\/" \/>/);
|
||||||
rendered.string.should.match(/<link rel="amphtml" href="http:\/\/testurl.com\/post\/amp\/" \/>/);
|
rendered.string.should.match(/<link rel="amphtml" href="http:\/\/testurl.com\/post\/amp\/" \/>/);
|
||||||
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
||||||
|
@ -766,6 +782,7 @@ describe('{{ghost_head}} helper', function () {
|
||||||
{data: {root: {context: ['featured']}}}
|
{data: {root: {context: ['featured']}}}
|
||||||
).then(function (rendered) {
|
).then(function (rendered) {
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
|
rendered.string.should.match(/<link rel="shortcut icon" href="core\/shared\/favicon.ico" type="x-icon" \/>/);
|
||||||
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/featured\/" \/>/);
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/featured\/" \/>/);
|
||||||
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
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:\/\/testurl.com\/rss\/" \/>/);
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/testurl.com\/rss\/" \/>/);
|
||||||
|
@ -794,6 +811,7 @@ describe('{{ghost_head}} helper', function () {
|
||||||
{data: {root: {context: ['post']}}}
|
{data: {root: {context: ['post']}}}
|
||||||
).then(function (rendered) {
|
).then(function (rendered) {
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
|
rendered.string.should.match(/<link rel="shortcut icon" href="core\/shared\/favicon.ico" type="x-icon" \/>/);
|
||||||
rendered.string.should.match(/<link rel="amphtml" href="http:\/\/testurl.com\/post\/amp\/" \/>/);
|
rendered.string.should.match(/<link rel="amphtml" href="http:\/\/testurl.com\/post\/amp\/" \/>/);
|
||||||
rendered.string.should.match(/<meta property="og:description" content="This is a short post" \/>/);
|
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" \/>/);
|
rendered.string.should.match(/<meta name="twitter:description" content="This is a short post" \/>/);
|
||||||
|
@ -816,6 +834,7 @@ describe('{{ghost_head}} helper', function () {
|
||||||
{data: {root: {context: ['page']}}}
|
{data: {root: {context: ['page']}}}
|
||||||
).then(function (rendered) {
|
).then(function (rendered) {
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
|
rendered.string.should.match(/<link rel="shortcut icon" href="core\/shared\/favicon.ico" type="x-icon" \/>/);
|
||||||
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/about\/" \/>/);
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/about\/" \/>/);
|
||||||
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
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:\/\/testurl.com\/rss\/" \/>/);
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/testurl.com\/rss\/" \/>/);
|
||||||
|
@ -830,6 +849,7 @@ describe('{{ghost_head}} helper', function () {
|
||||||
{data: {root: {context: ['index', 'paged'], pagination: {total: 4, page: 3, next: 4, prev: 2}}}}
|
{data: {root: {context: ['index', 'paged'], pagination: {total: 4, page: 3, next: 4, prev: 2}}}}
|
||||||
).then(function (rendered) {
|
).then(function (rendered) {
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
|
rendered.string.should.match(/<link rel="shortcut icon" href="core\/shared\/favicon.ico" type="x-icon" \/>/);
|
||||||
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/page\/3\/" \/>/);
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/page\/3\/" \/>/);
|
||||||
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
||||||
rendered.string.should.match(/<link rel="prev" href="http:\/\/testurl.com\/page\/2\/" \/>/);
|
rendered.string.should.match(/<link rel="prev" href="http:\/\/testurl.com\/page\/2\/" \/>/);
|
||||||
|
@ -848,6 +868,7 @@ describe('{{ghost_head}} helper', function () {
|
||||||
{data: {root: {context: ['index', 'paged'], pagination: {total: 3, page: 2, next: 3, prev: 1}}}}
|
{data: {root: {context: ['index', 'paged'], pagination: {total: 3, page: 2, next: 3, prev: 1}}}}
|
||||||
).then(function (rendered) {
|
).then(function (rendered) {
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
|
rendered.string.should.match(/<link rel="shortcut icon" href="core\/shared\/favicon.ico" type="x-icon" \/>/);
|
||||||
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/page\/2\/" \/>/);
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/page\/2\/" \/>/);
|
||||||
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
||||||
rendered.string.should.match(/<link rel="prev" href="http:\/\/testurl.com\/" \/>/);
|
rendered.string.should.match(/<link rel="prev" href="http:\/\/testurl.com\/" \/>/);
|
||||||
|
@ -868,7 +889,8 @@ describe('{{ghost_head}} helper', function () {
|
||||||
title: 'Ghost',
|
title: 'Ghost',
|
||||||
description: 'blog description',
|
description: 'blog description',
|
||||||
cover: '/content/images/blog-cover.png',
|
cover: '/content/images/blog-cover.png',
|
||||||
amp: true
|
amp: true,
|
||||||
|
icon: '/content/images/favicon.png'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -879,6 +901,7 @@ describe('{{ghost_head}} helper', function () {
|
||||||
{data: {root: {context: []}}}
|
{data: {root: {context: []}}}
|
||||||
).then(function (rendered) {
|
).then(function (rendered) {
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/content\/images\/favicon.png" type="png" \/>/);
|
||||||
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/blog\/" \/>/);
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/blog\/" \/>/);
|
||||||
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
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:\/\/testurl.com\/blog\/rss\/" \/>/);
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/testurl.com\/blog\/rss\/" \/>/);
|
||||||
|
@ -897,7 +920,8 @@ describe('{{ghost_head}} helper', function () {
|
||||||
title: 'Ghost',
|
title: 'Ghost',
|
||||||
description: 'blog description',
|
description: 'blog description',
|
||||||
cover: '/content/images/blog-cover.png',
|
cover: '/content/images/blog-cover.png',
|
||||||
amp: true
|
amp: true,
|
||||||
|
icon: '/content/images/favicon.png'
|
||||||
},
|
},
|
||||||
referrerPolicy: 'origin'
|
referrerPolicy: 'origin'
|
||||||
});
|
});
|
||||||
|
@ -909,6 +933,7 @@ describe('{{ghost_head}} helper', function () {
|
||||||
{data: {root: {context: []}}}
|
{data: {root: {context: []}}}
|
||||||
).then(function (rendered) {
|
).then(function (rendered) {
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
|
rendered.string.should.match(/<link rel="shortcut icon" href="\/content\/images\/favicon.png" type="png" \/>/);
|
||||||
rendered.string.should.match(/<meta name="referrer" content="origin" \/>/);
|
rendered.string.should.match(/<meta name="referrer" content="origin" \/>/);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
|
@ -924,7 +949,8 @@ describe('{{ghost_head}} helper', function () {
|
||||||
title: 'Ghost',
|
title: 'Ghost',
|
||||||
description: 'blog description',
|
description: 'blog description',
|
||||||
cover: '/content/images/blog-cover.png',
|
cover: '/content/images/blog-cover.png',
|
||||||
amp: true
|
amp: true,
|
||||||
|
icon: '/content/images/favicon.png'
|
||||||
},
|
},
|
||||||
privacy: {
|
privacy: {
|
||||||
useStructuredData: false
|
useStructuredData: false
|
||||||
|
@ -956,6 +982,7 @@ describe('{{ghost_head}} helper', function () {
|
||||||
{data: {root: {context: ['post']}}}
|
{data: {root: {context: ['post']}}}
|
||||||
).then(function (rendered) {
|
).then(function (rendered) {
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
|
rendered.string.should.match(/<link rel="shortcut icon" href="http:\/\/testurl.com\/content\/images\/favicon.png" type="png" \/>/);
|
||||||
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/post\/" \/>/);
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/post\/" \/>/);
|
||||||
rendered.string.should.match(/<link rel="amphtml" href="http:\/\/testurl.com\/post\/amp\/" \/>/);
|
rendered.string.should.match(/<link rel="amphtml" href="http:\/\/testurl.com\/post\/amp\/" \/>/);
|
||||||
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
||||||
|
@ -979,7 +1006,8 @@ describe('{{ghost_head}} helper', function () {
|
||||||
theme: {
|
theme: {
|
||||||
title: 'Ghost',
|
title: 'Ghost',
|
||||||
description: 'blog description',
|
description: 'blog description',
|
||||||
cover: '/content/images/blog-cover.png'
|
cover: '/content/images/blog-cover.png',
|
||||||
|
icon: '/content/images/favicon.png'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -990,6 +1018,7 @@ describe('{{ghost_head}} helper', function () {
|
||||||
{data: {root: {context: []}}}
|
{data: {root: {context: []}}}
|
||||||
).then(function (rendered) {
|
).then(function (rendered) {
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
|
rendered.string.should.match(/<link rel="shortcut icon" href="http:\/\/testurl.com\/content\/images\/favicon.png" type="png" \/>/);
|
||||||
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/" \/>/);
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/" \/>/);
|
||||||
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
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:\/\/testurl.com\/rss\/" \/>/);
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/testurl.com\/rss\/" \/>/);
|
||||||
|
@ -1022,6 +1051,7 @@ describe('{{ghost_head}} helper', function () {
|
||||||
{data: {root: {context: []}}}
|
{data: {root: {context: []}}}
|
||||||
).then(function (rendered) {
|
).then(function (rendered) {
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
|
rendered.string.should.match(/<link rel="shortcut icon" href="http:\/\/testurl.com\/content\/images\/favicon.png" type="png" \/>/);
|
||||||
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/" \/>/);
|
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/" \/>/);
|
||||||
rendered.string.should.match(/<meta name="generator" content="Ghost 0.3" \/>/);
|
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:\/\/testurl.com\/rss\/" \/>/);
|
rendered.string.should.match(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/testurl.com\/rss\/" \/>/);
|
||||||
|
|
BIN
core/test/utils/fixtures/images/favicon.ico
Normal file
BIN
core/test/utils/fixtures/images/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
Loading…
Add table
Reference in a new issue