mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-23 10:53:34 +03:00
5b77f052d9
closes #5071 - Remove hardcoded notification in admin controller - NOTE: update check notifications are no longer blocking the admin rendering - this is one of the most import changes - we remove the hardcoded release message - we also remove adding a notification manually in here, because this will work differently from now on -> you receive a notification (release or custom) in the update check module and this module adds the notification as is to our database - Change default core settings keys - remove displayUpdateNotification -> this was used to store the release version number send from the UCS -> based on this value, Ghost creates a notification container with self defined values -> not needed anymore - rename seenNotifications to notifications -> the new notifications key will hold both 1. the notification from the USC 2. the information about if a notification was seen or not - this key hold only one release notification - and n custom notifications - Update Check Module: Request to the USC depends on the privacy configuration - useUpdateCheck: true -> does a checkin in the USC (exposes data) - useUpdateCheck: false -> does only a GET query to the USC (does not expose any data) - make the request handling dynamic, so it depends on the flag - add an extra logic to be able to define a custom USC endpoint (helpful for testing) - add an extra logic to be able to force the request to the service (helpful for testing) - Update check module: re-work condition when a check should happen - only if the env is not correct - remove deprecated config.updateCheck - remove isPrivacyDisabled check (handled differently now, explained in last commit) - Update check module: remove `showUpdateNotification` and readability - showUpdateNotification was used in the admin controller to fetch the latest release version number from the db - no need to check against semver in general, the USC takes care of that (no need to double check) - improve readability of `nextUpdateCheck` condition - Update check module: refactor `updateCheckResponse` - remove db call to displayUpdateNotification, not used anymore - support receiving multiple custom notifications - support custom notification groups - the default group is `all` - this will always be consumed - groups can be extended via config e.g. `notificationGroups: ['migration']` - Update check module: refactor createCustomNotification helper - get rid of taking over notification duplication handling (this is not the task of the update check module) - ensure we have good fallback values for non present attributes in a notification - get rid of semver check (happens in the USC) - could be reconsidered later if LTS is gone - Refactor notification API - reason: get rid of in process notification store -> this was an object hold in process -> everything get's lost after restart -> not helpful anymore, because imagine the following case -> you get a notification -> you store it in process -> you mark this notification as seen -> you restart Ghost, you will receive the same notification on the next check again -> because we are no longer have a separate seen notifications object - use database settings key `notification` instead - refactor all api endpoints to support reading and storing into the `notifications` object - most important: notification deletion happens via a `seen` property (the notification get's physically deleted 3 month automatically) -> we have to remember a seen property, because otherwise you don't know which notification was already received/seen - Add listener to remove seen notifications automatically after 3 month - i just decided for 3 month (we can decrease?) - at the end it doesn't really matter, as long as the windows is not tooooo short - listen on updates for the notifications settings - check if notification was seen and is older than 3 month - ignore release notification - Updated our privacy document - Updated docs.ghost.org for privacy config behaviour - contains a migration script to remove old settings keys
646 lines
23 KiB
JavaScript
646 lines
23 KiB
JavaScript
var _ = require('lodash'),
|
|
Promise = require('bluebird'),
|
|
should = require('should'),
|
|
rewire = require('rewire'),
|
|
sinon = require('sinon'),
|
|
moment = require('moment'),
|
|
uuid = require('uuid'),
|
|
testUtils = require('../utils'),
|
|
configUtils = require('../utils/configUtils'),
|
|
packageInfo = require('../../../package'),
|
|
updateCheck = rewire('../../server/update-check'),
|
|
SettingsAPI = require('../../server/api/settings'),
|
|
NotificationsAPI = require('../../server/api/notifications'),
|
|
sandbox = sinon.sandbox.create();
|
|
|
|
describe('Update Check', function () {
|
|
beforeEach(function () {
|
|
updateCheck = rewire('../../server/update-check');
|
|
});
|
|
|
|
afterEach(function () {
|
|
sandbox.restore();
|
|
configUtils.restore();
|
|
});
|
|
|
|
describe('fn: updateCheck', function () {
|
|
var updateCheckRequestSpy,
|
|
updateCheckResponseSpy,
|
|
updateCheckErrorSpy;
|
|
|
|
beforeEach(testUtils.setup('owner', 'posts', 'perms:setting', 'perms:user', 'perms:init'));
|
|
afterEach(testUtils.teardown);
|
|
|
|
beforeEach(function () {
|
|
updateCheckRequestSpy = sandbox.stub().returns(Promise.resolve());
|
|
updateCheckResponseSpy = sandbox.stub().returns(Promise.resolve());
|
|
updateCheckErrorSpy = sandbox.stub();
|
|
|
|
updateCheck.__set__('updateCheckRequest', updateCheckRequestSpy);
|
|
updateCheck.__set__('updateCheckResponse', updateCheckResponseSpy);
|
|
updateCheck.__set__('updateCheckError', updateCheckErrorSpy);
|
|
updateCheck.__set__('allowedCheckEnvironments', ['development', 'production', 'testing', 'testing-mysql', 'testing-pg']);
|
|
});
|
|
|
|
it('update check was never executed', function (done) {
|
|
sandbox.stub(SettingsAPI, 'read').returns(Promise.resolve({
|
|
settings: [{
|
|
value: null
|
|
}]
|
|
}));
|
|
|
|
updateCheck()
|
|
.then(function () {
|
|
updateCheckRequestSpy.calledOnce.should.eql(true);
|
|
updateCheckResponseSpy.calledOnce.should.eql(true);
|
|
updateCheckErrorSpy.called.should.eql(false);
|
|
done();
|
|
})
|
|
.catch(done);
|
|
});
|
|
|
|
it('update check won\'t happen if it\'s too early', function (done) {
|
|
sandbox.stub(SettingsAPI, 'read').returns(Promise.resolve({
|
|
settings: [{
|
|
value: moment().add('10', 'minutes').unix()
|
|
}]
|
|
}));
|
|
|
|
updateCheck()
|
|
.then(function () {
|
|
updateCheckRequestSpy.calledOnce.should.eql(false);
|
|
updateCheckResponseSpy.calledOnce.should.eql(false);
|
|
updateCheckErrorSpy.called.should.eql(false);
|
|
done();
|
|
})
|
|
.catch(done);
|
|
});
|
|
|
|
it('update check will happen if it\'s time to check', function (done) {
|
|
sandbox.stub(SettingsAPI, 'read').returns(Promise.resolve({
|
|
settings: [{
|
|
value: moment().subtract('10', 'minutes').unix()
|
|
}]
|
|
}));
|
|
|
|
updateCheck()
|
|
.then(function () {
|
|
updateCheckRequestSpy.calledOnce.should.eql(true);
|
|
updateCheckResponseSpy.calledOnce.should.eql(true);
|
|
updateCheckErrorSpy.called.should.eql(false);
|
|
done();
|
|
})
|
|
.catch(done);
|
|
});
|
|
});
|
|
|
|
describe('fn: updateCheckData', function () {
|
|
var environmentsOrig;
|
|
|
|
before(function () {
|
|
configUtils.set('privacy:useUpdateCheck', true);
|
|
});
|
|
|
|
after(function () {
|
|
configUtils.restore();
|
|
});
|
|
|
|
beforeEach(testUtils.setup('owner', 'settings', 'posts', 'perms:setting', 'perms:user', 'perms:init'));
|
|
|
|
afterEach(testUtils.teardown);
|
|
|
|
it('should report the correct data', function (done) {
|
|
var updateCheckData = updateCheck.__get__('updateCheckData');
|
|
|
|
updateCheckData().then(function (data) {
|
|
should.exist(data);
|
|
data.ghost_version.should.equal(packageInfo.version);
|
|
data.node_version.should.equal(process.versions.node);
|
|
data.env.should.equal(process.env.NODE_ENV);
|
|
data.database_type.should.match(/sqlite3|mysql/);
|
|
data.blog_id.should.be.a.String();
|
|
data.blog_id.should.not.be.empty();
|
|
data.theme.should.be.equal('casper');
|
|
data.apps.should.be.a.String();
|
|
data.blog_created_at.should.be.a.Number();
|
|
data.user_count.should.be.above(0);
|
|
data.post_count.should.be.above(0);
|
|
data.npm_version.should.be.a.String();
|
|
data.npm_version.should.not.be.empty();
|
|
data.lts.should.eql(false);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
});
|
|
|
|
describe('fn: createCustomNotification', function () {
|
|
var currentVersionOrig;
|
|
|
|
before(function () {
|
|
currentVersionOrig = updateCheck.__get__('ghostVersion.original');
|
|
updateCheck.__set__('ghostVersion.original', '0.9.0');
|
|
});
|
|
|
|
after(function () {
|
|
updateCheck.__set__('ghostVersion.original', currentVersionOrig);
|
|
});
|
|
|
|
beforeEach(testUtils.setup('owner', 'posts', 'settings', 'perms:setting', 'perms:notification', 'perms:user', 'perms:init'));
|
|
|
|
beforeEach(function () {
|
|
return NotificationsAPI.destroyAll(testUtils.context.internal);
|
|
});
|
|
|
|
afterEach(testUtils.teardown);
|
|
|
|
it('should create a release notification for target version', function (done) {
|
|
var createCustomNotification = updateCheck.__get__('createCustomNotification'),
|
|
notification = {
|
|
id: 1,
|
|
custom: 0,
|
|
messages: [{
|
|
id: uuid.v4(),
|
|
version: '0.9.x',
|
|
content: '<p>Hey there! This is for 0.9.0 version</p>',
|
|
dismissible: true,
|
|
top: true
|
|
}]
|
|
};
|
|
|
|
createCustomNotification(notification).then(function () {
|
|
return NotificationsAPI.browse(testUtils.context.internal);
|
|
}).then(function (results) {
|
|
should.exist(results);
|
|
should.exist(results.notifications);
|
|
results.notifications.length.should.eql(1);
|
|
|
|
var targetNotification = _.find(results.notifications, {id: notification.messages[0].id});
|
|
should.exist(targetNotification);
|
|
|
|
targetNotification.dismissible.should.eql(notification.messages[0].dismissible);
|
|
targetNotification.id.should.eql(notification.messages[0].id);
|
|
targetNotification.top.should.eql(notification.messages[0].top);
|
|
targetNotification.type.should.eql('info');
|
|
targetNotification.message.should.eql(notification.messages[0].content);
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('should create a custom notification', function (done) {
|
|
var createCustomNotification = updateCheck.__get__('createCustomNotification'),
|
|
notification = {
|
|
id: 1,
|
|
custom: 1,
|
|
messages: [{
|
|
id: uuid.v4(),
|
|
version: 'custom1',
|
|
content: '<p>How about migrating your blog?</p>',
|
|
dismissible: false,
|
|
top: true,
|
|
type: 'warn'
|
|
}]
|
|
};
|
|
|
|
createCustomNotification(notification).then(function () {
|
|
return NotificationsAPI.browse(testUtils.context.internal);
|
|
}).then(function (results) {
|
|
should.exist(results);
|
|
should.exist(results.notifications);
|
|
results.notifications.length.should.eql(1);
|
|
|
|
var targetNotification = _.find(results.notifications, {id: notification.messages[0].id});
|
|
should.exist(targetNotification);
|
|
targetNotification.dismissible.should.eql(notification.messages[0].dismissible);
|
|
targetNotification.top.should.eql(notification.messages[0].top);
|
|
targetNotification.type.should.eql(notification.messages[0].type);
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('should not add duplicates', function (done) {
|
|
var createCustomNotification = updateCheck.__get__('createCustomNotification'),
|
|
notification = {
|
|
id: 1,
|
|
custom: 1,
|
|
messages: [{
|
|
id: uuid.v4(),
|
|
version: 'custom1',
|
|
content: '<p>How about migrating your blog?</p>',
|
|
dismissible: false,
|
|
top: true,
|
|
type: 'warn'
|
|
}]
|
|
};
|
|
|
|
createCustomNotification(notification)
|
|
.then(function () {
|
|
return NotificationsAPI.browse(testUtils.context.internal);
|
|
})
|
|
.then(function (results) {
|
|
should.exist(results);
|
|
should.exist(results.notifications);
|
|
results.notifications.length.should.eql(1);
|
|
})
|
|
.then(function () {
|
|
return createCustomNotification(notification);
|
|
})
|
|
.then(function () {
|
|
return NotificationsAPI.browse(testUtils.context.internal);
|
|
})
|
|
.then(function (results) {
|
|
should.exist(results);
|
|
should.exist(results.notifications);
|
|
results.notifications.length.should.eql(1);
|
|
done();
|
|
})
|
|
.catch(done);
|
|
});
|
|
});
|
|
|
|
describe('fn: updateCheckResponse', function () {
|
|
beforeEach(testUtils.setup('settings', 'perms:setting', 'perms:init'));
|
|
afterEach(testUtils.teardown);
|
|
|
|
it('receives a notifications with messages', function (done) {
|
|
var updateCheckResponse = updateCheck.__get__('updateCheckResponse'),
|
|
createNotificationSpy = sandbox.spy(),
|
|
message = {
|
|
id: uuid.v4(),
|
|
version: '^0.11.11',
|
|
content: 'Test',
|
|
dismissible: true,
|
|
top: true
|
|
};
|
|
|
|
updateCheck.__set__('createCustomNotification', createNotificationSpy);
|
|
|
|
updateCheckResponse({version: '0.11.12', messages: [message]})
|
|
.then(function () {
|
|
createNotificationSpy.callCount.should.eql(1);
|
|
done();
|
|
})
|
|
.catch(done);
|
|
});
|
|
|
|
it('receives multiple notifications', function (done) {
|
|
var updateCheckResponse = updateCheck.__get__('updateCheckResponse'),
|
|
createNotificationSpy = sandbox.spy(),
|
|
message1 = {
|
|
id: uuid.v4(),
|
|
version: '^0.11.11',
|
|
content: 'Test1',
|
|
dismissible: true,
|
|
top: true
|
|
},
|
|
message2 = {
|
|
id: uuid.v4(),
|
|
version: '^0',
|
|
content: 'Test2',
|
|
dismissible: true,
|
|
top: false
|
|
},
|
|
notifications = [
|
|
{version: '0.11.12', messages: [message1]},
|
|
{version: 'custom1', messages: [message2]}
|
|
];
|
|
|
|
updateCheck.__set__('createCustomNotification', createNotificationSpy);
|
|
|
|
updateCheckResponse(notifications)
|
|
.then(function () {
|
|
createNotificationSpy.callCount.should.eql(2);
|
|
done();
|
|
})
|
|
.catch(done);
|
|
});
|
|
|
|
it('ignores some custom notifications which are not marked as group', function (done) {
|
|
var updateCheckResponse = updateCheck.__get__('updateCheckResponse'),
|
|
createNotificationSpy = sandbox.spy(),
|
|
message1 = {
|
|
id: uuid.v4(),
|
|
version: '^0.11.11',
|
|
content: 'Test1',
|
|
dismissible: true,
|
|
top: true
|
|
},
|
|
message2 = {
|
|
id: uuid.v4(),
|
|
version: '^0',
|
|
content: 'Test2',
|
|
dismissible: true,
|
|
top: false
|
|
},
|
|
message3 = {
|
|
id: uuid.v4(),
|
|
version: '^0',
|
|
content: 'Test2',
|
|
dismissible: true,
|
|
top: false
|
|
},
|
|
notifications = [
|
|
{version: '0.11.12', messages: [message1]},
|
|
{version: 'all1', messages: [message2], custom: 1},
|
|
{version: 'migration1', messages: [message3], custom: 1}
|
|
];
|
|
|
|
updateCheck.__set__('createCustomNotification', createNotificationSpy);
|
|
|
|
updateCheckResponse(notifications)
|
|
.then(function () {
|
|
createNotificationSpy.callCount.should.eql(2);
|
|
done();
|
|
})
|
|
.catch(done);
|
|
});
|
|
|
|
it('group matches', function (done) {
|
|
var updateCheckResponse = updateCheck.__get__('updateCheckResponse'),
|
|
createNotificationSpy = sandbox.spy(),
|
|
message1 = {
|
|
id: uuid.v4(),
|
|
version: '^0.11.11',
|
|
content: 'Test1',
|
|
dismissible: true,
|
|
top: true
|
|
},
|
|
message2 = {
|
|
id: uuid.v4(),
|
|
version: '^0',
|
|
content: 'Test2',
|
|
dismissible: true,
|
|
top: false
|
|
},
|
|
message3 = {
|
|
id: uuid.v4(),
|
|
version: '^0',
|
|
content: 'Test2',
|
|
dismissible: true,
|
|
top: false
|
|
},
|
|
notifications = [
|
|
{version: '0.11.12', messages: [message1], custom: 0},
|
|
{version: 'all1', messages: [message2], custom: 1},
|
|
{version: 'migration1', messages: [message3], custom: 1}
|
|
];
|
|
|
|
updateCheck.__set__('createCustomNotification', createNotificationSpy);
|
|
|
|
configUtils.set({notificationGroups: ['migration']});
|
|
|
|
updateCheckResponse(notifications)
|
|
.then(function () {
|
|
createNotificationSpy.callCount.should.eql(3);
|
|
done();
|
|
})
|
|
.catch(done);
|
|
});
|
|
|
|
it('single custom notification received, group matches', function (done) {
|
|
var updateCheckResponse = updateCheck.__get__('updateCheckResponse'),
|
|
createNotificationSpy = sandbox.spy(),
|
|
message1 = {
|
|
id: uuid.v4(),
|
|
version: '^0.11.11',
|
|
content: 'Custom',
|
|
dismissible: true,
|
|
top: true
|
|
},
|
|
notifications = [
|
|
{version: 'something', messages: [message1], custom: 1}
|
|
];
|
|
|
|
updateCheck.__set__('createCustomNotification', createNotificationSpy);
|
|
|
|
configUtils.set({notificationGroups: ['something']});
|
|
|
|
updateCheckResponse(notifications)
|
|
.then(function () {
|
|
createNotificationSpy.callCount.should.eql(1);
|
|
done();
|
|
})
|
|
.catch(done);
|
|
});
|
|
|
|
it('single custom notification received, group does not match', function (done) {
|
|
var updateCheckResponse = updateCheck.__get__('updateCheckResponse'),
|
|
createNotificationSpy = sandbox.spy(),
|
|
message1 = {
|
|
id: uuid.v4(),
|
|
version: '^0.11.11',
|
|
content: 'Custom',
|
|
dismissible: true,
|
|
top: true
|
|
},
|
|
notifications = [
|
|
{version: 'something', messages: [message1], custom: 1}
|
|
];
|
|
|
|
updateCheck.__set__('createCustomNotification', createNotificationSpy);
|
|
|
|
configUtils.set({notificationGroups: ['migration']});
|
|
|
|
updateCheckResponse(notifications)
|
|
.then(function () {
|
|
createNotificationSpy.callCount.should.eql(0);
|
|
done();
|
|
})
|
|
.catch(done);
|
|
});
|
|
});
|
|
|
|
describe('fn: updateCheckRequest', function () {
|
|
beforeEach(function () {
|
|
configUtils.set('privacy:useUpdateCheck', true);
|
|
});
|
|
|
|
afterEach(function () {
|
|
configUtils.restore();
|
|
});
|
|
|
|
it('[default]', function () {
|
|
var updateCheckRequest = updateCheck.__get__('updateCheckRequest'),
|
|
updateCheckDataSpy = sandbox.stub(),
|
|
hostname,
|
|
reqObj,
|
|
data = {
|
|
ghost_version: '0.11.11',
|
|
blog_id: 'something',
|
|
npm_version: 'something'
|
|
};
|
|
|
|
updateCheck.__set__('request', function (_hostname, _reqObj) {
|
|
hostname = _hostname;
|
|
reqObj = _reqObj;
|
|
|
|
return Promise.resolve({
|
|
statusCode: 200,
|
|
body: {version: 'something'}
|
|
});
|
|
});
|
|
|
|
updateCheck.__set__('updateCheckData', updateCheckDataSpy);
|
|
|
|
updateCheckDataSpy.returns(Promise.resolve(data));
|
|
|
|
return updateCheckRequest()
|
|
.then(function () {
|
|
hostname.should.eql('https://updates.ghost.org');
|
|
should.exist(reqObj.headers['Content-Length']);
|
|
reqObj.body.should.eql(data);
|
|
reqObj.json.should.eql(true);
|
|
});
|
|
});
|
|
|
|
it('privacy flag is used', function () {
|
|
var updateCheckRequest = updateCheck.__get__('updateCheckRequest'),
|
|
updateCheckDataSpy = sandbox.stub(),
|
|
reqObj,
|
|
hostname;
|
|
|
|
configUtils.set({
|
|
privacy: {
|
|
useUpdateCheck: false
|
|
}
|
|
});
|
|
|
|
updateCheck.__set__('request', function (_hostname, _reqObj) {
|
|
hostname = _hostname;
|
|
reqObj = _reqObj;
|
|
|
|
return Promise.resolve({
|
|
statusCode: 200,
|
|
body: {version: 'something'}
|
|
});
|
|
});
|
|
|
|
updateCheck.__set__('updateCheckData', updateCheckDataSpy);
|
|
|
|
updateCheckDataSpy.returns(Promise.resolve({
|
|
ghost_version: '0.11.11',
|
|
blog_id: 'something',
|
|
npm_version: 'something'
|
|
}));
|
|
|
|
return updateCheckRequest()
|
|
.then(function () {
|
|
hostname.should.eql('https://updates.ghost.org');
|
|
reqObj.query.should.eql({
|
|
ghost_version: '0.11.11'
|
|
});
|
|
|
|
should.not.exist(reqObj.body);
|
|
reqObj.json.should.eql(true);
|
|
should.not.exist(reqObj.headers['Content-Length']);
|
|
});
|
|
});
|
|
|
|
it('received 500 from the service', function () {
|
|
var updateCheckRequest = updateCheck.__get__('updateCheckRequest'),
|
|
updateCheckDataSpy = sandbox.stub(),
|
|
reqObj,
|
|
hostname;
|
|
|
|
updateCheck.__set__('request', function (_hostname, _reqObj) {
|
|
hostname = _hostname;
|
|
reqObj = _reqObj;
|
|
|
|
return Promise.reject({
|
|
statusCode: 500,
|
|
message: 'something went wrong'
|
|
});
|
|
});
|
|
|
|
updateCheck.__set__('updateCheckData', updateCheckDataSpy);
|
|
|
|
updateCheckDataSpy.returns(Promise.resolve({
|
|
ghost_version: '0.11.11',
|
|
blog_id: 'something',
|
|
npm_version: 'something'
|
|
}));
|
|
|
|
return updateCheckRequest()
|
|
.then(function () {
|
|
throw new Error('Should fail.');
|
|
})
|
|
.catch(function (err) {
|
|
err.message.should.eql('something went wrong');
|
|
});
|
|
});
|
|
|
|
it('received 404 from the service', function () {
|
|
var updateCheckRequest = updateCheck.__get__('updateCheckRequest'),
|
|
updateCheckDataSpy = sandbox.stub(),
|
|
reqObj,
|
|
hostname;
|
|
|
|
updateCheck.__set__('request', function (_hostname, _reqObj) {
|
|
hostname = _hostname;
|
|
reqObj = _reqObj;
|
|
|
|
return Promise.reject({
|
|
statusCode: 404,
|
|
response: {
|
|
body: {
|
|
errors: [{detail: 'No Notifications available.'}]
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
updateCheck.__set__('updateCheckData', updateCheckDataSpy);
|
|
|
|
updateCheckDataSpy.returns(Promise.resolve({
|
|
ghost_version: '0.11.11',
|
|
blog_id: 'something',
|
|
npm_version: 'something'
|
|
}));
|
|
|
|
return updateCheckRequest()
|
|
.then(function () {
|
|
hostname.should.eql('https://updates.ghost.org');
|
|
});
|
|
});
|
|
|
|
it('custom url', function () {
|
|
var updateCheckRequest = updateCheck.__get__('updateCheckRequest'),
|
|
updateCheckDataSpy = sandbox.stub(),
|
|
reqObj,
|
|
hostname;
|
|
|
|
configUtils.set({
|
|
updateCheck: {
|
|
url: 'http://localhost:3000'
|
|
}
|
|
});
|
|
|
|
updateCheck.__set__('request', function (_hostname, _reqObj) {
|
|
hostname = _hostname;
|
|
reqObj = _reqObj;
|
|
|
|
return Promise.resolve({
|
|
statusCode: 200,
|
|
body: {
|
|
version: 'something'
|
|
}
|
|
});
|
|
});
|
|
|
|
updateCheck.__set__('updateCheckData', updateCheckDataSpy);
|
|
|
|
updateCheckDataSpy.returns(Promise.resolve({
|
|
ghost_version: '0.11.11',
|
|
blog_id: 'something',
|
|
npm_version: 'something'
|
|
}));
|
|
|
|
return updateCheckRequest()
|
|
.then(function () {
|
|
hostname.should.eql('http://localhost:3000');
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|