mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-03 16:38:22 +03:00
Merge pull request #6223 from ErisDS/ghost-url
Prep shared API URL util for use on external sites
This commit is contained in:
commit
efaa04ba61
@ -32,6 +32,7 @@ function ConfigManager(config) {
|
||||
this.urlJoin = configUrl.urlJoin;
|
||||
this.urlFor = configUrl.urlFor;
|
||||
this.urlPathForPost = configUrl.urlPathForPost;
|
||||
this.apiUrl = configUrl.apiUrl;
|
||||
|
||||
// If we're given an initial config object then we can set it.
|
||||
if (config && _.isObject(config)) {
|
||||
|
@ -3,7 +3,9 @@
|
||||
|
||||
var moment = require('moment'),
|
||||
_ = require('lodash'),
|
||||
ghostConfig = '';
|
||||
ghostConfig = '',
|
||||
// @TODO: unify this with routes.apiBaseUrl
|
||||
apiPath = '/ghost/api/v0.1';
|
||||
|
||||
// ## setConfig
|
||||
// Simple utility function to allow
|
||||
@ -146,7 +148,7 @@ function urlFor(context, data, absolute) {
|
||||
knownPaths = {
|
||||
home: '/',
|
||||
rss: '/rss/',
|
||||
api: '/ghost/api/v0.1',
|
||||
api: apiPath,
|
||||
sitemap_xsl: '/sitemap.xsl'
|
||||
};
|
||||
|
||||
@ -218,7 +220,25 @@ function urlFor(context, data, absolute) {
|
||||
return createUrl(urlPath, absolute, secure);
|
||||
}
|
||||
|
||||
function apiUrl() {
|
||||
// @TODO unify this with urlFor
|
||||
var url;
|
||||
|
||||
if (ghostConfig.forceAdminSSL) {
|
||||
url = (ghostConfig.urlSSL || ghostConfig.url).replace(/^.*?:\/\//g, 'https://');
|
||||
} else if (ghostConfig.urlSSL) {
|
||||
url = ghostConfig.urlSSL.replace(/^.*?:\/\//g, 'https://');
|
||||
} else if (ghostConfig.url.match(/^https:/)) {
|
||||
url = ghostConfig.url;
|
||||
} else {
|
||||
url = ghostConfig.url.replace(/^.*?:\/\//g, '//');
|
||||
}
|
||||
|
||||
return url.replace(/\/$/, '') + apiPath + '/';
|
||||
}
|
||||
|
||||
module.exports.setConfig = setConfig;
|
||||
module.exports.urlJoin = urlJoin;
|
||||
module.exports.urlFor = urlFor;
|
||||
module.exports.urlPathForPost = urlPathForPost;
|
||||
module.exports.apiUrl = apiUrl;
|
||||
|
@ -278,30 +278,14 @@ function finaliseSchema(schema, head) {
|
||||
}
|
||||
|
||||
function getAjaxHelper(clientId, clientSecret) {
|
||||
var apiPath = require('../routes').apiBaseUri,
|
||||
url, useOrigin;
|
||||
|
||||
if (config.forceAdminSSL) {
|
||||
url = 'https://' + (config.urlSSL || config.url).replace(/.*?:\/\//g, '').replace(/\/$/, '') + apiPath;
|
||||
useOrigin = false;
|
||||
} else {
|
||||
url = config.paths.subdir + apiPath;
|
||||
useOrigin = true;
|
||||
}
|
||||
|
||||
return '<script type="text/javascript">\n' +
|
||||
'window.ghost = window.ghost || {};\n' +
|
||||
'window.ghost.config = {\n' +
|
||||
'\turl: \'' + url + '\',\n' +
|
||||
'\tuseOrigin: ' + (useOrigin ? 'true' : 'false') + ',\n' +
|
||||
'\torigin: window.location.origin,\n' +
|
||||
'\tclientId: \'' + clientId + '\',\n' +
|
||||
'\tclientSecret: \'' + clientSecret + '\'\n' +
|
||||
'};' +
|
||||
'</script>' +
|
||||
'<script type="text/javascript" src="' +
|
||||
assetHelper('shared/ghost-url.js', {hash: {minifyInProduction: true}}) +
|
||||
'"></script>';
|
||||
return '<script type="text/javascript" src="' +
|
||||
assetHelper('shared/ghost-url.js', {hash: {minifyInProduction: true}}) + '"></script>\n' +
|
||||
'<script type="text/javascript">\n' +
|
||||
'ghost.init({\n' +
|
||||
'\tclientId: "' + clientId + '",\n' +
|
||||
'\tclientSecret: "' + clientSecret + '"\n' +
|
||||
'});\n' +
|
||||
'</script>';
|
||||
}
|
||||
|
||||
ghost_head = function (options) {
|
||||
@ -364,8 +348,6 @@ ghost_head = function (options) {
|
||||
}
|
||||
|
||||
if (metaData.clientId && metaData.clientSecret) {
|
||||
head.push(writeMetaTag('ghost:client_id', metaData.clientId));
|
||||
head.push(writeMetaTag('ghost:client_secret', metaData.clientSecret));
|
||||
head.push(getAjaxHelper(metaData.clientId, metaData.clientSecret));
|
||||
}
|
||||
}
|
||||
|
@ -73,6 +73,10 @@ setupMiddleware = function setupMiddleware(blogApp, adminApp) {
|
||||
// Favicon
|
||||
blogApp.use(serveSharedFile('favicon.ico', 'image/x-icon', utils.ONE_DAY_S));
|
||||
|
||||
// Ghost-Url
|
||||
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));
|
||||
|
||||
// Static assets
|
||||
blogApp.use('/shared', express.static(path.join(corePath, '/shared'), {maxAge: utils.ONE_HOUR_MS}));
|
||||
blogApp.use('/content/images', storage.getStorage().serve());
|
||||
|
@ -7,11 +7,15 @@ var crypto = require('crypto'),
|
||||
// Handles requests to robots.txt and favicon.ico (and caches them)
|
||||
function serveSharedFile(file, type, maxAge) {
|
||||
var content,
|
||||
filePath = path.join(config.paths.corePath, 'shared', file),
|
||||
re = /(\{\{blog-url\}\})/g;
|
||||
corePath = config.paths.corePath,
|
||||
filePath,
|
||||
blogRegex = /(\{\{blog-url\}\})/g,
|
||||
apiRegex = /(\{\{api-url\}\})/g;
|
||||
|
||||
filePath = file.match(/^shared/) ? path.join(corePath, file) : path.join(corePath, 'shared', file);
|
||||
|
||||
return function serveSharedFile(req, res, next) {
|
||||
if (req.url === '/' + file) {
|
||||
if (req.path === '/' + file) {
|
||||
if (content) {
|
||||
res.writeHead(200, content.headers);
|
||||
res.end(content.body);
|
||||
@ -20,8 +24,10 @@ function serveSharedFile(file, type, maxAge) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
if (type === 'text/xsl' || type === 'text/plain') {
|
||||
buf = buf.toString().replace(re, config.url.replace(/\/$/, ''));
|
||||
|
||||
if (type === 'text/xsl' || type === 'text/plain' || type === 'application/javascript') {
|
||||
buf = buf.toString().replace(blogRegex, config.url.replace(/\/$/, ''));
|
||||
buf = buf.toString().replace(apiRegex, config.apiUrl());
|
||||
}
|
||||
content = {
|
||||
headers: {
|
||||
|
@ -1,6 +1,12 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var apiUrl = '{{api-url}}',
|
||||
clientId,
|
||||
clientSecret,
|
||||
url,
|
||||
init;
|
||||
|
||||
function generateQueryString(object) {
|
||||
var queries = [],
|
||||
i;
|
||||
@ -21,12 +27,9 @@
|
||||
return '';
|
||||
}
|
||||
|
||||
var url = {
|
||||
config: {},
|
||||
|
||||
url = {
|
||||
api: function () {
|
||||
var args = Array.prototype.slice.call(arguments),
|
||||
url = (this.config.useOrigin) ? this.config.origin + this.config.url : this.config.url,
|
||||
queryOptions;
|
||||
|
||||
if (args.length && typeof args[args.length - 1] === 'object') {
|
||||
@ -35,26 +38,35 @@
|
||||
queryOptions = {};
|
||||
}
|
||||
|
||||
queryOptions.client_id = this.config.clientId;
|
||||
queryOptions.client_secret = this.config.clientSecret;
|
||||
queryOptions.client_id = clientId;
|
||||
queryOptions.client_secret = clientSecret;
|
||||
|
||||
if (args.length) {
|
||||
args.forEach(function (el) {
|
||||
url += el.replace(/^\/|\/$/g, '') + '/';
|
||||
apiUrl += el.replace(/^\/|\/$/g, '') + '/';
|
||||
});
|
||||
}
|
||||
|
||||
return url + generateQueryString(queryOptions);
|
||||
return apiUrl + generateQueryString(queryOptions);
|
||||
}
|
||||
};
|
||||
|
||||
init = function (options) {
|
||||
clientId = options.clientId ? options.clientId : '';
|
||||
clientSecret = options.clientSecret ? options.clientSecret : '';
|
||||
apiUrl = options.url ? options.url : '';
|
||||
};
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
window.ghost = window.ghost || {};
|
||||
url.config = window.ghost.config || {};
|
||||
window.ghost.url = url;
|
||||
window.ghost.init = init;
|
||||
}
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = url;
|
||||
module.exports = {
|
||||
url: url,
|
||||
init: init
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
@ -372,7 +372,7 @@ describe('Config', function () {
|
||||
|
||||
describe('urlPathForPost', function () {
|
||||
it('should output correct url for post', function () {
|
||||
config.set({theme: {permalinks: '/:slug/'}});
|
||||
configUtils.set({theme: {permalinks: '/:slug/'}});
|
||||
|
||||
var testData = testUtils.DataGenerator.Content.posts[2],
|
||||
postLink = '/short-and-sweet/';
|
||||
@ -381,7 +381,7 @@ describe('Config', function () {
|
||||
});
|
||||
|
||||
it('should output correct url for post with date permalink', function () {
|
||||
config.set({theme: {permalinks: '/:year/:month/:day/:slug/'}});
|
||||
configUtils.set({theme: {permalinks: '/:year/:month/:day/:slug/'}});
|
||||
var testData = testUtils.DataGenerator.Content.posts[2],
|
||||
today = testData.published_at,
|
||||
dd = ('0' + today.getDate()).slice(-2),
|
||||
@ -393,7 +393,7 @@ describe('Config', function () {
|
||||
});
|
||||
|
||||
it('should output correct url for page with date permalink', function () {
|
||||
config.set({theme: {permalinks: '/:year/:month/:day/:slug/'}});
|
||||
configUtils.set({theme: {permalinks: '/:year/:month/:day/:slug/'}});
|
||||
|
||||
var testData = testUtils.DataGenerator.Content.posts[5],
|
||||
postLink = '/static-page-test/';
|
||||
@ -402,7 +402,7 @@ describe('Config', function () {
|
||||
});
|
||||
|
||||
it('should output correct url for post with complex permalink', function () {
|
||||
config.set({theme: {permalinks: '/:year/:id/:author/'}});
|
||||
configUtils.set({theme: {permalinks: '/:year/:id/:author/'}});
|
||||
|
||||
var testData = _.extend(
|
||||
{}, testUtils.DataGenerator.Content.posts[2], {id: 3}, {author: {slug: 'joe-bloggs'}}
|
||||
@ -414,6 +414,71 @@ describe('Config', function () {
|
||||
config.urlPathForPost(testData).should.equal(postLink);
|
||||
});
|
||||
});
|
||||
|
||||
describe('apiUrl', function () {
|
||||
it('should return https config.url if forceAdminSSL set', function () {
|
||||
configUtils.set({
|
||||
url: 'http://my-ghost-blog.com',
|
||||
forceAdminSSL: true
|
||||
});
|
||||
|
||||
config.apiUrl().should.eql('https://my-ghost-blog.com/ghost/api/v0.1/');
|
||||
});
|
||||
|
||||
it('should return https config.urlSSL if forceAdminSSL set and urlSSL is misconfigured', function () {
|
||||
configUtils.set({
|
||||
url: 'http://my-ghost-blog.com',
|
||||
urlSSL: 'http://other-ghost-blog.com',
|
||||
forceAdminSSL: true
|
||||
});
|
||||
|
||||
config.apiUrl().should.eql('https://other-ghost-blog.com/ghost/api/v0.1/');
|
||||
});
|
||||
|
||||
it('should return https config.urlSSL if forceAdminSSL set', function () {
|
||||
configUtils.set({
|
||||
url: 'http://my-ghost-blog.com',
|
||||
urlSSL: 'https://other-ghost-blog.com',
|
||||
forceAdminSSL: true
|
||||
});
|
||||
|
||||
config.apiUrl().should.eql('https://other-ghost-blog.com/ghost/api/v0.1/');
|
||||
});
|
||||
|
||||
it('should return https config.urlSSL if set and misconfigured & forceAdminSSL is NOT set', function () {
|
||||
configUtils.set({
|
||||
url: 'http://my-ghost-blog.com',
|
||||
urlSSL: 'http://other-ghost-blog.com'
|
||||
});
|
||||
|
||||
config.apiUrl().should.eql('https://other-ghost-blog.com/ghost/api/v0.1/');
|
||||
});
|
||||
|
||||
it('should return https config.urlSSL if set & forceAdminSSL is NOT set', function () {
|
||||
configUtils.set({
|
||||
url: 'http://my-ghost-blog.com',
|
||||
urlSSL: 'https://other-ghost-blog.com'
|
||||
});
|
||||
|
||||
config.apiUrl().should.eql('https://other-ghost-blog.com/ghost/api/v0.1/');
|
||||
});
|
||||
|
||||
it('should return https config.url if config.url is https & forceAdminSSL is NOT set', function () {
|
||||
configUtils.set({
|
||||
url: 'https://my-ghost-blog.com'
|
||||
});
|
||||
|
||||
config.apiUrl().should.eql('https://my-ghost-blog.com/ghost/api/v0.1/');
|
||||
});
|
||||
|
||||
it('should return no protocol config.url if config.url is NOT https & forceAdminSSL/urlSSL is NOT set', function () {
|
||||
configUtils.set({
|
||||
url: 'http://my-ghost-blog.com'
|
||||
});
|
||||
|
||||
config.apiUrl().should.eql('//my-ghost-blog.com/ghost/api/v0.1/');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('File', function () {
|
||||
|
@ -1,68 +1,63 @@
|
||||
/* globals describe, afterEach, it */
|
||||
/* globals describe, beforeEach, afterEach, it */
|
||||
/*jshint expr:true*/
|
||||
var url = require('../../shared/ghost-url');
|
||||
var should = require('should'),
|
||||
ghostUrl = require('../../shared/ghost-url'),
|
||||
|
||||
configUtils = require('../utils/configUtils');
|
||||
|
||||
should.equal(true, true);
|
||||
|
||||
describe('Ghost Ajax Helper', function () {
|
||||
beforeEach(function () {
|
||||
configUtils.set({
|
||||
url: 'http://testblog.com/'
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
url.config = {};
|
||||
configUtils.restore();
|
||||
});
|
||||
|
||||
it('renders basic url correctly when no arguments are presented & useOrigin is set to false', function () {
|
||||
url.config = {
|
||||
url: 'http://testblog.com/',
|
||||
useOrigin: false,
|
||||
it('renders basic url correctly when no arguments are presented', function () {
|
||||
ghostUrl.init({
|
||||
clientId: '',
|
||||
clientSecret: ''
|
||||
};
|
||||
clientSecret: '',
|
||||
url: configUtils.config.apiUrl()
|
||||
});
|
||||
|
||||
url.api().should.equal('http://testblog.com/');
|
||||
});
|
||||
|
||||
it('renders basic url correctly when no arguments are presented & useOrigin is set to true', function () {
|
||||
url.config = {
|
||||
url: '/url/',
|
||||
useOrigin: true,
|
||||
origin: 'http://originblog.com',
|
||||
clientId: '',
|
||||
clientSecret: ''
|
||||
};
|
||||
|
||||
url.api().should.equal('http://originblog.com/url/');
|
||||
ghostUrl.url.api().should.equal('//testblog.com/ghost/api/v0.1/');
|
||||
});
|
||||
|
||||
it('strips arguments of forward and trailing slashes correctly', function () {
|
||||
url.config = {
|
||||
url: 'http://testblog.com/',
|
||||
useOrigin: false,
|
||||
ghostUrl.init({
|
||||
clientId: '',
|
||||
clientSecret: ''
|
||||
};
|
||||
clientSecret: '',
|
||||
url: configUtils.config.apiUrl()
|
||||
});
|
||||
|
||||
url.api('a/', '/b', '/c/').should.equal('http://testblog.com/a/b/c/');
|
||||
ghostUrl.url.api('a/', '/b', '/c/').should.equal('//testblog.com/ghost/api/v0.1/a/b/c/');
|
||||
});
|
||||
|
||||
it('appends client_id & client_secret to query string automatically', function () {
|
||||
url.config = {
|
||||
url: 'http://testblog.com/',
|
||||
useOrigin: false,
|
||||
ghostUrl.init({
|
||||
clientId: 'ghost-frontend',
|
||||
clientSecret: 'notasecret'
|
||||
};
|
||||
clientSecret: 'notasecret',
|
||||
url: configUtils.config.apiUrl()
|
||||
});
|
||||
|
||||
url.api().should.equal('http://testblog.com/?client_id=ghost-frontend&client_secret=notasecret');
|
||||
ghostUrl.url.api().should.equal('//testblog.com/ghost/api/v0.1/?client_id=ghost-frontend&client_secret=notasecret');
|
||||
});
|
||||
|
||||
it('generates query parameters correctly', function () {
|
||||
url.config = {
|
||||
url: 'http://testblog.com/',
|
||||
useOrigin: false,
|
||||
ghostUrl.init({
|
||||
clientId: 'ghost-frontend',
|
||||
clientSecret: 'notasecret'
|
||||
};
|
||||
clientSecret: 'notasecret',
|
||||
url: configUtils.config.apiUrl()
|
||||
});
|
||||
|
||||
var rendered = url.api({a: 'string', b: 5, c: 'en coded'});
|
||||
var rendered = ghostUrl.url.api({a: 'string', b: 5, c: 'en coded'});
|
||||
|
||||
rendered.should.match(/http:\/\/testblog\.com\/\?/);
|
||||
rendered.should.match(/\/\/testblog\.com\/ghost\/api\/v0\.1\/\?/);
|
||||
rendered.should.match(/client_id=ghost-frontend/);
|
||||
rendered.should.match(/client_secret=notasecret/);
|
||||
rendered.should.match(/a/);
|
||||
@ -71,15 +66,51 @@ describe('Ghost Ajax Helper', function () {
|
||||
});
|
||||
|
||||
it('generates complex query correctly', function () {
|
||||
url.config = {
|
||||
url: '/blog/ghost/api/v0.1/',
|
||||
useOrigin: true,
|
||||
origin: 'https://testblog.com',
|
||||
ghostUrl.init({
|
||||
clientId: 'ghost-frontend',
|
||||
clientSecret: 'notasecret'
|
||||
};
|
||||
clientSecret: 'notasecret',
|
||||
url: configUtils.config.apiUrl()
|
||||
});
|
||||
|
||||
var rendered = url.api('posts/', '/tags/', '/count', {include: 'tags,tests', page: 2});
|
||||
var rendered = ghostUrl.url.api('posts/', '/tags/', '/count', {include: 'tags,tests', page: 2});
|
||||
|
||||
rendered.should.match(/\/\/testblog\.com\/ghost\/api\/v0\.1\/posts\/tags\/count\/\?/);
|
||||
rendered.should.match(/client_id=ghost-frontend/);
|
||||
rendered.should.match(/client_secret=notasecret/);
|
||||
rendered.should.match(/include=tags%2Ctests/);
|
||||
rendered.should.match(/page=2/);
|
||||
});
|
||||
|
||||
it('works with an https config', function () {
|
||||
configUtils.set({
|
||||
url: 'https://testblog.com/'
|
||||
});
|
||||
ghostUrl.init({
|
||||
clientId: 'ghost-frontend',
|
||||
clientSecret: 'notasecret',
|
||||
url: configUtils.config.apiUrl()
|
||||
});
|
||||
|
||||
var rendered = ghostUrl.url.api('posts/', '/tags/', '/count', {include: 'tags,tests', page: 2});
|
||||
|
||||
rendered.should.match(/https:\/\/testblog\.com\/ghost\/api\/v0\.1\/posts\/tags\/count\/\?/);
|
||||
rendered.should.match(/client_id=ghost-frontend/);
|
||||
rendered.should.match(/client_secret=notasecret/);
|
||||
rendered.should.match(/include=tags%2Ctests/);
|
||||
rendered.should.match(/page=2/);
|
||||
});
|
||||
|
||||
it('works with an https config and subdirectory', function () {
|
||||
configUtils.set({
|
||||
url: 'https://testblog.com/blog/'
|
||||
});
|
||||
ghostUrl.init({
|
||||
clientId: 'ghost-frontend',
|
||||
clientSecret: 'notasecret',
|
||||
url: configUtils.config.apiUrl()
|
||||
});
|
||||
|
||||
var rendered = ghostUrl.url.api('posts/', '/tags/', '/count', {include: 'tags,tests', page: 2});
|
||||
|
||||
rendered.should.match(/https:\/\/testblog\.com\/blog\/ghost\/api\/v0\.1\/posts\/tags\/count\/\?/);
|
||||
rendered.should.match(/client_id=ghost-frontend/);
|
||||
|
@ -2,14 +2,14 @@
|
||||
/*jshint expr:true*/
|
||||
var fs = require('fs'),
|
||||
sinon = require('sinon'),
|
||||
serveSharedFile = require('../../../server/middleware/serve-shared-file');
|
||||
serveSharedFile = require('../../../server/middleware/serve-shared-file'),
|
||||
|
||||
sandbox = sinon.sandbox.create();
|
||||
|
||||
describe('serveSharedFile', function () {
|
||||
var res, req, next, sandbox;
|
||||
var res, req, next;
|
||||
|
||||
beforeEach(function () {
|
||||
sandbox = sinon.sandbox.create();
|
||||
|
||||
res = sinon.spy();
|
||||
req = sinon.spy();
|
||||
next = sinon.spy();
|
||||
@ -27,7 +27,7 @@ describe('serveSharedFile', function () {
|
||||
|
||||
it('should skip if the request does NOT match the file', function () {
|
||||
var middleware = serveSharedFile('robots.txt', 'text/plain', 3600);
|
||||
req.url = '/favicon.ico';
|
||||
req.path = '/favicon.ico';
|
||||
middleware(req, res, next);
|
||||
next.called.should.be.true;
|
||||
});
|
||||
@ -35,7 +35,7 @@ describe('serveSharedFile', function () {
|
||||
it('should load the file and send it', function () {
|
||||
var middleware = serveSharedFile('robots.txt', 'text/plain', 3600),
|
||||
body = 'User-agent: * Disallow: /';
|
||||
req.url = '/robots.txt';
|
||||
req.path = '/robots.txt';
|
||||
|
||||
sandbox.stub(fs, 'readFile', function (file, cb) {
|
||||
cb(null, body);
|
||||
@ -61,7 +61,7 @@ describe('serveSharedFile', function () {
|
||||
it('should send the correct headers', function () {
|
||||
var middleware = serveSharedFile('robots.txt', 'text/plain', 3600),
|
||||
body = 'User-agent: * Disallow: /';
|
||||
req.url = '/robots.txt';
|
||||
req.path = '/robots.txt';
|
||||
|
||||
sandbox.stub(fs, 'readFile', function (file, cb) {
|
||||
cb(null, body);
|
||||
@ -85,7 +85,7 @@ describe('serveSharedFile', function () {
|
||||
it('should replace {{blog-url}} in text/plain', function () {
|
||||
var middleware = serveSharedFile('robots.txt', 'text/plain', 3600),
|
||||
body = 'User-agent: {{blog-url}}';
|
||||
req.url = '/robots.txt';
|
||||
req.path = '/robots.txt';
|
||||
|
||||
sandbox.stub(fs, 'readFile', function (file, cb) {
|
||||
cb(null, body);
|
||||
|
@ -45,11 +45,6 @@ describe('{{ghost_head}} helper', function () {
|
||||
sandbox.stub(labs, 'isSet').returns(true);
|
||||
});
|
||||
|
||||
function expectGhostClientMeta(rendered) {
|
||||
rendered.string.should.match(/<meta property="ghost:client_id" content="ghost-frontend" \/>/);
|
||||
rendered.string.should.match(/<meta property="ghost:client_secret" content="[a-f0-9]{12}" \/>/);
|
||||
}
|
||||
|
||||
describe('without Code Injection', function () {
|
||||
beforeEach(function () {
|
||||
configUtils.set({
|
||||
@ -72,7 +67,6 @@ describe('{{ghost_head}} helper', function () {
|
||||
{data: {root: {context: ['paged', 'index']}}}
|
||||
).then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
expectGhostClientMeta(rendered);
|
||||
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(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/testurl.com\/rss\/" \/>/);
|
||||
@ -89,7 +83,6 @@ describe('{{ghost_head}} helper', function () {
|
||||
{data: {root: {context: ['home', 'index']}}}
|
||||
).then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
expectGhostClientMeta(rendered);
|
||||
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/" \/>/);
|
||||
rendered.string.should.match(/<meta name="referrer" content="origin" \/>/);
|
||||
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
||||
@ -130,7 +123,6 @@ describe('{{ghost_head}} helper', function () {
|
||||
{data: {root: {context: ['tag']}}}
|
||||
).then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
expectGhostClientMeta(rendered);
|
||||
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:type" content="website" \/>/);
|
||||
@ -172,7 +164,6 @@ describe('{{ghost_head}} helper', function () {
|
||||
{data: {root: {context: ['tag']}}}
|
||||
).then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
expectGhostClientMeta(rendered);
|
||||
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:type" content="website" \/>/);
|
||||
@ -212,14 +203,13 @@ describe('{{ghost_head}} helper', function () {
|
||||
{safeVersion: '0.3', relativeUrl: '/tag/tagtitle/', tag: tag, context: ['tag']},
|
||||
{data: {root: {context: ['tag']}}}
|
||||
).then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
expectGhostClientMeta(rendered);
|
||||
rendered.string.should.not.match(/<meta property="og:description" \/>/);
|
||||
rendered.string.should.not.match(/<meta name="twitter:description"\/>/);
|
||||
rendered.string.should.not.match(/"description":/);
|
||||
should.exist(rendered);
|
||||
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);
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('does not return structured data on paginated tag pages', function (done) {
|
||||
@ -235,7 +225,6 @@ describe('{{ghost_head}} helper', function () {
|
||||
{data: {root: {context: ['tag']}}}
|
||||
).then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
expectGhostClientMeta(rendered);
|
||||
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(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/testurl.com\/rss\/" \/>/);
|
||||
@ -261,7 +250,6 @@ describe('{{ghost_head}} helper', function () {
|
||||
{data: {root: {context: ['author']}}}
|
||||
).then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
expectGhostClientMeta(rendered);
|
||||
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:type" content="profile" \/>/);
|
||||
@ -304,7 +292,6 @@ describe('{{ghost_head}} helper', function () {
|
||||
{data: {root: {context: ['paged', 'author']}}}
|
||||
).then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
expectGhostClientMeta(rendered);
|
||||
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(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/testurl.com\/rss\/" \/>/);
|
||||
@ -356,7 +343,6 @@ describe('{{ghost_head}} helper', function () {
|
||||
re4 = new RegExp('"dateModified": "' + post.updated_at);
|
||||
|
||||
should.exist(rendered);
|
||||
expectGhostClientMeta(rendered);
|
||||
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/post\/" \/>/);
|
||||
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
||||
rendered.string.should.match(/<meta property="og:type" content="article" \/>/);
|
||||
@ -428,7 +414,6 @@ describe('{{ghost_head}} helper', function () {
|
||||
re4 = new RegExp('"dateModified": "' + post.updated_at);
|
||||
|
||||
should.exist(rendered);
|
||||
expectGhostClientMeta(rendered);
|
||||
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/post\/" \/>/);
|
||||
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
||||
rendered.string.should.match(/<meta property="og:type" content="article" \/>/);
|
||||
@ -498,7 +483,6 @@ describe('{{ghost_head}} helper', function () {
|
||||
re4 = new RegExp('"dateModified": "' + post.updated_at);
|
||||
|
||||
should.exist(rendered);
|
||||
expectGhostClientMeta(rendered);
|
||||
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/post\/" \/>/);
|
||||
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
||||
rendered.string.should.match(/<meta property="og:type" content="article" \/>/);
|
||||
@ -567,7 +551,6 @@ describe('{{ghost_head}} helper', function () {
|
||||
re4 = new RegExp('"dateModified": "' + post.updated_at);
|
||||
|
||||
should.exist(rendered);
|
||||
expectGhostClientMeta(rendered);
|
||||
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/post\/" \/>/);
|
||||
rendered.string.should.match(/<meta property="og:site_name" content="Ghost" \/>/);
|
||||
rendered.string.should.match(/<meta property="og:type" content="article" \/>/);
|
||||
@ -614,7 +597,6 @@ describe('{{ghost_head}} helper', function () {
|
||||
{data: {root: {context: ['page']}}}
|
||||
).then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
expectGhostClientMeta(rendered);
|
||||
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(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/testurl.com\/rss\/" \/>/);
|
||||
@ -631,7 +613,6 @@ describe('{{ghost_head}} helper', function () {
|
||||
{data: {root: {context: ['index', 'paged'], pagination: {total: 4, page: 3, next: 4, prev: 2}}}}
|
||||
).then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
expectGhostClientMeta(rendered);
|
||||
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(/<link rel="prev" href="http:\/\/testurl.com\/page\/2\/" \/>/);
|
||||
@ -650,7 +631,6 @@ describe('{{ghost_head}} helper', function () {
|
||||
{data: {root: {context: ['index', 'paged'], pagination: {total: 3, page: 2, next: 3, prev: 1}}}}
|
||||
).then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
expectGhostClientMeta(rendered);
|
||||
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(/<link rel="prev" href="http:\/\/testurl.com\/" \/>/);
|
||||
@ -681,7 +661,6 @@ describe('{{ghost_head}} helper', function () {
|
||||
{data: {root: {context: []}}}
|
||||
).then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
expectGhostClientMeta(rendered);
|
||||
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(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/testurl.com\/blog\/rss\/" \/>/);
|
||||
@ -729,7 +708,6 @@ describe('{{ghost_head}} helper', function () {
|
||||
{data: {root: {context: ['post']}}}
|
||||
).then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
expectGhostClientMeta(rendered);
|
||||
rendered.string.should.match(/<link rel="canonical" href="http:\/\/testurl.com\/post\/" \/>/);
|
||||
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\/" \/>/);
|
||||
@ -763,7 +741,6 @@ describe('{{ghost_head}} helper', function () {
|
||||
{data: {root: {context: []}}}
|
||||
).then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
expectGhostClientMeta(rendered);
|
||||
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(/<link rel="alternate" type="application\/rss\+xml" title="Ghost" href="http:\/\/testurl.com\/rss\/" \/>/);
|
||||
@ -775,102 +752,30 @@ describe('{{ghost_head}} helper', function () {
|
||||
});
|
||||
|
||||
describe('with Ajax Helper', function () {
|
||||
beforeEach(function () {
|
||||
configUtils.set({
|
||||
url: '',
|
||||
urlSSL: '',
|
||||
forceAdminSSL: false
|
||||
});
|
||||
});
|
||||
|
||||
it('renders script tags with basic configuration', function (done) {
|
||||
configUtils.set({
|
||||
url: 'http://example.com/'
|
||||
});
|
||||
|
||||
it('renders script tag with src', function (done) {
|
||||
helpers.ghost_head.call(
|
||||
{safeVersion: '0.3', context: ['paged', 'index'], post: false},
|
||||
{data: {root: {context: []}}}
|
||||
).then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
expectGhostClientMeta(rendered);
|
||||
rendered.string.should.match(/<script type="text\/javascript">/);
|
||||
rendered.string.should.match(/<script type="text\/javascript" src="\/shared\/ghost-url\.js\?v=/);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('renders basic url correctly', function (done) {
|
||||
configUtils.set({
|
||||
url: 'http://testurl.com/'
|
||||
});
|
||||
|
||||
it('renders script tag with init correctly', function (done) {
|
||||
helpers.ghost_head.call(
|
||||
{safeVersion: '0.3', context: ['paged', 'index'], post: false},
|
||||
{data: {root: {context: []}}}
|
||||
).then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
expectGhostClientMeta(rendered);
|
||||
rendered.string.should.match(/url: '\/ghost\/api\/v0\.1\/'/);
|
||||
rendered.string.should.match(/useOrigin: true/);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('renders basic url correctly with subdirectory', function (done) {
|
||||
configUtils.set({
|
||||
url: 'http://testurl.com/blog/'
|
||||
});
|
||||
|
||||
helpers.ghost_head.call(
|
||||
{safeVersion: '0.3', context: ['paged', 'index'], post: false},
|
||||
{data: {root: {context: []}}}
|
||||
).then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
expectGhostClientMeta(rendered);
|
||||
rendered.string.should.match(/url: '\/blog\/ghost\/api\/v0\.1\/'/);
|
||||
rendered.string.should.match(/useOrigin: true/);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('renders correct https url with forceAdminSSL set', function (done) {
|
||||
configUtils.set({
|
||||
url: 'http://testurl.com/',
|
||||
forceAdminSSL: true
|
||||
});
|
||||
|
||||
helpers.ghost_head.call(
|
||||
{safeVersion: '0.3', context: ['paged', 'index'], post: false},
|
||||
{data: {root: {context: []}}}
|
||||
).then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
expectGhostClientMeta(rendered);
|
||||
rendered.string.should.match(/url: 'https:\/\/testurl\.com\/ghost\/api\/v0\.1\/'/);
|
||||
rendered.string.should.match(/useOrigin: false/);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('renders correct https url if urlSSL is set and forceAdminSSL is also set', function (done) {
|
||||
configUtils.set({
|
||||
url: 'http://testurl.com/',
|
||||
urlSSL: 'https://sslurl.com/',
|
||||
forceAdminSSL: true
|
||||
});
|
||||
|
||||
helpers.ghost_head.call(
|
||||
{safeVersion: '0.3', context: ['paged', 'index'], post: false},
|
||||
{data: {root: {context: []}}}
|
||||
).then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
expectGhostClientMeta(rendered);
|
||||
rendered.string.should.match(/url: 'https:\/\/sslurl\.com\/ghost\/api\/v0\.1\/'/);
|
||||
rendered.string.should.match(/useOrigin: false/);
|
||||
rendered.string.should.match(/<script type="text\/javascript">\n/);
|
||||
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();
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user