98a64ed0f8
refs https://github.com/TryGhost/Team/issues/727 - The latest code standards require using tpl module in combination with local messages object instead of i18n injected in the constructor
382 lines
13 KiB
JavaScript
382 lines
13 KiB
JavaScript
require('./utils');
|
|
|
|
const sinon = require('sinon');
|
|
const moment = require('moment');
|
|
const uuid = require('uuid');
|
|
|
|
const UpdateCheckService = require('../lib/update-check-service');
|
|
|
|
describe('Update Check', function () {
|
|
const internal = {context: {internal: true}};
|
|
let settingsStub;
|
|
let loggingStub;
|
|
let requestStub;
|
|
|
|
beforeEach(function () {
|
|
settingsStub = sinon.stub().resolves({
|
|
settings: []
|
|
});
|
|
settingsStub.withArgs(Object.assign({key: 'db_hash'}, internal)).resolves({
|
|
settings: [{
|
|
value: 'dummy_db_hash'
|
|
}]
|
|
});
|
|
settingsStub.withArgs(Object.assign({key: 'active_theme'}, internal)).resolves({
|
|
settings: [{
|
|
value: 'casperito'
|
|
}]
|
|
});
|
|
|
|
loggingStub = {
|
|
error: sinon.stub()
|
|
};
|
|
|
|
requestStub = sinon.stub();
|
|
});
|
|
|
|
afterEach(function () {
|
|
sinon.restore();
|
|
});
|
|
|
|
describe('UpdateCheck execution', function () {
|
|
it('update check was executed', async function () {
|
|
const updateCheckService = new UpdateCheckService({
|
|
api: {
|
|
settings: {
|
|
read: settingsStub,
|
|
edit: settingsStub
|
|
},
|
|
users: {
|
|
browse: sinon.stub().resolves()
|
|
},
|
|
posts: {
|
|
browse: sinon.stub().resolves()
|
|
}
|
|
},
|
|
config: {
|
|
checkEndpoint: 'https://updates.ghost.org',
|
|
siteUrl: 'https://localhost:2368/test',
|
|
isPrivacyDisabled: true,
|
|
ghostVersion: '0.8.0'
|
|
},
|
|
logging: loggingStub,
|
|
request: requestStub
|
|
});
|
|
|
|
await updateCheckService.check();
|
|
|
|
requestStub.calledOnce.should.equal(true);
|
|
|
|
requestStub.args[0][0].should.equal('https://updates.ghost.org');
|
|
requestStub.args[0][1].query.ghost_version.should.equal('0.8.0');
|
|
});
|
|
|
|
it('update check won\'t happen if it\'s too early', async function () {
|
|
const lateSettingStub = sinon.stub().resolves({
|
|
settings: [{
|
|
value: moment().add('10', 'minutes').unix()
|
|
}]
|
|
});
|
|
|
|
const updateCheckService = new UpdateCheckService({
|
|
api: {
|
|
settings: {
|
|
read: lateSettingStub
|
|
}
|
|
},
|
|
config: {},
|
|
request: requestStub
|
|
});
|
|
|
|
await updateCheckService.check();
|
|
|
|
requestStub.called.should.equal(false);
|
|
});
|
|
|
|
it('update check will happen if it\'s time to check', async function () {
|
|
const updateCheckDelayPassed = sinon.stub().resolves({
|
|
settings: [{
|
|
value: moment().subtract('10', 'minutes').unix()
|
|
}]
|
|
});
|
|
|
|
const updateCheckService = new UpdateCheckService({
|
|
api: {
|
|
settings: {
|
|
read: updateCheckDelayPassed,
|
|
edit: settingsStub
|
|
},
|
|
users: {
|
|
browse: sinon.stub().resolves()
|
|
},
|
|
posts: {
|
|
browse: sinon.stub().resolves()
|
|
}
|
|
},
|
|
config: {
|
|
checkEndpoint: 'https://updates.ghost.org',
|
|
siteUrl: 'https://example.com',
|
|
isPrivacyDisabled: true,
|
|
ghostVersion: '5.3.4'
|
|
},
|
|
logging: loggingStub,
|
|
request: requestStub
|
|
});
|
|
|
|
await updateCheckService.check();
|
|
|
|
requestStub.calledOnce.should.equal(true);
|
|
|
|
requestStub.args[0][0].should.equal('https://updates.ghost.org');
|
|
requestStub.args[0][1].query.ghost_version.should.equal('5.3.4');
|
|
});
|
|
});
|
|
|
|
describe('Data sent with the POST request', function () {
|
|
it('should report the correct data', async function () {
|
|
const updateCheckService = new UpdateCheckService({
|
|
api: {
|
|
settings: {
|
|
read: settingsStub,
|
|
edit: settingsStub
|
|
},
|
|
users: {
|
|
browse: sinon.stub().resolves({
|
|
users: [{
|
|
created_at: '1995-12-24T23:15:00Z'
|
|
}, {}]
|
|
})
|
|
},
|
|
posts: {
|
|
browse: sinon.stub().resolves({
|
|
meta: {
|
|
pagination: {
|
|
total: 13
|
|
}
|
|
}
|
|
})
|
|
}
|
|
},
|
|
config: {
|
|
checkEndpoint: 'https://updates.ghost.org',
|
|
siteUrl: 'https://localhost:2368/test',
|
|
isPrivacyDisabled: false,
|
|
env: process.env.NODE_ENV,
|
|
databaseType: 'mysql',
|
|
ghostVersion: '4.0.0'
|
|
},
|
|
logging: loggingStub,
|
|
request: requestStub,
|
|
ghostMailer: {
|
|
send: sinon.stub().resolves()
|
|
}
|
|
});
|
|
|
|
await updateCheckService.check();
|
|
|
|
requestStub.calledOnce.should.equal(true);
|
|
|
|
requestStub.args[0][0].should.equal('https://updates.ghost.org');
|
|
|
|
const data = requestStub.args[0][1].body;
|
|
data.ghost_version.should.equal('4.0.0');
|
|
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('casperito');
|
|
data.blog_created_at.should.equal(819846900);
|
|
data.user_count.should.be.equal(2);
|
|
data.post_count.should.be.equal(13);
|
|
data.npm_version.should.be.a.String();
|
|
data.npm_version.should.not.be.empty();
|
|
});
|
|
});
|
|
|
|
describe('Notifications', function () {
|
|
it('should create a release notification for target version', async function () {
|
|
const notification = {
|
|
id: 1,
|
|
custom: 0,
|
|
messages: [{
|
|
id: uuid.v4(),
|
|
version: '999.9.x',
|
|
content: '<p>Hey there! This is for 999.9.0 version</p>',
|
|
dismissible: true,
|
|
top: true
|
|
}]
|
|
};
|
|
|
|
const notificationsAPIAddStub = sinon.stub().resolves();
|
|
|
|
const updateCheckService = new UpdateCheckService({
|
|
api: {
|
|
settings: {
|
|
read: settingsStub,
|
|
edit: settingsStub
|
|
},
|
|
users: {
|
|
browse: sinon.stub().resolves({
|
|
users: [{
|
|
roles: [{
|
|
name: 'Owner'
|
|
}]
|
|
}]
|
|
})
|
|
},
|
|
posts: {
|
|
browse: sinon.stub().resolves()
|
|
},
|
|
notifications: {
|
|
add: notificationsAPIAddStub
|
|
}
|
|
},
|
|
config: {
|
|
siteUrl: 'https://localhost:2368/test'
|
|
},
|
|
logging: loggingStub,
|
|
request: sinon.stub().resolves({
|
|
body: {
|
|
notifications: [notification]
|
|
}
|
|
})
|
|
});
|
|
|
|
await updateCheckService.check();
|
|
|
|
notificationsAPIAddStub.calledOnce.should.equal(true);
|
|
notificationsAPIAddStub.args[0][0].notifications.length.should.equal(1);
|
|
|
|
const targetNotification = notificationsAPIAddStub.args[0][0].notifications[0];
|
|
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);
|
|
});
|
|
|
|
it('should send an email for critical notification', async function () {
|
|
const notification = {
|
|
id: 1,
|
|
messages: [{
|
|
id: uuid.v4(),
|
|
version: 'custom1',
|
|
content: '<p>Critical message. Upgrade your site!</p>',
|
|
dismissible: false,
|
|
top: true,
|
|
type: 'alert'
|
|
}]
|
|
};
|
|
|
|
const notificationsAPIAddStub = sinon.stub().resolves();
|
|
const sendEmailStub = sinon.stub().resolves();
|
|
|
|
const updateCheckService = new UpdateCheckService({
|
|
api: {
|
|
settings: {
|
|
read: settingsStub,
|
|
edit: settingsStub
|
|
},
|
|
users: {
|
|
browse: sinon.stub().resolves({
|
|
users: [{
|
|
email: 'jbloggs@example.com',
|
|
roles: [{
|
|
name: 'Owner'
|
|
}]
|
|
}]
|
|
})
|
|
},
|
|
posts: {
|
|
browse: sinon.stub().resolves()
|
|
},
|
|
notifications: {
|
|
add: notificationsAPIAddStub
|
|
}
|
|
},
|
|
config: {
|
|
siteUrl: 'http://127.0.0.1:2369'
|
|
},
|
|
logging: loggingStub,
|
|
request: sinon.stub().resolves({
|
|
body: [notification]
|
|
}),
|
|
sendEmail: sendEmailStub
|
|
});
|
|
|
|
await updateCheckService.check();
|
|
|
|
sendEmailStub.called.should.be.true();
|
|
sendEmailStub.args[0][0].to.should.equal('jbloggs@example.com');
|
|
sendEmailStub.args[0][0].subject.should.equal('Action required: Critical alert from Ghost instance http://127.0.0.1:2369');
|
|
sendEmailStub.args[0][0].html.should.equal('<p>Critical message. Upgrade your site!</p>');
|
|
sendEmailStub.args[0][0].forceTextContent.should.equal(true);
|
|
|
|
notificationsAPIAddStub.calledOnce.should.equal(true);
|
|
notificationsAPIAddStub.args[0][0].notifications.length.should.equal(1);
|
|
});
|
|
|
|
it('not create a notification if the check response has no messages', async function () {
|
|
const notificationsAPIAddStub = sinon.stub().resolves();
|
|
|
|
const updateCheckService = new UpdateCheckService({
|
|
api: {
|
|
settings: {
|
|
read: settingsStub,
|
|
edit: settingsStub
|
|
},
|
|
users: {
|
|
browse: sinon.stub().resolves({
|
|
users: [{
|
|
roles: [{
|
|
name: 'Owner'
|
|
}]
|
|
}]
|
|
})
|
|
},
|
|
posts: {
|
|
browse: sinon.stub().resolves()
|
|
},
|
|
notifications: {
|
|
add: notificationsAPIAddStub
|
|
}
|
|
},
|
|
config: {
|
|
siteUrl: 'https://localhost:2368/test'
|
|
},
|
|
logging: loggingStub,
|
|
request: sinon.stub().resolves({
|
|
body: {
|
|
notifications: []
|
|
}
|
|
})
|
|
});
|
|
|
|
await updateCheckService.check();
|
|
|
|
notificationsAPIAddStub.calledOnce.should.equal(false);
|
|
});
|
|
});
|
|
|
|
describe('Error handling', function () {
|
|
it('logs an error when error', function () {
|
|
const updateCheckService = new UpdateCheckService({
|
|
api: {
|
|
settings: {
|
|
edit: settingsStub
|
|
}
|
|
},
|
|
logging: loggingStub
|
|
});
|
|
|
|
updateCheckService.updateCheckError({});
|
|
|
|
settingsStub.called.should.be.true();
|
|
loggingStub.error.called.should.be.true();
|
|
loggingStub.error.args[0][0].context.should.equal('Checking for updates failed, your site will continue to function.');
|
|
loggingStub.error.args[0][0].help.should.equal('If you get this error repeatedly, please seek help from https://ghost.org/docs/');
|
|
});
|
|
});
|
|
});
|