diff --git a/core/server/adapters/scheduling/post-scheduling/index.js b/core/server/adapters/scheduling/post-scheduling/index.js
index 59c9d2fbff..9e6424b7d7 100644
--- a/core/server/adapters/scheduling/post-scheduling/index.js
+++ b/core/server/adapters/scheduling/post-scheduling/index.js
@@ -3,7 +3,7 @@ const Promise = require('bluebird'),
localUtils = require('../utils'),
common = require('../../../lib/common'),
models = require('../../../models'),
- urlService = require('../../../services/url'),
+ urlUtils = require('../../../lib/url-utils'),
_private = {};
/**
@@ -18,7 +18,7 @@ _private.normalize = function normalize(options) {
// NOTE: The scheduler expects a unix timestmap.
time: moment(model.get('published_at')).valueOf(),
// @TODO: We are still using API v0.1
- url: `${urlService.utils.urlJoin(apiUrl, 'schedules', 'posts', model.get('id'))}?client_id=${client.get('slug')}&client_secret=${client.get('secret')}`,
+ url: `${urlUtils.urlJoin(apiUrl, 'schedules', 'posts', model.get('id'))}?client_id=${client.get('slug')}&client_secret=${client.get('secret')}`,
extra: {
httpMethod: 'PUT',
oldTime: model.previous('published_at') ? moment(model.previous('published_at')).valueOf() : null
diff --git a/core/server/adapters/storage/LocalFileStorage.js b/core/server/adapters/storage/LocalFileStorage.js
index 71d2af0f65..cece529cbd 100644
--- a/core/server/adapters/storage/LocalFileStorage.js
+++ b/core/server/adapters/storage/LocalFileStorage.js
@@ -9,7 +9,7 @@ const serveStatic = require('express').static,
config = require('../../config'),
common = require('../../lib/common'),
constants = require('../../lib/constants'),
- urlService = require('../../services/url'),
+ urlUtils = require('../../lib/url-utils'),
StorageBase = require('ghost-storage-base');
class LocalFileStore extends StorageBase {
@@ -35,8 +35,8 @@ class LocalFileStore extends StorageBase {
.then(() => {
// For local file system storage can use relative path so add a slash
const fullUrl = (
- urlService.utils.urlJoin('/', urlService.utils.getSubdir(),
- urlService.utils.STATIC_IMAGE_URL_PREFIX,
+ urlUtils.urlJoin('/', urlUtils.getSubdir(),
+ urlUtils.STATIC_IMAGE_URL_PREFIX,
targetPath)
).replace(new RegExp(`\\${path.sep}`, 'g'), '/');
@@ -68,8 +68,8 @@ class LocalFileStore extends StorageBase {
// The src for the image must be in URI format, not a file system path, which in Windows uses \
// For local file system storage can use relative path so add a slash
const fullUrl = (
- urlService.utils.urlJoin('/', urlService.utils.getSubdir(),
- urlService.utils.STATIC_IMAGE_URL_PREFIX,
+ urlUtils.urlJoin('/', urlUtils.getSubdir(),
+ urlUtils.STATIC_IMAGE_URL_PREFIX,
path.relative(this.storagePath, targetFilename))
).replace(new RegExp(`\\${path.sep}`, 'g'), '/');
diff --git a/core/server/adapters/storage/utils.js b/core/server/adapters/storage/utils.js
index de2736b9e3..1aa729bee6 100644
--- a/core/server/adapters/storage/utils.js
+++ b/core/server/adapters/storage/utils.js
@@ -1,5 +1,4 @@
-const urlService = require('../../services/url');
-
+const urlUtils = require('../../lib/url-utils');
/**
* @TODO: move `events.js` to here - e.g. storageUtils.getStorage
*/
@@ -15,16 +14,16 @@ const urlService = require('../../services/url');
*/
exports.getLocalFileStoragePath = function getLocalFileStoragePath(imagePath) {
// The '/' in urlJoin is necessary to add the '/' to `content/images`, if no subdirectory is setup
- const urlRegExp = new RegExp(`^${urlService.utils.urlJoin(
- urlService.utils.urlFor('home', true),
- urlService.utils.getSubdir(),
+ const urlRegExp = new RegExp(`^${urlUtils.urlJoin(
+ urlUtils.urlFor('home', true),
+ urlUtils.getSubdir(),
'/',
- urlService.utils.STATIC_IMAGE_URL_PREFIX)}`
+ urlUtils.STATIC_IMAGE_URL_PREFIX)}`
),
- filePathRegExp = new RegExp(`^${urlService.utils.urlJoin(
- urlService.utils.getSubdir(),
+ filePathRegExp = new RegExp(`^${urlUtils.urlJoin(
+ urlUtils.getSubdir(),
'/',
- urlService.utils.STATIC_IMAGE_URL_PREFIX)}`
+ urlUtils.STATIC_IMAGE_URL_PREFIX)}`
);
if (imagePath.match(urlRegExp)) {
diff --git a/core/server/api/v0.1/authentication.js b/core/server/api/v0.1/authentication.js
index 284795bd5c..c133ba7204 100644
--- a/core/server/api/v0.1/authentication.js
+++ b/core/server/api/v0.1/authentication.js
@@ -6,8 +6,8 @@ const Promise = require('bluebird'),
security = require('../../lib/security'),
constants = require('../../lib/constants'),
pipeline = require('../../lib/promise/pipeline'),
+ urlUtils = require('../../lib/url-utils'),
mail = require('../../services/mail'),
- urlService = require('../../services/url'),
localUtils = require('./utils'),
models = require('../../models'),
web = require('../../web'),
@@ -185,8 +185,8 @@ authentication = {
}
function sendResetNotification(data) {
- const adminUrl = urlService.utils.urlFor('admin', true),
- resetUrl = urlService.utils.urlJoin(adminUrl, 'reset', security.url.encodeBase64(data.resetToken), '/');
+ const adminUrl = urlUtils.urlFor('admin', true),
+ resetUrl = urlUtils.urlJoin(adminUrl, 'reset', security.url.encodeBase64(data.resetToken), '/');
return mail.utils.generateContent({
data: {
diff --git a/core/server/api/v0.1/configuration.js b/core/server/api/v0.1/configuration.js
index 9e6ddd17ba..2f22949a7c 100644
--- a/core/server/api/v0.1/configuration.js
+++ b/core/server/api/v0.1/configuration.js
@@ -2,7 +2,7 @@
// RESTful API for browsing the configuration
const Promise = require('bluebird'),
{isPlainObject} = require('lodash'),
- urlService = require('../../services/url'),
+ urlUtils = require('../../lib/url-utils'),
models = require('../../models'),
config = require('../../config'),
labs = require('../../services/labs'),
@@ -29,7 +29,7 @@ function getBaseConfig() {
return {
useGravatar: !config.isPrivacyDisabled('useGravatar'),
publicAPI: labs.isSet('publicAPI'),
- blogUrl: urlService.utils.urlFor('home', true),
+ blogUrl: urlUtils.urlFor('home', true),
blogTitle: settingsCache.get('title'),
clientExtensions: config.get('clientExtensions'),
enableDeveloperExperiments: config.get('enableDeveloperExperiments')
diff --git a/core/server/api/v0.1/decorators/urls.js b/core/server/api/v0.1/decorators/urls.js
index 6971946e98..dd22b80381 100644
--- a/core/server/api/v0.1/decorators/urls.js
+++ b/core/server/api/v0.1/decorators/urls.js
@@ -1,5 +1,5 @@
const urlService = require('../../../services/url');
-const {urlFor, makeAbsoluteUrls} = require('../../../services/url/utils');
+const {urlFor, makeAbsoluteUrls} = require('../../../lib/url-utils');
const urlsForPost = (id, attrs, options) => {
attrs.url = urlService.getUrlByResourceId(id);
diff --git a/core/server/api/v0.1/index.js b/core/server/api/v0.1/index.js
index 17ed4f1125..337bdb8ff8 100644
--- a/core/server/api/v0.1/index.js
+++ b/core/server/api/v0.1/index.js
@@ -7,7 +7,7 @@
const {isEmpty} = require('lodash');
const Promise = require('bluebird');
const models = require('../../models');
-const urlService = require('../../services/url');
+const urlUtils = require('../../lib/url-utils');
const configuration = require('./configuration');
const db = require('./db');
const mail = require('./mail');
@@ -97,7 +97,7 @@ const cacheInvalidationHeader = (req, result) => {
return INVALIDATE_ALL;
} else {
// routeKeywords.preview: 'p'
- return urlService.utils.urlFor({relativeUrl: urlService.utils.urlJoin('/p', post.uuid, '/')});
+ return urlUtils.urlFor({relativeUrl: urlUtils.urlJoin('/p', post.uuid, '/')});
}
}
}
@@ -115,7 +115,7 @@ const cacheInvalidationHeader = (req, result) => {
* @return {String} Resolves to header string
*/
const locationHeader = (req, result) => {
- const apiRoot = urlService.utils.urlFor('api', {version: 'v0.1'});
+ const apiRoot = urlUtils.urlFor('api', {version: 'v0.1'});
let location,
newObject,
statusQuery;
@@ -124,23 +124,23 @@ const locationHeader = (req, result) => {
if (result.hasOwnProperty('posts')) {
newObject = result.posts[0];
statusQuery = `/?status=${newObject.status}`;
- location = urlService.utils.urlJoin(apiRoot, 'posts', newObject.id, statusQuery);
+ location = urlUtils.urlJoin(apiRoot, 'posts', newObject.id, statusQuery);
} else if (result.hasOwnProperty('notifications')) {
newObject = result.notifications[0];
// CASE: you add one notification, but it's a duplicate, the API will return {notifications: []}
if (newObject) {
- location = urlService.utils.urlJoin(apiRoot, 'notifications', newObject.id, '/');
+ location = urlUtils.urlJoin(apiRoot, 'notifications', newObject.id, '/');
}
} else if (result.hasOwnProperty('users')) {
newObject = result.users[0];
- location = urlService.utils.urlJoin(apiRoot, 'users', newObject.id, '/');
+ location = urlUtils.urlJoin(apiRoot, 'users', newObject.id, '/');
} else if (result.hasOwnProperty('tags')) {
newObject = result.tags[0];
- location = urlService.utils.urlJoin(apiRoot, 'tags', newObject.id, '/');
+ location = urlUtils.urlJoin(apiRoot, 'tags', newObject.id, '/');
} else if (result.hasOwnProperty('webhooks')) {
newObject = result.webhooks[0];
- location = urlService.utils.urlJoin(apiRoot, 'webhooks', newObject.id, '/');
+ location = urlUtils.urlJoin(apiRoot, 'webhooks', newObject.id, '/');
}
}
diff --git a/core/server/api/v0.1/invites.js b/core/server/api/v0.1/invites.js
index 9bde6f7714..00c1cc991b 100644
--- a/core/server/api/v0.1/invites.js
+++ b/core/server/api/v0.1/invites.js
@@ -2,7 +2,7 @@ const Promise = require('bluebird'),
{omit, merge} = require('lodash'),
pipeline = require('../../lib/promise/pipeline'),
mail = require('../../services/mail'),
- urlService = require('../../services/url'),
+ urlUtils = require('../../lib/url-utils'),
localUtils = require('./utils'),
models = require('../../models'),
common = require('../../lib/common'),
@@ -106,14 +106,14 @@ const invites = {
return settingsAPI.read({key: 'title'});
})
.then((response) => {
- const adminUrl = urlService.utils.urlFor('admin', true);
+ const adminUrl = urlUtils.urlFor('admin', true);
emailData = {
blogName: response.settings[0].value,
invitedByName: loggedInUser.get('name'),
invitedByEmail: loggedInUser.get('email'),
// @TODO: resetLink sounds weird
- resetLink: urlService.utils.urlJoin(adminUrl, 'signup', security.url.encodeBase64(invite.get('token')), '/')
+ resetLink: urlUtils.urlJoin(adminUrl, 'signup', security.url.encodeBase64(invite.get('token')), '/')
};
return mail.utils.generateContent({data: emailData, template: 'invite-user'});
diff --git a/core/server/api/v2/invites.js b/core/server/api/v2/invites.js
index 4b913bed77..5f365628ca 100644
--- a/core/server/api/v2/invites.js
+++ b/core/server/api/v2/invites.js
@@ -2,7 +2,7 @@ const Promise = require('bluebird');
const common = require('../../lib/common');
const security = require('../../lib/security');
const mailService = require('../../services/mail');
-const urlService = require('../../services/url');
+const urlUtils = require('../../lib/url-utils');
const settingsCache = require('../../services/settings/cache');
const models = require('../../models');
const api = require('./index');
@@ -122,13 +122,13 @@ module.exports = {
.then((_invite) => {
invite = _invite;
- const adminUrl = urlService.utils.urlFor('admin', true);
+ const adminUrl = urlUtils.urlFor('admin', true);
emailData = {
blogName: settingsCache.get('title'),
invitedByName: frame.user.get('name'),
invitedByEmail: frame.user.get('email'),
- resetLink: urlService.utils.urlJoin(adminUrl, 'signup', security.url.encodeBase64(invite.get('token')), '/')
+ resetLink: urlUtils.urlJoin(adminUrl, 'signup', security.url.encodeBase64(invite.get('token')), '/')
};
return mailService.utils.generateContent({data: emailData, template: 'invite-user'});
diff --git a/core/server/api/v2/pages.js b/core/server/api/v2/pages.js
index a5fb776909..5e5dba7764 100644
--- a/core/server/api/v2/pages.js
+++ b/core/server/api/v2/pages.js
@@ -1,6 +1,6 @@
const models = require('../../models');
const common = require('../../lib/common');
-const urlService = require('../../services/url');
+const urlUtils = require('../../lib/url-utils');
const ALLOWED_INCLUDES = ['tags', 'authors', 'authors.roles'];
const UNSAFE_ATTRS = ['status', 'authors'];
@@ -142,8 +142,8 @@ module.exports = {
model.get('status') === 'scheduled' && model.wasChanged()
) {
this.headers.cacheInvalidate = {
- value: urlService.utils.urlFor({
- relativeUrl: urlService.utils.urlJoin('/p', model.get('uuid'), '/')
+ value: urlUtils.urlFor({
+ relativeUrl: urlUtils.urlJoin('/p', model.get('uuid'), '/')
})
};
} else {
diff --git a/core/server/api/v2/posts.js b/core/server/api/v2/posts.js
index 09f244fbfd..70fd329168 100644
--- a/core/server/api/v2/posts.js
+++ b/core/server/api/v2/posts.js
@@ -1,6 +1,6 @@
const models = require('../../models');
const common = require('../../lib/common');
-const urlService = require('../../services/url');
+const urlUtils = require('../../lib/url-utils');
const allowedIncludes = ['tags', 'authors', 'authors.roles'];
const unsafeAttrs = ['status', 'authors'];
@@ -146,8 +146,8 @@ module.exports = {
model.get('status') === 'scheduled' && model.wasChanged()
) {
this.headers.cacheInvalidate = {
- value: urlService.utils.urlFor({
- relativeUrl: urlService.utils.urlJoin('/p', model.get('uuid'), '/')
+ value: urlUtils.urlFor({
+ relativeUrl: urlUtils.urlJoin('/p', model.get('uuid'), '/')
})
};
} else {
diff --git a/core/server/api/v2/site.js b/core/server/api/v2/site.js
index bad1dd5245..68cb903640 100644
--- a/core/server/api/v2/site.js
+++ b/core/server/api/v2/site.js
@@ -1,6 +1,6 @@
const ghostVersion = require('../../lib/ghost-version');
const settingsCache = require('../../services/settings/cache');
-const urlService = require('../../services/url');
+const urlUtils = require('../../lib/url-utils');
const site = {
docName: 'site',
@@ -10,7 +10,7 @@ const site = {
query() {
return {
title: settingsCache.get('title'),
- url: urlService.utils.urlFor('home', true),
+ url: urlUtils.urlFor('home', true),
version: ghostVersion.safe
};
}
diff --git a/core/server/api/v2/utils/serializers/input/utils/url.js b/core/server/api/v2/utils/serializers/input/utils/url.js
index 4c421a9cc1..31c27bfb0a 100644
--- a/core/server/api/v2/utils/serializers/input/utils/url.js
+++ b/core/server/api/v2/utils/serializers/input/utils/url.js
@@ -1,9 +1,9 @@
const _ = require('lodash');
const url = require('url');
-const utils = require('../../../../../../services/url/utils');
+const urlUtils = require('../../../../../../lib/url-utils');
const handleCanonicalUrl = (canonicalUrl) => {
- const blogURl = utils.getBlogUrl();
+ const blogURl = urlUtils.getBlogUrl();
const isSameProtocol = url.parse(canonicalUrl).protocol === url.parse(blogURl).protocol;
const blogDomain = blogURl.replace(/^http(s?):\/\//, '').replace(/\/$/, '');
const absolute = canonicalUrl.replace(/^http(s?):\/\//, '');
@@ -12,33 +12,33 @@ const handleCanonicalUrl = (canonicalUrl) => {
// Blog URL incl. the same protocol. This allows users to keep e.g. Facebook comments after
// a http -> https switch
if (absolute.startsWith(blogDomain) && isSameProtocol) {
- return utils.absoluteToRelative(canonicalUrl, {withoutSubdirectory: true});
+ return urlUtils.absoluteToRelative(canonicalUrl, {withoutSubdirectory: true});
}
return canonicalUrl;
};
const handleImageUrl = (imageUrl) => {
- const blogDomain = utils.getBlogUrl().replace(/^http(s?):\/\//, '').replace(/\/$/, '');
+ const blogDomain = urlUtils.getBlogUrl().replace(/^http(s?):\/\//, '').replace(/\/$/, '');
const imageUrlAbsolute = imageUrl.replace(/^http(s?):\/\//, '');
- const imagePathRe = new RegExp(`^${blogDomain}/${utils.STATIC_IMAGE_URL_PREFIX}`);
+ const imagePathRe = new RegExp(`^${blogDomain}/${urlUtils.STATIC_IMAGE_URL_PREFIX}`);
if (imagePathRe.test(imageUrlAbsolute)) {
- return utils.absoluteToRelative(imageUrl);
+ return urlUtils.absoluteToRelative(imageUrl);
}
return imageUrl;
};
const handleContentUrls = (content) => {
- const blogDomain = utils.getBlogUrl().replace(/^http(s?):\/\//, '').replace(/\/$/, '');
- const imagePathRe = new RegExp(`(http(s?)://)?${blogDomain}/${utils.STATIC_IMAGE_URL_PREFIX}`, 'g');
+ const blogDomain = urlUtils.getBlogUrl().replace(/^http(s?):\/\//, '').replace(/\/$/, '');
+ const imagePathRe = new RegExp(`(http(s?)://)?${blogDomain}/${urlUtils.STATIC_IMAGE_URL_PREFIX}`, 'g');
const matches = _.uniq(content.match(imagePathRe));
if (matches) {
matches.forEach((match) => {
- const relative = utils.absoluteToRelative(match);
+ const relative = urlUtils.absoluteToRelative(match);
content = content.replace(new RegExp(match, 'g'), relative);
});
}
diff --git a/core/server/api/v2/utils/serializers/output/utils/url.js b/core/server/api/v2/utils/serializers/output/utils/url.js
index ba12e2bd2a..d6d2da321d 100644
--- a/core/server/api/v2/utils/serializers/output/utils/url.js
+++ b/core/server/api/v2/utils/serializers/output/utils/url.js
@@ -1,5 +1,6 @@
const _ = require('lodash');
const urlService = require('../../../../../../services/url');
+const urlUtils = require('../../../../../../lib/url-utils');
const localUtils = require('../../../index');
const forPost = (id, attrs, frame) => {
@@ -26,25 +27,25 @@ const forPost = (id, attrs, frame) => {
attrs.url = urlService
.utils
.urlFor({
- relativeUrl: urlService.utils.urlJoin('/p', attrs.uuid, '/')
+ relativeUrl: urlUtils.urlJoin('/p', attrs.uuid, '/')
}, null, true);
}
}
if (attrs.feature_image) {
- attrs.feature_image = urlService.utils.urlFor('image', {image: attrs.feature_image}, true);
+ attrs.feature_image = urlUtils.urlFor('image', {image: attrs.feature_image}, true);
}
if (attrs.og_image) {
- attrs.og_image = urlService.utils.urlFor('image', {image: attrs.og_image}, true);
+ attrs.og_image = urlUtils.urlFor('image', {image: attrs.og_image}, true);
}
if (attrs.twitter_image) {
- attrs.twitter_image = urlService.utils.urlFor('image', {image: attrs.twitter_image}, true);
+ attrs.twitter_image = urlUtils.urlFor('image', {image: attrs.twitter_image}, true);
}
if (attrs.canonical_url) {
- attrs.canonical_url = urlService.utils.relativeToAbsolute(attrs.canonical_url);
+ attrs.canonical_url = urlUtils.relativeToAbsolute(attrs.canonical_url);
}
if (attrs.html) {
@@ -56,9 +57,9 @@ const forPost = (id, attrs, frame) => {
urlOptions.assetsOnly = false;
}
- attrs.html = urlService.utils.makeAbsoluteUrls(
+ attrs.html = urlUtils.makeAbsoluteUrls(
attrs.html,
- urlService.utils.urlFor('home', true),
+ urlUtils.urlFor('home', true),
attrs.url,
urlOptions
).html();
@@ -77,11 +78,11 @@ const forUser = (id, attrs, options) => {
}
if (attrs.profile_image) {
- attrs.profile_image = urlService.utils.urlFor('image', {image: attrs.profile_image}, true);
+ attrs.profile_image = urlUtils.urlFor('image', {image: attrs.profile_image}, true);
}
if (attrs.cover_image) {
- attrs.cover_image = urlService.utils.urlFor('image', {image: attrs.cover_image}, true);
+ attrs.cover_image = urlUtils.urlFor('image', {image: attrs.cover_image}, true);
}
return attrs;
@@ -93,7 +94,7 @@ const forTag = (id, attrs, options) => {
}
if (attrs.feature_image) {
- attrs.feature_image = urlService.utils.urlFor('image', {image: attrs.feature_image}, true);
+ attrs.feature_image = urlUtils.urlFor('image', {image: attrs.feature_image}, true);
}
return attrs;
@@ -105,20 +106,20 @@ const forSettings = (attrs) => {
if (_.isArray(attrs)) {
attrs.forEach((obj) => {
if (['cover_image', 'logo', 'icon'].includes(obj.key) && obj.value) {
- obj.value = urlService.utils.urlFor('image', {image: obj.value}, true);
+ obj.value = urlUtils.urlFor('image', {image: obj.value}, true);
}
});
} else {
if (attrs.cover_image) {
- attrs.cover_image = urlService.utils.urlFor('image', {image: attrs.cover_image}, true);
+ attrs.cover_image = urlUtils.urlFor('image', {image: attrs.cover_image}, true);
}
if (attrs.logo) {
- attrs.logo = urlService.utils.urlFor('image', {image: attrs.logo}, true);
+ attrs.logo = urlUtils.urlFor('image', {image: attrs.logo}, true);
}
if (attrs.icon) {
- attrs.icon = urlService.utils.urlFor('image', {image: attrs.icon}, true);
+ attrs.icon = urlUtils.urlFor('image', {image: attrs.icon}, true);
}
}
@@ -126,7 +127,7 @@ const forSettings = (attrs) => {
};
const forImage = (path) => {
- return urlService.utils.urlFor('image', {image: path}, true);
+ return urlUtils.urlFor('image', {image: path}, true);
};
module.exports.forPost = forPost;
diff --git a/core/server/apps/amp/index.js b/core/server/apps/amp/index.js
index 2bd76ceebe..fa791ed9c5 100644
--- a/core/server/apps/amp/index.js
+++ b/core/server/apps/amp/index.js
@@ -1,6 +1,6 @@
const router = require('./lib/router'),
registerHelpers = require('./lib/helpers'),
- urlService = require('../../services/url'),
+ urlUtils = require('../../lib/url-utils'),
// Dirty requires
settingsCache = require('../../services/settings/cache');
@@ -11,7 +11,7 @@ function ampRouter(req, res) {
} else {
// routeKeywords.amp: 'amp'
let redirectUrl = req.originalUrl.replace(/amp\/$/, '');
- urlService.utils.redirect301(res, redirectUrl);
+ urlUtils.redirect301(res, redirectUrl);
}
}
diff --git a/core/server/apps/amp/lib/helpers/amp_content.js b/core/server/apps/amp/lib/helpers/amp_content.js
index 4ec659a4cd..e4ef60bb2d 100644
--- a/core/server/apps/amp/lib/helpers/amp_content.js
+++ b/core/server/apps/amp/lib/helpers/amp_content.js
@@ -13,7 +13,7 @@ const Promise = require('bluebird'),
logging = proxy.logging,
i18n = proxy.i18n,
errors = proxy.errors,
- urlService = require('../../../../services/url'),
+ urlUtils = require('../../../../lib/url-utils'),
amperizeCache = {};
let allowedAMPTags = [],
@@ -124,7 +124,7 @@ function getAmperizeHTML(html, post) {
amperize = amperize || new Amperize();
// make relative URLs abolute
- html = urlService.utils.makeAbsoluteUrls(html, urlService.utils.urlFor('home', true), post.url).html();
+ html = urlUtils.makeAbsoluteUrls(html, urlUtils.urlFor('home', true), post.url).html();
if (!amperizeCache[post.id] || moment(new Date(amperizeCache[post.id].updated_at)).diff(new Date(post.updated_at)) < 0) {
return new Promise((resolve) => {
diff --git a/core/server/apps/private-blogging/index.js b/core/server/apps/private-blogging/index.js
index 9ef3f543b9..5d9657033e 100644
--- a/core/server/apps/private-blogging/index.js
+++ b/core/server/apps/private-blogging/index.js
@@ -1,4 +1,4 @@
-const urlService = require('../../services/url'),
+const urlUtils = require('../../lib/url-utils'),
common = require('../../lib/common'),
middleware = require('./lib/middleware'),
router = require('./lib/router'),
@@ -9,8 +9,8 @@ const urlService = require('../../services/url'),
let checkSubdir = function checkSubdir() {
let paths = '';
- if (urlService.utils.getSubdir()) {
- paths = urlService.utils.getSubdir().split('/');
+ if (urlUtils.getSubdir()) {
+ paths = urlUtils.getSubdir().split('/');
if (paths.pop() === PRIVATE_KEYWORD) {
common.logging.error(new common.errors.GhostError({
diff --git a/core/server/apps/private-blogging/lib/middleware.js b/core/server/apps/private-blogging/lib/middleware.js
index 0354aa68ac..74f40fae2a 100644
--- a/core/server/apps/private-blogging/lib/middleware.js
+++ b/core/server/apps/private-blogging/lib/middleware.js
@@ -4,7 +4,7 @@ const session = require('cookie-session');
const crypto = require('crypto');
const path = require('path');
const config = require('../../../config');
-const urlService = require('../../../services/url');
+const urlUtils = require('../../../lib/url-utils');
const constants = require('../../../lib/constants');
const common = require('../../../lib/common');
const settingsCache = require('../../../services/settings/cache');
@@ -99,7 +99,7 @@ const privateBlogging = {
if (isVerified) {
return next();
} else {
- url = urlService.utils.urlFor({relativeUrl: privateRoute});
+ url = urlUtils.urlFor({relativeUrl: privateRoute});
url += '?r=' + encodeURIComponent(req.url);
return res.redirect(url);
}
@@ -108,7 +108,7 @@ const privateBlogging = {
// This is here so a call to /private/ after a session is verified will redirect to home;
isPrivateSessionAuth: function isPrivateSessionAuth(req, res, next) {
if (!res.isPrivateBlog) {
- return res.redirect(urlService.utils.urlFor('home', true));
+ return res.redirect(urlUtils.urlFor('home', true));
}
let hash = req.session.token || '',
@@ -117,7 +117,7 @@ const privateBlogging = {
if (isVerified) {
// redirect to home if user is already authenticated
- return res.redirect(urlService.utils.urlFor('home', true));
+ return res.redirect(urlUtils.urlFor('home', true));
} else {
return next();
}
@@ -140,7 +140,7 @@ const privateBlogging = {
req.session.token = hasher.digest('hex');
req.session.salt = salt;
- return res.redirect(urlService.utils.urlFor({relativeUrl: forward}));
+ return res.redirect(urlUtils.urlFor({relativeUrl: forward}));
} else {
res.error = {
message: common.i18n.t('errors.middleware.privateblogging.wrongPassword')
diff --git a/core/server/apps/subscribers/lib/helpers/subscribe_form.js b/core/server/apps/subscribers/lib/helpers/subscribe_form.js
index 2e1b090c38..53434640fd 100644
--- a/core/server/apps/subscribers/lib/helpers/subscribe_form.js
+++ b/core/server/apps/subscribers/lib/helpers/subscribe_form.js
@@ -5,7 +5,7 @@ const _ = require('lodash'),
proxy = require('../../../../helpers/proxy'),
createFrame = proxy.hbs.handlebars.createFrame,
templates = proxy.templates,
- urlService = proxy.urlService,
+ urlUtils = proxy.urlUtils,
SafeString = proxy.SafeString,
params = ['error', 'success', 'email'];
@@ -43,7 +43,7 @@ module.exports = function subscribe_form(options) { // eslint-disable-line camel
const context = _.merge({}, options.hash, _.pick(root, params), {
// routeKeywords.subscribe: 'subscribe'
- action: urlService.utils.urlJoin('/', urlService.utils.getSubdir(), 'subscribe/'),
+ action: urlUtils.urlJoin('/', urlUtils.getSubdir(), 'subscribe/'),
script: new SafeString(subscribeScript),
hidden: new SafeString(
makeHidden('confirm') +
diff --git a/core/server/apps/subscribers/lib/router.js b/core/server/apps/subscribers/lib/router.js
index 5499d10bc1..6c3cfdeefd 100644
--- a/core/server/apps/subscribers/lib/router.js
+++ b/core/server/apps/subscribers/lib/router.js
@@ -5,6 +5,7 @@ const path = require('path'),
bodyParser = require('body-parser'),
// Dirty requires
common = require('../../../lib/common'),
+ urlUtils = require('../../../lib/url-utils'),
urlService = require('../../../services/url'),
validator = require('../../../data/validation').validator,
routing = require('../../../services/routing'),
@@ -64,7 +65,7 @@ function handleSource(req, res, next) {
delete req.body.location;
delete req.body.referrer;
- const resource = urlService.getResource(urlService.utils.absoluteToRelative(req.body.subscribed_url, {withoutSubdirectory: true}));
+ const resource = urlService.getResource(urlUtils.absoluteToRelative(req.body.subscribed_url, {withoutSubdirectory: true}));
if (resource) {
req.body.post_id = resource.data.id;
diff --git a/core/server/data/db/backup.js b/core/server/data/db/backup.js
index cdfd5b4f7c..91eb5ff0c6 100644
--- a/core/server/data/db/backup.js
+++ b/core/server/data/db/backup.js
@@ -5,14 +5,14 @@ var fs = require('fs-extra'),
Promise = require('bluebird'),
config = require('../../config'),
common = require('../../lib/common'),
- urlService = require('../../services/url'),
+ urlUtils = require('../../lib/url-utils'),
exporter = require('../exporter'),
writeExportFile,
backup;
writeExportFile = function writeExportFile(exportResult) {
- var filename = path.resolve(urlService.utils.urlJoin(config.get('paths').contentPath, 'data', exportResult.filename));
+ var filename = path.resolve(urlUtils.urlJoin(config.get('paths').contentPath, 'data', exportResult.filename));
return fs.writeFile(filename, JSON.stringify(exportResult.data)).return(filename);
};
diff --git a/core/server/data/importer/handlers/image.js b/core/server/data/importer/handlers/image.js
index 730067cc67..d9c1fa44d0 100644
--- a/core/server/data/importer/handlers/image.js
+++ b/core/server/data/importer/handlers/image.js
@@ -2,7 +2,7 @@ var _ = require('lodash'),
Promise = require('bluebird'),
path = require('path'),
config = require('../../../config'),
- urlService = require('../../../services/url'),
+ urlUtils = require('../../../lib/url-utils'),
storage = require('../../../adapters/storage'),
ImageHandler;
@@ -16,7 +16,7 @@ ImageHandler = {
loadFile: function (files, baseDir) {
var store = storage.getStorage(),
baseDirRegex = baseDir ? new RegExp('^' + baseDir + '/') : new RegExp(''),
- imageFolderRegexes = _.map(urlService.utils.STATIC_IMAGE_URL_PREFIX.split('/'), function (dir) {
+ imageFolderRegexes = _.map(urlUtils.STATIC_IMAGE_URL_PREFIX.split('/'), function (dir) {
return new RegExp('^' + dir + '/');
});
@@ -37,7 +37,7 @@ ImageHandler = {
return Promise.map(files, function (image) {
return store.getUniqueFileName(image, image.targetDir).then(function (targetFilename) {
- image.newPath = urlService.utils.urlJoin('/', urlService.utils.getSubdir(), urlService.utils.STATIC_IMAGE_URL_PREFIX,
+ image.newPath = urlUtils.urlJoin('/', urlUtils.getSubdir(), urlUtils.STATIC_IMAGE_URL_PREFIX,
path.relative(config.getContentPath('images'), targetFilename));
return image;
diff --git a/core/server/data/meta/amp_url.js b/core/server/data/meta/amp_url.js
index 0868679e58..cace694171 100644
--- a/core/server/data/meta/amp_url.js
+++ b/core/server/data/meta/amp_url.js
@@ -1,4 +1,4 @@
-var urlService = require('../../services/url'),
+var urlUtils = require('../../lib/url-utils'),
getUrl = require('./url'),
_ = require('lodash');
@@ -6,7 +6,7 @@ function getAmplUrl(data) {
var context = data.context ? data.context : null;
if (_.includes(context, 'post') && !_.includes(context, 'amp')) {
- return urlService.utils.urlJoin(urlService.utils.urlFor('home', true), getUrl(data, false), 'amp/');
+ return urlUtils.urlJoin(urlUtils.urlFor('home', true), getUrl(data, false), 'amp/');
}
return null;
}
diff --git a/core/server/data/meta/asset_url.js b/core/server/data/meta/asset_url.js
index 93b30978eb..8c9a730435 100644
--- a/core/server/data/meta/asset_url.js
+++ b/core/server/data/meta/asset_url.js
@@ -1,7 +1,7 @@
const crypto = require('crypto'),
config = require('../../config'),
imageLib = require('../../lib/image'),
- urlService = require('../../services/url');
+ urlUtils = require('../../lib/url-utils');
/**
* Serve either uploaded favicon or default
@@ -20,11 +20,11 @@ function getAssetUrl(path, hasMinFile) {
// CASE: Build the output URL
// Add subdirectory...
- var output = urlService.utils.urlJoin(urlService.utils.getSubdir(), '/');
+ var output = urlUtils.urlJoin(urlUtils.getSubdir(), '/');
// Optionally add /assets/
if (!path.match(/^public/) && !path.match(/^asset/)) {
- output = urlService.utils.urlJoin(output, 'assets/');
+ output = urlUtils.urlJoin(output, 'assets/');
}
// replace ".foo" with ".min.foo" if configured
@@ -33,7 +33,7 @@ function getAssetUrl(path, hasMinFile) {
}
// Add the path for the requested asset
- output = urlService.utils.urlJoin(output, path);
+ output = urlUtils.urlJoin(output, path);
// Ensure we have an assetHash
// @TODO rework this!
diff --git a/core/server/data/meta/author_image.js b/core/server/data/meta/author_image.js
index 287493f2e7..8d8006ba85 100644
--- a/core/server/data/meta/author_image.js
+++ b/core/server/data/meta/author_image.js
@@ -1,4 +1,4 @@
-var urlService = require('../../services/url'),
+var urlUtils = require('../../lib/url-utils'),
getContextObject = require('./context_object.js'),
_ = require('lodash');
@@ -7,7 +7,7 @@ function getAuthorImage(data, absolute) {
contextObject = getContextObject(data, context);
if ((_.includes(context, 'post') || _.includes(context, 'page')) && contextObject.primary_author && contextObject.primary_author.profile_image) {
- return urlService.utils.urlFor('image', {image: contextObject.primary_author.profile_image}, absolute);
+ return urlUtils.urlFor('image', {image: contextObject.primary_author.profile_image}, absolute);
}
return null;
}
diff --git a/core/server/data/meta/blog_logo.js b/core/server/data/meta/blog_logo.js
index fc5f5e42e5..56229f52bf 100644
--- a/core/server/data/meta/blog_logo.js
+++ b/core/server/data/meta/blog_logo.js
@@ -1,4 +1,4 @@
-var urlService = require('../../services/url'),
+var urlUtils = require('../../lib/url-utils'),
settingsCache = require('../../services/settings/cache'),
imageLib = require('../../lib/image');
@@ -6,7 +6,7 @@ function getBlogLogo() {
var logo = {};
if (settingsCache.get('logo')) {
- logo.url = urlService.utils.urlFor('image', {image: settingsCache.get('logo')}, true);
+ logo.url = urlUtils.urlFor('image', {image: settingsCache.get('logo')}, true);
} else {
// CASE: no publication logo is updated. We can try to use either an uploaded publication icon
// or use the default one to make
diff --git a/core/server/data/meta/canonical_url.js b/core/server/data/meta/canonical_url.js
index 7feb796bba..87a7e70b84 100644
--- a/core/server/data/meta/canonical_url.js
+++ b/core/server/data/meta/canonical_url.js
@@ -1,5 +1,5 @@
const _ = require('lodash');
-const urlService = require('../../services/url');
+const urlUtils = require('../../lib/url-utils');
const getUrl = require('./url');
function getCanonicalUrl(data) {
@@ -8,7 +8,7 @@ function getCanonicalUrl(data) {
return data.post.canonical_url;
}
- let url = urlService.utils.urlJoin(urlService.utils.urlFor('home', true), getUrl(data, false));
+ let url = urlUtils.urlJoin(urlUtils.urlFor('home', true), getUrl(data, false));
if (url.indexOf('/amp/')) {
url = url.replace(/\/amp\/$/i, '/');
diff --git a/core/server/data/meta/cover_image.js b/core/server/data/meta/cover_image.js
index b61a7ece81..b2a3a71833 100644
--- a/core/server/data/meta/cover_image.js
+++ b/core/server/data/meta/cover_image.js
@@ -1,4 +1,4 @@
-var urlService = require('../../services/url'),
+var urlUtils = require('../../lib/url-utils'),
getContextObject = require('./context_object.js'),
_ = require('lodash');
@@ -8,11 +8,11 @@ function getCoverImage(data) {
if (_.includes(context, 'home') || _.includes(context, 'author')) {
if (contextObject.cover_image) {
- return urlService.utils.urlFor('image', {image: contextObject.cover_image}, true);
+ return urlUtils.urlFor('image', {image: contextObject.cover_image}, true);
}
} else {
if (contextObject.feature_image) {
- return urlService.utils.urlFor('image', {image: contextObject.feature_image}, true);
+ return urlUtils.urlFor('image', {image: contextObject.feature_image}, true);
}
}
return null;
diff --git a/core/server/data/meta/index.js b/core/server/data/meta/index.js
index a2d8fb3b37..e063032b13 100644
--- a/core/server/data/meta/index.js
+++ b/core/server/data/meta/index.js
@@ -1,6 +1,6 @@
var Promise = require('bluebird'),
settingsCache = require('../../services/settings/cache'),
- urlService = require('../../services/url'),
+ urlUtils = require('../../lib/url-utils'),
common = require('../../lib/common'),
getUrl = require('./url'),
getImageDimensions = require('./image-dimensions'),
@@ -61,7 +61,7 @@ function getMetaData(data, root) {
blog: {
title: settingsCache.get('title'),
description: settingsCache.get('description'),
- url: urlService.utils.urlFor('home', true),
+ url: urlUtils.urlFor('home', true),
facebook: settingsCache.get('facebook'),
twitter: settingsCache.get('twitter'),
timezone: settingsCache.get('active_timezone'),
diff --git a/core/server/data/meta/og_image.js b/core/server/data/meta/og_image.js
index f55db6372a..556187430e 100644
--- a/core/server/data/meta/og_image.js
+++ b/core/server/data/meta/og_image.js
@@ -1,4 +1,4 @@
-var urlService = require('../../services/url'),
+var urlUtils = require('../../lib/url-utils'),
getContextObject = require('./context_object.js'),
_ = require('lodash');
@@ -8,9 +8,9 @@ function getOgImage(data) {
if (_.includes(context, 'post') || _.includes(context, 'page') || _.includes(context, 'amp')) {
if (contextObject.og_image) {
- return urlService.utils.urlFor('image', {image: contextObject.og_image}, true);
+ return urlUtils.urlFor('image', {image: contextObject.og_image}, true);
} else if (contextObject.feature_image) {
- return urlService.utils.urlFor('image', {image: contextObject.feature_image}, true);
+ return urlUtils.urlFor('image', {image: contextObject.feature_image}, true);
}
}
diff --git a/core/server/data/meta/paginated_url.js b/core/server/data/meta/paginated_url.js
index f4233c5848..c468385d8e 100644
--- a/core/server/data/meta/paginated_url.js
+++ b/core/server/data/meta/paginated_url.js
@@ -1,5 +1,5 @@
var _ = require('lodash'),
- urlService = require('../../services/url');
+ urlUtils = require('../../lib/url-utils');
function getPaginatedUrl(page, data, absolute) {
// If we don't have enough information, return null right away
@@ -7,7 +7,7 @@ function getPaginatedUrl(page, data, absolute) {
return null;
}
// routeKeywords.page: 'page'
- var pagePath = urlService.utils.urlJoin('/page/'),
+ var pagePath = urlUtils.urlJoin('/page/'),
// Try to match the base url, as whatever precedes the pagePath
// routeKeywords.page: 'page'
baseUrlPattern = new RegExp('(.+)?(/page/\\d+/)'),
@@ -17,20 +17,20 @@ function getPaginatedUrl(page, data, absolute) {
newRelativeUrl;
if (page === 'next' && data.pagination.next) {
- newRelativeUrl = urlService.utils.urlJoin(pagePath, data.pagination.next, '/');
+ newRelativeUrl = urlUtils.urlJoin(pagePath, data.pagination.next, '/');
} else if (page === 'prev' && data.pagination.prev) {
- newRelativeUrl = data.pagination.prev > 1 ? urlService.utils.urlJoin(pagePath, data.pagination.prev, '/') : '/';
+ newRelativeUrl = data.pagination.prev > 1 ? urlUtils.urlJoin(pagePath, data.pagination.prev, '/') : '/';
} else if (_.isNumber(page)) {
- newRelativeUrl = page > 1 ? urlService.utils.urlJoin(pagePath, page, '/') : '/';
+ newRelativeUrl = page > 1 ? urlUtils.urlJoin(pagePath, page, '/') : '/';
} else {
// If none of the cases match, return null right away
return null;
}
// baseUrl can be undefined, if there was nothing preceding the pagePath (e.g. first page of the index channel)
- newRelativeUrl = baseUrl ? urlService.utils.urlJoin(baseUrl, newRelativeUrl) : newRelativeUrl;
+ newRelativeUrl = baseUrl ? urlUtils.urlJoin(baseUrl, newRelativeUrl) : newRelativeUrl;
- return urlService.utils.urlFor({relativeUrl: newRelativeUrl, secure: data.secure}, absolute);
+ return urlUtils.urlFor({relativeUrl: newRelativeUrl, secure: data.secure}, absolute);
}
module.exports = getPaginatedUrl;
diff --git a/core/server/data/meta/twitter_image.js b/core/server/data/meta/twitter_image.js
index 9c4b2e3808..1f838a416b 100644
--- a/core/server/data/meta/twitter_image.js
+++ b/core/server/data/meta/twitter_image.js
@@ -1,4 +1,4 @@
-var urlService = require('../../services/url'),
+var urlUtils = require('../../lib/url-utils'),
getContextObject = require('./context_object.js'),
_ = require('lodash');
@@ -8,9 +8,9 @@ function getTwitterImage(data) {
if (_.includes(context, 'post') || _.includes(context, 'page') || _.includes(context, 'amp')) {
if (contextObject.twitter_image) {
- return urlService.utils.urlFor('image', {image: contextObject.twitter_image}, true);
+ return urlUtils.urlFor('image', {image: contextObject.twitter_image}, true);
} else if (contextObject.feature_image) {
- return urlService.utils.urlFor('image', {image: contextObject.feature_image}, true);
+ return urlUtils.urlFor('image', {image: contextObject.feature_image}, true);
}
}
diff --git a/core/server/data/meta/url.js b/core/server/data/meta/url.js
index 0362e4d798..4338987364 100644
--- a/core/server/data/meta/url.js
+++ b/core/server/data/meta/url.js
@@ -1,4 +1,5 @@
var schema = require('../schema').checks,
+ urlUtils = require('../../lib/url-utils'),
urlService = require('../../services/url');
// This cleans the url from any `/amp` postfixes, so we'll never
@@ -26,9 +27,7 @@ function getUrl(data, absolute) {
* A long term solution should be part of the final version of Dynamic Routing.
*/
if (data.status !== 'published' && urlService.getUrlByResourceId(data.id) === '/404/') {
- return urlService
- .utils
- .urlFor({relativeUrl: urlService.utils.urlJoin('/p', data.uuid, '/'), secure: data.secure}, null, absolute);
+ return urlUtils.urlFor({relativeUrl: urlUtils.urlJoin('/p', data.uuid, '/'), secure: data.secure}, null, absolute);
}
return urlService.getUrlByResourceId(data.id, {secure: data.secure, absolute: absolute, withSubdirectory: true});
@@ -39,11 +38,11 @@ function getUrl(data, absolute) {
}
if (schema.isNav(data)) {
- return urlService.utils.urlFor('nav', {nav: data, secure: data.secure}, absolute);
+ return urlUtils.urlFor('nav', {nav: data, secure: data.secure}, absolute);
}
// sanitize any trailing `/amp` in the url
- return sanitizeAmpUrl(urlService.utils.urlFor(data, {}, absolute));
+ return sanitizeAmpUrl(urlUtils.urlFor(data, {}, absolute));
}
module.exports = getUrl;
diff --git a/core/server/data/validation/index.js b/core/server/data/validation/index.js
index f0751e4fc6..d3d35ac8d0 100644
--- a/core/server/data/validation/index.js
+++ b/core/server/data/validation/index.js
@@ -6,7 +6,7 @@ var schema = require('../schema').tables,
Promise = require('bluebird'),
common = require('../../lib/common'),
settingsCache = require('../../services/settings/cache'),
- urlService = require('../../services/url'),
+ urlUtils = require('../../lib/url-utils'),
validatePassword,
validateSchema,
@@ -96,7 +96,7 @@ validator.extend('isSlug', function isSlug(str) {
validatePassword = function validatePassword(password, email, blogTitle) {
var validationResult = {isValid: true},
disallowedPasswords = ['password', 'ghost', 'passw0rd'],
- blogUrl = urlService.utils.urlFor('home', true),
+ blogUrl = urlUtils.urlFor('home', true),
badPasswords = [
'1234567890',
'qwertyuiop',
diff --git a/core/server/data/xml/sitemap/base-generator.js b/core/server/data/xml/sitemap/base-generator.js
index 98c0dc90ef..fcdbb53ace 100644
--- a/core/server/data/xml/sitemap/base-generator.js
+++ b/core/server/data/xml/sitemap/base-generator.js
@@ -2,7 +2,7 @@ const _ = require('lodash'),
xml = require('xml'),
moment = require('moment'),
path = require('path'),
- urlService = require('../../../services/url'),
+ urlUtils = require('../../../lib/url-utils'),
localUtils = require('./utils');
// Sitemap specific xml namespace declarations that should not change
@@ -112,7 +112,7 @@ class BaseSiteMapGenerator {
}
// Grab the image url
- imageUrl = urlService.utils.urlFor('image', {image: image}, true);
+ imageUrl = urlUtils.urlFor('image', {image: image}, true);
// Verify the url structure
if (!this.validateImageUrl(imageUrl)) {
diff --git a/core/server/data/xml/sitemap/index-generator.js b/core/server/data/xml/sitemap/index-generator.js
index 16d50db178..bb87b6e308 100644
--- a/core/server/data/xml/sitemap/index-generator.js
+++ b/core/server/data/xml/sitemap/index-generator.js
@@ -1,7 +1,7 @@
const _ = require('lodash'),
xml = require('xml'),
moment = require('moment'),
- urlService = require('../../../services/url'),
+ urlUtils = require('../../../lib/url-utils'),
localUtils = require('./utils');
const XMLNS_DECLS = {
@@ -29,7 +29,7 @@ class SiteMapIndexGenerator {
generateSiteMapUrlElements() {
return _.map(this.types, (resourceType) => {
- var url = urlService.utils.urlFor({relativeUrl: '/sitemap-' + resourceType.name + '.xml'}, true),
+ var url = urlUtils.urlFor({relativeUrl: '/sitemap-' + resourceType.name + '.xml'}, true),
lastModified = resourceType.lastModified;
return {
diff --git a/core/server/data/xml/sitemap/utils.js b/core/server/data/xml/sitemap/utils.js
index 9a3eb7013b..2b46f78ef5 100644
--- a/core/server/data/xml/sitemap/utils.js
+++ b/core/server/data/xml/sitemap/utils.js
@@ -1,9 +1,9 @@
-var urlService = require('../../../services/url'),
+var urlUtils = require('../../../lib/url-utils'),
sitemapsUtils;
sitemapsUtils = {
getDeclarations: function () {
- var baseUrl = urlService.utils.urlFor('sitemap_xsl', true);
+ var baseUrl = urlUtils.urlFor('sitemap_xsl', true);
baseUrl = baseUrl.replace(/^(http:|https:)/, '');
return '' +
'';
diff --git a/core/server/ghost-server.js b/core/server/ghost-server.js
index 67be59ec08..682dd0f4f0 100644
--- a/core/server/ghost-server.js
+++ b/core/server/ghost-server.js
@@ -6,7 +6,7 @@ var debug = require('ghost-ignition').debug('server'),
path = require('path'),
_ = require('lodash'),
config = require('./config'),
- urlService = require('./services/url'),
+ urlUtils = require('./lib/url-utils'),
common = require('./lib/common'),
moment = require('moment');
@@ -193,7 +193,7 @@ GhostServer.prototype.logStartMessages = function () {
// Startup & Shutdown messages
if (config.get('env') === 'production') {
common.logging.info(common.i18n.t('notices.httpServer.ghostIsRunningIn', {env: config.get('env')}));
- common.logging.info(common.i18n.t('notices.httpServer.yourBlogIsAvailableOn', {url: urlService.utils.urlFor('home', true)}));
+ common.logging.info(common.i18n.t('notices.httpServer.yourBlogIsAvailableOn', {url: urlUtils.urlFor('home', true)}));
common.logging.info(common.i18n.t('notices.httpServer.ctrlCToShutDown'));
} else {
common.logging.info(common.i18n.t('notices.httpServer.ghostIsRunningIn', {env: config.get('env')}));
@@ -201,7 +201,7 @@ GhostServer.prototype.logStartMessages = function () {
host: config.get('server').socket || config.get('server').host,
port: config.get('server').port
}));
- common.logging.info(common.i18n.t('notices.httpServer.urlConfiguredAs', {url: urlService.utils.urlFor('home', true)}));
+ common.logging.info(common.i18n.t('notices.httpServer.urlConfiguredAs', {url: urlUtils.urlFor('home', true)}));
common.logging.info(common.i18n.t('notices.httpServer.ctrlCToShutDown'));
}
diff --git a/core/server/helpers/img_url.js b/core/server/helpers/img_url.js
index 2527fde7fc..d5156c555d 100644
--- a/core/server/helpers/img_url.js
+++ b/core/server/helpers/img_url.js
@@ -10,8 +10,8 @@
const url = require('url');
const _ = require('lodash');
const proxy = require('./proxy');
-const urlService = proxy.urlService;
-const STATIC_IMAGE_URL_PREFIX = `/${urlService.utils.STATIC_IMAGE_URL_PREFIX}`;
+const urlUtils = proxy.urlUtils;
+const STATIC_IMAGE_URL_PREFIX = `/${urlUtils.STATIC_IMAGE_URL_PREFIX}`;
module.exports = function imgUrl(requestedImageUrl, options) {
// CASE: if no url is passed, e.g. `{{img_url}}` we show a warning
@@ -47,11 +47,11 @@ module.exports = function imgUrl(requestedImageUrl, options) {
}
function getImageUrl(image) {
- return urlService.utils.urlFor('image', {image}, absoluteUrlRequested);
+ return urlUtils.urlFor('image', {image}, absoluteUrlRequested);
}
function ensureRelativePath(image) {
- return urlService.utils.absoluteToRelative(image);
+ return urlUtils.absoluteToRelative(image);
}
// CASE: only make paths relative if we didn't get a request for an absolute url
@@ -81,7 +81,7 @@ function getImageSizeOptions(options) {
}
function detectInternalImage(requestedImageUrl) {
- const siteUrl = urlService.utils.getBlogUrl();
+ const siteUrl = urlUtils.getBlogUrl();
const isAbsoluteImage = /https?:\/\//.test(requestedImageUrl);
const isAbsoluteInternalImage = isAbsoluteImage && requestedImageUrl.startsWith(siteUrl);
diff --git a/core/server/helpers/proxy.js b/core/server/helpers/proxy.js
index 59003c58f2..93f76552fe 100644
--- a/core/server/helpers/proxy.js
+++ b/core/server/helpers/proxy.js
@@ -60,5 +60,6 @@ module.exports = {
socialUrls: require('@tryghost/social-urls'),
blogIcon: require('../lib/image/blog-icon'),
urlService: require('../services/url'),
+ urlUtils: require('../lib/url-utils'),
localUtils: require('./utils')
};
diff --git a/core/server/index.js b/core/server/index.js
index 02fe1355b3..3233bf9e75 100644
--- a/core/server/index.js
+++ b/core/server/index.js
@@ -14,7 +14,7 @@ const Promise = require('bluebird');
const config = require('./config');
const common = require('./lib/common');
const migrator = require('./data/db/migrator');
-const urlService = require('./services/url');
+const urlUtils = require('./lib/url-utils');
let parentApp;
function initialiseServices() {
@@ -46,7 +46,7 @@ function initialiseServices() {
active: config.get('scheduling').active,
// NOTE: When changing API version need to consider how to migrate custom scheduling adapters
// that rely on URL to lookup persisted scheduled records (jobs, etc.). Ref: https://github.com/TryGhost/Ghost/pull/10726#issuecomment-489557162
- apiUrl: urlService.utils.urlFor('api', {version: 'v0.1', versionType: 'content'}, true),
+ apiUrl: urlUtils.urlFor('api', {version: 'v0.1', versionType: 'content'}, true),
internalPath: config.get('paths').internalSchedulingPath,
contentPath: config.getContentPath('scheduling')
})
diff --git a/core/server/lib/image/blog-icon.js b/core/server/lib/image/blog-icon.js
index 280ba47aab..9116f624d1 100644
--- a/core/server/lib/image/blog-icon.js
+++ b/core/server/lib/image/blog-icon.js
@@ -4,8 +4,8 @@ var sizeOf = require('image-size'),
path = require('path'),
config = require('../../config'),
common = require('../common'),
+ urlUtils = require('../../lib/url-utils'),
settingsCache = require('../../services/settings/cache'),
- urlService = require('../../services/url'),
storageUtils = require('../../adapters/storage/utils'),
getIconDimensions,
isIcoImageType,
@@ -89,15 +89,15 @@ getIconUrl = function getIconUrl(absolut) {
if (absolut) {
if (blogIcon) {
- return isIcoImageType(blogIcon) ? urlService.utils.urlFor({relativeUrl: '/favicon.ico'}, true) : urlService.utils.urlFor({relativeUrl: '/favicon.png'}, true);
+ return isIcoImageType(blogIcon) ? urlUtils.urlFor({relativeUrl: '/favicon.ico'}, true) : urlUtils.urlFor({relativeUrl: '/favicon.png'}, true);
} else {
- return urlService.utils.urlFor({relativeUrl: '/favicon.ico'}, true);
+ return urlUtils.urlFor({relativeUrl: '/favicon.ico'}, true);
}
} else {
if (blogIcon) {
- return isIcoImageType(blogIcon) ? urlService.utils.urlFor({relativeUrl: '/favicon.ico'}) : urlService.utils.urlFor({relativeUrl: '/favicon.png'});
+ return isIcoImageType(blogIcon) ? urlUtils.urlFor({relativeUrl: '/favicon.ico'}) : urlUtils.urlFor({relativeUrl: '/favicon.png'});
} else {
- return urlService.utils.urlFor({relativeUrl: '/favicon.ico'});
+ return urlUtils.urlFor({relativeUrl: '/favicon.ico'});
}
}
};
diff --git a/core/server/lib/image/image-size.js b/core/server/lib/image/image-size.js
index 83a8c093e7..ea40643e9d 100644
--- a/core/server/lib/image/image-size.js
+++ b/core/server/lib/image/image-size.js
@@ -5,7 +5,7 @@ const url = require('url');
const Promise = require('bluebird');
const _ = require('lodash');
const request = require('../request');
-const urlService = require('../../services/url');
+const urlUtils = require('../../lib/url-utils');
const common = require('../common');
const config = require('../../config');
const storage = require('../../adapters/storage');
@@ -133,7 +133,7 @@ const getImageSizeFromUrl = (imagePath) => {
// CASE: pre 1.0 users were able to use an asset path for their blog logo
if (imagePath.match(/^\/assets/)) {
- imagePath = urlService.utils.urlJoin(urlService.utils.urlFor('home', true), urlService.utils.getSubdir(), '/', imagePath);
+ imagePath = urlUtils.urlJoin(urlUtils.urlFor('home', true), urlUtils.getSubdir(), '/', imagePath);
}
debug('requested imagePath:', imagePath);
@@ -202,7 +202,7 @@ const getImageSizeFromUrl = (imagePath) => {
const getImageSizeFromStoragePath = (imagePath) => {
let filePath;
- imagePath = urlService.utils.urlFor('image', {image: imagePath}, true);
+ imagePath = urlUtils.urlFor('image', {image: imagePath}, true);
// get the storage readable filePath
filePath = storageUtils.getLocalFileStoragePath(imagePath);
diff --git a/core/server/lib/url-utils/index.js b/core/server/lib/url-utils/index.js
new file mode 100644
index 0000000000..372f103a40
--- /dev/null
+++ b/core/server/lib/url-utils/index.js
@@ -0,0 +1,13 @@
+const UrlUtils = require('@tryghost/url-utils');
+const config = require('../../config');
+
+const urlUtils = new UrlUtils({
+ url: config.get('url'),
+ adminUrl: config.get('admin:url'),
+ apiVersions: config.get('api:versions'),
+ slugs: config.get('slugs').protected,
+ redirectCacheMaxAge: config.get('caching:301:maxAge'),
+ baseApiPath: '/ghost/api'
+});
+
+module.exports = urlUtils;
diff --git a/core/server/models/base/index.js b/core/server/models/base/index.js
index 90c278eb33..3570c115b8 100644
--- a/core/server/models/base/index.js
+++ b/core/server/models/base/index.js
@@ -16,7 +16,7 @@ const _ = require('lodash'),
common = require('../../lib/common'),
security = require('../../lib/security'),
schema = require('../../data/schema'),
- urlService = require('../../services/url'),
+ urlUtils = require('../../lib/url-utils'),
validation = require('../../data/validation'),
plugins = require('../plugins');
@@ -1110,7 +1110,7 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
}
// Some keywords cannot be changed
- const slugList = _.union(config.get('slugs').reserved, urlService.utils.getProtectedSlugs());
+ const slugList = _.union(config.get('slugs').reserved, urlUtils.getProtectedSlugs());
slug = _.includes(slugList, slug) ? slug + '-' + baseName : slug;
// if slug is empty after trimming use the model name
diff --git a/core/server/services/auth/session/middleware.js b/core/server/services/auth/session/middleware.js
index e702122d37..2ff99bb9a0 100644
--- a/core/server/services/auth/session/middleware.js
+++ b/core/server/services/auth/session/middleware.js
@@ -6,7 +6,7 @@ const config = require('../../../config');
const settingsCache = require('../../settings/cache');
const models = require('../../../models');
const SessionStore = require('./store');
-const urlService = require('../../url');
+const urlUtils = require('../../../lib/url-utils');
const getOrigin = (req) => {
const origin = req.get('origin');
@@ -39,9 +39,9 @@ const getSession = (req, res, next) => {
cookie: {
maxAge: constants.SIX_MONTH_MS,
httpOnly: true,
- path: urlService.utils.getSubdir() + '/ghost',
+ path: urlUtils.getSubdir() + '/ghost',
sameSite: 'lax',
- secure: urlService.utils.isSSL(config.get('url'))
+ secure: urlUtils.isSSL(config.get('url'))
}
});
}
diff --git a/core/server/services/mail/GhostMailer.js b/core/server/services/mail/GhostMailer.js
index 9581b893d7..bbd2718613 100644
--- a/core/server/services/mail/GhostMailer.js
+++ b/core/server/services/mail/GhostMailer.js
@@ -6,7 +6,7 @@ var _ = require('lodash'),
config = require('../../config'),
common = require('../../lib/common'),
settingsCache = require('../settings/cache'),
- urlService = require('../url');
+ urlUtils = require('../../lib/url-utils');
function GhostMailer() {
var nodemailer = require('nodemailer'),
@@ -39,7 +39,7 @@ GhostMailer.prototype.from = function () {
// Moved it to its own module
GhostMailer.prototype.getDomain = function () {
- var domain = urlService.utils.urlFor('home', true).match(new RegExp('^https?://([^/:?#]+)(?:[/:?#]|$)', 'i'));
+ var domain = urlUtils.urlFor('home', true).match(new RegExp('^https?://([^/:?#]+)(?:[/:?#]|$)', 'i'));
return domain && domain[1];
};
diff --git a/core/server/services/mail/utils.js b/core/server/services/mail/utils.js
index e0b2887f63..6b627fe813 100644
--- a/core/server/services/mail/utils.js
+++ b/core/server/services/mail/utils.js
@@ -2,7 +2,7 @@ var _ = require('lodash').runInContext(),
fs = require('fs-extra'),
path = require('path'),
htmlToText = require('html-to-text'),
- urlService = require('../url'),
+ urlUtils = require('../../lib/url-utils'),
templatesDir = path.resolve(__dirname, '..', 'mail', 'templates');
_.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
@@ -12,7 +12,7 @@ exports.generateContent = function generateContent(options) {
data;
defaults = {
- siteUrl: urlService.utils.urlFor('home', true)
+ siteUrl: urlUtils.urlFor('home', true)
};
data = _.defaults(defaults, options.data);
diff --git a/core/server/services/members/api.js b/core/server/services/members/api.js
index a8b9069f4a..99721fce41 100644
--- a/core/server/services/members/api.js
+++ b/core/server/services/members/api.js
@@ -1,6 +1,6 @@
const url = require('url');
const settingsCache = require('../settings/cache');
-const urlService = require('../url');
+const urlUtils = require('../../lib/url-utils');
const MembersApi = require('@tryghost/members-api');
const MembersSSR = require('@tryghost/members-ssr');
const common = require('../../lib/common');
@@ -110,7 +110,7 @@ function getSubscriptionSettings() {
return membersSettings;
}
-const siteUrl = urlService.utils.getSiteUrl();
+const siteUrl = urlUtils.getSiteUrl();
const siteOrigin = doBlock(() => {
const {protocol, host} = url.parse(siteUrl);
return `${protocol}//${host}`;
@@ -118,7 +118,7 @@ const siteOrigin = doBlock(() => {
const getApiUrl = ({version, type}) => {
const {href} = new url.URL(
- urlService.utils.getApiPath({version, type}),
+ urlUtils.getApiPath({version, type}),
siteUrl
);
return href;
@@ -217,7 +217,7 @@ common.events.on('settings.edited', updateSettingFromModel);
module.exports = membersApiInstance;
module.exports.ssr = MembersSSR({
- cookieSecure: urlService.utils.isSSL(siteUrl),
+ cookieSecure: urlUtils.isSSL(siteUrl),
cookieKeys: [settingsCache.get('theme_session_secret')],
membersApi: membersApiInstance
});
diff --git a/core/server/services/routing/CollectionRouter.js b/core/server/services/routing/CollectionRouter.js
index c679363622..65609f1be2 100644
--- a/core/server/services/routing/CollectionRouter.js
+++ b/core/server/services/routing/CollectionRouter.js
@@ -1,6 +1,6 @@
const debug = require('ghost-ignition').debug('services:routing:collection-router');
const common = require('../../lib/common');
-const urlService = require('../url');
+const urlUtils = require('../../lib/url-utils');
const ParentRouter = require('./ParentRouter');
const controllers = require('./controllers');
@@ -46,7 +46,7 @@ class CollectionRouter extends ParentRouter {
// @NOTE: url options are only required when registering urls in express.
// e.g. the UrlService will access the routes and doesn't want to know about possible url options
if (options.withUrlOptions) {
- return urlService.utils.urlJoin(this.permalinks.value, '/:options(edit)?/');
+ return urlUtils.urlJoin(this.permalinks.value, '/:options(edit)?/');
}
return this.permalinks.value;
@@ -73,7 +73,7 @@ class CollectionRouter extends ParentRouter {
// REGISTER: enable pagination by default
this.router().param('page', middlewares.pageParam);
- this.mountRoute(urlService.utils.urlJoin(this.route.value, 'page', ':page(\\d+)'), controllers.collection);
+ this.mountRoute(urlUtils.urlJoin(this.route.value, 'page', ':page(\\d+)'), controllers.collection);
// REGISTER: is rss enabled?
if (this.rss) {
@@ -179,7 +179,7 @@ class CollectionRouter extends ParentRouter {
getRoute(options) {
options = options || {};
- return urlService.utils.createUrl(this.route.value, options.absolute, options.secure);
+ return urlUtils.createUrl(this.route.value, options.absolute, options.secure);
}
/**
@@ -192,7 +192,7 @@ class CollectionRouter extends ParentRouter {
return null;
}
- return urlService.utils.createUrl(urlService.utils.urlJoin(this.route.value, this.rssRouter.route.value), options.absolute, options.secure);
+ return urlUtils.createUrl(urlUtils.urlJoin(this.route.value, this.rssRouter.route.value), options.absolute, options.secure);
}
reset() {
diff --git a/core/server/services/routing/ParentRouter.js b/core/server/services/routing/ParentRouter.js
index 8d330d9500..a7b3f342f2 100644
--- a/core/server/services/routing/ParentRouter.js
+++ b/core/server/services/routing/ParentRouter.js
@@ -13,7 +13,7 @@ const debug = require('ghost-ignition').debug('services:routing:ParentRouter'),
_ = require('lodash'),
url = require('url'),
security = require('../../lib/security'),
- urlService = require('../url'),
+ urlUtils = require('../../lib/url-utils'),
registry = require('./registry');
/**
@@ -107,8 +107,8 @@ class ParentRouter extends EventEmitter {
const matchPath = this.permalinks.getValue().replace(/:\w+/g, '[a-zA-Z0-9-_]+');
const toAppend = req.url.replace(new RegExp(matchPath), '');
- return urlService.utils.redirect301(res, url.format({
- pathname: urlService.utils.createUrl(urlService.utils.urlJoin(targetRoute, toAppend), false, false, true),
+ return urlUtils.redirect301(res, url.format({
+ pathname: urlUtils.createUrl(urlUtils.urlJoin(targetRoute, toAppend), false, false, true),
search: url.parse(req.originalUrl).search
}));
}
@@ -201,7 +201,7 @@ class ParentRouter extends EventEmitter {
getRoute(options) {
options = options || {};
- return urlService.utils.createUrl(this.route.value, options.absolute, options.secure);
+ return urlUtils.createUrl(this.route.value, options.absolute, options.secure);
}
/**
diff --git a/core/server/services/routing/PreviewRouter.js b/core/server/services/routing/PreviewRouter.js
index 91ab22ffad..8c9d40f3ca 100644
--- a/core/server/services/routing/PreviewRouter.js
+++ b/core/server/services/routing/PreviewRouter.js
@@ -1,5 +1,5 @@
const ParentRouter = require('./ParentRouter');
-const urlService = require('../url');
+const urlUtils = require('../../lib/url-utils');
const controllers = require('./controllers');
/**
@@ -26,7 +26,7 @@ class PreviewRouter extends ParentRouter {
this.router().use(this._prepareContext.bind(this));
// REGISTER: actual preview route
- this.mountRoute(urlService.utils.urlJoin(this.route.value, ':uuid', ':options?'), controllers.preview);
+ this.mountRoute(urlUtils.urlJoin(this.route.value, ':uuid', ':options?'), controllers.preview);
}
/**
diff --git a/core/server/services/routing/RSSRouter.js b/core/server/services/routing/RSSRouter.js
index 034d3bdf0a..02b73b6eee 100644
--- a/core/server/services/routing/RSSRouter.js
+++ b/core/server/services/routing/RSSRouter.js
@@ -1,5 +1,5 @@
const ParentRouter = require('./ParentRouter');
-const urlService = require('../url');
+const urlUtils = require('../../lib/url-utils');
const controllers = require('./controllers');
const middlewares = require('./middlewares');
@@ -28,7 +28,7 @@ class RSSRouter extends ParentRouter {
this.router().param('page', middlewares.pageParam);
// REGISTER: actual rss route
- this.mountRoute(urlService.utils.urlJoin(this.route.value, ':page(\\d+)'), controllers.rss);
+ this.mountRoute(urlUtils.urlJoin(this.route.value, ':page(\\d+)'), controllers.rss);
// REGISTER: redirect rule
this.mountRoute('/feed/', this._redirectFeedRequest.bind(this));
@@ -41,11 +41,10 @@ class RSSRouter extends ParentRouter {
* @private
*/
_redirectFeedRequest(req, res) {
- urlService
- .utils
+ urlUtils
.redirect301(
res,
- urlService.utils.urlJoin(urlService.utils.getSubdir(), req.baseUrl, this.route.value)
+ urlUtils.urlJoin(urlUtils.getSubdir(), req.baseUrl, this.route.value)
);
}
}
diff --git a/core/server/services/routing/StaticPagesRouter.js b/core/server/services/routing/StaticPagesRouter.js
index 7e8108735f..3f326f43e8 100644
--- a/core/server/services/routing/StaticPagesRouter.js
+++ b/core/server/services/routing/StaticPagesRouter.js
@@ -1,5 +1,5 @@
const debug = require('ghost-ignition').debug('services:routing:static-pages-router');
-const urlService = require('../url');
+const urlUtils = require('../../lib/url-utils');
const ParentRouter = require('./ParentRouter');
const controllers = require('./controllers');
const common = require('../../lib/common');
@@ -24,7 +24,7 @@ class StaticPagesRouter extends ParentRouter {
// @NOTE: url options are only required when registering urls in express.
// e.g. the UrlService will access the routes and doesn't want to know about possible url options
if (options.withUrlOptions) {
- return urlService.utils.urlJoin(this.permalinks.value, '/:options(edit)?/');
+ return urlUtils.urlJoin(this.permalinks.value, '/:options(edit)?/');
}
return this.permalinks.value;
diff --git a/core/server/services/routing/StaticRoutesRouter.js b/core/server/services/routing/StaticRoutesRouter.js
index d00e56a3ca..e0afc6ff1e 100644
--- a/core/server/services/routing/StaticRoutesRouter.js
+++ b/core/server/services/routing/StaticRoutesRouter.js
@@ -1,6 +1,6 @@
const debug = require('ghost-ignition').debug('services:routing:static-routes-router');
const common = require('../../lib/common');
-const urlService = require('../../services/url');
+const urlUtils = require('../../lib/url-utils');
const RSSRouter = require('./RSSRouter');
const controllers = require('./controllers');
const middlewares = require('./middlewares');
@@ -59,7 +59,7 @@ class StaticRoutesRouter extends ParentRouter {
// REGISTER: pagination
this.router().param('page', middlewares.pageParam);
- this.mountRoute(urlService.utils.urlJoin(this.route.value, 'page', ':page(\\d+)'), controllers[this.controller]);
+ this.mountRoute(urlUtils.urlJoin(this.route.value, 'page', ':page(\\d+)'), controllers[this.controller]);
common.events.emit('router.created', this);
}
diff --git a/core/server/services/routing/TaxonomyRouter.js b/core/server/services/routing/TaxonomyRouter.js
index 5103e80de1..1b3209d641 100644
--- a/core/server/services/routing/TaxonomyRouter.js
+++ b/core/server/services/routing/TaxonomyRouter.js
@@ -2,7 +2,7 @@ const debug = require('ghost-ignition').debug('services:routing:taxonomy-router'
const common = require('../../lib/common');
const ParentRouter = require('./ParentRouter');
const RSSRouter = require('./RSSRouter');
-const urlService = require('../url');
+const urlUtils = require('../../lib/url-utils');
const controllers = require('./controllers');
const middlewares = require('./middlewares');
@@ -50,10 +50,10 @@ class TaxonomyRouter extends ParentRouter {
// REGISTER: enable pagination for each taxonomy by default
this.router().param('page', middlewares.pageParam);
- this.mountRoute(urlService.utils.urlJoin(this.permalinks.value, 'page', ':page(\\d+)'), controllers.channel);
+ this.mountRoute(urlUtils.urlJoin(this.permalinks.value, 'page', ':page(\\d+)'), controllers.channel);
// REGISTER: edit redirect to admin client e.g. /tag/:slug/edit
- this.mountRoute(urlService.utils.urlJoin(this.permalinks.value, 'edit'), this._redirectEditOption.bind(this));
+ this.mountRoute(urlUtils.urlJoin(this.permalinks.value, 'edit'), this._redirectEditOption.bind(this));
common.events.emit('router.created', this);
}
@@ -88,7 +88,7 @@ class TaxonomyRouter extends ParentRouter {
* @private
*/
_redirectEditOption(req, res) {
- urlService.utils.redirectToAdmin(302, res, this.RESOURCE_CONFIG.TAXONOMIES[this.taxonomyKey].editRedirect.replace(':slug', req.params.slug));
+ urlUtils.redirectToAdmin(302, res, this.RESOURCE_CONFIG.TAXONOMIES[this.taxonomyKey].editRedirect.replace(':slug', req.params.slug));
}
/**
diff --git a/core/server/services/routing/controllers/entry.js b/core/server/services/routing/controllers/entry.js
index 6ac7875c4f..c3c39d5284 100644
--- a/core/server/services/routing/controllers/entry.js
+++ b/core/server/services/routing/controllers/entry.js
@@ -1,6 +1,7 @@
const debug = require('ghost-ignition').debug('services:routing:controllers:entry'),
url = require('url'),
urlService = require('../../url'),
+ urlUtils = require('../../../lib/url-utils'),
helpers = require('../helpers');
/**
@@ -34,7 +35,7 @@ module.exports = function entryController(req, res, next) {
debug('redirect. is edit url');
const resourceType = entry.page ? 'page' : 'post';
- return urlService.utils.redirectToAdmin(302, res, `/editor/${resourceType}/${entry.id}`);
+ return urlUtils.redirectToAdmin(302, res, `/editor/${resourceType}/${entry.id}`);
}
/**
@@ -74,10 +75,10 @@ module.exports = function entryController(req, res, next) {
* @TODO:
* Simplify if we drop v0.1.
*/
- if (urlService.utils.absoluteToRelative(entry.url, {withoutSubdirectory: true}) !== req.path) {
+ if (urlUtils.absoluteToRelative(entry.url, {withoutSubdirectory: true}) !== req.path) {
debug('redirect');
- return urlService.utils.redirect301(res, url.format({
+ return urlUtils.redirect301(res, url.format({
pathname: url.parse(entry.url).pathname,
search: url.parse(req.originalUrl).search
}));
diff --git a/core/server/services/routing/controllers/preview.js b/core/server/services/routing/controllers/preview.js
index ebab3c7ac6..9e81f0fd05 100644
--- a/core/server/services/routing/controllers/preview.js
+++ b/core/server/services/routing/controllers/preview.js
@@ -1,5 +1,6 @@
const debug = require('ghost-ignition').debug('services:routing:controllers:preview'),
urlService = require('../../url'),
+ urlUtils = require('../../../lib/url-utils'),
helpers = require('../helpers');
/**
@@ -37,14 +38,14 @@ module.exports = function previewController(req, res, next) {
const resourceType = post.page ? 'page' : 'post';
// CASE: last param of the url is /edit, redirect to admin
- return urlService.utils.redirectToAdmin(302, res, `/editor/${resourceType}/${post.id}`);
+ return urlUtils.redirectToAdmin(302, res, `/editor/${resourceType}/${post.id}`);
} else if (req.params.options) {
// CASE: unknown options param detected, ignore
return next();
}
if (post.status === 'published') {
- return urlService.utils.redirect301(res, urlService.getUrlByResourceId(post.id, {withSubdirectory: true}));
+ return urlUtils.redirect301(res, urlService.getUrlByResourceId(post.id, {withSubdirectory: true}));
}
// @TODO: See helpers/secure
diff --git a/core/server/services/routing/middlewares/page-param.js b/core/server/services/routing/middlewares/page-param.js
index 38e2ad03c1..201f1740ae 100644
--- a/core/server/services/routing/middlewares/page-param.js
+++ b/core/server/services/routing/middlewares/page-param.js
@@ -1,5 +1,5 @@
const common = require('../../../lib/common'),
- urlService = require('../../url');
+ urlUtils = require('../../../lib/url-utils');
/**
* @description Middleware, which validates and interprets the page param e.g. /page/1
@@ -20,9 +20,9 @@ module.exports = function handlePageParam(req, res, next, page) {
// CASE: page 1 is an alias for the collection index, do a permanent 301 redirect
// @TODO: this belongs into the rss router!
if (rssRegex.test(req.url)) {
- return urlService.utils.redirect301(res, req.originalUrl.replace(rssRegex, '/rss/'));
+ return urlUtils.redirect301(res, req.originalUrl.replace(rssRegex, '/rss/'));
} else {
- return urlService.utils.redirect301(res, req.originalUrl.replace(pageRegex, '/'));
+ return urlUtils.redirect301(res, req.originalUrl.replace(pageRegex, '/'));
}
} else if (page < 1 || isNaN(page)) {
return next(new common.errors.NotFoundError({
diff --git a/core/server/services/rss/generate-feed.js b/core/server/services/rss/generate-feed.js
index 1f0f057a2b..4695272f6b 100644
--- a/core/server/services/rss/generate-feed.js
+++ b/core/server/services/rss/generate-feed.js
@@ -1,6 +1,7 @@
var downsize = require('downsize'),
Promise = require('bluebird'),
RSS = require('rss'),
+ urlUtils = require('../../lib/url-utils'),
urlService = require('../../services/url'),
generateFeed,
generateItem,
@@ -21,7 +22,7 @@ generateTags = function generateTags(data) {
generateItem = function generateItem(post, siteUrl, secure) {
var itemUrl = urlService.getUrlByResourceId(post.id, {secure: secure, absolute: true}),
- htmlContent = urlService.utils.makeAbsoluteUrls(post.html, siteUrl, itemUrl),
+ htmlContent = urlUtils.makeAbsoluteUrls(post.html, siteUrl, itemUrl),
item = {
title: post.title,
// @TODO: DRY this up with data/meta/index & other excerpt code
@@ -36,7 +37,7 @@ generateItem = function generateItem(post, siteUrl, secure) {
imageUrl;
if (post.feature_image) {
- imageUrl = urlService.utils.urlFor('image', {image: post.feature_image, secure: secure}, true);
+ imageUrl = urlUtils.urlFor('image', {image: post.feature_image, secure: secure}, true);
// Add a media content tag
item.custom_elements.push({
@@ -71,14 +72,14 @@ generateItem = function generateItem(post, siteUrl, secure) {
* @param {{title, description, safeVersion, secure, posts}} data
*/
generateFeed = function generateFeed(baseUrl, data) {
- const siteUrl = urlService.utils.urlFor('home', {secure: data.secure}, true);
+ const siteUrl = urlUtils.urlFor('home', {secure: data.secure}, true);
const feed = new RSS({
title: data.title,
description: data.description,
generator: 'Ghost ' + data.safeVersion,
- feed_url: urlService.utils.urlFor({relativeUrl: baseUrl, secure: data.secure}, true),
+ feed_url: urlUtils.urlFor({relativeUrl: baseUrl, secure: data.secure}, true),
site_url: siteUrl,
- image_url: urlService.utils.urlFor({relativeUrl: 'favicon.png'}, true),
+ image_url: urlUtils.urlFor({relativeUrl: 'favicon.png'}, true),
ttl: '60',
custom_namespaces: {
content: 'http://purl.org/rss/1.0/modules/content/',
diff --git a/core/server/services/slack.js b/core/server/services/slack.js
index 0e89973c70..fd1dcc4674 100644
--- a/core/server/services/slack.js
+++ b/core/server/services/slack.js
@@ -1,6 +1,7 @@
var common = require('../lib/common'),
request = require('../lib/request'),
imageLib = require('../lib/image'),
+ urlUtils = require('../lib/url-utils'),
urlService = require('../services/url'),
settingsCache = require('./settings/cache'),
schema = require('../data/schema').checks,
@@ -71,7 +72,7 @@ function ping(post) {
title: title,
title_link: message,
author_name: blogTitle,
- image_url: post ? urlService.utils.urlFor('image', {image: post.feature_image}, true) : null,
+ image_url: post ? urlUtils.urlFor('image', {image: post.feature_image}, true) : null,
color: '#008952',
fields: [
{
@@ -84,7 +85,7 @@ function ping(post) {
{
fallback: 'Sorry, content cannot be shown.',
color: '#008952',
- thumb_url: author ? urlService.utils.urlFor('image', {image: author.profile_image}, true) : null,
+ thumb_url: author ? urlUtils.urlFor('image', {image: author.profile_image}, true) : null,
fields: [
{
title: 'Author',
diff --git a/core/server/services/themes/middleware.js b/core/server/services/themes/middleware.js
index efda48c570..fe0e7a370e 100644
--- a/core/server/services/themes/middleware.js
+++ b/core/server/services/themes/middleware.js
@@ -1,6 +1,6 @@
const _ = require('lodash');
const hbs = require('./engine');
-const urlService = require('../url');
+const urlUtils = require('../../lib/url-utils');
const config = require('../../config');
const common = require('../../lib/common');
const settingsCache = require('../settings/cache');
@@ -75,7 +75,7 @@ function updateLocalTemplateData(req, res, next) {
function updateLocalTemplateOptions(req, res, next) {
const localTemplateOptions = hbs.getLocalTemplateOptions(res.locals);
const siteData = {
- url: urlService.utils.urlFor('home', {secure: req.secure, trailingSlash: false}, true)
+ url: urlUtils.urlFor('home', {secure: req.secure, trailingSlash: false}, true)
};
hbs.updateLocalTemplateOptions(res.locals, _.merge({}, localTemplateOptions, {
diff --git a/core/server/services/url/UrlGenerator.js b/core/server/services/url/UrlGenerator.js
index 7a58f353dc..11f3cebc09 100644
--- a/core/server/services/url/UrlGenerator.js
+++ b/core/server/services/url/UrlGenerator.js
@@ -1,7 +1,7 @@
const _ = require('lodash'),
nql = require('@nexes/nql'),
debug = require('ghost-ignition').debug('services:url:generator'),
- localUtils = require('./utils'),
+ localUtils = require('../../lib/url-utils'),
// @TODO: merge with filter plugin
EXPANSIONS = [{
key: 'author',
diff --git a/core/server/services/url/UrlService.js b/core/server/services/url/UrlService.js
index 320c374c12..1a0ae0020c 100644
--- a/core/server/services/url/UrlService.js
+++ b/core/server/services/url/UrlService.js
@@ -6,7 +6,7 @@ const _debug = require('ghost-ignition').debug._base,
Queue = require('./Queue'),
Urls = require('./Urls'),
Resources = require('./Resources'),
- localUtils = require('./utils');
+ localUtils = require('../../lib/url-utils');
/**
* The url service class holds all instances in a centralised place.
diff --git a/core/server/services/url/Urls.js b/core/server/services/url/Urls.js
index 02d91dbd7a..20fc63c4df 100644
--- a/core/server/services/url/Urls.js
+++ b/core/server/services/url/Urls.js
@@ -1,6 +1,6 @@
const _ = require('lodash');
const debug = require('ghost-ignition').debug('services:url:urls');
-const localUtils = require('./utils');
+const localUtils = require('../../lib/url-utils');
const common = require('../../lib/common');
/**
diff --git a/core/server/services/url/utils.js b/core/server/services/url/utils.js
deleted file mode 100644
index d51377a1cd..0000000000
--- a/core/server/services/url/utils.js
+++ /dev/null
@@ -1,503 +0,0 @@
-// Contains all path information to be used throughout the codebase.
-// Assumes that config.url is set, and is valid
-const moment = require('moment-timezone'),
- _ = require('lodash'),
- url = require('url'),
- cheerio = require('cheerio'),
- config = require('../../config'),
- settingsCache = require('../settings/cache'),
- BASE_API_PATH = '/ghost/api',
- STATIC_IMAGE_URL_PREFIX = 'content/images';
-
-/**
- * Returns API path combining base path and path for specific version asked or deprecated by default
- * @param {Object} options {version} for which to get the path(stable, actice, deprecated),
- * {type} admin|content: defaults to {version: deprecated, type: content}
- * @return {string} API Path for version
- */
-function getApiPath(options) {
- const versionPath = getVersionPath(options);
- return `${BASE_API_PATH}${versionPath}`;
-}
-
-/**
- * Returns path containing only the path for the specific version asked or deprecated by default
- * @param {Object} options {version} for which to get the path(stable, actice, deprecated),
- * {type} admin|content: defaults to {version: deprecated, type: content}
- * @return {string} API version path
- */
-function getVersionPath(options) {
- const apiVersions = config.get('api:versions');
- let requestedVersion = options.version || 'v0.1';
- let requestedVersionType = options.type || 'content';
- let versionData = apiVersions[requestedVersion];
- if (typeof versionData === 'string') {
- versionData = apiVersions[versionData];
- }
- let versionPath = versionData[requestedVersionType];
- return `/${versionPath}/`;
-}
-
-/**
- * Returns the base URL of the blog as set in the config.
- *
- * Secure:
- * If the request is secure, we want to force returning the blog url as https.
- * Imagine Ghost runs with http, but nginx allows SSL connections.
- *
- * @param {boolean} secure
- * @return {string} URL returns the url as defined in config, but always with a trailing `/`
- */
-function getBlogUrl(secure) {
- var blogUrl;
-
- if (secure) {
- blogUrl = config.get('url').replace('http://', 'https://');
- } else {
- blogUrl = config.get('url');
- }
-
- if (!blogUrl.match(/\/$/)) {
- blogUrl += '/';
- }
-
- return blogUrl;
-}
-
-/**
- * Returns a subdirectory URL, if defined so in the config.
- * @return {string} URL a subdirectory if configured.
- */
-function getSubdir() {
- // Parse local path location
- var localPath = url.parse(config.get('url')).path,
- subdir;
-
- // Remove trailing slash
- if (localPath !== '/') {
- localPath = localPath.replace(/\/$/, '');
- }
-
- subdir = localPath === '/' ? '' : localPath;
- return subdir;
-}
-
-function deduplicateSubDir(url) {
- var subDir = getSubdir(),
- subDirRegex;
-
- if (!subDir) {
- return url;
- }
-
- subDir = subDir.replace(/^\/|\/+$/, '');
- // we can have subdirs that match TLDs so we need to restrict matches to
- // duplicates that start with a / or the beginning of the url
- subDirRegex = new RegExp('(^|/)' + subDir + '/' + subDir + '/');
-
- return url.replace(subDirRegex, '$1' + subDir + '/');
-}
-
-function getProtectedSlugs() {
- var subDir = getSubdir();
-
- if (!_.isEmpty(subDir)) {
- return config.get('slugs').protected.concat([subDir.split('/').pop()]);
- } else {
- return config.get('slugs').protected;
- }
-}
-
-/** urlJoin
- * Returns a URL/path for internal use in Ghost.
- * @param {string} arguments takes arguments and concats those to a valid path/URL.
- * @return {string} URL concatinated URL/path of arguments.
- */
-function urlJoin() {
- var args = Array.prototype.slice.call(arguments),
- prefixDoubleSlash = false,
- url;
-
- // Remove empty item at the beginning
- if (args[0] === '') {
- args.shift();
- }
-
- // Handle schemeless protocols
- if (args[0].indexOf('//') === 0) {
- prefixDoubleSlash = true;
- }
-
- // join the elements using a slash
- url = args.join('/');
-
- // Fix multiple slashes
- url = url.replace(/(^|[^:])\/\/+/g, '$1/');
-
- // Put the double slash back at the beginning if this was a schemeless protocol
- if (prefixDoubleSlash) {
- url = url.replace(/^\//, '//');
- }
-
- url = deduplicateSubDir(url);
- return url;
-}
-
-/**
- * admin:url is optional
- */
-function getAdminUrl() {
- var adminUrl = config.get('admin:url'),
- subDir = getSubdir();
-
- if (!adminUrl) {
- return;
- }
-
- if (!adminUrl.match(/\/$/)) {
- adminUrl += '/';
- }
-
- adminUrl = urlJoin(adminUrl, subDir, '/');
- adminUrl = deduplicateSubDir(adminUrl);
- return adminUrl;
-}
-
-// ## createUrl
-// Simple url creation from a given path
-// Ensures that our urls contain the subdirectory if there is one
-// And are correctly formatted as either relative or absolute
-// Usage:
-// createUrl('/', true) -> http://my-ghost-blog.com/
-// E.g. /blog/ subdir
-// createUrl('/welcome-to-ghost/') -> /blog/welcome-to-ghost/
-// Parameters:
-// - urlPath - string which must start and end with a slash
-// - absolute (optional, default:false) - boolean whether or not the url should be absolute
-// - secure (optional, default:false) - boolean whether or not to force SSL
-// Returns:
-// - a URL which always ends with a slash
-function createUrl(urlPath, absolute, secure, trailingSlash) {
- urlPath = urlPath || '/';
- absolute = absolute || false;
- var base;
-
- // create base of url, always ends without a slash
- if (absolute) {
- base = getBlogUrl(secure);
- } else {
- base = getSubdir();
- }
-
- if (trailingSlash) {
- if (!urlPath.match(/\/$/)) {
- urlPath += '/';
- }
- }
-
- return urlJoin(base, urlPath);
-}
-
-/**
- * creates the url path for a post based on blog timezone and permalink pattern
- */
-function replacePermalink(permalink, resource) {
- let output = permalink,
- primaryTagFallback = 'all',
- publishedAtMoment = moment.tz(resource.published_at || Date.now(), settingsCache.get('active_timezone')),
- permalinkLookUp = {
- year: function () {
- return publishedAtMoment.format('YYYY');
- },
- month: function () {
- return publishedAtMoment.format('MM');
- },
- day: function () {
- return publishedAtMoment.format('DD');
- },
- author: function () {
- return resource.primary_author.slug;
- },
- primary_author: function () {
- return resource.primary_author ? resource.primary_author.slug : primaryTagFallback;
- },
- primary_tag: function () {
- return resource.primary_tag ? resource.primary_tag.slug : primaryTagFallback;
- },
- slug: function () {
- return resource.slug;
- },
- id: function () {
- return resource.id;
- }
- };
-
- // replace tags like :slug or :year with actual values
- output = output.replace(/(:[a-z_]+)/g, function (match) {
- if (_.has(permalinkLookUp, match.substr(1))) {
- return permalinkLookUp[match.substr(1)]();
- }
- });
-
- return output;
-}
-
-// ## urlFor
-// Synchronous url creation for a given context
-// Can generate a url for a named path and given path.
-// Determines what sort of context it has been given, and delegates to the correct generation method,
-// Finally passing to createUrl, to ensure any subdirectory is honoured, and the url is absolute if needed
-// Usage:
-// urlFor('home', true) -> http://my-ghost-blog.com/
-// E.g. /blog/ subdir
-// urlFor({relativeUrl: '/my-static-page/'}) -> /blog/my-static-page/
-// Parameters:
-// - context - a string, or json object describing the context for which you need a url
-// - data (optional) - a json object containing data needed to generate a url
-// - absolute (optional, default:false) - boolean whether or not the url should be absolute
-// This is probably not the right place for this, but it's the best place for now
-// @TODO: rewrite, very hard to read, create private functions!
-function urlFor(context, data, absolute) {
- var urlPath = '/',
- secure, imagePathRe,
- knownObjects = ['image', 'nav'], baseUrl,
- hostname,
-
- // this will become really big
- knownPaths = {
- home: '/',
- sitemap_xsl: '/sitemap.xsl'
- };
-
- // Make data properly optional
- if (_.isBoolean(data)) {
- absolute = data;
- data = null;
- }
-
- // Can pass 'secure' flag in either context or data arg
- secure = (context && context.secure) || (data && data.secure);
-
- if (_.isObject(context) && context.relativeUrl) {
- urlPath = context.relativeUrl;
- } else if (_.isString(context) && _.indexOf(knownObjects, context) !== -1) {
- if (context === 'image' && data.image) {
- urlPath = data.image;
- imagePathRe = new RegExp('^' + getSubdir() + '/' + STATIC_IMAGE_URL_PREFIX);
- absolute = imagePathRe.test(data.image) ? absolute : false;
-
- if (absolute) {
- // Remove the sub-directory from the URL because ghostConfig will add it back.
- urlPath = urlPath.replace(new RegExp('^' + getSubdir()), '');
- baseUrl = getBlogUrl(secure).replace(/\/$/, '');
- urlPath = baseUrl + urlPath;
- }
-
- return urlPath;
- } else if (context === 'nav' && data.nav) {
- urlPath = data.nav.url;
- secure = data.nav.secure || secure;
- baseUrl = getBlogUrl(secure);
- hostname = baseUrl.split('//')[1];
-
- // If the hostname is present in the url
- if (urlPath.indexOf(hostname) > -1
- // do no not apply, if there is a subdomain, or a mailto link
- && !urlPath.split(hostname)[0].match(/\.|mailto:/)
- // do not apply, if there is a port after the hostname
- && urlPath.split(hostname)[1].substring(0, 1) !== ':') {
- // make link relative to account for possible mismatch in http/https etc, force absolute
- urlPath = urlPath.split(hostname)[1];
- urlPath = urlJoin('/', urlPath);
- absolute = true;
- }
- }
- } else if (context === 'home' && absolute) {
- urlPath = getBlogUrl(secure);
-
- // CASE: there are cases where urlFor('home') needs to be returned without trailing
- // slash e. g. the `{{@site.url}}` helper. See https://github.com/TryGhost/Ghost/issues/8569
- if (data && data.trailingSlash === false) {
- urlPath = urlPath.replace(/\/$/, '');
- }
- } else if (context === 'admin') {
- urlPath = getAdminUrl() || getBlogUrl();
-
- if (absolute) {
- urlPath += 'ghost/';
- } else {
- urlPath = '/ghost/';
- }
- } else if (context === 'api') {
- urlPath = getAdminUrl() || getBlogUrl();
- let apiPath = getApiPath({version: 'v0.1', type: 'content'});
- // CASE: with or without protocol? If your blog url (or admin url) is configured to http, it's still possible that e.g. nginx allows both https+http.
- // So it depends how you serve your blog. The main focus here is to avoid cors problems.
- // @TODO: rename cors
- if (data && data.cors) {
- if (!urlPath.match(/^https:/)) {
- urlPath = urlPath.replace(/^.*?:\/\//g, '//');
- }
- }
-
- if (data && data.version) {
- apiPath = getApiPath({version: data.version, type: data.versionType});
- }
-
- if (absolute) {
- urlPath = urlPath.replace(/\/$/, '') + apiPath;
- } else {
- urlPath = apiPath;
- }
- } else if (_.isString(context) && _.indexOf(_.keys(knownPaths), context) !== -1) {
- // trying to create a url for a named path
- urlPath = knownPaths[context];
- }
-
- // This url already has a protocol so is likely an external url to be returned
- // or it is an alternative scheme, protocol-less, or an anchor-only path
- if (urlPath && (urlPath.indexOf('://') !== -1 || urlPath.match(/^(\/\/|#|[a-zA-Z0-9-]+:)/))) {
- return urlPath;
- }
-
- return createUrl(urlPath, absolute, secure);
-}
-
-function isSSL(urlToParse) {
- var protocol = url.parse(urlToParse).protocol;
- return protocol === 'https:';
-}
-
-function redirect301(res, redirectUrl) {
- res.set({'Cache-Control': 'public, max-age=' + config.get('caching:301:maxAge')});
- return res.redirect(301, redirectUrl);
-}
-
-function redirectToAdmin(status, res, adminPath) {
- var redirectUrl = urlJoin(urlFor('admin'), adminPath, '/');
-
- if (status === 301) {
- return redirect301(res, redirectUrl);
- }
- return res.redirect(redirectUrl);
-}
-
-/**
- * Make absolute URLs
- * @param {string} html
- * @param {string} siteUrl (blog URL)
- * @param {string} itemUrl (URL of current context)
- * @returns {object} htmlContent
- * @description Takes html, blog url and item url and converts relative url into
- * absolute urls. Returns an object. The html string can be accessed by calling `html()` on
- * the variable that takes the result of this function
- */
-function makeAbsoluteUrls(html, siteUrl, itemUrl, options = {assetsOnly: false}) {
- html = html || '';
- const htmlContent = cheerio.load(html, {decodeEntities: false});
- const staticImageUrlPrefixRegex = new RegExp(STATIC_IMAGE_URL_PREFIX);
-
- // convert relative resource urls to absolute
- ['href', 'src'].forEach(function forEach(attributeName) {
- htmlContent('[' + attributeName + ']').each(function each(ix, el) {
- el = htmlContent(el);
-
- let attributeValue = el.attr(attributeName);
-
- // if URL is absolute move on to the next element
- try {
- const parsed = url.parse(attributeValue);
-
- if (parsed.protocol) {
- return;
- }
-
- // Do not convert protocol relative URLs
- if (attributeValue.lastIndexOf('//', 0) === 0) {
- return;
- }
- } catch (e) {
- return;
- }
-
- // CASE: don't convert internal links
- if (attributeValue[0] === '#') {
- return;
- }
-
- if (options.assetsOnly && !attributeValue.match(staticImageUrlPrefixRegex)) {
- return;
- }
-
- // compose an absolute URL
- // if the relative URL begins with a '/' use the blog URL (including sub-directory)
- // as the base URL, otherwise use the post's URL.
- const baseUrl = attributeValue[0] === '/' ? siteUrl : itemUrl;
- attributeValue = urlJoin(baseUrl, attributeValue);
- el.attr(attributeName, attributeValue);
- });
- });
-
- return htmlContent;
-}
-
-function absoluteToRelative(urlToModify, options) {
- options = options || {};
-
- const urlObj = url.parse(urlToModify);
- const relativePath = urlObj.pathname;
-
- if (options.withoutSubdirectory) {
- const subDir = getSubdir();
-
- if (!subDir) {
- return relativePath;
- }
-
- const subDirRegex = new RegExp('^' + subDir);
- return relativePath.replace(subDirRegex, '');
- }
-
- return relativePath;
-}
-
-function relativeToAbsolute(url) {
- if (!url.startsWith('/') || url.startsWith('//')) {
- return url;
- }
-
- return createUrl(url, true);
-}
-
-function deduplicateDoubleSlashes(url) {
- return url.replace(/\/\//g, '/');
-}
-
-module.exports.absoluteToRelative = absoluteToRelative;
-module.exports.relativeToAbsolute = relativeToAbsolute;
-module.exports.makeAbsoluteUrls = makeAbsoluteUrls;
-module.exports.getProtectedSlugs = getProtectedSlugs;
-module.exports.getSubdir = getSubdir;
-module.exports.urlJoin = urlJoin;
-module.exports.urlFor = urlFor;
-module.exports.isSSL = isSSL;
-module.exports.replacePermalink = replacePermalink;
-module.exports.redirectToAdmin = redirectToAdmin;
-module.exports.redirect301 = redirect301;
-module.exports.createUrl = createUrl;
-module.exports.deduplicateDoubleSlashes = deduplicateDoubleSlashes;
-module.exports.getApiPath = getApiPath;
-module.exports.getVersionPath = getVersionPath;
-module.exports.getBlogUrl = getBlogUrl;
-module.exports.getSiteUrl = getBlogUrl;
-
-/**
- * If you request **any** image in Ghost, it get's served via
- * http://your-blog.com/content/images/2017/01/02/author.png
- *
- * /content/images/ is a static prefix for serving images!
- *
- * But internally the image is located for example in your custom content path:
- * my-content/another-dir/images/2017/01/02/author.png
- */
-module.exports.STATIC_IMAGE_URL_PREFIX = STATIC_IMAGE_URL_PREFIX;
diff --git a/core/server/update-check.js b/core/server/update-check.js
index 68b3c57eb3..ca51d19acb 100644
--- a/core/server/update-check.js
+++ b/core/server/update-check.js
@@ -16,7 +16,7 @@ const crypto = require('crypto'),
debug = require('ghost-ignition').debug('update-check'),
api = require('./api').v2,
config = require('./config'),
- urlService = require('./services/url'),
+ urlUtils = require('./lib/url-utils'),
common = require('./lib/common'),
request = require('./lib/request'),
ghostVersion = require('./lib/ghost-version'),
@@ -111,7 +111,7 @@ function updateCheckData() {
posts = descriptors.posts.value(),
users = descriptors.users.value(),
npm = descriptors.npm.value(),
- blogUrl = url.parse(urlService.utils.urlFor('home', true)),
+ blogUrl = url.parse(urlUtils.urlFor('home', true)),
blogId = blogUrl.hostname + blogUrl.pathname.replace(/\//, '') + hash.value;
data.blog_id = crypto.createHash('md5').update(blogId).digest('hex');
diff --git a/core/server/web/admin/app.js b/core/server/web/admin/app.js
index 9b9d4dbb7f..6af8258105 100644
--- a/core/server/web/admin/app.js
+++ b/core/server/web/admin/app.js
@@ -3,7 +3,7 @@ const express = require('express');
const serveStatic = require('express').static;
const config = require('../../config');
const constants = require('../../lib/constants');
-const urlService = require('../../services/url');
+const urlUtils = require('../../lib/url-utils');
const shared = require('../shared');
const adminMiddleware = require('./middleware');
@@ -25,7 +25,7 @@ module.exports = function setupAdminApp() {
// Ember CLI's live-reload script
if (config.get('env') === 'development') {
adminApp.get('/ember-cli-live-reload.js', function emberLiveReload(req, res) {
- res.redirect(`http://localhost:4200${urlService.utils.getSubdir()}/ghost/ember-cli-live-reload.js`);
+ res.redirect(`http://localhost:4200${urlUtils.getSubdir()}/ghost/ember-cli-live-reload.js`);
});
}
diff --git a/core/server/web/admin/middleware.js b/core/server/web/admin/middleware.js
index f328188cb9..451dd519b9 100644
--- a/core/server/web/admin/middleware.js
+++ b/core/server/web/admin/middleware.js
@@ -1,12 +1,12 @@
-const urlService = require('../../services/url');
+const urlUtils = require('../../lib/url-utils');
function redirectAdminUrls(req, res, next) {
- const subdir = urlService.utils.getSubdir(),
+ const subdir = urlUtils.getSubdir(),
ghostPathRegex = new RegExp(`^${subdir}/ghost/(.+)`),
ghostPathMatch = req.originalUrl.match(ghostPathRegex);
if (ghostPathMatch) {
- return res.redirect(urlService.utils.urlJoin(urlService.utils.urlFor('admin'), '#', ghostPathMatch[1]));
+ return res.redirect(urlUtils.urlJoin(urlUtils.urlFor('admin'), '#', ghostPathMatch[1]));
}
next();
diff --git a/core/server/web/api/index.js b/core/server/web/api/index.js
index 2d2d433e5b..bbfa2cded6 100644
--- a/core/server/web/api/index.js
+++ b/core/server/web/api/index.js
@@ -1,6 +1,6 @@
const debug = require('ghost-ignition').debug('web:api:default:app');
const express = require('express');
-const urlUtils = require('../../services/url/utils');
+const urlUtils = require('../../lib/url-utils');
const errorHandler = require('../shared/middlewares/error-handler');
const membersService = require('../../services/members');
@@ -22,4 +22,4 @@ module.exports = function setupApiApp() {
debug('Parent API setup end');
return apiApp;
-};
\ No newline at end of file
+};
diff --git a/core/server/web/shared/middlewares/admin-redirects.js b/core/server/web/shared/middlewares/admin-redirects.js
index 5c762e9e73..7f42fa0cd2 100644
--- a/core/server/web/shared/middlewares/admin-redirects.js
+++ b/core/server/web/shared/middlewares/admin-redirects.js
@@ -1,9 +1,9 @@
const express = require('express');
-const urlService = require('../../../services/url');
+const urlUtils = require('../../../lib/url-utils');
const adminRedirect = (path) => {
return function doRedirect(req, res) {
- return urlService.utils.redirectToAdmin(301, res, path);
+ return urlUtils.redirectToAdmin(301, res, path);
};
};
diff --git a/core/server/web/shared/middlewares/api/cors.js b/core/server/web/shared/middlewares/api/cors.js
index 02adfa7521..da35c4b486 100644
--- a/core/server/web/shared/middlewares/api/cors.js
+++ b/core/server/web/shared/middlewares/api/cors.js
@@ -2,7 +2,7 @@ const cors = require('cors');
const url = require('url');
const os = require('os');
const some = require('lodash/some');
-const urlService = require('../../../../services/url');
+const urlUtils = require('../../../../lib/url-utils');
let whitelist = [];
const ENABLE_CORS = {origin: true, maxAge: 86400};
@@ -33,8 +33,8 @@ function getIPs() {
}
function getUrls() {
- const blogHost = url.parse(urlService.utils.urlFor('home', true)).hostname;
- const adminHost = url.parse(urlService.utils.urlFor('admin', true)).hostname;
+ const blogHost = url.parse(urlUtils.urlFor('home', true)).hostname;
+ const adminHost = url.parse(urlUtils.urlFor('admin', true)).hostname;
const urls = [];
urls.push(blogHost);
diff --git a/core/server/web/shared/middlewares/serve-favicon.js b/core/server/web/shared/middlewares/serve-favicon.js
index 52a747f062..da21da236a 100644
--- a/core/server/web/shared/middlewares/serve-favicon.js
+++ b/core/server/web/shared/middlewares/serve-favicon.js
@@ -4,7 +4,7 @@ const crypto = require('crypto');
const config = require('../../../config');
const imageLib = require('../../../lib/image');
const storage = require('../../../adapters/storage');
-const urlService = require('../../../services/url');
+const urlUtils = require('../../../lib/url-utils');
const settingsCache = require('../../../services/settings/cache');
let content;
@@ -46,7 +46,7 @@ function serveFavicon() {
if (settingsCache.get('icon')) {
// depends on the uploaded icon extension
if (originalExtension !== requestedExtension) {
- return res.redirect(302, urlService.utils.urlFor({relativeUrl: `/favicon${originalExtension}`}));
+ return res.redirect(302, urlUtils.urlFor({relativeUrl: `/favicon${originalExtension}`}));
}
storage.getStorage()
@@ -64,7 +64,7 @@ function serveFavicon() {
// CASE: always redirect to .ico for default icon
if (originalExtension !== requestedExtension) {
- return res.redirect(302, urlService.utils.urlFor({relativeUrl: '/favicon.ico'}));
+ return res.redirect(302, urlUtils.urlFor({relativeUrl: '/favicon.ico'}));
}
fs.readFile(filePath, (err, buf) => {
diff --git a/core/server/web/shared/middlewares/serve-public-file.js b/core/server/web/shared/middlewares/serve-public-file.js
index f9178dcf5d..ee391f6ba8 100644
--- a/core/server/web/shared/middlewares/serve-public-file.js
+++ b/core/server/web/shared/middlewares/serve-public-file.js
@@ -2,7 +2,7 @@ const crypto = require('crypto');
const fs = require('fs-extra');
const path = require('path');
const config = require('../../../config');
-const urlService = require('../../../services/url');
+const urlUtils = require('../../../lib/url-utils');
function createPublicFileMiddleware(file, type, maxAge) {
let content;
@@ -24,8 +24,8 @@ function createPublicFileMiddleware(file, type, maxAge) {
let str = buf.toString();
if (type === 'text/xsl' || type === 'text/plain' || type === 'application/javascript') {
- str = str.replace(blogRegex, urlService.utils.urlFor('home', true).replace(/\/$/, ''));
- str = str.replace(apiRegex, urlService.utils.urlFor('api', {cors: true, version: 'v0.1', versionType: 'content'}, true));
+ str = str.replace(blogRegex, urlUtils.urlFor('home', true).replace(/\/$/, ''));
+ str = str.replace(apiRegex, urlUtils.urlFor('api', {cors: true, version: 'v0.1', versionType: 'content'}, true));
}
content = {
diff --git a/core/server/web/shared/middlewares/uncapitalise.js b/core/server/web/shared/middlewares/uncapitalise.js
index cce2ba061d..919c8ced57 100644
--- a/core/server/web/shared/middlewares/uncapitalise.js
+++ b/core/server/web/shared/middlewares/uncapitalise.js
@@ -12,7 +12,7 @@
// req.baseUrl = /blog
// req.path = /ghost/signin/
-const urlService = require('../../../services/url');
+const urlUtils = require('../../../lib/url-utils');
const common = require('../../../lib/common');
const localUtils = require('../utils');
@@ -48,7 +48,7 @@ const uncapitalise = (req, res, next) => {
*/
if (/[A-Z]/.test(decodedURI)) {
redirectPath = (localUtils.removeOpenRedirectFromUrl((req.originalUrl || req.url).replace(pathToTest, pathToTest.toLowerCase())));
- return urlService.utils.redirect301(res, redirectPath);
+ return urlUtils.redirect301(res, redirectPath);
}
next();
diff --git a/core/server/web/shared/middlewares/url-redirects.js b/core/server/web/shared/middlewares/url-redirects.js
index de46e2a0c5..090fa69d03 100644
--- a/core/server/web/shared/middlewares/url-redirects.js
+++ b/core/server/web/shared/middlewares/url-redirects.js
@@ -1,7 +1,7 @@
const url = require('url');
const path = require('path');
const debug = require('ghost-ignition').debug('web:shared:mw:url-redirects');
-const urlService = require('../../../services/url');
+const urlUtils = require('../../../lib/url-utils');
const _private = {};
@@ -28,8 +28,8 @@ _private.redirectUrl = (options) => {
};
_private.getAdminRedirectUrl = (options) => {
- const blogHostWithProtocol = urlService.utils.urlFor('home', true);
- const adminHostWithProtocol = urlService.utils.urlFor('admin', true);
+ const blogHostWithProtocol = urlUtils.urlFor('home', true);
+ const adminHostWithProtocol = urlUtils.urlFor('admin', true);
const adminHostWithoutProtocol = adminHostWithProtocol.replace(/(^\w+:|^)\/\//, '');
const blogHostWithoutProtocol = blogHostWithProtocol.replace(/(^\w+:|^)\/\//, '');
const requestedHost = options.requestedHost;
@@ -37,14 +37,14 @@ _private.getAdminRedirectUrl = (options) => {
const queryParameters = options.queryParameters;
const secure = options.secure;
- debug('getAdminRedirectUrl', requestedHost, requestedUrl, adminHostWithoutProtocol, blogHostWithoutProtocol, urlService.utils.urlJoin(blogHostWithoutProtocol, 'ghost/'));
+ debug('getAdminRedirectUrl', requestedHost, requestedUrl, adminHostWithoutProtocol, blogHostWithoutProtocol, urlUtils.urlJoin(blogHostWithoutProtocol, 'ghost/'));
// CASE: we only redirect the admin access if `admin.url` is configured
// If url and admin.url are not equal AND the requested host does not match, redirect.
// The first condition is the most important, because it ensures that you have a custom admin url configured,
// because we don't force an admin redirect if you have a custom url configured, but no admin url.
- if (adminHostWithoutProtocol !== urlService.utils.urlJoin(blogHostWithoutProtocol, 'ghost/') &&
- adminHostWithoutProtocol !== urlService.utils.urlJoin(requestedHost, urlService.utils.getSubdir(), 'ghost/')) {
+ if (adminHostWithoutProtocol !== urlUtils.urlJoin(blogHostWithoutProtocol, 'ghost/') &&
+ adminHostWithoutProtocol !== urlUtils.urlJoin(requestedHost, urlUtils.getSubdir(), 'ghost/')) {
debug('redirect because admin host does not match');
return _private.redirectUrl({
@@ -55,7 +55,7 @@ _private.getAdminRedirectUrl = (options) => {
}
// CASE: configured admin url is HTTPS, but request is HTTP
- if (urlService.utils.isSSL(adminHostWithProtocol) && !secure) {
+ if (urlUtils.isSSL(adminHostWithProtocol) && !secure) {
debug('redirect because protocol does not match');
return _private.redirectUrl({
@@ -67,7 +67,7 @@ _private.getAdminRedirectUrl = (options) => {
};
_private.getBlogRedirectUrl = (options) => {
- const blogHostWithProtocol = urlService.utils.urlFor('home', true);
+ const blogHostWithProtocol = urlUtils.urlFor('home', true);
const requestedHost = options.requestedHost;
const requestedUrl = options.requestedUrl;
const queryParameters = options.queryParameters;
@@ -76,7 +76,7 @@ _private.getBlogRedirectUrl = (options) => {
debug('getBlogRedirectUrl', requestedHost, requestedUrl, blogHostWithProtocol);
// CASE: configured canonical url is HTTPS, but request is HTTP, redirect to requested host + SSL
- if (urlService.utils.isSSL(blogHostWithProtocol) && !secure) {
+ if (urlUtils.isSSL(blogHostWithProtocol) && !secure) {
debug('redirect because protocol does not match');
return _private.redirectUrl({
@@ -104,7 +104,7 @@ _private.redirect = (req, res, next, redirectFn) => {
if (redirectUrl) {
debug(`url redirect to: ${redirectUrl}`);
- return urlService.utils.redirect301(res, redirectUrl);
+ return urlUtils.redirect301(res, redirectUrl);
}
debug('no url redirect');
diff --git a/core/server/web/site/app.js b/core/server/web/site/app.js
index 87207e7de9..fb76b3726d 100644
--- a/core/server/web/site/app.js
+++ b/core/server/web/site/app.js
@@ -8,13 +8,14 @@ const apps = require('../../services/apps');
const constants = require('../../lib/constants');
const storage = require('../../adapters/storage');
const urlService = require('../../services/url');
+const urlUtils = require('../../lib/url-utils');
const sitemapHandler = require('../../data/xml/sitemap/handler');
const themeMiddleware = require('../../services/themes').middleware;
const membersService = require('../../services/members');
const siteRoutes = require('./routes');
const shared = require('../shared');
-const STATIC_IMAGE_URL_PREFIX = `/${urlService.utils.STATIC_IMAGE_URL_PREFIX}`;
+const STATIC_IMAGE_URL_PREFIX = `/${urlUtils.STATIC_IMAGE_URL_PREFIX}`;
let router;
diff --git a/core/test/regression/api/admin_spec.js b/core/test/regression/api/admin_spec.js
index 6a73e650b3..73f9efa8d1 100644
--- a/core/test/regression/api/admin_spec.js
+++ b/core/test/regression/api/admin_spec.js
@@ -7,6 +7,7 @@ var should = require('should'),
supertest = require('supertest'),
testUtils = require('../../utils/index'),
configUtils = require('../../utils/configUtils'),
+ urlUtils = require('../../utils/urlUtils'),
ghost = testUtils.startGhost,
common = require('../../../server/lib/common/index'),
config = require('../../../server/config/index'),
@@ -120,6 +121,7 @@ describe('Admin Routing', function () {
before(function () {
configUtils.set('url', 'https://localhost:2390');
+ urlUtils.stubUrlUtilsFromConfig();
return ghost({forceStart: true})
.then(function (_ghostServer) {
@@ -129,6 +131,7 @@ describe('Admin Routing', function () {
});
after(function () {
+ urlUtils.restore();
configUtils.restore();
});
diff --git a/core/test/regression/api/v0.1/public_api_spec.js b/core/test/regression/api/v0.1/public_api_spec.js
index 887f9057ef..c599abe1cf 100644
--- a/core/test/regression/api/v0.1/public_api_spec.js
+++ b/core/test/regression/api/v0.1/public_api_spec.js
@@ -7,6 +7,7 @@ var should = require('should'),
testUtils = require('../../../utils/index'),
localUtils = require('./utils'),
configUtils = require('../../../utils/configUtils'),
+ urlUtils = require('../../../utils/urlUtils'),
config = require('../../../../server/config/index'),
models = require('../../../../server/models/index'),
ghost = testUtils.startGhost,
@@ -42,6 +43,7 @@ describe('Public API', function () {
afterEach(function () {
configUtils.restore();
+ urlUtils.restore();
});
it('browse posts', function (done) {
@@ -468,6 +470,7 @@ describe('Public API', function () {
it('ensure origin header on redirect is not getting lost', function (done) {
// NOTE: force a redirect to the admin url
configUtils.set('admin:url', 'http://localhost:9999');
+ urlUtils.stubUrlUtilsFromConfig();
request.get(localUtils.API.getApiQuery('posts?client_id=ghost-test&client_secret=not_available'))
.set('Origin', 'https://example.com')
diff --git a/core/test/regression/api/v2/content/posts_spec.js b/core/test/regression/api/v2/content/posts_spec.js
index f486784631..594837c0d4 100644
--- a/core/test/regression/api/v2/content/posts_spec.js
+++ b/core/test/regression/api/v2/content/posts_spec.js
@@ -4,6 +4,7 @@ const _ = require('lodash');
const testUtils = require('../../../../utils');
const localUtils = require('./utils');
const configUtils = require('../../../../utils/configUtils');
+const urlUtils = require('../../../../utils/urlUtils');
const config = require('../../../../../server/config');
const ghost = testUtils.startGhost;
@@ -22,6 +23,7 @@ describe('Posts', function () {
afterEach(function () {
configUtils.restore();
+ urlUtils.restore();
});
const validKey = localUtils.getValidKey();
@@ -89,6 +91,7 @@ describe('Posts', function () {
it('ensure origin header on redirect is not getting lost', function (done) {
// NOTE: force a redirect to the admin url
configUtils.set('admin:url', 'http://localhost:9999');
+ urlUtils.stubUrlUtilsFromConfig();
request.get(localUtils.API.getApiQuery(`posts?key=${validKey}`))
.set('Origin', 'https://example.com')
diff --git a/core/test/regression/site/frontend_spec.js b/core/test/regression/site/frontend_spec.js
index 9cc32efe26..e8ea49d435 100644
--- a/core/test/regression/site/frontend_spec.js
+++ b/core/test/regression/site/frontend_spec.js
@@ -10,6 +10,7 @@ var should = require('should'),
_ = require('lodash'),
testUtils = require('../../utils'),
configUtils = require('../../utils/configUtils'),
+ urlUtils = require('../../utils/urlUtils'),
config = require('../../../server/config'),
settingsCache = require('../../../server/services/settings/cache'),
origCache = _.cloneDeep(settingsCache),
@@ -479,6 +480,7 @@ describe('Frontend Routing', function () {
before(function () {
configUtils.set('url', 'http://localhost/blog');
+ urlUtils.stubUrlUtilsFromConfig();
return ghost({forceStart: true, subdir: true})
.then(function (_ghostServer) {
@@ -490,6 +492,7 @@ describe('Frontend Routing', function () {
after(function () {
configUtils.restore();
+ urlUtils.restore();
});
it('http://localhost should 404', function (done) {
@@ -557,6 +560,7 @@ describe('Frontend Routing', function () {
before(function () {
configUtils.set('url', 'http://localhost/blog/');
+ urlUtils.stubUrlUtilsFromConfig();
return ghost({forceStart: true, subdir: true})
.then(function (_ghostServer) {
@@ -567,6 +571,7 @@ describe('Frontend Routing', function () {
after(function () {
configUtils.restore();
+ urlUtils.restore();
});
it('http://localhost should 404', function (done) {
@@ -643,6 +648,7 @@ describe('Frontend Routing', function () {
before(function () {
configUtils.set('url', 'http://localhost:2370/');
+ urlUtils.stubUrlUtilsFromConfig();
return ghost({forceStart: true})
.then(function (_ghostServer) {
@@ -653,6 +659,7 @@ describe('Frontend Routing', function () {
after(function () {
configUtils.restore();
+ urlUtils.restore();
});
it('should set links to url over non-HTTPS', function (done) {
@@ -679,6 +686,7 @@ describe('Frontend Routing', function () {
before(function () {
configUtils.set('url', 'http://localhost:2370/');
+ urlUtils.stubUrlUtilsFromConfig();
return ghost({forceStart: true})
.then(function (_ghostServer) {
@@ -689,6 +697,7 @@ describe('Frontend Routing', function () {
after(function () {
configUtils.restore();
+ urlUtils.restore();
});
describe('1 case', function () {
diff --git a/core/test/regression/site/site_spec.js b/core/test/regression/site/site_spec.js
index de2464a943..5c21b34b53 100644
--- a/core/test/regression/site/site_spec.js
+++ b/core/test/regression/site/site_spec.js
@@ -4,6 +4,7 @@ const should = require('should'),
cheerio = require('cheerio'),
testUtils = require('../../utils'),
configUtils = require('../../utils/configUtils'),
+ urlUtils = require('../../utils/urlUtils'),
appsService = require('../../../server/services/apps'),
settingsService = require('../../../server/services/settings'),
themeService = require('../../../server/services/themes'),
@@ -37,9 +38,12 @@ describe('Integration - Web - Site', function () {
});
});
- beforeEach(function () {
+ before(function () {
configUtils.set('url', 'http://example.com');
+ urlUtils.stubUrlUtilsFromConfig();
+ });
+ beforeEach(function () {
sinon.spy(api.posts, 'browse');
});
@@ -49,6 +53,7 @@ describe('Integration - Web - Site', function () {
after(function () {
configUtils.restore();
+ urlUtils.restore();
sinon.restore();
});
@@ -227,8 +232,6 @@ describe('Integration - Web - Site', function () {
});
it('serve theme asset', function () {
- //configUtils.set('url', 'https://example.com');
-
const req = {
secure: true,
method: 'GET',
@@ -309,94 +312,96 @@ describe('Integration - Web - Site', function () {
});
});
});
+ });
+ });
- describe('protocol', function () {
- it('blog is https, request is http', function () {
- configUtils.set('url', 'https://example.com');
+ describe('https', function () {
+ before(function () {
+ configUtils.set('url', 'https://example.com');
+ urlUtils.stubUrlUtilsFromConfig();
+ });
- const req = {
- secure: false,
- host: 'example.com',
- method: 'GET',
- url: '/html-ipsum'
- };
+ after(function () {
+ urlUtils.restore();
+ configUtils.restore();
+ });
- return testUtils.mocks.express.invoke(app, req)
- .then(function (response) {
- response.statusCode.should.eql(301);
- response.headers.location.should.eql('https://example.com/html-ipsum/');
- });
- });
+ describe('protocol', function () {
+ it('blog is https, request is http', function () {
+ const req = {
+ secure: false,
+ host: 'example.com',
+ method: 'GET',
+ url: '/html-ipsum'
+ };
- it('blog is https, request is http, trailing slash exists already', function () {
- configUtils.set('url', 'https://example.com');
-
- const req = {
- secure: false,
- method: 'GET',
- url: '/html-ipsum/',
- host: 'example.com'
- };
-
- return testUtils.mocks.express.invoke(app, req)
- .then(function (response) {
- response.statusCode.should.eql(301);
- response.headers.location.should.eql('https://example.com/html-ipsum/');
- });
- });
+ return testUtils.mocks.express.invoke(app, req)
+ .then(function (response) {
+ response.statusCode.should.eql(301);
+ response.headers.location.should.eql('https://example.com/html-ipsum/');
+ });
});
- describe('assets', function () {
- it('blog is https, request is http', function () {
- configUtils.set('url', 'https://example.com');
+ it('blog is https, request is http, trailing slash exists already', function () {
+ const req = {
+ secure: false,
+ method: 'GET',
+ url: '/html-ipsum/',
+ host: 'example.com'
+ };
- const req = {
- secure: false,
- method: 'GET',
- url: '/public/ghost-sdk.js',
- host: 'example.com'
- };
+ return testUtils.mocks.express.invoke(app, req)
+ .then(function (response) {
+ response.statusCode.should.eql(301);
+ response.headers.location.should.eql('https://example.com/html-ipsum/');
+ });
+ });
+ });
- return testUtils.mocks.express.invoke(app, req)
- .then(function (response) {
- response.statusCode.should.eql(301);
- response.headers.location.should.eql('https://example.com/public/ghost-sdk.js');
- });
- });
+ describe('assets', function () {
+ it('blog is https, request is http', function () {
+ const req = {
+ secure: false,
+ method: 'GET',
+ url: '/public/ghost-sdk.js',
+ host: 'example.com'
+ };
- it('blog is https, request is http', function () {
- configUtils.set('url', 'https://example.com');
+ return testUtils.mocks.express.invoke(app, req)
+ .then(function (response) {
+ response.statusCode.should.eql(301);
+ response.headers.location.should.eql('https://example.com/public/ghost-sdk.js');
+ });
+ });
- const req = {
- secure: false,
- method: 'GET',
- url: '/favicon.png',
- host: 'example.com'
- };
+ it('blog is https, request is http', function () {
+ const req = {
+ secure: false,
+ method: 'GET',
+ url: '/favicon.png',
+ host: 'example.com'
+ };
- return testUtils.mocks.express.invoke(app, req)
- .then(function (response) {
- response.statusCode.should.eql(301);
- response.headers.location.should.eql('https://example.com/favicon.png');
- });
- });
+ return testUtils.mocks.express.invoke(app, req)
+ .then(function (response) {
+ response.statusCode.should.eql(301);
+ response.headers.location.should.eql('https://example.com/favicon.png');
+ });
+ });
- it('blog is https, request is http', function () {
- configUtils.set('url', 'https://example.com');
+ it('blog is https, request is http', function () {
+ const req = {
+ secure: false,
+ method: 'GET',
+ url: '/assets/css/main.css',
+ host: 'example.com'
+ };
- const req = {
- secure: false,
- method: 'GET',
- url: '/assets/css/main.css',
- host: 'example.com'
- };
-
- return testUtils.mocks.express.invoke(app, req)
- .then(function (response) {
- response.statusCode.should.eql(301);
- response.headers.location.should.eql('https://example.com/assets/css/main.css');
- });
- });
+ return testUtils.mocks.express.invoke(app, req)
+ .then(function (response) {
+ response.statusCode.should.eql(301);
+ response.headers.location.should.eql('https://example.com/assets/css/main.css');
+ });
});
});
});
@@ -446,6 +451,7 @@ describe('Integration - Web - Site', function () {
afterEach(function () {
configUtils.restore();
+ urlUtils.restore();
});
after(function () {
@@ -564,6 +570,7 @@ describe('Integration - Web - Site', function () {
afterEach(function () {
configUtils.restore();
+ urlUtils.restore();
});
after(function () {
@@ -624,6 +631,7 @@ describe('Integration - Web - Site', function () {
afterEach(function () {
configUtils.restore();
+ urlUtils.restore();
});
after(function () {
@@ -725,6 +733,7 @@ describe('Integration - Web - Site', function () {
afterEach(function () {
configUtils.restore();
+ urlUtils.restore();
});
after(function () {
@@ -810,6 +819,7 @@ describe('Integration - Web - Site', function () {
afterEach(function () {
configUtils.restore();
+ urlUtils.restore();
});
after(function () {
@@ -948,6 +958,7 @@ describe('Integration - Web - Site', function () {
afterEach(function () {
configUtils.restore();
+ urlUtils.restore();
});
after(function () {
@@ -1050,6 +1061,7 @@ describe('Integration - Web - Site', function () {
afterEach(function () {
configUtils.restore();
+ urlUtils.restore();
});
after(function () {
@@ -1119,6 +1131,7 @@ describe('Integration - Web - Site', function () {
afterEach(function () {
configUtils.restore();
+ urlUtils.restore();
});
after(function () {
@@ -1177,6 +1190,7 @@ describe('Integration - Web - Site', function () {
afterEach(function () {
configUtils.restore();
+ urlUtils.restore();
});
after(function () {
@@ -1382,6 +1396,7 @@ describe('Integration - Web - Site', function () {
afterEach(function () {
configUtils.restore();
+ urlUtils.restore();
});
after(function () {
@@ -1666,6 +1681,7 @@ describe('Integration - Web - Site', function () {
afterEach(function () {
configUtils.restore();
+ urlUtils.restore();
});
after(function () {
@@ -1785,9 +1801,13 @@ describe('Integration - Web - Site', function () {
});
});
+ before(function () {
+ configUtils.set('url', 'http://example.com');
+ urlUtils.stubUrlUtilsFromConfig();
+ });
+
beforeEach(function () {
const postsAPI = require('../../../server/api/v2/posts-public');
- configUtils.set('url', 'http://example.com');
postSpy = sinon.spy(postsAPI.browse, 'query');
});
@@ -1797,6 +1817,7 @@ describe('Integration - Web - Site', function () {
after(function () {
configUtils.restore();
+ urlUtils.restore();
sinon.restore();
});
@@ -2057,94 +2078,96 @@ describe('Integration - Web - Site', function () {
});
});
});
+ });
+ });
- describe('protocol', function () {
- it('blog is https, request is http', function () {
- configUtils.set('url', 'https://example.com');
+ describe('https', function () {
+ before(function () {
+ configUtils.set('url', 'https://example.com');
+ urlUtils.stubUrlUtilsFromConfig();
+ });
- const req = {
- secure: false,
- host: 'example.com',
- method: 'GET',
- url: '/html-ipsum'
- };
+ after(function () {
+ urlUtils.restore();
+ configUtils.restore();
+ });
- return testUtils.mocks.express.invoke(app, req)
- .then(function (response) {
- response.statusCode.should.eql(301);
- response.headers.location.should.eql('https://example.com/html-ipsum/');
- });
- });
+ describe('protocol', function () {
+ it('blog is https, request is http', function () {
+ const req = {
+ secure: false,
+ host: 'example.com',
+ method: 'GET',
+ url: '/html-ipsum'
+ };
- it('blog is https, request is http, trailing slash exists already', function () {
- configUtils.set('url', 'https://example.com');
-
- const req = {
- secure: false,
- method: 'GET',
- url: '/html-ipsum/',
- host: 'example.com'
- };
-
- return testUtils.mocks.express.invoke(app, req)
- .then(function (response) {
- response.statusCode.should.eql(301);
- response.headers.location.should.eql('https://example.com/html-ipsum/');
- });
- });
+ return testUtils.mocks.express.invoke(app, req)
+ .then(function (response) {
+ response.statusCode.should.eql(301);
+ response.headers.location.should.eql('https://example.com/html-ipsum/');
+ });
});
- describe('assets', function () {
- it('blog is https, request is http', function () {
- configUtils.set('url', 'https://example.com');
+ it('blog is https, request is http, trailing slash exists already', function () {
+ const req = {
+ secure: false,
+ method: 'GET',
+ url: '/html-ipsum/',
+ host: 'example.com'
+ };
- const req = {
- secure: false,
- method: 'GET',
- url: '/public/ghost-sdk.js',
- host: 'example.com'
- };
+ return testUtils.mocks.express.invoke(app, req)
+ .then(function (response) {
+ response.statusCode.should.eql(301);
+ response.headers.location.should.eql('https://example.com/html-ipsum/');
+ });
+ });
+ });
- return testUtils.mocks.express.invoke(app, req)
- .then(function (response) {
- response.statusCode.should.eql(301);
- response.headers.location.should.eql('https://example.com/public/ghost-sdk.js');
- });
- });
+ describe('assets', function () {
+ it('blog is https, request is http', function () {
+ const req = {
+ secure: false,
+ method: 'GET',
+ url: '/public/ghost-sdk.js',
+ host: 'example.com'
+ };
- it('blog is https, request is http', function () {
- configUtils.set('url', 'https://example.com');
+ return testUtils.mocks.express.invoke(app, req)
+ .then(function (response) {
+ response.statusCode.should.eql(301);
+ response.headers.location.should.eql('https://example.com/public/ghost-sdk.js');
+ });
+ });
- const req = {
- secure: false,
- method: 'GET',
- url: '/favicon.png',
- host: 'example.com'
- };
+ it('blog is https, request is http', function () {
+ const req = {
+ secure: false,
+ method: 'GET',
+ url: '/favicon.png',
+ host: 'example.com'
+ };
- return testUtils.mocks.express.invoke(app, req)
- .then(function (response) {
- response.statusCode.should.eql(301);
- response.headers.location.should.eql('https://example.com/favicon.png');
- });
- });
+ return testUtils.mocks.express.invoke(app, req)
+ .then(function (response) {
+ response.statusCode.should.eql(301);
+ response.headers.location.should.eql('https://example.com/favicon.png');
+ });
+ });
- it('blog is https, request is http', function () {
- configUtils.set('url', 'https://example.com');
+ it('blog is https, request is http', function () {
+ const req = {
+ secure: false,
+ method: 'GET',
+ url: '/assets/css/main.css',
+ host: 'example.com'
+ };
- const req = {
- secure: false,
- method: 'GET',
- url: '/assets/css/main.css',
- host: 'example.com'
- };
-
- return testUtils.mocks.express.invoke(app, req)
- .then(function (response) {
- response.statusCode.should.eql(301);
- response.headers.location.should.eql('https://example.com/assets/css/main.css');
- });
- });
+ return testUtils.mocks.express.invoke(app, req)
+ .then(function (response) {
+ response.statusCode.should.eql(301);
+ response.headers.location.should.eql('https://example.com/assets/css/main.css');
+ });
});
});
});
@@ -2194,6 +2217,7 @@ describe('Integration - Web - Site', function () {
afterEach(function () {
configUtils.restore();
+ urlUtils.restore();
});
after(function () {
@@ -2312,6 +2336,7 @@ describe('Integration - Web - Site', function () {
afterEach(function () {
configUtils.restore();
+ urlUtils.restore();
});
after(function () {
@@ -2372,6 +2397,7 @@ describe('Integration - Web - Site', function () {
afterEach(function () {
configUtils.restore();
+ urlUtils.restore();
});
after(function () {
@@ -2473,6 +2499,7 @@ describe('Integration - Web - Site', function () {
afterEach(function () {
configUtils.restore();
+ urlUtils.restore();
});
after(function () {
@@ -2558,6 +2585,7 @@ describe('Integration - Web - Site', function () {
afterEach(function () {
configUtils.restore();
+ urlUtils.restore();
});
after(function () {
@@ -2714,6 +2742,7 @@ describe('Integration - Web - Site', function () {
afterEach(function () {
configUtils.restore();
+ urlUtils.restore();
});
after(function () {
@@ -2830,6 +2859,7 @@ describe('Integration - Web - Site', function () {
afterEach(function () {
configUtils.restore();
+ urlUtils.restore();
});
after(function () {
@@ -2899,6 +2929,7 @@ describe('Integration - Web - Site', function () {
afterEach(function () {
configUtils.restore();
+ urlUtils.restore();
});
after(function () {
@@ -2957,6 +2988,7 @@ describe('Integration - Web - Site', function () {
afterEach(function () {
configUtils.restore();
+ urlUtils.restore();
});
after(function () {
@@ -3142,6 +3174,7 @@ describe('Integration - Web - Site', function () {
afterEach(function () {
configUtils.restore();
+ urlUtils.restore();
});
after(function () {
@@ -3392,6 +3425,7 @@ describe('Integration - Web - Site', function () {
afterEach(function () {
configUtils.restore();
+ urlUtils.restore();
});
after(function () {
diff --git a/core/test/unit/adapters/scheduling/post-scheduling/index_spec.js b/core/test/unit/adapters/scheduling/post-scheduling/index_spec.js
index a227ba34af..996038c51d 100644
--- a/core/test/unit/adapters/scheduling/post-scheduling/index_spec.js
+++ b/core/test/unit/adapters/scheduling/post-scheduling/index_spec.js
@@ -9,7 +9,7 @@ var should = require('should'),
schedulingUtils = require('../../../../../server/adapters/scheduling/utils'),
SchedulingDefault = require('../../../../../server/adapters/scheduling/SchedulingDefault'),
postScheduling = require('../../../../../server/adapters/scheduling/post-scheduling'),
- urlService = require('../../../../../server/services/url');
+ urlUtils = require('../../../../../server/lib/url-utils');
describe('Scheduling: Post Scheduling', function () {
var scope = {
@@ -68,7 +68,7 @@ describe('Scheduling: Post Scheduling', function () {
scope.adapter.schedule.calledWith({
time: moment(scope.post.get('published_at')).valueOf(),
- url: urlService.utils.urlJoin(scope.apiUrl, 'schedules', 'posts', scope.post.get('id')) + '?client_id=' + scope.client.get('slug') + '&client_secret=' + scope.client.get('secret'),
+ url: urlUtils.urlJoin(scope.apiUrl, 'schedules', 'posts', scope.post.get('id')) + '?client_id=' + scope.client.get('slug') + '&client_secret=' + scope.client.get('secret'),
extra: {
httpMethod: 'PUT',
oldTime: null
diff --git a/core/test/unit/adapters/storage/utils_spec.js b/core/test/unit/adapters/storage/utils_spec.js
index 59d7140238..21a757e7ff 100644
--- a/core/test/unit/adapters/storage/utils_spec.js
+++ b/core/test/unit/adapters/storage/utils_spec.js
@@ -1,6 +1,6 @@
var should = require('should'),
sinon = require('sinon'),
- urlService = require('../../../../server/services/url'),
+ urlUtils = require('../../../../server/lib/url-utils'),
// Stuff we are testing
storageUtils = require('../../../../server/adapters/storage/utils');
@@ -22,9 +22,9 @@ describe('storage utils', function () {
var url = 'http://myblog.com/content/images/2017/07/ghost-logo.png',
result;
- urlForStub = sinon.stub(urlService.utils, 'urlFor');
+ urlForStub = sinon.stub(urlUtils, 'urlFor');
urlForStub.withArgs('home').returns('http://myblog.com/');
- urlGetSubdirStub = sinon.stub(urlService.utils, 'getSubdir');
+ urlGetSubdirStub = sinon.stub(urlUtils, 'getSubdir');
urlGetSubdirStub.returns('');
result = storageUtils.getLocalFileStoragePath(url);
@@ -39,9 +39,9 @@ describe('storage utils', function () {
var url = 'https://myblog.com/content/images/2017/07/ghost-logo.png',
result;
- urlForStub = sinon.stub(urlService.utils, 'urlFor');
+ urlForStub = sinon.stub(urlUtils, 'urlFor');
urlForStub.withArgs('home').returns('http://myblog.com/');
- urlGetSubdirStub = sinon.stub(urlService.utils, 'getSubdir');
+ urlGetSubdirStub = sinon.stub(urlUtils, 'getSubdir');
urlGetSubdirStub.returns('');
result = storageUtils.getLocalFileStoragePath(url);
@@ -53,9 +53,9 @@ describe('storage utils', function () {
var url = 'http://myblog.com/blog/content/images/2017/07/ghost-logo.png',
result;
- urlForStub = sinon.stub(urlService.utils, 'urlFor');
+ urlForStub = sinon.stub(urlUtils, 'urlFor');
urlForStub.withArgs('home').returns('http://myblog.com/');
- urlGetSubdirStub = sinon.stub(urlService.utils, 'getSubdir');
+ urlGetSubdirStub = sinon.stub(urlUtils, 'getSubdir');
urlGetSubdirStub.returns('/blog');
result = storageUtils.getLocalFileStoragePath(url);
@@ -67,9 +67,9 @@ describe('storage utils', function () {
var filePath = '/content/images/2017/07/ghost-logo.png',
result;
- urlForStub = sinon.stub(urlService.utils, 'urlFor');
+ urlForStub = sinon.stub(urlUtils, 'urlFor');
urlForStub.withArgs('home').returns('http://myblog.com/');
- urlGetSubdirStub = sinon.stub(urlService.utils, 'getSubdir');
+ urlGetSubdirStub = sinon.stub(urlUtils, 'getSubdir');
urlGetSubdirStub.returns('');
result = storageUtils.getLocalFileStoragePath(filePath);
@@ -81,9 +81,9 @@ describe('storage utils', function () {
var filePath = '/blog/content/images/2017/07/ghost-logo.png',
result;
- urlForStub = sinon.stub(urlService.utils, 'urlFor');
+ urlForStub = sinon.stub(urlUtils, 'urlFor');
urlForStub.withArgs('home').returns('http://myblog.com/');
- urlGetSubdirStub = sinon.stub(urlService.utils, 'getSubdir');
+ urlGetSubdirStub = sinon.stub(urlUtils, 'getSubdir');
urlGetSubdirStub.returns('/blog');
result = storageUtils.getLocalFileStoragePath(filePath);
@@ -95,9 +95,9 @@ describe('storage utils', function () {
var url = 'http://example-blog.com/ghost-logo.png',
result;
- urlForStub = sinon.stub(urlService.utils, 'urlFor');
+ urlForStub = sinon.stub(urlUtils, 'urlFor');
urlForStub.withArgs('home').returns('http://myblog.com/');
- urlGetSubdirStub = sinon.stub(urlService.utils, 'getSubdir');
+ urlGetSubdirStub = sinon.stub(urlUtils, 'getSubdir');
urlGetSubdirStub.returns('');
result = storageUtils.getLocalFileStoragePath(url);
@@ -111,9 +111,9 @@ describe('storage utils', function () {
var url = 'http://myblog.com/content/images/2017/07/ghost-logo.png',
result;
- urlForStub = sinon.stub(urlService.utils, 'urlFor');
+ urlForStub = sinon.stub(urlUtils, 'urlFor');
urlForStub.withArgs('home').returns('http://myblog.com/');
- urlGetSubdirStub = sinon.stub(urlService.utils, 'getSubdir');
+ urlGetSubdirStub = sinon.stub(urlUtils, 'getSubdir');
urlGetSubdirStub.returns('');
result = storageUtils.isLocalImage(url);
@@ -128,9 +128,9 @@ describe('storage utils', function () {
var url = 'https://myblog.com/content/images/2017/07/ghost-logo.png',
result;
- urlForStub = sinon.stub(urlService.utils, 'urlFor');
+ urlForStub = sinon.stub(urlUtils, 'urlFor');
urlForStub.withArgs('home').returns('http://myblog.com/');
- urlGetSubdirStub = sinon.stub(urlService.utils, 'getSubdir');
+ urlGetSubdirStub = sinon.stub(urlUtils, 'getSubdir');
urlGetSubdirStub.returns('');
result = storageUtils.isLocalImage(url);
@@ -142,9 +142,9 @@ describe('storage utils', function () {
var url = 'http://myblog.com/blog/content/images/2017/07/ghost-logo.png',
result;
- urlForStub = sinon.stub(urlService.utils, 'urlFor');
+ urlForStub = sinon.stub(urlUtils, 'urlFor');
urlForStub.withArgs('home').returns('http://myblog.com/');
- urlGetSubdirStub = sinon.stub(urlService.utils, 'getSubdir');
+ urlGetSubdirStub = sinon.stub(urlUtils, 'getSubdir');
urlGetSubdirStub.returns('/blog');
result = storageUtils.isLocalImage(url);
@@ -156,9 +156,9 @@ describe('storage utils', function () {
var url = '/content/images/2017/07/ghost-logo.png',
result;
- urlForStub = sinon.stub(urlService.utils, 'urlFor');
+ urlForStub = sinon.stub(urlUtils, 'urlFor');
urlForStub.withArgs('home').returns('http://myblog.com/');
- urlGetSubdirStub = sinon.stub(urlService.utils, 'getSubdir');
+ urlGetSubdirStub = sinon.stub(urlUtils, 'getSubdir');
urlGetSubdirStub.returns('');
result = storageUtils.isLocalImage(url);
@@ -170,9 +170,9 @@ describe('storage utils', function () {
var url = '/blog/content/images/2017/07/ghost-logo.png',
result;
- urlForStub = sinon.stub(urlService.utils, 'urlFor');
+ urlForStub = sinon.stub(urlUtils, 'urlFor');
urlForStub.withArgs('home').returns('http://myblog.com/');
- urlGetSubdirStub = sinon.stub(urlService.utils, 'getSubdir');
+ urlGetSubdirStub = sinon.stub(urlUtils, 'getSubdir');
urlGetSubdirStub.returns('/blog');
result = storageUtils.isLocalImage(url);
@@ -184,9 +184,9 @@ describe('storage utils', function () {
var url = 'http://somewebsite.com/ghost-logo.png',
result;
- urlForStub = sinon.stub(urlService.utils, 'urlFor');
+ urlForStub = sinon.stub(urlUtils, 'urlFor');
urlForStub.withArgs('home').returns('http://myblog.com/');
- urlGetSubdirStub = sinon.stub(urlService.utils, 'getSubdir');
+ urlGetSubdirStub = sinon.stub(urlUtils, 'getSubdir');
urlGetSubdirStub.returns('');
result = storageUtils.isLocalImage(url);
diff --git a/core/test/unit/api/shared/serializers/input/utils/url_spec.js b/core/test/unit/api/shared/serializers/input/utils/url_spec.js
index 242573fa1e..1472f2fe26 100644
--- a/core/test/unit/api/shared/serializers/input/utils/url_spec.js
+++ b/core/test/unit/api/shared/serializers/input/utils/url_spec.js
@@ -1,12 +1,12 @@
const should = require('should');
const sinon = require('sinon');
-const utils = require('../../../../../../../server/services/url/utils');
+const urlUtils = require('../../../../../../../server/lib/url-utils');
const url = require('../../../../../../../server/api/v2/utils/serializers/input/utils/url');
describe('Unit: v2/utils/serializers/input/utils/url', function () {
describe('forPost', function () {
beforeEach(function () {
- sinon.stub(utils, 'getBlogUrl')
+ sinon.stub(urlUtils, 'getBlogUrl')
.returns('https://blogurl.com');
});
diff --git a/core/test/unit/api/v2/utils/serializers/input/posts_spec.js b/core/test/unit/api/v2/utils/serializers/input/posts_spec.js
index a6d021ab62..3c6e72d599 100644
--- a/core/test/unit/api/v2/utils/serializers/input/posts_spec.js
+++ b/core/test/unit/api/v2/utils/serializers/input/posts_spec.js
@@ -1,6 +1,7 @@
const should = require('should');
+const sinon = require('sinon');
const serializers = require('../../../../../../../server/api/v2/utils/serializers');
-const configUtils = require('../../../../../../utils/configUtils');
+const urlUtils = require('../../../../../../utils/urlUtils');
describe('Unit: v2/utils/serializers/input/posts', function () {
describe('browse', function () {
@@ -221,152 +222,170 @@ describe('Unit: v2/utils/serializers/input/posts', function () {
describe('edit', function () {
describe('Ensure relative urls are returned for standard image urls', function () {
- after(function () {
- configUtils.restore();
- });
+ describe('no subdir', function () {
+ let sandbox;
- it('when mobiledoc contains an absolute URL to image', function () {
- configUtils.set({url: 'https://mysite.com'});
- const apiConfig = {};
- const frame = {
- options: {
- context: {
- user: 0,
- api_key: {
- id: 1,
- type: 'content'
+ after(function () {
+ sandbox.restore();
+ });
+
+ before(function () {
+ sandbox = sinon.createSandbox();
+ urlUtils.stubUrlUtils({url: 'https://mysite.com'}, sandbox);
+ });
+
+ it('when mobiledoc contains an absolute URL to image', function () {
+ const apiConfig = {};
+ const frame = {
+ options: {
+ context: {
+ user: 0,
+ api_key: {
+ id: 1,
+ type: 'content'
+ },
},
},
- },
- data: {
- posts: [
- {
- id: 'id1',
- mobiledoc: '{"version":"0.3.1","atoms":[],"cards":[["image",{"src":"https://mysite.com/content/images/2019/02/image.jpg"}]]}'
- }
- ]
- }
- };
+ data: {
+ posts: [
+ {
+ id: 'id1',
+ mobiledoc: '{"version":"0.3.1","atoms":[],"cards":[["image",{"src":"https://mysite.com/content/images/2019/02/image.jpg"}]]}'
+ }
+ ]
+ }
+ };
- serializers.input.posts.edit(apiConfig, frame);
+ serializers.input.posts.edit(apiConfig, frame);
- let postData = frame.data.posts[0];
- postData.mobiledoc.should.equal('{"version":"0.3.1","atoms":[],"cards":[["image",{"src":"/content/images/2019/02/image.jpg"}]]}');
- });
+ let postData = frame.data.posts[0];
+ postData.mobiledoc.should.equal('{"version":"0.3.1","atoms":[],"cards":[["image",{"src":"/content/images/2019/02/image.jpg"}]]}');
+ });
- it('when mobiledoc contains multiple absolute URLs to images with different protocols', function () {
- configUtils.set({url: 'https://mysite.com'});
- const apiConfig = {};
- const frame = {
- options: {
- context: {
- user: 0,
- api_key: {
- id: 1,
- type: 'content'
+ it('when mobiledoc contains multiple absolute URLs to images with different protocols', function () {
+ const apiConfig = {};
+ const frame = {
+ options: {
+ context: {
+ user: 0,
+ api_key: {
+ id: 1,
+ type: 'content'
+ },
},
},
- },
- data: {
- posts: [
- {
- id: 'id1',
- mobiledoc: '{"version":"0.3.1","atoms":[],"cards":[["image",{"src":"https://mysite.com/content/images/2019/02/image.jpg"}],["image",{"src":"http://mysite.com/content/images/2019/02/image.png"}]]'
- }
- ]
- }
- };
+ data: {
+ posts: [
+ {
+ id: 'id1',
+ mobiledoc: '{"version":"0.3.1","atoms":[],"cards":[["image",{"src":"https://mysite.com/content/images/2019/02/image.jpg"}],["image",{"src":"http://mysite.com/content/images/2019/02/image.png"}]]'
+ }
+ ]
+ }
+ };
- serializers.input.posts.edit(apiConfig, frame);
+ serializers.input.posts.edit(apiConfig, frame);
- let postData = frame.data.posts[0];
- postData.mobiledoc.should.equal('{"version":"0.3.1","atoms":[],"cards":[["image",{"src":"/content/images/2019/02/image.jpg"}],["image",{"src":"/content/images/2019/02/image.png"}]]');
+ let postData = frame.data.posts[0];
+ postData.mobiledoc.should.equal('{"version":"0.3.1","atoms":[],"cards":[["image",{"src":"/content/images/2019/02/image.jpg"}],["image",{"src":"/content/images/2019/02/image.png"}]]');
+ });
+
+ it('when blog url is without subdir', function () {
+ const apiConfig = {};
+ const frame = {
+ options: {
+ context: {
+ user: 0,
+ api_key: {
+ id: 1,
+ type: 'content'
+ },
+ },
+ withRelated: ['tags', 'authors']
+ },
+ data: {
+ posts: [
+ {
+ id: 'id1',
+ feature_image: 'https://mysite.com/content/images/image.jpg',
+ og_image: 'https://mysite.com/mycustomstorage/images/image.jpg',
+ twitter_image: 'https://mysite.com/blog/content/images/image.jpg',
+ tags: [{
+ id: 'id3',
+ feature_image: 'http://mysite.com/content/images/image.jpg'
+ }],
+ authors: [{
+ id: 'id4',
+ name: 'Ghosty',
+ profile_image: 'https://somestorage.com/blog/images/image.jpg'
+ }]
+ }
+ ]
+ }
+ };
+ serializers.input.posts.edit(apiConfig, frame);
+ let postData = frame.data.posts[0];
+ postData.feature_image.should.eql('/content/images/image.jpg');
+ postData.og_image.should.eql('https://mysite.com/mycustomstorage/images/image.jpg');
+ postData.twitter_image.should.eql('https://mysite.com/blog/content/images/image.jpg');
+ postData.tags[0].feature_image.should.eql('/content/images/image.jpg');
+ postData.authors[0].profile_image.should.eql('https://somestorage.com/blog/images/image.jpg');
+ });
});
- it('when blog url is without subdir', function () {
- configUtils.set({url: 'https://mysite.com'});
- const apiConfig = {};
- const frame = {
- options: {
- context: {
- user: 0,
- api_key: {
- id: 1,
- type: 'content'
- },
- },
- withRelated: ['tags', 'authors']
- },
- data: {
- posts: [
- {
- id: 'id1',
- feature_image: 'https://mysite.com/content/images/image.jpg',
- og_image: 'https://mysite.com/mycustomstorage/images/image.jpg',
- twitter_image: 'https://mysite.com/blog/content/images/image.jpg',
- tags: [{
- id: 'id3',
- feature_image: 'http://mysite.com/content/images/image.jpg'
- }],
- authors: [{
- id: 'id4',
- name: 'Ghosty',
- profile_image: 'https://somestorage.com/blog/images/image.jpg'
- }]
- }
- ]
- }
- };
- serializers.input.posts.edit(apiConfig, frame);
- let postData = frame.data.posts[0];
- postData.feature_image.should.eql('/content/images/image.jpg');
- postData.og_image.should.eql('https://mysite.com/mycustomstorage/images/image.jpg');
- postData.twitter_image.should.eql('https://mysite.com/blog/content/images/image.jpg');
- postData.tags[0].feature_image.should.eql('/content/images/image.jpg');
- postData.authors[0].profile_image.should.eql('https://somestorage.com/blog/images/image.jpg');
- });
+ describe('with subdir', function () {
+ let sandbox;
- it('when blog url is with subdir', function () {
- configUtils.set({url: 'https://mysite.com/blog'});
- const apiConfig = {};
- const frame = {
- options: {
- context: {
- user: 0,
- api_key: {
- id: 1,
- type: 'content'
+ after(function () {
+ sandbox.restore();
+ });
+
+ before(function () {
+ sandbox = sinon.createSandbox();
+ urlUtils.stubUrlUtils({url: 'https://mysite.com/blog'}, sandbox);
+ });
+
+ it('when blog url is with subdir', function () {
+ const apiConfig = {};
+ const frame = {
+ options: {
+ context: {
+ user: 0,
+ api_key: {
+ id: 1,
+ type: 'content'
+ },
},
+ withRelated: ['tags', 'authors']
},
- withRelated: ['tags', 'authors']
- },
- data: {
- posts: [
- {
- id: 'id1',
- feature_image: 'https://mysite.com/blog/content/images/image.jpg',
- og_image: 'https://mysite.com/content/images/image.jpg',
- twitter_image: 'https://mysite.com/mycustomstorage/images/image.jpg',
- tags: [{
- id: 'id3',
- feature_image: 'http://mysite.com/blog/mycustomstorage/content/images/image.jpg'
- }],
- authors: [{
- id: 'id4',
- name: 'Ghosty',
- profile_image: 'https://somestorage.com/blog/content/images/image.jpg'
- }]
- }
- ]
- }
- };
- serializers.input.posts.edit(apiConfig, frame);
- let postData = frame.data.posts[0];
- postData.feature_image.should.eql('/blog/content/images/image.jpg');
- postData.og_image.should.eql('https://mysite.com/content/images/image.jpg');
- postData.twitter_image.should.eql('https://mysite.com/mycustomstorage/images/image.jpg');
- postData.tags[0].feature_image.should.eql('http://mysite.com/blog/mycustomstorage/content/images/image.jpg');
- postData.authors[0].profile_image.should.eql('https://somestorage.com/blog/content/images/image.jpg');
+ data: {
+ posts: [
+ {
+ id: 'id1',
+ feature_image: 'https://mysite.com/blog/content/images/image.jpg',
+ og_image: 'https://mysite.com/content/images/image.jpg',
+ twitter_image: 'https://mysite.com/mycustomstorage/images/image.jpg',
+ tags: [{
+ id: 'id3',
+ feature_image: 'http://mysite.com/blog/mycustomstorage/content/images/image.jpg'
+ }],
+ authors: [{
+ id: 'id4',
+ name: 'Ghosty',
+ profile_image: 'https://somestorage.com/blog/content/images/image.jpg'
+ }]
+ }
+ ]
+ }
+ };
+ serializers.input.posts.edit(apiConfig, frame);
+ let postData = frame.data.posts[0];
+ postData.feature_image.should.eql('/blog/content/images/image.jpg');
+ postData.og_image.should.eql('https://mysite.com/content/images/image.jpg');
+ postData.twitter_image.should.eql('https://mysite.com/mycustomstorage/images/image.jpg');
+ postData.tags[0].feature_image.should.eql('http://mysite.com/blog/mycustomstorage/content/images/image.jpg');
+ postData.authors[0].profile_image.should.eql('https://somestorage.com/blog/content/images/image.jpg');
+ });
});
});
diff --git a/core/test/unit/api/v2/utils/serializers/output/utils/url_spec.js b/core/test/unit/api/v2/utils/serializers/output/utils/url_spec.js
index cff6fa630f..3e1b996bdd 100644
--- a/core/test/unit/api/v2/utils/serializers/output/utils/url_spec.js
+++ b/core/test/unit/api/v2/utils/serializers/output/utils/url_spec.js
@@ -2,13 +2,14 @@ const should = require('should');
const sinon = require('sinon');
const testUtils = require('../../../../../../../utils');
const urlService = require('../../../../../../../../server/services/url');
+const urlUtils = require('../../../../../../../../server/lib/url-utils');
const urlUtil = require('../../../../../../../../server/api/v2/utils/serializers/output/utils/url');
describe('Unit: v2/utils/serializers/output/utils/url', () => {
beforeEach(() => {
sinon.stub(urlService, 'getUrlByResourceId').returns('getUrlByResourceId');
- sinon.stub(urlService.utils, 'urlFor').returns('urlFor');
- sinon.stub(urlService.utils, 'makeAbsoluteUrls').returns({html: sinon.stub()});
+ sinon.stub(urlUtils, 'urlFor').returns('urlFor');
+ sinon.stub(urlUtils, 'makeAbsoluteUrls').returns({html: sinon.stub()});
});
afterEach(() => {
@@ -34,12 +35,12 @@ describe('Unit: v2/utils/serializers/output/utils/url', () => {
post.hasOwnProperty('url').should.be.true();
- urlService.utils.urlFor.callCount.should.eql(2);
- urlService.utils.urlFor.getCall(0).args.should.eql(['image', {image: 'value'}, true]);
- urlService.utils.urlFor.getCall(1).args.should.eql(['home', true]);
+ urlUtils.urlFor.callCount.should.eql(2);
+ urlUtils.urlFor.getCall(0).args.should.eql(['image', {image: 'value'}, true]);
+ urlUtils.urlFor.getCall(1).args.should.eql(['home', true]);
- urlService.utils.makeAbsoluteUrls.callCount.should.eql(1);
- urlService.utils.makeAbsoluteUrls.getCall(0).args.should.eql([
+ urlUtils.makeAbsoluteUrls.callCount.should.eql(1);
+ urlUtils.makeAbsoluteUrls.getCall(0).args.should.eql([
'## markdown',
'urlFor',
'getUrlByResourceId',
diff --git a/core/test/unit/apps/amp/amp_content_spec.js b/core/test/unit/apps/amp/amp_content_spec.js
index 685026198c..a47d1ed435 100644
--- a/core/test/unit/apps/amp/amp_content_spec.js
+++ b/core/test/unit/apps/amp/amp_content_spec.js
@@ -1,6 +1,6 @@
var should = require('should'),
rewire = require('rewire'),
- configUtils = require('../../../../test/utils/configUtils'),
+ urlUtils = require('../../../../test/utils/urlUtils'),
ampContentHelper = rewire('../../../../server/apps/amp/lib/helpers/amp_content');
// TODO: Amperize really needs to get stubbed, so we can test returning errors
@@ -109,12 +109,11 @@ describe('{{amp_content}} helper', function () {
describe('Transforms and sanitizes HTML', function () {
beforeEach(function () {
- configUtils.set({url: 'https://blog.ghost.org/'});
+ ampContentHelper.__set__('urlUtils', urlUtils.getInstance({url: 'https://blog.ghost.org/'}));
});
afterEach(function () {
ampContentHelper.__set__('amperizeCache', {});
- configUtils.restore();
});
it('can transform img tags to amp-img', function (done) {
diff --git a/core/test/unit/data/importer/index_spec.js b/core/test/unit/data/importer/index_spec.js
index f212d612d9..58d15eec71 100644
--- a/core/test/unit/data/importer/index_spec.js
+++ b/core/test/unit/data/importer/index_spec.js
@@ -1,5 +1,6 @@
var should = require('should'),
sinon = require('sinon'),
+ rewire = require('rewire'),
Promise = require('bluebird'),
_ = require('lodash'),
testUtils = require('../../../utils'),
@@ -10,19 +11,19 @@ var should = require('should'),
// Stuff we are testing
ImportManager = require('../../../../server/data/importer'),
JSONHandler = require('../../../../server/data/importer/handlers/json'),
- ImageHandler = require('../../../../server/data/importer/handlers/image'),
+ ImageHandler = rewire('../../../../server/data/importer/handlers/image'),
MarkdownHandler = require('../../../../server/data/importer/handlers/markdown'),
DataImporter = require('../../../../server/data/importer/importers/data'),
ImageImporter = require('../../../../server/data/importer/importers/image'),
storage = require('../../../../server/adapters/storage'),
- configUtils = require('../../../utils/configUtils');
+ urlUtils = require('../../../utils/urlUtils');
describe('Importer', function () {
afterEach(function () {
sinon.restore();
- configUtils.restore();
+ ImageHandler = rewire('../../../../server/data/importer/handlers/image');
});
describe('ImportManager', function () {
@@ -124,9 +125,8 @@ describe('Importer', function () {
imageSpy = sinon.stub(ImageHandler, 'loadFile'),
mdSpy = sinon.stub(MarkdownHandler, 'loadFile');
+ getFileSpy.returns([]);
getFileSpy.withArgs(JSONHandler).returns(['/tmp/dir/myFile.json']);
- getFileSpy.withArgs(ImageHandler).returns([]);
- getFileSpy.withArgs(MarkdownHandler).returns([]);
ImportManager.processZip(testZip).then(function (zipResult) {
extractSpy.calledOnce.should.be.true();
@@ -418,7 +418,7 @@ describe('Importer', function () {
});
it('can load a file (subdirectory)', function (done) {
- configUtils.set({url: 'http://localhost:82832/subdir'});
+ ImageHandler.__set__('urlUtils', urlUtils.getInstance({url: 'http://localhost:82832/subdir'}));
var filename = 'test-image.jpeg',
file = [{
diff --git a/core/test/unit/data/meta/amp_url_spec.js b/core/test/unit/data/meta/amp_url_spec.js
index fcbb61da8d..8197a3df05 100644
--- a/core/test/unit/data/meta/amp_url_spec.js
+++ b/core/test/unit/data/meta/amp_url_spec.js
@@ -1,7 +1,7 @@
const should = require('should'),
sinon = require('sinon'),
rewire = require('rewire'),
- urlService = require('../../../../server/services/url'),
+ urlUtils = require('../../../../server/lib/url-utils'),
testUtils = require('../../../utils');
let getAmpUrl = rewire('../../../../server/data/meta/amp_url');
@@ -15,8 +15,8 @@ describe('getAmpUrl', function () {
getAmpUrl = rewire('../../../../server/data/meta/amp_url');
getAmpUrl.__set__('getUrl', getUrlStub);
- sinon.stub(urlService.utils, 'urlJoin');
- sinon.stub(urlService.utils, 'urlFor').withArgs('home', true).returns('http://localhost:9999');
+ sinon.stub(urlUtils, 'urlJoin');
+ sinon.stub(urlUtils, 'urlFor').withArgs('home', true).returns('http://localhost:9999');
});
afterEach(function () {
@@ -30,12 +30,12 @@ describe('getAmpUrl', function () {
post.context = ['post'];
getUrlStub.withArgs(post, false).returns('url');
- urlService.utils.urlJoin.withArgs('http://localhost:9999', 'url', 'amp/').returns('url');
+ urlUtils.urlJoin.withArgs('http://localhost:9999', 'url', 'amp/').returns('url');
should.exist(getAmpUrl(post));
- urlService.utils.urlJoin.calledOnce.should.be.true();
- urlService.utils.urlFor.calledOnce.should.be.true();
+ urlUtils.urlJoin.calledOnce.should.be.true();
+ urlUtils.urlFor.calledOnce.should.be.true();
getUrlStub.calledOnce.should.be.true();
});
@@ -47,8 +47,8 @@ describe('getAmpUrl', function () {
should.not.exist(getAmpUrl(tag));
- urlService.utils.urlJoin.called.should.be.false();
- urlService.utils.urlFor.called.should.be.false();
+ urlUtils.urlJoin.called.should.be.false();
+ urlUtils.urlFor.called.should.be.false();
getUrlStub.called.should.be.false();
});
@@ -60,8 +60,8 @@ describe('getAmpUrl', function () {
should.not.exist(getAmpUrl(author));
- urlService.utils.urlJoin.called.should.be.false();
- urlService.utils.urlFor.called.should.be.false();
+ urlUtils.urlJoin.called.should.be.false();
+ urlUtils.urlFor.called.should.be.false();
getUrlStub.called.should.be.false();
});
@@ -73,8 +73,8 @@ describe('getAmpUrl', function () {
should.not.exist(getAmpUrl(post));
- urlService.utils.urlJoin.called.should.be.false();
- urlService.utils.urlFor.called.should.be.false();
+ urlUtils.urlJoin.called.should.be.false();
+ urlUtils.urlFor.called.should.be.false();
getUrlStub.called.should.be.false();
});
});
diff --git a/core/test/unit/data/meta/asset_url_spec.js b/core/test/unit/data/meta/asset_url_spec.js
index 61b537022d..eb02ffa4e5 100644
--- a/core/test/unit/data/meta/asset_url_spec.js
+++ b/core/test/unit/data/meta/asset_url_spec.js
@@ -1,10 +1,14 @@
var should = require('should'),
sinon = require('sinon'),
- getAssetUrl = require('../../../../server/data/meta/asset_url'),
+ rewire = require('rewire'),
+ imageLib = require('../../../../server/lib/image'),
settingsCache = require('../../../../server/services/settings/cache'),
configUtils = require('../../../utils/configUtils'),
+ urlUtils = require('../../../utils/urlUtils'),
config = configUtils.config;
+const getAssetUrl = rewire('../../../../server/data/meta/asset_url');
+
describe('getAssetUrl', function () {
afterEach(function () {
configUtils.restore();
@@ -77,7 +81,7 @@ describe('getAssetUrl', function () {
describe('with /blog subdirectory', function () {
beforeEach(function () {
- configUtils.set({url: 'http://localhost:82832/blog'});
+ getAssetUrl.__set__('urlUtils', urlUtils.getInstance({url: 'http://localhost:82832/blog'}));
});
it('should return asset url with just context', function () {
@@ -102,16 +106,19 @@ describe('getAssetUrl', function () {
describe('favicon', function () {
it('should not add asset to url if favicon.ico', function () {
+ sinon.stub(imageLib.blogIcon, 'getIconUrl').returns('/blog/favicon.ico');
var testUrl = getAssetUrl('favicon.ico');
testUrl.should.equal('/blog/favicon.ico');
});
it('should not add asset to url if favicon.png', function () {
+ sinon.stub(imageLib.blogIcon, 'getIconUrl').returns('/blog/favicon.ico');
var testUrl = getAssetUrl('favicon.png');
testUrl.should.equal('/blog/favicon.ico');
});
it('should return correct favicon path for custom png', function () {
+ sinon.stub(imageLib.blogIcon, 'getIconUrl').returns('/blog/favicon.png');
sinon.stub(settingsCache, 'get').withArgs('icon').returns('/content/images/2017/04/my-icon.png');
var testUrl = getAssetUrl('favicon.ico');
testUrl.should.equal('/blog/favicon.png');
diff --git a/core/test/unit/data/meta/canonical_url_spec.js b/core/test/unit/data/meta/canonical_url_spec.js
index 35b8bf9b97..3ea6fcf45f 100644
--- a/core/test/unit/data/meta/canonical_url_spec.js
+++ b/core/test/unit/data/meta/canonical_url_spec.js
@@ -1,7 +1,7 @@
const should = require('should'),
sinon = require('sinon'),
rewire = require('rewire'),
- urlService = require('../../../../server/services/url'),
+ urlUtils = require('../../../../server/lib/url-utils'),
testUtils = require('../../../utils');
let getCanonicalUrl = rewire('../../../../server/data/meta/canonical_url');
@@ -15,8 +15,8 @@ describe('getCanonicalUrl', function () {
getCanonicalUrl = rewire('../../../../server/data/meta/canonical_url');
getCanonicalUrl.__set__('getUrl', getUrlStub);
- sinon.stub(urlService.utils, 'urlJoin');
- sinon.stub(urlService.utils, 'urlFor').withArgs('home', true).returns('http://localhost:9999');
+ sinon.stub(urlUtils, 'urlJoin');
+ sinon.stub(urlUtils, 'urlFor').withArgs('home', true).returns('http://localhost:9999');
});
afterEach(function () {
@@ -27,12 +27,12 @@ describe('getCanonicalUrl', function () {
const post = testUtils.DataGenerator.forKnex.createPost();
getUrlStub.withArgs(post, false).returns('/post-url/');
- urlService.utils.urlJoin.withArgs('http://localhost:9999', '/post-url/').returns('canonical url');
+ urlUtils.urlJoin.withArgs('http://localhost:9999', '/post-url/').returns('canonical url');
getCanonicalUrl(post).should.eql('canonical url');
- urlService.utils.urlJoin.calledOnce.should.be.true();
- urlService.utils.urlFor.calledOnce.should.be.true();
+ urlUtils.urlJoin.calledOnce.should.be.true();
+ urlUtils.urlFor.calledOnce.should.be.true();
getUrlStub.calledOnce.should.be.true();
});
@@ -51,23 +51,23 @@ describe('getCanonicalUrl', function () {
const post = testUtils.DataGenerator.forKnex.createPost();
getUrlStub.withArgs(post, false).returns('/post-url/amp/');
- urlService.utils.urlJoin.withArgs('http://localhost:9999', '/post-url/amp/').returns('*/amp/');
+ urlUtils.urlJoin.withArgs('http://localhost:9999', '/post-url/amp/').returns('*/amp/');
getCanonicalUrl(post).should.eql('*/');
- urlService.utils.urlJoin.calledOnce.should.be.true();
- urlService.utils.urlFor.calledOnce.should.be.true();
+ urlUtils.urlJoin.calledOnce.should.be.true();
+ urlUtils.urlFor.calledOnce.should.be.true();
getUrlStub.calledOnce.should.be.true();
});
it('should return home if empty secure data', function () {
getUrlStub.withArgs({secure: true}, false).returns('/');
- urlService.utils.urlJoin.withArgs('http://localhost:9999', '/').returns('canonical url');
+ urlUtils.urlJoin.withArgs('http://localhost:9999', '/').returns('canonical url');
getCanonicalUrl({secure: true}).should.eql('canonical url');
- urlService.utils.urlJoin.calledOnce.should.be.true();
- urlService.utils.urlFor.calledOnce.should.be.true();
+ urlUtils.urlJoin.calledOnce.should.be.true();
+ urlUtils.urlFor.calledOnce.should.be.true();
getUrlStub.calledOnce.should.be.true();
});
});
diff --git a/core/test/unit/data/meta/paginated_url_spec.js b/core/test/unit/data/meta/paginated_url_spec.js
index 101d06cb0b..5d18bcd4c0 100644
--- a/core/test/unit/data/meta/paginated_url_spec.js
+++ b/core/test/unit/data/meta/paginated_url_spec.js
@@ -1,6 +1,7 @@
var should = require('should'),
+ sinon = require('sinon'),
getPaginatedUrl = require('../../../../server/data/meta/paginated_url'),
- configUtils = require('../../../utils/configUtils');
+ urlUtils = require('../../../utils/urlUtils');
describe('getPaginatedUrl', function () {
var data, getTestUrls;
@@ -124,12 +125,15 @@ describe('getPaginatedUrl', function () {
});
describe('with /blog subdirectory', function () {
+ let sandbox;
+
before(function () {
- configUtils.set({url: 'http://localhost:82832/blog'});
+ sandbox = sinon.createSandbox();
+ urlUtils.stubUrlUtils({url: 'http://localhost:82832/blog'}, sandbox);
});
after(function () {
- configUtils.restore();
+ sandbox.restore();
});
it('should calculate correct urls for index', function () {
diff --git a/core/test/unit/data/meta/url_spec.js b/core/test/unit/data/meta/url_spec.js
index 9c4a320b0a..f2247b1288 100644
--- a/core/test/unit/data/meta/url_spec.js
+++ b/core/test/unit/data/meta/url_spec.js
@@ -1,5 +1,6 @@
const should = require('should'),
sinon = require('sinon'),
+ urlUtils = require('../../../../server/lib/url-utils'),
urlService = require('../../../../server/services/url'),
getUrl = require('../../../../server/data/meta/url'),
testUtils = require('../../../utils/');
@@ -7,7 +8,7 @@ const should = require('should'),
describe('getUrl', function () {
beforeEach(function () {
sinon.stub(urlService, 'getUrlByResourceId');
- sinon.stub(urlService.utils, 'urlFor');
+ sinon.stub(urlUtils, 'urlFor');
});
afterEach(function () {
@@ -27,11 +28,11 @@ describe('getUrl', function () {
it('not absolute, not secure', function () {
const post = testUtils.DataGenerator.forKnex.createPost({status: 'draft'});
urlService.getUrlByResourceId.withArgs(post.id).returns('/404/');
- urlService.utils.urlFor.withArgs({relativeUrl: '/p/' + post.uuid + '/', secure: undefined}, null, undefined).returns('relative');
+ urlUtils.urlFor.withArgs({relativeUrl: '/p/' + post.uuid + '/', secure: undefined}, null, undefined).returns('relative');
let url = getUrl(post);
urlService.getUrlByResourceId.calledOnce.should.be.true();
- urlService.utils.urlFor.withArgs({relativeUrl: '/p/' + post.uuid + '/', secure: undefined}, null, undefined)
+ urlUtils.urlFor.withArgs({relativeUrl: '/p/' + post.uuid + '/', secure: undefined}, null, undefined)
.calledOnce.should.be.true();
url.should.eql('relative');
@@ -40,11 +41,11 @@ describe('getUrl', function () {
it('absolute, not secure', function () {
const post = testUtils.DataGenerator.forKnex.createPost({status: 'draft'});
urlService.getUrlByResourceId.withArgs(post.id).returns('/404/');
- urlService.utils.urlFor.withArgs({relativeUrl: '/p/' + post.uuid + '/', secure: undefined}, null, true).returns('absolute');
+ urlUtils.urlFor.withArgs({relativeUrl: '/p/' + post.uuid + '/', secure: undefined}, null, true).returns('absolute');
let url = getUrl(post, true);
urlService.getUrlByResourceId.calledOnce.should.be.true();
- urlService.utils.urlFor.withArgs({relativeUrl: '/p/' + post.uuid + '/', secure: undefined}, null, true)
+ urlUtils.urlFor.withArgs({relativeUrl: '/p/' + post.uuid + '/', secure: undefined}, null, true)
.calledOnce.should.be.true();
url.should.eql('absolute');
@@ -54,11 +55,11 @@ describe('getUrl', function () {
const post = testUtils.DataGenerator.forKnex.createPost({status: 'draft'});
post.secure = true;
urlService.getUrlByResourceId.withArgs(post.id).returns('/404/');
- urlService.utils.urlFor.withArgs({relativeUrl: '/p/' + post.uuid + '/', secure: true}, null, true).returns('absolute secure');
+ urlUtils.urlFor.withArgs({relativeUrl: '/p/' + post.uuid + '/', secure: true}, null, true).returns('absolute secure');
let url = getUrl(post, true);
urlService.getUrlByResourceId.calledOnce.should.be.true();
- urlService.utils.urlFor.withArgs({relativeUrl: '/p/' + post.uuid + '/', secure: true}, null, true)
+ urlUtils.urlFor.withArgs({relativeUrl: '/p/' + post.uuid + '/', secure: true}, null, true)
.calledOnce.should.be.true();
url.should.eql('absolute secure');
@@ -77,7 +78,7 @@ describe('getUrl', function () {
it('should return absolute url for a post and remove /amp/ in url', function () {
const data = {relativeUrl: '/*/amp/'};
- urlService.utils.urlFor.withArgs(data, {}, true).returns('absolute/*/amp/');
+ urlUtils.urlFor.withArgs(data, {}, true).returns('absolute/*/amp/');
getUrl(data, true).should.eql('absolute/*/');
urlService.getUrlByResourceId.called.should.be.false();
});
@@ -142,7 +143,7 @@ describe('getUrl', function () {
current: true
};
- urlService.utils.urlFor.withArgs('nav', {nav: data, secure: data.secure}, undefined)
+ urlUtils.urlFor.withArgs('nav', {nav: data, secure: data.secure}, undefined)
.returns('nav url');
getUrl(data).should.equal('nav url');
@@ -156,7 +157,7 @@ describe('getUrl', function () {
current: true
};
- urlService.utils.urlFor.withArgs('nav', {nav: data, secure: data.secure}, true)
+ urlUtils.urlFor.withArgs('nav', {nav: data, secure: data.secure}, true)
.returns('absolute nav url');
getUrl(data, true).should.equal('absolute nav url');
@@ -165,7 +166,7 @@ describe('getUrl', function () {
it('should return `relativeUrl` and remove /amp/ in url', function () {
const data = {relativeUrl: '/*/amp/'};
- urlService.utils.urlFor.withArgs(data, {}, undefined).returns(data.relativeUrl);
+ urlUtils.urlFor.withArgs(data, {}, undefined).returns(data.relativeUrl);
getUrl(data).should.eql('/*/');
urlService.getUrlByResourceId.called.should.be.false();
});
diff --git a/core/test/unit/data/xml/sitemap/generator_spec.js b/core/test/unit/data/xml/sitemap/generator_spec.js
index 4514862000..8d92defe5d 100644
--- a/core/test/unit/data/xml/sitemap/generator_spec.js
+++ b/core/test/unit/data/xml/sitemap/generator_spec.js
@@ -3,7 +3,7 @@ const should = require('should'),
ObjectId = require('bson-objectid'),
_ = require('lodash'),
testUtils = require('../../../../utils'),
- urlService = require('../../../../../server/services/url'),
+ urlUtils = require('../../../../../server/lib/url-utils'),
IndexGenerator = require('../../../../../server/data/xml/sitemap/index-generator'),
PostGenerator = require('../../../../../server/data/xml/sitemap/post-generator'),
PageGenerator = require('../../../../../server/data/xml/sitemap/page-generator'),
@@ -95,7 +95,7 @@ describe('Generators', function () {
describe('fn: getXml', function () {
beforeEach(function () {
- sinon.stub(urlService.utils, 'urlFor');
+ sinon.stub(urlUtils, 'urlFor');
});
it('get cached xml', function () {
@@ -109,10 +109,10 @@ describe('Generators', function () {
it('compare content output', function () {
let idxFirst, idxSecond, idxThird;
- urlService.utils.urlFor.withArgs('image', {image: 'post-100.jpg'}, true).returns('http://my-ghost-blog.com/images/post-100.jpg');
- urlService.utils.urlFor.withArgs('image', {image: 'post-200.jpg'}, true).returns('http://my-ghost-blog.com/images/post-200.jpg');
- urlService.utils.urlFor.withArgs('image', {image: 'post-300.jpg'}, true).returns('http://my-ghost-blog.com/images/post-300.jpg');
- urlService.utils.urlFor.withArgs('sitemap_xsl', true).returns('http://my-ghost-blog.com/sitemap.xsl');
+ urlUtils.urlFor.withArgs('image', {image: 'post-100.jpg'}, true).returns('http://my-ghost-blog.com/images/post-100.jpg');
+ urlUtils.urlFor.withArgs('image', {image: 'post-200.jpg'}, true).returns('http://my-ghost-blog.com/images/post-200.jpg');
+ urlUtils.urlFor.withArgs('image', {image: 'post-300.jpg'}, true).returns('http://my-ghost-blog.com/images/post-300.jpg');
+ urlUtils.urlFor.withArgs('sitemap_xsl', true).returns('http://my-ghost-blog.com/sitemap.xsl');
generator.addUrl('http://my-ghost-blog.com/url/100/', testUtils.DataGenerator.forKnex.createPost({
feature_image: 'post-100.jpg',
diff --git a/core/test/unit/helpers/asset_spec.js b/core/test/unit/helpers/asset_spec.js
index 255dbfe045..8403327419 100644
--- a/core/test/unit/helpers/asset_spec.js
+++ b/core/test/unit/helpers/asset_spec.js
@@ -1,3 +1,6 @@
+// NOTE: the sole purpose of this suite is to test is it calls through to getAssetUrlHelper
+// more complicated use cases are tested directly in asset_url.spec
+
var should = require('should'),
sinon = require('sinon'),
configUtils = require('../../utils/configUtils'),
@@ -70,58 +73,4 @@ describe('{{asset}} helper', function () {
String(rendered).should.equal('/assets/js/asset.min.js?v=abc');
});
});
-
- describe('with /blog subdirectory', function () {
- before(function () {
- configUtils.set({url: 'http://localhost:82832/blog'});
- });
-
- it('handles favicon correctly', function () {
- rendered = helpers.asset('favicon.ico');
- should.exist(rendered);
- String(rendered).should.equal('/blog/favicon.ico');
- });
-
- it('handles ghost.css for default templates correctly', function () {
- rendered = helpers.asset('public/ghost.css');
- should.exist(rendered);
- String(rendered).should.equal('/blog/public/ghost.css?v=abc');
- });
-
- it('handles custom favicon correctly', function () {
- localSettingsCache.icon = '/content/images/favicon.png';
-
- // with png
- rendered = helpers.asset('favicon.png');
- should.exist(rendered);
- String(rendered).should.equal('/blog/favicon.png');
-
- localSettingsCache.icon = '/content/images/favicon.ico';
-
- // with ico
- rendered = helpers.asset('favicon.ico');
- should.exist(rendered);
- String(rendered).should.equal('/blog/favicon.ico');
- });
-
- it('handles public assets correctly', function () {
- rendered = helpers.asset('public/asset.js');
- should.exist(rendered);
- String(rendered).should.equal('/blog/public/asset.js?v=abc');
- });
-
- it('handles theme assets correctly', function () {
- rendered = helpers.asset('js/asset.js');
- should.exist(rendered);
- String(rendered).should.equal('/blog/assets/js/asset.js?v=abc');
- });
-
- it('handles hasMinFile assets correctly', function () {
- rendered = helpers.asset('js/asset.js', {hash: {hasMinFile: true}});
- should.exist(rendered);
- String(rendered).should.equal('/blog/assets/js/asset.min.js?v=abc');
- });
-
- configUtils.restore();
- });
});
diff --git a/core/test/unit/helpers/ghost_head_spec.js b/core/test/unit/helpers/ghost_head_spec.js
index a90f5a2047..4a45739e84 100644
--- a/core/test/unit/helpers/ghost_head_spec.js
+++ b/core/test/unit/helpers/ghost_head_spec.js
@@ -3,6 +3,7 @@ const should = require('should'),
_ = require('lodash'),
moment = require('moment'),
testUtils = require('../../utils'),
+ testUrlUtils = require('../../utils/urlUtils'),
configUtils = require('../../utils/configUtils'),
themes = require('../../../server/services/themes'),
models = require('../../../server/models'),
@@ -296,8 +297,16 @@ describe('{{ghost_head}} helper', function () {
});
describe('without Code Injection', function () {
+ let sandbox;
+
before(function () {
- configUtils.set('url', 'http://localhost:65530/');
+ sandbox = sinon.createSandbox();
+
+ testUrlUtils.stubUrlUtils({url: 'http://localhost:65530/'}, sandbox);
+ });
+
+ after(function () {
+ sandbox.restore();
});
it('returns meta tag string on paginated index page without structured data and schema', function (done) {
@@ -1234,50 +1243,62 @@ describe('{{ghost_head}} helper', function () {
done();
}).catch(done);
});
+ });
- describe('with /blog subdirectory', function () {
- before(function () {
- settingsCache.get.withArgs('icon').returns('/content/images/favicon.png');
+ describe('with /blog subdirectory', function () {
+ let sandbox;
- configUtils.set({
- url: 'http://localhost:65530/blog/'
- });
+ before(function () {
+ sandbox = sinon.createSandbox();
- routing.registry.getRssUrl.returns('http://localhost:65530/blog/rss/');
- });
+ settingsCache.get.withArgs('icon').returns('/content/images/favicon.png');
- after(function () {
- routing.registry.getRssUrl.returns('http://localhost:65530/rss/');
- });
+ testUrlUtils.stubUrlUtils({url: 'http://localhost:65530/blog'}, sandbox);
- 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(//);
- rendered.string.should.match(//);
- rendered.string.should.match(//);
- rendered.string.should.match(//);
- rendered.string.should.not.match(//);
+ rendered.string.should.match(//);
+ rendered.string.should.match(//);
+ rendered.string.should.match(//);
+ rendered.string.should.not.match(/body {background: red;}');
- configUtils.set({
- url: 'http://localhost:65530/'
- });
+ testUrlUtils.stubUrlUtils({url: 'http://localhost:65530/'}, sandbox);
+ });
+
+ after(function () {
+ sandbox.restore();
});
it('returns meta tag plus injected code', function (done) {
@@ -1456,10 +1490,15 @@ describe('{{ghost_head}} helper', function () {
});
describe('with Ajax Helper', function () {
+ let sandbox;
+
before(function () {
- configUtils.set({
- url: 'http://localhost:65530/'
- });
+ sandbox = sinon.createSandbox();
+ testUrlUtils.stubUrlUtils({url: 'http://localhost:65530/'}, sandbox);
+ });
+
+ after(function () {
+ sandbox.restore();
});
it('renders script tag with src', function (done) {
@@ -1530,10 +1569,6 @@ describe('{{ghost_head}} helper', function () {
describe('amp is disabled', function () {
before(function () {
- configUtils.set({
- url: 'http://localhost:65530/'
- });
-
settingsCache.get.withArgs('amp').returns(false);
});
diff --git a/core/test/unit/helpers/img_url_spec.js b/core/test/unit/helpers/img_url_spec.js
index aa7cfec88a..acff348aa1 100644
--- a/core/test/unit/helpers/img_url_spec.js
+++ b/core/test/unit/helpers/img_url_spec.js
@@ -1,6 +1,6 @@
var should = require('should'),
sinon = require('sinon'),
- configUtils = require('../../utils/configUtils'),
+ urlUtils = require('../../utils/urlUtils'),
// Stuff we are testing
helpers = require('../../../server/helpers'),
@@ -9,10 +9,6 @@ var should = require('should'),
describe('{{image}} helper', function () {
var logWarnStub;
- before(function () {
- configUtils.set({url: 'http://localhost:82832/'});
- });
-
beforeEach(function () {
logWarnStub = sinon.stub(common.logging, 'warn');
});
@@ -21,68 +17,81 @@ describe('{{image}} helper', function () {
sinon.restore();
});
- after(function () {
- configUtils.restore();
- });
+ describe('without sub-directory', function () {
+ let sandbox;
- it('should output relative url of image', function () {
- var rendered = helpers.img_url('/content/images/image-relative-url.png', {});
- should.exist(rendered);
- rendered.should.equal('/content/images/image-relative-url.png');
- logWarnStub.called.should.be.false();
- });
+ before(function () {
+ sandbox = sinon.createSandbox();
+ urlUtils.stubUrlUtils({url: 'http://localhost:82832/'}, sandbox);
+ });
- it('should output relative url of image if the input is absolute', function () {
- var rendered = helpers.img_url('http://localhost:82832/content/images/image-relative-url.png', {});
- should.exist(rendered);
- rendered.should.equal('/content/images/image-relative-url.png');
- logWarnStub.called.should.be.false();
- });
+ after(function () {
+ sandbox.restore();
+ });
- it('should output absolute url of image if the option is present ', function () {
- var rendered = helpers.img_url('/content/images/image-relative-url.png', {hash: {absolute: 'true'}});
- should.exist(rendered);
- rendered.should.equal('http://localhost:82832/content/images/image-relative-url.png');
- logWarnStub.called.should.be.false();
- });
+ it('should output relative url of image', function () {
+ var rendered = helpers.img_url('/content/images/image-relative-url.png', {});
+ should.exist(rendered);
+ rendered.should.equal('/content/images/image-relative-url.png');
+ logWarnStub.called.should.be.false();
+ });
- it('should NOT output absolute url of image if the option is "false" ', function () {
- var rendered = helpers.img_url('/content/images/image-relative-url.png', {hash: {absolute: 'false'}});
- should.exist(rendered);
- rendered.should.equal('/content/images/image-relative-url.png');
- });
+ it('should output relative url of image if the input is absolute', function () {
+ var rendered = helpers.img_url('http://localhost:82832/content/images/image-relative-url.png', {});
+ should.exist(rendered);
+ rendered.should.equal('/content/images/image-relative-url.png');
+ logWarnStub.called.should.be.false();
+ });
- it('should output author url', function () {
- var rendered = helpers.img_url('/content/images/author-image-relative-url.png', {});
- should.exist(rendered);
- rendered.should.equal('/content/images/author-image-relative-url.png');
- logWarnStub.called.should.be.false();
- });
+ it('should output absolute url of image if the option is present ', function () {
+ var rendered = helpers.img_url('/content/images/image-relative-url.png', {hash: {absolute: 'true'}});
+ should.exist(rendered);
+ rendered.should.equal('http://localhost:82832/content/images/image-relative-url.png');
+ logWarnStub.called.should.be.false();
+ });
- it('should have no output if the image attributeis not provided (with warning)', function () {
- var rendered = helpers.img_url({hash: {absolute: 'true'}});
- should.not.exist(rendered);
- logWarnStub.calledOnce.should.be.true();
- });
+ it('should NOT output absolute url of image if the option is "false" ', function () {
+ var rendered = helpers.img_url('/content/images/image-relative-url.png', {hash: {absolute: 'false'}});
+ should.exist(rendered);
+ rendered.should.equal('/content/images/image-relative-url.png');
+ });
- it('should have no output if the image attribute evaluates to undefined (with warning)', function () {
- var rendered = helpers.img_url(undefined, {hash: {absolute: 'true'}});
- should.not.exist(rendered);
- logWarnStub.calledOnce.should.be.true();
- });
+ it('should output author url', function () {
+ var rendered = helpers.img_url('/content/images/author-image-relative-url.png', {});
+ should.exist(rendered);
+ rendered.should.equal('/content/images/author-image-relative-url.png');
+ logWarnStub.called.should.be.false();
+ });
- it('should have no output if the image attribute evaluates to null (no waring)', function () {
- var rendered = helpers.img_url(null, {hash: {absolute: 'true'}});
- should.not.exist(rendered);
- logWarnStub.calledOnce.should.be.false();
+ it('should have no output if the image attributeis not provided (with warning)', function () {
+ var rendered = helpers.img_url({hash: {absolute: 'true'}});
+ should.not.exist(rendered);
+ logWarnStub.calledOnce.should.be.true();
+ });
+
+ it('should have no output if the image attribute evaluates to undefined (with warning)', function () {
+ var rendered = helpers.img_url(undefined, {hash: {absolute: 'true'}});
+ should.not.exist(rendered);
+ logWarnStub.calledOnce.should.be.true();
+ });
+
+ it('should have no output if the image attribute evaluates to null (no waring)', function () {
+ var rendered = helpers.img_url(null, {hash: {absolute: 'true'}});
+ should.not.exist(rendered);
+ logWarnStub.calledOnce.should.be.false();
+ });
});
describe('with sub-directory', function () {
+ let sandbox;
+
before(function () {
- configUtils.set({url: 'http://localhost:82832/blog'});
+ sandbox = sinon.createSandbox();
+ urlUtils.stubUrlUtils({url: 'http://localhost:82832/blog'}, sandbox);
});
+
after(function () {
- configUtils.restore();
+ sandbox.restore();
});
it('should output relative url of image', function () {
@@ -105,12 +114,17 @@ describe('{{image}} helper', function () {
});
describe('image_sizes', function () {
+ let sandbox;
+
before(function () {
- configUtils.set({url: 'http://localhost:82832'});
+ sandbox = sinon.createSandbox();
+ urlUtils.stubUrlUtils({url: 'http://localhost:82832/'}, sandbox);
});
+
after(function () {
- configUtils.restore();
+ sandbox.restore();
});
+
it('should output correct url for absolute paths which are internal', function () {
var rendered = helpers.img_url('http://localhost:82832/content/images/my-coole-img.jpg', {
hash: {
diff --git a/core/test/unit/helpers/url_spec.js b/core/test/unit/helpers/url_spec.js
index 56ab6d15fa..070442902f 100644
--- a/core/test/unit/helpers/url_spec.js
+++ b/core/test/unit/helpers/url_spec.js
@@ -2,18 +2,15 @@ var should = require('should'),
sinon = require('sinon'),
Promise = require('bluebird'),
testUtils = require('../../utils'),
- configUtils = require('../../utils/configUtils'),
+ urlUtils = require('../../utils/urlUtils'),
markdownToMobiledoc = require('../../utils/fixtures/data-generator').markdownToMobiledoc,
helpers = require('../../../server/helpers'),
urlService = require('../../../server/services/url'),
api = require('../../../server/api');
describe('{{url}} helper', function () {
- var rendered;
-
- before(function () {
- configUtils.set({url: 'http://localhost:82832/'});
- });
+ let rendered;
+ let sandbox;
beforeEach(function () {
rendered = null;
@@ -29,246 +26,263 @@ describe('{{url}} helper', function () {
sinon.restore();
});
- after(function () {
- configUtils.restore();
- });
-
- it('should return the slug with a prefix slash if the context is a post', function () {
- const post = testUtils.DataGenerator.forKnex.createPost({
- html: 'content',
- mobiledoc: markdownToMobiledoc('ff'),
- title: 'title',
- slug: 'slug',
- created_at: new Date(0),
- url: '/slug/'
+ describe('no subdir', function () {
+ before(function () {
+ sandbox = sinon.createSandbox();
+ urlUtils.stubUrlUtils({url: 'http://localhost:82832/'}, sandbox);
});
- urlService.getUrlByResourceId.withArgs(post.id, {absolute: undefined, secure: undefined, withSubdirectory: true}).returns('/slug/');
-
- rendered = helpers.url.call(post);
- should.exist(rendered);
- rendered.string.should.equal('/slug/');
- });
-
- it('should output an absolute URL if the option is present', function () {
- const post = testUtils.DataGenerator.forKnex.createPost({
- html: 'content',
- mobiledoc: markdownToMobiledoc('ff'),
- title: 'title',
- slug: 'slug',
- url: '/slug/',
- created_at: new Date(0)
+ after(function () {
+ sandbox.restore();
});
- urlService.getUrlByResourceId.withArgs(post.id, {absolute: true, secure: undefined, withSubdirectory: true}).returns('http://localhost:82832/slug/');
+ it('should return the slug with a prefix slash if the context is a post', function () {
+ const post = testUtils.DataGenerator.forKnex.createPost({
+ html: 'content',
+ mobiledoc: markdownToMobiledoc('ff'),
+ title: 'title',
+ slug: 'slug',
+ created_at: new Date(0),
+ url: '/slug/'
+ });
- rendered = helpers.url.call(post, {hash: {absolute: 'true'}});
- should.exist(rendered);
- rendered.string.should.equal('http://localhost:82832/slug/');
- });
+ urlService.getUrlByResourceId.withArgs(post.id, {absolute: undefined, secure: undefined, withSubdirectory: true}).returns('/slug/');
- it('should output an absolute URL with https if the option is present and secure', function () {
- const post = testUtils.DataGenerator.forKnex.createPost({
- html: 'content',
- mobiledoc: markdownToMobiledoc('ff'),
- title: 'title',
- slug: 'slug',
- url: '/slug/',
- created_at: new Date(0),
- secure: true
+ rendered = helpers.url.call(post);
+ should.exist(rendered);
+ rendered.string.should.equal('/slug/');
});
- urlService.getUrlByResourceId.withArgs(post.id, {absolute: true, secure: true, withSubdirectory: true}).returns('https://localhost:82832/slug/');
+ it('should output an absolute URL if the option is present', function () {
+ const post = testUtils.DataGenerator.forKnex.createPost({
+ html: 'content',
+ mobiledoc: markdownToMobiledoc('ff'),
+ title: 'title',
+ slug: 'slug',
+ url: '/slug/',
+ created_at: new Date(0)
+ });
- rendered = helpers.url.call(post, {hash: {absolute: 'true'}});
- should.exist(rendered);
- rendered.string.should.equal('https://localhost:82832/slug/');
- });
+ urlService.getUrlByResourceId.withArgs(post.id, {absolute: true, secure: undefined, withSubdirectory: true}).returns('http://localhost:82832/slug/');
- it('should return the slug with a prefixed /tag/ if the context is a tag', function () {
- const tag = testUtils.DataGenerator.forKnex.createTag({
- name: 'the tag',
- slug: 'the-tag',
- description: null,
- parent: null
+ rendered = helpers.url.call(post, {hash: {absolute: 'true'}});
+ should.exist(rendered);
+ rendered.string.should.equal('http://localhost:82832/slug/');
});
- urlService.getUrlByResourceId.withArgs(tag.id, {absolute: undefined, secure: undefined, withSubdirectory: true}).returns('/tag/the-tag/');
-
- rendered = helpers.url.call(tag);
- should.exist(rendered);
- rendered.string.should.equal('/tag/the-tag/');
- });
-
- it('should return the slug with a prefixed /author/ if the context is author', function () {
- const user = testUtils.DataGenerator.forKnex.createUser({
- bio: null,
- website: null,
- profile_image: null,
- location: null,
- slug: 'some-author'
- });
-
- urlService.getUrlByResourceId.withArgs(user.id, {absolute: undefined, secure: undefined, withSubdirectory: true}).returns('/author/some-author/');
-
- rendered = helpers.url.call(user);
- should.exist(rendered);
- rendered.string.should.equal('/author/some-author/');
- });
-
- it('should return / if not a post or tag', function () {
- rendered = helpers.url.call({something: 'key'});
- should.exist(rendered);
- rendered.string.should.equal('/');
- });
-
- it('should return a relative url if passed through a nav context', function () {
- rendered = helpers.url.call(
- {url: '/foo', label: 'Foo', slug: 'foo', current: true});
- should.exist(rendered);
- rendered.string.should.equal('/foo');
- });
-
- it('should return an absolute url if passed through a nav context', function () {
- rendered = helpers.url.call(
- {url: '/bar', label: 'Bar', slug: 'bar', current: true},
- {hash: {absolute: 'true'}});
- should.exist(rendered);
- rendered.string.should.equal('http://localhost:82832/bar');
- });
-
- it('should return an absolute url with https if context is secure', function () {
- rendered = helpers.url.call(
- {url: '/bar', label: 'Bar', slug: 'bar', current: true, secure: true},
- {hash: {absolute: 'true'}});
- should.exist(rendered);
- rendered.string.should.equal('https://localhost:82832/bar');
- });
-
- it('external urls should be retained in a nav context', function () {
- rendered = helpers.url.call(
- {url: 'http://casper.website/baz', label: 'Baz', slug: 'baz', current: true},
- {hash: {absolute: 'true'}});
- should.exist(rendered);
- rendered.string.should.equal('http://casper.website/baz');
- });
-
- it('should handle hosted urls in a nav context', function () {
- rendered = helpers.url.call(
- {url: 'http://localhost:82832/qux', label: 'Qux', slug: 'qux', current: true},
- {hash: {absolute: 'true'}});
- should.exist(rendered);
- rendered.string.should.equal('http://localhost:82832/qux');
- });
-
- it('should handle hosted urls in a nav context with secure', function () {
- rendered = helpers.url.call(
- {
- url: 'http://localhost:82832/qux', label: 'Qux', slug: 'qux', current: true,
+ it('should output an absolute URL with https if the option is present and secure', function () {
+ const post = testUtils.DataGenerator.forKnex.createPost({
+ html: 'content',
+ mobiledoc: markdownToMobiledoc('ff'),
+ title: 'title',
+ slug: 'slug',
+ url: '/slug/',
+ created_at: new Date(0),
secure: true
- },
- {hash: {absolute: 'true'}});
- should.exist(rendered);
- rendered.string.should.equal('https://localhost:82832/qux');
- });
+ });
- it('should handle hosted https urls in a nav context with secure', function () {
- rendered = helpers.url.call(
- {
- url: 'https://localhost:82832/qux', label: 'Qux', slug: 'qux', current: true,
- secure: true
- },
- {hash: {absolute: 'true'}});
- should.exist(rendered);
- rendered.string.should.equal('https://localhost:82832/qux');
- });
+ urlService.getUrlByResourceId.withArgs(post.id, {absolute: true, secure: true, withSubdirectory: true}).returns('https://localhost:82832/slug/');
- it('should handle hosted urls with the wrong protocol in a nav context', function () {
- rendered = helpers.url.call(
- {url: 'https://localhost:82832/quux', label: 'Quux', slug: 'quux', current: true},
- {hash: {absolute: 'true'}});
- should.exist(rendered);
- rendered.string.should.equal('http://localhost:82832/quux');
- });
+ rendered = helpers.url.call(post, {hash: {absolute: 'true'}});
+ should.exist(rendered);
+ rendered.string.should.equal('https://localhost:82832/slug/');
+ });
- it('should pass through protocol-less URLs regardless of absolute setting', function () {
- rendered = helpers.url.call(
- {url: '//casper.website/baz', label: 'Baz', slug: 'baz', current: true},
- {hash: {}});
- should.exist(rendered);
- rendered.string.should.equal('//casper.website/baz');
+ it('should return the slug with a prefixed /tag/ if the context is a tag', function () {
+ const tag = testUtils.DataGenerator.forKnex.createTag({
+ name: 'the tag',
+ slug: 'the-tag',
+ description: null,
+ parent: null
+ });
- rendered = helpers.url.call(
- {url: '//casper.website/baz', label: 'Baz', slug: 'baz', current: true},
- {hash: {absolute: 'true'}});
- should.exist(rendered);
- rendered.string.should.equal('//casper.website/baz');
- });
+ urlService.getUrlByResourceId.withArgs(tag.id, {absolute: undefined, secure: undefined, withSubdirectory: true}).returns('/tag/the-tag/');
- it('should pass through URLs with alternative schemes regardless of absolute setting', function () {
- rendered = helpers.url.call(
- {url: 'tel:01234567890', label: 'Baz', slug: 'baz', current: true},
- {hash: {}});
- should.exist(rendered);
- rendered.string.should.equal('tel:01234567890');
+ rendered = helpers.url.call(tag);
+ should.exist(rendered);
+ rendered.string.should.equal('/tag/the-tag/');
+ });
- rendered = helpers.url.call(
- {url: 'mailto:example@ghost.org', label: 'Baz', slug: 'baz', current: true},
- {hash: {}});
- should.exist(rendered);
- rendered.string.should.equal('mailto:example@ghost.org');
+ it('should return the slug with a prefixed /author/ if the context is author', function () {
+ const user = testUtils.DataGenerator.forKnex.createUser({
+ bio: null,
+ website: null,
+ profile_image: null,
+ location: null,
+ slug: 'some-author'
+ });
- rendered = helpers.url.call(
- {url: 'tel:01234567890', label: 'Baz', slug: 'baz', current: true},
- {hash: {absolute: 'true'}});
- should.exist(rendered);
- rendered.string.should.equal('tel:01234567890');
+ urlService.getUrlByResourceId.withArgs(user.id, {absolute: undefined, secure: undefined, withSubdirectory: true}).returns('/author/some-author/');
- rendered = helpers.url.call(
- {url: 'mailto:example@ghost.org', label: 'Baz', slug: 'baz', current: true},
- {hash: {absolute: 'true'}});
- should.exist(rendered);
- rendered.string.should.equal('mailto:example@ghost.org');
- });
+ rendered = helpers.url.call(user);
+ should.exist(rendered);
+ rendered.string.should.equal('/author/some-author/');
+ });
- it('should pass through anchor-only URLs regardless of absolute setting', function () {
- rendered = helpers.url.call(
- {url: '#thatsthegoodstuff', label: 'Baz', slug: 'baz', current: true},
- {hash: {}});
- should.exist(rendered);
- rendered.string.should.equal('#thatsthegoodstuff');
+ it('should return / if not a post or tag', function () {
+ rendered = helpers.url.call({something: 'key'});
+ should.exist(rendered);
+ rendered.string.should.equal('/');
+ });
- rendered = helpers.url.call(
- {url: '#thatsthegoodstuff', label: 'Baz', slug: 'baz', current: true},
- {hash: {absolute: 'true'}});
- should.exist(rendered);
- rendered.string.should.equal('#thatsthegoodstuff');
- });
+ it('should return a relative url if passed through a nav context', function () {
+ rendered = helpers.url.call(
+ {url: '/foo', label: 'Foo', slug: 'foo', current: true});
+ should.exist(rendered);
+ rendered.string.should.equal('/foo');
+ });
- it('should not HTML-escape URLs', function () {
- rendered = helpers.url.call(
- {url: '/foo?foo=bar&baz=qux', label: 'Foo', slug: 'foo', current: true});
- should.exist(rendered);
- rendered.string.should.equal('/foo?foo=bar&baz=qux');
- });
+ it('should return an absolute url if passed through a nav context', function () {
+ rendered = helpers.url.call(
+ {url: '/bar', label: 'Bar', slug: 'bar', current: true},
+ {hash: {absolute: 'true'}});
+ should.exist(rendered);
+ rendered.string.should.equal('http://localhost:82832/bar');
+ });
- it('should encode URLs', function () {
- rendered = helpers.url.call(
- {url: '/foo?foo=bar&baz=qux&', label: 'Foo', slug: 'foo', current: true});
- should.exist(rendered);
- rendered.string.should.equal('/foo?foo=bar&baz=qux&%3Cscript%3Ealert(%22gotcha%22)%3C/script%3E');
- });
+ it('should return an absolute url with https if context is secure', function () {
+ rendered = helpers.url.call(
+ {url: '/bar', label: 'Bar', slug: 'bar', current: true, secure: true},
+ {hash: {absolute: 'true'}});
+ should.exist(rendered);
+ rendered.string.should.equal('https://localhost:82832/bar');
+ });
- it('should not double-encode URLs', function () {
- rendered = helpers.url.call(
- {url: '/?foo=space%20bar', label: 'Foo', slug: 'foo', current: true});
- should.exist(rendered);
- rendered.string.should.equal('/?foo=space%20bar');
+ it('external urls should be retained in a nav context', function () {
+ rendered = helpers.url.call(
+ {url: 'http://casper.website/baz', label: 'Baz', slug: 'baz', current: true},
+ {hash: {absolute: 'true'}});
+ should.exist(rendered);
+ rendered.string.should.equal('http://casper.website/baz');
+ });
+
+ it('should handle hosted urls in a nav context', function () {
+ rendered = helpers.url.call(
+ {url: 'http://localhost:82832/qux', label: 'Qux', slug: 'qux', current: true},
+ {hash: {absolute: 'true'}});
+ should.exist(rendered);
+ rendered.string.should.equal('http://localhost:82832/qux');
+ });
+
+ it('should handle hosted urls in a nav context with secure', function () {
+ rendered = helpers.url.call(
+ {
+ url: 'http://localhost:82832/qux', label: 'Qux', slug: 'qux', current: true,
+ secure: true
+ },
+ {hash: {absolute: 'true'}});
+ should.exist(rendered);
+ rendered.string.should.equal('https://localhost:82832/qux');
+ });
+
+ it('should handle hosted https urls in a nav context with secure', function () {
+ rendered = helpers.url.call(
+ {
+ url: 'https://localhost:82832/qux', label: 'Qux', slug: 'qux', current: true,
+ secure: true
+ },
+ {hash: {absolute: 'true'}});
+ should.exist(rendered);
+ rendered.string.should.equal('https://localhost:82832/qux');
+ });
+
+ it('should handle hosted urls with the wrong protocol in a nav context', function () {
+ rendered = helpers.url.call(
+ {url: 'https://localhost:82832/quux', label: 'Quux', slug: 'quux', current: true},
+ {hash: {absolute: 'true'}});
+ should.exist(rendered);
+ rendered.string.should.equal('http://localhost:82832/quux');
+ });
+
+ it('should pass through protocol-less URLs regardless of absolute setting', function () {
+ rendered = helpers.url.call(
+ {url: '//casper.website/baz', label: 'Baz', slug: 'baz', current: true},
+ {hash: {}});
+ should.exist(rendered);
+ rendered.string.should.equal('//casper.website/baz');
+
+ rendered = helpers.url.call(
+ {url: '//casper.website/baz', label: 'Baz', slug: 'baz', current: true},
+ {hash: {absolute: 'true'}});
+ should.exist(rendered);
+ rendered.string.should.equal('//casper.website/baz');
+ });
+
+ it('should pass through URLs with alternative schemes regardless of absolute setting', function () {
+ rendered = helpers.url.call(
+ {url: 'tel:01234567890', label: 'Baz', slug: 'baz', current: true},
+ {hash: {}});
+ should.exist(rendered);
+ rendered.string.should.equal('tel:01234567890');
+
+ rendered = helpers.url.call(
+ {url: 'mailto:example@ghost.org', label: 'Baz', slug: 'baz', current: true},
+ {hash: {}});
+ should.exist(rendered);
+ rendered.string.should.equal('mailto:example@ghost.org');
+
+ rendered = helpers.url.call(
+ {url: 'tel:01234567890', label: 'Baz', slug: 'baz', current: true},
+ {hash: {absolute: 'true'}});
+ should.exist(rendered);
+ rendered.string.should.equal('tel:01234567890');
+
+ rendered = helpers.url.call(
+ {url: 'mailto:example@ghost.org', label: 'Baz', slug: 'baz', current: true},
+ {hash: {absolute: 'true'}});
+ should.exist(rendered);
+ rendered.string.should.equal('mailto:example@ghost.org');
+ });
+
+ it('should pass through anchor-only URLs regardless of absolute setting', function () {
+ rendered = helpers.url.call(
+ {url: '#thatsthegoodstuff', label: 'Baz', slug: 'baz', current: true},
+ {hash: {}});
+ should.exist(rendered);
+ rendered.string.should.equal('#thatsthegoodstuff');
+
+ rendered = helpers.url.call(
+ {url: '#thatsthegoodstuff', label: 'Baz', slug: 'baz', current: true},
+ {hash: {absolute: 'true'}});
+ should.exist(rendered);
+ rendered.string.should.equal('#thatsthegoodstuff');
+ });
+
+ it('should not HTML-escape URLs', function () {
+ rendered = helpers.url.call(
+ {url: '/foo?foo=bar&baz=qux', label: 'Foo', slug: 'foo', current: true});
+ should.exist(rendered);
+ rendered.string.should.equal('/foo?foo=bar&baz=qux');
+ });
+
+ it('should encode URLs', function () {
+ rendered = helpers.url.call(
+ {url: '/foo?foo=bar&baz=qux&', label: 'Foo', slug: 'foo', current: true});
+ should.exist(rendered);
+ rendered.string.should.equal('/foo?foo=bar&baz=qux&%3Cscript%3Ealert(%22gotcha%22)%3C/script%3E');
+ });
+
+ it('should not double-encode URLs', function () {
+ rendered = helpers.url.call(
+ {url: '/?foo=space%20bar', label: 'Foo', slug: 'foo', current: true});
+ should.exist(rendered);
+ rendered.string.should.equal('/?foo=space%20bar');
+ });
});
describe('with subdir', function () {
+ let sandbox;
+
+ before(function () {
+ sandbox = sinon.createSandbox();
+ urlUtils.stubUrlUtils({url: 'http://localhost:82832/blog'}, sandbox);
+ });
+
+ after(function () {
+ sandbox.restore();
+ });
+
it('external urls should be retained in a nav context with subdir', function () {
- configUtils.set({url: 'http://localhost:82832/blog'});
rendered = helpers.url.call(
{url: 'http://casper.website/baz', label: 'Baz', slug: 'baz', current: true},
{hash: {absolute: 'true'}});
@@ -277,8 +291,6 @@ describe('{{url}} helper', function () {
});
it('should handle subdir being set in nav context', function () {
- configUtils.set({url: 'http://localhost:82832/blog'});
-
rendered = helpers.url.call(
{url: '/xyzzy', label: 'xyzzy', slug: 'xyzzy', current: true},
{hash: {absolute: 'true'}});
diff --git a/core/test/unit/lib/image/blog-icon_spec.js b/core/test/unit/lib/image/blog-icon_spec.js
index 51700f623b..6eee1cf082 100644
--- a/core/test/unit/lib/image/blog-icon_spec.js
+++ b/core/test/unit/lib/image/blog-icon_spec.js
@@ -4,20 +4,14 @@ var should = require('should'),
path = require('path'),
rewire = require('rewire'),
settingsCache = require('../../../../server/services/settings/cache'),
- configUtils = require('../../../utils/configUtils'),
- testUtils = require('../../../utils'),
- config = configUtils.config,
+ storageUtils = require('../../../../server/adapters/storage/utils'),
+ urlUtils = require('../../../utils/urlUtils'),
// stuff we are testing
blogIcon = rewire('../../../../server/lib/image/blog-icon');
describe('lib/image: blog icon', function () {
- before(function () {
- configUtils.restore();
- });
-
afterEach(function () {
- configUtils.restore();
sinon.restore();
rewire('../../../../server/lib/image/blog-icon');
});
@@ -36,21 +30,22 @@ describe('lib/image: blog icon', function () {
it('default ico blog icon', function () {
blogIcon.getIconUrl().should.eql('/favicon.ico');
});
+
describe('absolute URL', function () {
it('custom uploaded ico blog icon', function () {
- configUtils.set({url: 'http://my-ghost-blog.com/'});
+ blogIcon.__set__('urlUtils', urlUtils.getInstance({url: 'http://my-ghost-blog.com/'}));
sinon.stub(settingsCache, 'get').withArgs('icon').returns('/content/images/2017/04/my-icon.ico');
blogIcon.getIconUrl(true).should.eql('http://my-ghost-blog.com/favicon.ico');
});
it('custom uploaded png blog icon', function () {
- configUtils.set({url: 'http://my-ghost-blog.com/'});
+ blogIcon.__set__('urlUtils', urlUtils.getInstance({url: 'http://my-ghost-blog.com/'}));
sinon.stub(settingsCache, 'get').withArgs('icon').returns('/content/images/2017/04/my-icon.png');
blogIcon.getIconUrl(true).should.eql('http://my-ghost-blog.com/favicon.png');
});
it('default ico blog icon', function () {
- configUtils.set({url: 'http://my-ghost-blog.com/'});
+ blogIcon.__set__('urlUtils', urlUtils.getInstance({url: 'http://my-ghost-blog.com/'}));
blogIcon.getIconUrl(true).should.eql('http://my-ghost-blog.com/favicon.ico');
});
});
@@ -58,20 +53,20 @@ describe('lib/image: blog icon', function () {
describe('with subdirectory', function () {
it('custom uploaded ico blog icon', function () {
sinon.stub(settingsCache, 'get').withArgs('icon').returns('/content/images/2017/04/my-icon.ico');
- configUtils.set({url: 'http://my-ghost-blog.com/blog'});
+ blogIcon.__set__('urlUtils', urlUtils.getInstance({url: 'http://my-ghost-blog.com/blog'}));
blogIcon.getIconUrl().should.eql('/blog/favicon.ico');
});
it('custom uploaded png blog icon', function () {
sinon.stub(settingsCache, 'get').withArgs('icon').returns('/content/images/2017/04/my-icon.png');
- configUtils.set({url: 'http://my-ghost-blog.com/blog'});
+ blogIcon.__set__('urlUtils', urlUtils.getInstance({url: 'http://my-ghost-blog.com/blog'}));
blogIcon.getIconUrl().should.eql('/blog/favicon.png');
});
it('default ico blog icon', function () {
- configUtils.set({url: 'http://my-ghost-blog.com/blog'});
+ blogIcon.__set__('urlUtils', urlUtils.getInstance({url: 'http://my-ghost-blog.com/blog'}));
blogIcon.getIconUrl().should.eql('/blog/favicon.ico');
});
});
@@ -80,38 +75,23 @@ describe('lib/image: blog icon', function () {
describe('getIconPath', function () {
it('custom uploaded ico blog icon', function () {
sinon.stub(settingsCache, 'get').withArgs('icon').returns('/content/images/2017/04/my-icon.ico');
- blogIcon.getIconPath().should.eql('/2017/04/my-icon.ico');
+ sinon.stub(storageUtils, 'getLocalFileStoragePath');
+ blogIcon.getIconPath();
+
+ storageUtils.getLocalFileStoragePath.calledOnce.should.be.true();
});
it('custom uploaded png blog icon', function () {
sinon.stub(settingsCache, 'get').withArgs('icon').returns('/content/images/2017/04/my-icon.png');
- blogIcon.getIconPath().should.eql('/2017/04/my-icon.png');
+ sinon.stub(storageUtils, 'getLocalFileStoragePath');
+ blogIcon.getIconPath();
+
+ storageUtils.getLocalFileStoragePath.calledOnce.should.be.true();
});
it('default ico blog icon', function () {
blogIcon.getIconPath().should.eql(path.join(__dirname, '../../../../server/public/favicon.ico'));
});
-
- describe('with subdirectory', function () {
- it('custom uploaded ico blog icon', function () {
- sinon.stub(settingsCache, 'get').withArgs('icon').returns('/blog/content/images/2017/04/my-icon.ico');
- configUtils.set({url: 'http://my-ghost-blog.com/blog'});
-
- blogIcon.getIconPath().should.eql('/2017/04/my-icon.ico');
- });
-
- it('custom uploaded png blog icon', function () {
- sinon.stub(settingsCache, 'get').withArgs('icon').returns('/blog/content/images/2017/04/my-icon.png');
- configUtils.set({url: 'http://my-ghost-blog.com/blog'});
-
- blogIcon.getIconPath().should.eql('/2017/04/my-icon.png');
- });
-
- it('default ico blog icon', function () {
- configUtils.set({url: 'http://my-ghost-blog.com/blog'});
- blogIcon.getIconPath().should.eql(path.join(__dirname, '../../../../server/public/favicon.ico'));
- });
- });
});
describe('isIcoImageType', function () {
diff --git a/core/test/unit/lib/image/image-size_spec.js b/core/test/unit/lib/image/image-size_spec.js
index 020e615df3..6470e8ac3d 100644
--- a/core/test/unit/lib/image/image-size_spec.js
+++ b/core/test/unit/lib/image/image-size_spec.js
@@ -4,7 +4,7 @@ const should = require('should'),
nock = require('nock'),
path = require('path'),
configUtils = require('../../../utils/configUtils'),
- urlService = require('../../../../server/services/url'),
+ urlUtils = require('../../../../server/lib/url-utils'),
common = require('../../../../server/lib/common'),
storage = require('../../../../server/adapters/storage');
@@ -146,9 +146,9 @@ describe('lib/image: image size', function () {
width: 1
};
- const urlForStub = sinon.stub(urlService.utils, 'urlFor');
+ const urlForStub = sinon.stub(urlUtils, 'urlFor');
urlForStub.withArgs('home').returns('http://myblog.com/');
- const urlGetSubdirStub = sinon.stub(urlService.utils, 'getSubdir');
+ const urlGetSubdirStub = sinon.stub(urlUtils, 'getSubdir');
urlGetSubdirStub.returns('');
const requestMock = nock('http://myblog.com')
@@ -258,10 +258,10 @@ describe('lib/image: image size', function () {
};
storage.getStorage().storagePath = path.join(__dirname, '../../../../test/utils/fixtures/images/');
- const urlForStub = sinon.stub(urlService.utils, 'urlFor');
+ const urlForStub = sinon.stub(urlUtils, 'urlFor');
urlForStub.withArgs('image').returns('http://myblog.com/content/images/favicon.png');
urlForStub.withArgs('home').returns('http://myblog.com/');
- const urlGetSubdirStub = sinon.stub(urlService.utils, 'getSubdir');
+ const urlGetSubdirStub = sinon.stub(urlUtils, 'getSubdir');
urlGetSubdirStub.returns('');
const requestMock = nock('http://myblog.com')
@@ -423,10 +423,10 @@ describe('lib/image: image size', function () {
};
storage.getStorage().storagePath = path.join(__dirname, '../../../../test/utils/fixtures/images/');
- const urlForStub = sinon.stub(urlService.utils, 'urlFor');
+ const urlForStub = sinon.stub(urlUtils, 'urlFor');
urlForStub.withArgs('image').returns('http://myblog.com/content/images/ghost-logo.png');
urlForStub.withArgs('home').returns('http://myblog.com/');
- const urlGetSubdirStub = sinon.stub(urlService.utils, 'getSubdir');
+ const urlGetSubdirStub = sinon.stub(urlUtils, 'getSubdir');
urlGetSubdirStub.returns('');
imageSize.getImageSizeFromStoragePath(url).then(function (res) {
@@ -450,10 +450,10 @@ describe('lib/image: image size', function () {
};
storage.getStorage().storagePath = path.join(__dirname, '../../../../test/utils/fixtures/images/');
- const urlForStub = sinon.stub(urlService.utils, 'urlFor');
+ const urlForStub = sinon.stub(urlUtils, 'urlFor');
urlForStub.withArgs('image').returns('http://myblog.com/blog/content/images/favicon_too_large.png');
urlForStub.withArgs('home').returns('http://myblog.com/');
- const urlGetSubdirStub = sinon.stub(urlService.utils, 'getSubdir');
+ const urlGetSubdirStub = sinon.stub(urlUtils, 'getSubdir');
urlGetSubdirStub.returns('/blog');
imageSize.getImageSizeFromStoragePath(url).then(function (res) {
@@ -477,10 +477,10 @@ describe('lib/image: image size', function () {
};
storage.getStorage().storagePath = path.join(__dirname, '../../../../test/utils/fixtures/images/');
- const urlForStub = sinon.stub(urlService.utils, 'urlFor');
+ const urlForStub = sinon.stub(urlUtils, 'urlFor');
urlForStub.withArgs('image').returns('http://myblog.com/content/images/favicon_multi_sizes.ico');
urlForStub.withArgs('home').returns('http://myblog.com/');
- const urlGetSubdirStub = sinon.stub(urlService.utils, 'getSubdir');
+ const urlGetSubdirStub = sinon.stub(urlUtils, 'getSubdir');
urlGetSubdirStub.returns('');
imageSize.getImageSizeFromStoragePath(url).then(function (res) {
@@ -499,10 +499,10 @@ describe('lib/image: image size', function () {
const url = '/content/images/not-existing-image.png';
storage.getStorage().storagePath = path.join(__dirname, '../../../../test/utils/fixtures/images/');
- const urlForStub = sinon.stub(urlService.utils, 'urlFor');
+ const urlForStub = sinon.stub(urlUtils, 'urlFor');
urlForStub.withArgs('image').returns('http://myblog.com/content/images/not-existing-image.png');
urlForStub.withArgs('home').returns('http://myblog.com/');
- const urlGetSubdirStub = sinon.stub(urlService.utils, 'getSubdir');
+ const urlGetSubdirStub = sinon.stub(urlUtils, 'getSubdir');
urlGetSubdirStub.returns('');
imageSize.getImageSizeFromStoragePath(url)
@@ -521,10 +521,10 @@ describe('lib/image: image size', function () {
imageSize.__set__('sizeOf', sizeOfStub);
storage.getStorage().storagePath = path.join(__dirname, '../../../../test/utils/fixtures/images/');
- const urlForStub = sinon.stub(urlService.utils, 'urlFor');
+ const urlForStub = sinon.stub(urlUtils, 'urlFor');
urlForStub.withArgs('image').returns('http://myblog.com/content/images/ghost-logo.pngx');
urlForStub.withArgs('home').returns('http://myblog.com/');
- const urlGetSubdirStub = sinon.stub(urlService.utils, 'getSubdir');
+ const urlGetSubdirStub = sinon.stub(urlUtils, 'getSubdir');
urlGetSubdirStub.returns('');
imageSize.getImageSizeFromStoragePath(url)
diff --git a/core/test/unit/models/base/index_spec.js b/core/test/unit/models/base/index_spec.js
index 0ce0eba4e3..278589ebbf 100644
--- a/core/test/unit/models/base/index_spec.js
+++ b/core/test/unit/models/base/index_spec.js
@@ -5,7 +5,7 @@ var should = require('should'),
security = require('../../../../server/lib/security'),
models = require('../../../../server/models'),
common = require('../../../../server/lib/common'),
- urlService = require('../../../../server/services/url'),
+ urlUtils = require('../../../../server/lib/url-utils'),
testUtils = require('../../../utils');
describe('Models: base', function () {
@@ -23,7 +23,7 @@ describe('Models: base', function () {
beforeEach(function () {
sinon.stub(security.string, 'safe');
- sinon.stub(urlService.utils, 'getProtectedSlugs').returns(['upsi', 'schwupsi']);
+ sinon.stub(urlUtils, 'getProtectedSlugs').returns(['upsi', 'schwupsi']);
Model = sinon.stub();
Model.prototype = {
diff --git a/core/test/unit/services/mail/GhostMailer_spec.js b/core/test/unit/services/mail/GhostMailer_spec.js
index 11c44389d1..2101e3de66 100644
--- a/core/test/unit/services/mail/GhostMailer_spec.js
+++ b/core/test/unit/services/mail/GhostMailer_spec.js
@@ -4,6 +4,7 @@ var should = require('should'),
mail = require('../../../../server/services/mail'),
settingsCache = require('../../../../server/services/settings/cache'),
configUtils = require('../../../utils/configUtils'),
+ urlUtils = require('../../../../server/lib/url-utils'),
common = require('../../../../server/lib/common'),
mailer,
@@ -176,31 +177,42 @@ describe('Mail: Ghostmailer', function () {
mailer.from().should.equal('"Blog Title" ');
});
- it('should fall back to [blog.title] ', function () {
- sinon.stub(settingsCache, 'get').returns('Test');
+ describe('should fall back to [blog.title] ', function () {
+ let mailer;
- // Standard domain
- configUtils.set({url: 'http://default.com', mail: {from: null}});
+ beforeEach(function () {
+ mailer = new mail.GhostMailer();
+ sinon.stub(settingsCache, 'get').returns('Test');
+ });
- mailer = new mail.GhostMailer();
+ it('standard domain', function () {
+ sinon.stub(urlUtils, 'urlFor').returns('http://default.com');
+ configUtils.set({mail: {from: null}});
- mailer.from().should.equal('"Test" ');
+ mailer.from().should.equal('"Test" ');
+ });
- // Trailing slash
- configUtils.set({url: 'http://default.com/', mail: {from: null}});
+ it('trailing slash', function () {
+ sinon.stub(urlUtils, 'urlFor').returns('http://default.com/');
+ configUtils.set({mail: {from: null}});
- mailer.from().should.equal('"Test" ');
+ mailer.from().should.equal('"Test" ');
+ });
- // Strip Port
- configUtils.set({url: 'http://default.com:2368/', mail: {from: null}});
- mailer.from().should.equal('"Test" ');
+ it('strip port', function () {
+ sinon.stub(urlUtils, 'urlFor').returns('http://default.com:2368/');
+ configUtils.set({mail: {from: null}});
+ mailer.from().should.equal('"Test" ');
+ });
- settingsCache.get.restore();
- sinon.stub(settingsCache, 'get').returns('Test"');
+ it('Escape title', function () {
+ settingsCache.get.restore();
+ sinon.stub(settingsCache, 'get').returns('Test"');
- // Escape title
- configUtils.set({url: 'http://default.com:2368/', mail: {from: null}});
- mailer.from().should.equal('"Test\\"" ');
+ sinon.stub(urlUtils, 'urlFor').returns('http://default.com:2368/');
+ configUtils.set({mail: {from: null}});
+ mailer.from().should.equal('"Test\\"" ');
+ });
});
it('should use mail.from', function () {
@@ -239,7 +251,8 @@ describe('Mail: Ghostmailer', function () {
});
it('should use default title if not theme title is provided', function () {
- configUtils.set({url: 'http://default.com:2368/', mail: {from: null}});
+ configUtils.set({mail: {from: null}});
+ sinon.stub(urlUtils, 'urlFor').returns('http://default.com:2368/');
mailer = new mail.GhostMailer();
diff --git a/core/test/unit/services/routing/ParentRouter_spec.js b/core/test/unit/services/routing/ParentRouter_spec.js
index 706d1d8c13..18a52157d8 100644
--- a/core/test/unit/services/routing/ParentRouter_spec.js
+++ b/core/test/unit/services/routing/ParentRouter_spec.js
@@ -2,7 +2,7 @@ const should = require('should'),
sinon = require('sinon'),
configUtils = require('../../../utils/configUtils'),
common = require('../../../../server/lib/common'),
- urlService = require('../../../../server/services/url'),
+ urlUtils = require('../../../../server/lib/url-utils'),
ParentRouter = require('../../../../server/services/routing/ParentRouter');
describe('UNIT - services/routing/ParentRouter', function () {
@@ -12,7 +12,7 @@ describe('UNIT - services/routing/ParentRouter', function () {
sinon.stub(common.events, 'emit');
sinon.stub(common.events, 'on');
- sinon.stub(urlService.utils, 'redirect301');
+ sinon.stub(urlUtils, 'redirect301');
req = sinon.stub();
req.app = {
@@ -76,7 +76,7 @@ describe('UNIT - services/routing/ParentRouter', function () {
parentRouter._respectDominantRouter(req, res, next, 'bacon');
next.called.should.eql(false);
- urlService.utils.redirect301.withArgs(res, '/channel/').calledOnce.should.be.true();
+ urlUtils.redirect301.withArgs(res, '/channel/').calledOnce.should.be.true();
});
it('redirect with query params', function () {
@@ -106,7 +106,7 @@ describe('UNIT - services/routing/ParentRouter', function () {
parentRouter._respectDominantRouter(req, res, next, 'bacon');
next.called.should.eql(false);
- urlService.utils.redirect301.withArgs(res, '/channel/?a=b').calledOnce.should.be.true();
+ urlUtils.redirect301.withArgs(res, '/channel/?a=b').calledOnce.should.be.true();
});
it('redirect rss', function () {
@@ -136,7 +136,7 @@ describe('UNIT - services/routing/ParentRouter', function () {
parentRouter._respectDominantRouter(req, res, next, 'bacon');
next.called.should.eql(false);
- urlService.utils.redirect301.withArgs(res, '/channel/rss/').calledOnce.should.be.true();
+ urlUtils.redirect301.withArgs(res, '/channel/rss/').calledOnce.should.be.true();
});
it('redirect pagination', function () {
@@ -166,11 +166,11 @@ describe('UNIT - services/routing/ParentRouter', function () {
parentRouter._respectDominantRouter(req, res, next, 'bacon');
next.called.should.eql(false);
- urlService.utils.redirect301.withArgs(res, '/channel/page/2/').calledOnce.should.be.true();
+ urlUtils.redirect301.withArgs(res, '/channel/page/2/').calledOnce.should.be.true();
});
it('redirect correctly with subdirectory', function () {
- configUtils.set('url', 'http://localhost:7777/blog/');
+ sinon.stub(urlUtils, 'createUrl').returns('/blog/channel/');
const parentRouter = new ParentRouter('tag', '/tag/:slug/');
parentRouter.getResourceType = sinon.stub().returns('tags');
@@ -198,7 +198,7 @@ describe('UNIT - services/routing/ParentRouter', function () {
parentRouter._respectDominantRouter(req, res, next, 'bacon');
next.called.should.eql(false);
- urlService.utils.redirect301.withArgs(res, '/blog/channel/').calledOnce.should.be.true();
+ urlUtils.redirect301.withArgs(res, '/blog/channel/').calledOnce.should.be.true();
});
it('no redirect: different data key', function () {
@@ -225,7 +225,7 @@ describe('UNIT - services/routing/ParentRouter', function () {
parentRouter._respectDominantRouter(req, res, next, 'bacon');
next.called.should.eql(true);
- urlService.utils.redirect301.called.should.be.false();
+ urlUtils.redirect301.called.should.be.false();
});
it('no redirect: no channel defined', function () {
@@ -247,7 +247,7 @@ describe('UNIT - services/routing/ParentRouter', function () {
parentRouter._respectDominantRouter(req, res, next, 'bacon');
next.called.should.eql(true);
- urlService.utils.redirect301.called.should.be.false();
+ urlUtils.redirect301.called.should.be.false();
});
it('redirect primary tag permalink', function () {
@@ -277,7 +277,7 @@ describe('UNIT - services/routing/ParentRouter', function () {
parentRouter._respectDominantRouter(req, res, next, 'welcome');
next.called.should.eql(false);
- urlService.utils.redirect301.withArgs(res, '/route/?x=y').calledOnce.should.be.true();
+ urlUtils.redirect301.withArgs(res, '/route/?x=y').calledOnce.should.be.true();
});
});
diff --git a/core/test/unit/services/routing/RSSRouter_spec.js b/core/test/unit/services/routing/RSSRouter_spec.js
index 71b14b93a8..e92b274021 100644
--- a/core/test/unit/services/routing/RSSRouter_spec.js
+++ b/core/test/unit/services/routing/RSSRouter_spec.js
@@ -4,7 +4,7 @@ const should = require('should'),
common = require('../../../../server/lib/common'),
controllers = require('../../../../server/services/routing/controllers'),
RSSRouter = require('../../../../server/services/routing/RSSRouter'),
- urlService = require('../../../../server/services/url');
+ urlUtils = require('../../../../server/lib/url-utils');
describe('UNIT - services/routing/RSSRouter', function () {
describe('instantiate', function () {
@@ -15,7 +15,7 @@ describe('UNIT - services/routing/RSSRouter', function () {
sinon.spy(RSSRouter.prototype, 'mountRoute');
sinon.spy(RSSRouter.prototype, 'mountRouter');
- sinon.stub(urlService.utils, 'urlJoin');
+ sinon.stub(urlUtils, 'urlJoin');
});
afterEach(function () {
@@ -24,7 +24,7 @@ describe('UNIT - services/routing/RSSRouter', function () {
});
it('default', function () {
- urlService.utils.urlJoin.withArgs('/rss/', ':page(\\d+)').returns('/rss-pagination/');
+ urlUtils.urlJoin.withArgs('/rss/', ':page(\\d+)').returns('/rss-pagination/');
const rssRouter = new RSSRouter();
@@ -47,7 +47,7 @@ describe('UNIT - services/routing/RSSRouter', function () {
it('subdirectory is enabled', function () {
configUtils.set('url', 'http://localhost:22222/blog/');
- urlService.utils.urlJoin.withArgs('/rss/', ':page(\\d+)').returns('/rss-pagination/');
+ urlUtils.urlJoin.withArgs('/rss/', ':page(\\d+)').returns('/rss-pagination/');
const rssRouter = new RSSRouter();
diff --git a/core/test/unit/services/routing/controllers/entry_spec.js b/core/test/unit/services/routing/controllers/entry_spec.js
index 35124412be..cda882a0c4 100644
--- a/core/test/unit/services/routing/controllers/entry_spec.js
+++ b/core/test/unit/services/routing/controllers/entry_spec.js
@@ -2,6 +2,7 @@ const should = require('should'),
sinon = require('sinon'),
testUtils = require('../../../../utils'),
urlService = require('../../../../../server/services/url'),
+ urlUtils = require('../../../../../server/lib/url-utils'),
controllers = require('../../../../../server/services/routing/controllers'),
helpers = require('../../../../../server/services/routing/helpers'),
EDITOR_URL = `/editor/post/`;
@@ -31,8 +32,8 @@ describe('Unit - services/routing/controllers/entry', function () {
return renderStub;
});
- sinon.stub(urlService.utils, 'redirectToAdmin');
- sinon.stub(urlService.utils, 'redirect301');
+ sinon.stub(urlUtils, 'redirectToAdmin');
+ sinon.stub(urlUtils, 'redirect301');
sinon.stub(urlService, 'getResourceById');
req = {
@@ -114,7 +115,7 @@ describe('Unit - services/routing/controllers/entry', function () {
entry: post
});
- urlService.utils.redirectToAdmin.callsFake(function (statusCode, res, editorUrl) {
+ urlUtils.redirectToAdmin.callsFake(function (statusCode, res, editorUrl) {
statusCode.should.eql(302);
editorUrl.should.eql(EDITOR_URL + post.id);
done();
@@ -164,7 +165,7 @@ describe('Unit - services/routing/controllers/entry', function () {
entry: post
});
- urlService.utils.redirect301.callsFake(function (res, postUrl) {
+ urlUtils.redirect301.callsFake(function (res, postUrl) {
postUrl.should.eql(post.url);
done();
});
@@ -193,7 +194,7 @@ describe('Unit - services/routing/controllers/entry', function () {
entry: post
});
- urlService.utils.redirect301.callsFake(function (res, postUrl) {
+ urlUtils.redirect301.callsFake(function (res, postUrl) {
postUrl.should.eql(post.url + '?query=true');
done();
});
diff --git a/core/test/unit/services/routing/controllers/preview_spec.js b/core/test/unit/services/routing/controllers/preview_spec.js
index dc898bf2a0..c6823148af 100644
--- a/core/test/unit/services/routing/controllers/preview_spec.js
+++ b/core/test/unit/services/routing/controllers/preview_spec.js
@@ -7,6 +7,8 @@ const should = require('should'),
controllers = require('../../../../../server/services/routing/controllers'),
helpers = require('../../../../../server/services/routing/helpers'),
urlService = require('../../../../../server/services/url'),
+ urlUtils = require('../../../../../server/lib/url-utils'),
+
EDITOR_URL = '/editor/post/';
describe('Unit - services/routing/controllers/preview', function () {
@@ -55,8 +57,8 @@ describe('Unit - services/routing/controllers/preview', function () {
secureStub = sinon.stub();
- sinon.stub(urlService.utils, 'redirectToAdmin');
- sinon.stub(urlService.utils, 'redirect301');
+ sinon.stub(urlUtils, 'redirectToAdmin');
+ sinon.stub(urlUtils, 'redirect301');
sinon.stub(urlService, 'getUrlByResourceId');
sinon.stub(helpers, 'secure').get(function () {
@@ -102,7 +104,7 @@ describe('Unit - services/routing/controllers/preview', function () {
post.status = 'published';
urlService.getUrlByResourceId.withArgs(post.id).returns('/something/');
- urlService.utils.redirect301.callsFake(function (res, postUrl) {
+ urlUtils.redirect301.callsFake(function (res, postUrl) {
postUrl.should.eql('/something/');
renderStub.called.should.be.false();
secureStub.called.should.be.false();
@@ -115,7 +117,7 @@ describe('Unit - services/routing/controllers/preview', function () {
it('should call redirect if /edit/ (options param) is detected', function (done) {
req.params.options = 'edit';
- urlService.utils.redirectToAdmin.callsFake(function (statusCode, res, editorUrl) {
+ urlUtils.redirectToAdmin.callsFake(function (statusCode, res, editorUrl) {
statusCode.should.eql(302);
editorUrl.should.eql(EDITOR_URL + post.id);
renderStub.called.should.be.false();
@@ -170,8 +172,8 @@ describe('Unit - services/routing/controllers/preview', function () {
secureStub = sinon.stub();
- sinon.stub(urlService.utils, 'redirectToAdmin');
- sinon.stub(urlService.utils, 'redirect301');
+ sinon.stub(urlUtils, 'redirectToAdmin');
+ sinon.stub(urlUtils, 'redirect301');
sinon.stub(urlService, 'getUrlByResourceId');
sinon.stub(helpers, 'secure').get(function () {
diff --git a/core/test/unit/services/routing/middlewares/page-param_spec.js b/core/test/unit/services/routing/middlewares/page-param_spec.js
index 7a84392af9..4425b7dfd3 100644
--- a/core/test/unit/services/routing/middlewares/page-param_spec.js
+++ b/core/test/unit/services/routing/middlewares/page-param_spec.js
@@ -2,6 +2,7 @@ const should = require('should'),
sinon = require('sinon'),
common = require('../../../../../server/lib/common'),
urlService = require('../../../../../server/services/url'),
+ urlUtils = require('../../../../../server/lib/url-utils'),
middlewares = require('../../../../../server/services/routing/middlewares');
describe('UNIT: services/routing/middlewares/page-param', function () {
@@ -14,7 +15,7 @@ describe('UNIT: services/routing/middlewares/page-param', function () {
res = sinon.stub();
next = sinon.stub();
- sinon.stub(urlService.utils, 'redirect301');
+ sinon.stub(urlUtils, 'redirect301');
});
afterEach(function () {
@@ -27,7 +28,7 @@ describe('UNIT: services/routing/middlewares/page-param', function () {
middlewares.pageParam(req, res, next, 2);
- urlService.utils.redirect301.called.should.be.false();
+ urlUtils.redirect301.called.should.be.false();
next.calledOnce.should.be.true();
req.params.page.should.eql(2);
});
@@ -38,7 +39,7 @@ describe('UNIT: services/routing/middlewares/page-param', function () {
middlewares.pageParam(req, res, next, 1);
- urlService.utils.redirect301.calledOnce.should.be.true();
+ urlUtils.redirect301.calledOnce.should.be.true();
next.called.should.be.false();
});
@@ -48,7 +49,7 @@ describe('UNIT: services/routing/middlewares/page-param', function () {
middlewares.pageParam(req, res, next, 0);
- urlService.utils.redirect301.called.should.be.false();
+ urlUtils.redirect301.called.should.be.false();
next.calledOnce.should.be.true();
(next.args[0][0] instanceof common.errors.NotFoundError).should.be.true();
});
@@ -59,7 +60,7 @@ describe('UNIT: services/routing/middlewares/page-param', function () {
middlewares.pageParam(req, res, next, 'something');
- urlService.utils.redirect301.called.should.be.false();
+ urlUtils.redirect301.called.should.be.false();
next.calledOnce.should.be.true();
(next.args[0][0] instanceof common.errors.NotFoundError).should.be.true();
});
@@ -70,7 +71,7 @@ describe('UNIT: services/routing/middlewares/page-param', function () {
middlewares.pageParam(req, res, next, 1);
- urlService.utils.redirect301.calledOnce.should.be.true();
+ urlUtils.redirect301.calledOnce.should.be.true();
next.called.should.be.false();
});
});
diff --git a/core/test/unit/services/rss/generate-feed_spec.js b/core/test/unit/services/rss/generate-feed_spec.js
index 70a368862b..4c25560367 100644
--- a/core/test/unit/services/rss/generate-feed_spec.js
+++ b/core/test/unit/services/rss/generate-feed_spec.js
@@ -2,7 +2,7 @@ var should = require('should'),
sinon = require('sinon'),
_ = require('lodash'),
testUtils = require('../../../utils'),
- configUtils = require('../../../utils/configUtils'),
+ urlUtils = require('../../../utils/urlUtils'),
urlService = require('../../../../server/services/url'),
generateFeed = require('../../../../server/services/rss/generate-feed');
@@ -26,13 +26,10 @@ describe('RSS: Generate Feed', function () {
});
afterEach(function () {
- configUtils.restore();
sinon.restore();
});
beforeEach(function () {
- configUtils.set({url: 'http://my-ghost-blog.com'});
-
sinon.stub(urlService, 'getUrlByResourceId');
baseUrl = '/rss/';
@@ -43,190 +40,214 @@ describe('RSS: Generate Feed', function () {
data.meta = {pagination: {pages: 1}};
});
- it('should get the RSS tags correct', function (done) {
- data.posts = [];
+ describe('without subdirectory', function () {
+ let sandbox;
- generateFeed(baseUrl, data).then(function (xmlData) {
- should.exist(xmlData);
-
- // xml & rss tags
- xmlData.should.match(/^<\?xml version="1.0" encoding="UTF-8"\?>/);
- xmlData.should.match(/<\/title>/);
- xmlData.should.match(/<\/description>/);
- xmlData.should.match(/http:\/\/my-ghost-blog.com\/<\/link>/);
- xmlData.should.match(/http:\/\/my-ghost-blog.com\/favicon.png<\/url>Test Title<\/title>http:\/\/my-ghost-blog.com\/<\/link><\/image>/);
- xmlData.should.match(/Ghost 0.6<\/generator>/);
- xmlData.should.match(/.*?<\/lastBuildDate>/);
- xmlData.should.match(/60<\/ttl>/);
- xmlData.should.match(/<\/channel><\/rss>$/);
-
- done();
- }).catch(done);
- });
-
- it('should get the item tags correct', function (done) {
- data.posts = posts;
-
- _.each(data.posts, function (post) {
- urlService.getUrlByResourceId.withArgs(post.id, {secure: undefined, absolute: true}).returns('http://my-ghost-blog.com/' + post.slug + '/');
+ beforeEach(function () {
+ sandbox = sinon.createSandbox();
+ urlUtils.stubUrlUtils({url: 'http://my-ghost-blog.com'}, sandbox);
});
- generateFeed(baseUrl, data).then(function (xmlData) {
- should.exist(xmlData);
-
- // item tags
- xmlData.should.match(/- <\/title>/);
- xmlData.should.match(/HTML Ipsum Presents<\/h1>/);
- xmlData.should.match(/http:\/\/my-ghost-blog.com\/html-ipsum\/<\/link>/);
- xmlData.should.match(/http:\/\/my-ghost-blog.com\/favicon.png<\/url>Test Title<\/title>http:\/\/my-ghost-blog.com\/<\/link><\/image>/);
- xmlData.should.match(//);
- xmlData.should.match(/<\/guid><\/dc:creator>/);
- xmlData.should.match(/Thu, 01 Jan 2015/);
- xmlData.should.match(/HTML Ipsum Presents<\/h1>/);
- xmlData.should.match(/<\/code><\/pre>\]\]><\/content:encoded><\/item>/);
- xmlData.should.not.match(//);
-
- // basic structure check
- var postEnd = '<\/code><\/pre>\]\]><\/content:encoded>',
- firstIndex = xmlData.indexOf(postEnd);
-
- // The first title should be before the first content
- xmlData.indexOf('HTML Ipsum').should.be.below(firstIndex);
- // The second title should be after the first content
- xmlData.indexOf('Ghostly Kitchen Sink').should.be.above(firstIndex);
-
- done();
- }).catch(done);
- });
-
- it('should only return visible tags', function (done) {
- var postWithTags = posts[2];
- postWithTags.tags = [
- {name: 'public', visibility: 'public'},
- {name: 'internal', visibility: 'internal'},
- {name: 'visibility'}
- ];
-
- data.posts = [postWithTags];
-
- generateFeed(baseUrl, data).then(function (xmlData) {
- should.exist(xmlData);
- // item tags
- xmlData.should.match(//);
- xmlData.should.match(/