0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-01-06 22:40:14 -05:00

Model regression tests cleanup (#10639)

refs #9178

- Migrated settings model regression to unit tests
- Removed redundant/unuseful post tests
- Extracted post model regression tests to API tests 
- Renamed test suites for consistency
This commit is contained in:
Naz Gargol 2019-03-26 11:37:32 +08:00 committed by GitHub
parent 6629b4d490
commit c219446f85
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 249 additions and 570 deletions

View file

@ -59,8 +59,8 @@ describe('Posts API', function () {
});
});
it('fields combined with formats and include', function (done) {
request.get(localUtils.API.getApiQuery('posts/?formats=mobiledoc,html&fields=id,title&include=authors'))
it('combined fields, formats, include and non existing', function (done) {
request.get(localUtils.API.getApiQuery('posts/?formats=mobiledoc,html,plaintext&fields=id,title,primary_tag,doesnotexist&include=authors,tags'))
.set('Origin', config.get('url'))
.expect('Content-Type', /json/)
.expect('Cache-Control', testUtils.cacheRules.private)
@ -81,7 +81,7 @@ describe('Posts API', function () {
'post',
null,
null,
['mobiledoc', 'id', 'title', 'html', 'authors']
['mobiledoc', 'plaintext', 'id', 'title', 'html', 'authors', 'tags', 'primary_tag']
);
localUtils.API.checkResponse(jsonResponse.meta.pagination, 'pagination');
@ -91,7 +91,7 @@ describe('Posts API', function () {
});
});
describe('read', function () {
describe('Read', function () {
it('can\'t retrieve non existent post', function (done) {
request.get(localUtils.API.getApiQuery(`posts/${ObjectId.generate()}/`))
.set('Origin', config.get('url'))
@ -123,7 +123,28 @@ describe('Posts API', function () {
});
});
describe('edit', function () {
describe('Add', function () {
it('adds default title when it is missing', function () {
return request
.post(localUtils.API.getApiQuery('posts/'))
.set('Origin', config.get('url'))
.send({
posts: [{
title: '',
}]
})
.expect('Content-Type', /json/)
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(201)
.then((res) => {
should.exist(res.body.posts);
should.exist(res.body.posts[0].title);
res.body.posts[0].title.should.equal('(Untitled)');
});
});
});
describe('Edit', function () {
it('published_at = null', function () {
return request
.get(localUtils.API.getApiQuery(`posts/${testUtils.DataGenerator.Content.posts[0].id}/`))
@ -151,6 +172,35 @@ describe('Posts API', function () {
});
});
it('html to plaintext', function () {
return request
.get(localUtils.API.getApiQuery(`posts/${testUtils.DataGenerator.Content.posts[0].id}/`))
.set('Origin', config.get('url'))
.expect(200)
.then((res) => {
return request
.put(localUtils.API.getApiQuery('posts/' + testUtils.DataGenerator.Content.posts[0].id + '/?source=html&formats=html,plaintext'))
.set('Origin', config.get('url'))
.send({
posts: [{
html: '<p>HTML Ipsum presents</p>',
updated_at: res.body.posts[0].updated_at
}]
})
.expect('Content-Type', /json/)
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(200);
})
.then((res) => {
return models.Post.findOne({
id: res.body.posts[0].id
}, testUtils.context.internal);
})
.then((model) => {
model.get('plaintext').should.equal('HTML Ipsum presents');
});
});
it('canonical_url', function () {
return request
.get(localUtils.API.getApiQuery(`posts/${testUtils.DataGenerator.Content.posts[0].id}/`))
@ -236,9 +286,65 @@ describe('Posts API', function () {
should.exist(res.headers['x-cache-invalidate']);
});
});
it('trims title', function () {
const untrimmedTitle = ' test trimmed update title ';
return request
.get(localUtils.API.getApiQuery(`posts/${testUtils.DataGenerator.Content.posts[0].id}/`))
.set('Origin', config.get('url'))
.expect(200)
.then((res) => {
return request
.put(localUtils.API.getApiQuery('posts/' + testUtils.DataGenerator.Content.posts[0].id + '/'))
.set('Origin', config.get('url'))
.send({
posts: [{
title: untrimmedTitle,
updated_at: res.body.posts[0].updated_at
}]
})
.expect('Content-Type', /json/)
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(200);
})
.then((res) => {
should.exist(res.body.posts);
should.exist(res.body.posts[0].title);
res.body.posts[0].title.should.equal(untrimmedTitle.trim());
});
});
it('strips invisible unicode from slug', function () {
const slug = 'this-is\u0008-invisible';
return request
.get(localUtils.API.getApiQuery(`posts/${testUtils.DataGenerator.Content.posts[0].id}/`))
.set('Origin', config.get('url'))
.expect(200)
.then((res) => {
return request
.put(localUtils.API.getApiQuery('posts/' + testUtils.DataGenerator.Content.posts[0].id + '/'))
.set('Origin', config.get('url'))
.send({
posts: [{
slug: slug,
updated_at: res.body.posts[0].updated_at
}]
})
.expect('Content-Type', /json/)
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(200);
})
.then((res) => {
should.exist(res.body.posts);
should.exist(res.body.posts[0].slug);
res.body.posts[0].slug.should.equal('this-is-invisible');
});
});
});
describe('destroy', function () {
describe('Destroy', function () {
it('non existent post', function () {
return request
.del(localUtils.API.getApiQuery('posts/' + ObjectId.generate() + '/'))

View file

@ -38,50 +38,6 @@ describe('Post Model', function () {
sinon.stub(urlService, 'getUrlByResourceId').withArgs(testUtils.DataGenerator.Content.posts[0].id).returns('/html-ipsum/');
});
function checkFirstPostData(firstPost, options) {
options = options || {};
should.not.exist(firstPost.author_id);
firstPost.author.should.be.an.Object();
if (options.withRelated && options.withRelated.indexOf('authors') !== -1) {
firstPost.authors.length.should.eql(1);
firstPost.authors[0].should.eql(firstPost.author);
}
firstPost.tags.should.be.an.Array();
firstPost.author.name.should.equal(DataGenerator.Content.users[0].name);
firstPost.created_at.should.be.an.instanceof(Date);
firstPost.created_by.should.be.an.Object();
firstPost.updated_by.should.be.an.Object();
firstPost.published_by.should.be.an.Object();
firstPost.created_by.name.should.equal(DataGenerator.Content.users[0].name);
firstPost.updated_by.name.should.equal(DataGenerator.Content.users[0].name);
firstPost.published_by.name.should.equal(DataGenerator.Content.users[0].name);
firstPost.tags[0].name.should.equal(DataGenerator.Content.tags[0].name);
firstPost.custom_excerpt.should.equal(DataGenerator.Content.posts[0].custom_excerpt);
if (options.formats) {
if (options.formats.indexOf('mobiledoc') !== -1) {
firstPost.mobiledoc.should.match(/HTML Ipsum Presents/);
}
if (options.formats.indexOf('html') !== -1) {
firstPost.html.should.match(/HTML Ipsum Presents/);
}
if (options.formats.indexOf('plaintext') !== -1) {
firstPost.plaintext.should.match(/HTML Ipsum Presents/);
}
} else {
firstPost.html.should.match(/HTML Ipsum Presents/);
should.equal(firstPost.plaintext, undefined);
should.equal(firstPost.mobiledoc, undefined);
should.equal(firstPost.amp, undefined);
}
}
describe('Single author posts', function () {
afterEach(function () {
configUtils.restore();
@ -99,110 +55,7 @@ describe('Post Model', function () {
});
});
describe('findAll', function () {
it('can findAll, returning all related data', function (done) {
var options = {withRelated: ['author', 'authors', 'tags', 'created_by', 'updated_by', 'published_by']};
models.Post.findAll(options)
.then(function (results) {
should.exist(results);
results.length.should.be.above(0);
var posts = results.models.map(function (model) {
return model.toJSON();
}), firstPost = _.find(posts, {title: testUtils.DataGenerator.Content.posts[0].title});
checkFirstPostData(firstPost, options);
done();
}).catch(done);
});
it('can findAll, use formats option', function (done) {
var options = {
formats: ['mobiledoc', 'plaintext'],
withRelated: ['author', 'fields', 'tags', 'created_by', 'updated_by', 'published_by']
};
models.Post.findAll(options)
.then(function (results) {
should.exist(results);
results.length.should.be.above(0);
var posts = results.models.map(function (model) {
return model.toJSON(options);
}), firstPost = _.find(posts, {title: testUtils.DataGenerator.Content.posts[0].title});
checkFirstPostData(firstPost, options);
done();
}).catch(done);
});
});
describe('findPage', function () {
it('can findPage, returning all related data', function (done) {
models.Post.findPage({withRelated: ['author', 'fields', 'tags', 'created_by', 'updated_by', 'published_by']})
.then(function (results) {
should.exist(results);
results.meta.pagination.page.should.equal(1);
results.meta.pagination.limit.should.equal(15);
results.meta.pagination.pages.should.equal(1);
results.data.length.should.equal(4);
var firstPost = _.find(results.data, {attributes:{title: testUtils.DataGenerator.Content.posts[0].title}});
checkFirstPostData(firstPost.toJSON());
done();
}).catch(done);
});
it('returns computed fields when columns are asked for explicitly', function (done) {
const options = {
columns: ['id', 'slug', 'primary_tag'],
withRelated: 'tags'
};
models.Post.findPage(options).then(function (results) {
should.exist(results);
var post = _.find(results.data, {attributes: {slug: testUtils.DataGenerator.Content.posts[0].slug}}).toJSON(options);
post.primary_tag.slug.should.equal('kitchen-sink');
// If a computed property is inadvertently passed into a "fetch" operation,
// there's a bug in bookshelf where the model will come back with it as
// a column enclosed in quotes.
should.not.exist(post['"primary_tag"']);
done();
}).catch(done);
});
it('ignores columns that do not exist', function (done) {
models.Post.findPage({columns: ['id', 'slug', 'doesnotexist']}).then(function (results) {
should.exist(results);
var post = _.find(results.data, {attributes: {slug: testUtils.DataGenerator.Content.posts[0].slug}}).toJSON();
post.id.should.equal(testUtils.DataGenerator.Content.posts[0].id);
post.slug.should.equal('html-ipsum');
should.not.exist(post.doesnotexist);
done();
}).catch(done);
});
it('can NOT findPage for a page that overflows the datatype', function (done) {
models.Post.findPage({page: 5700000000055345439587894375457849375284932759842375894372589243758947325894375894275894275894725897432859724309})
.then(function (paginationResult) {
should.exist(paginationResult.meta);
paginationResult.meta.pagination.page.should.be.a.Number();
done();
}).catch(done);
});
// @TODO: this test case fails for mysql currently if you run all regression tests, the test does not fail if you run this as a single test
describe.skip('with more posts/tags', function () {
beforeEach(function () {
@ -329,22 +182,6 @@ describe('Post Model', function () {
});
});
});
describe('findOne', function () {
it('can findOne, returning all related data', function (done) {
var firstPost;
models.Post.findOne({}, {withRelated: ['author', 'fields', 'tags', 'created_by', 'updated_by', 'published_by']})
.then(function (result) {
should.exist(result);
firstPost = result.toJSON();
checkFirstPostData(firstPost);
done();
}).catch(done);
});
});
});
describe('edit', function () {
@ -457,83 +294,6 @@ describe('Post Model', function () {
});
});
it('[success] custom excerpt soft limit respected', function (done) {
var postId = testUtils.DataGenerator.Content.posts[0].id;
models.Post.findOne({id: postId}).then(function (results) {
var post;
should.exist(results);
post = results.toJSON();
post.id.should.equal(postId);
return models.Post.edit({
custom_excerpt: new Array(300).join('a')
}, _.extend({}, context, {id: postId}));
}).then(function (edited) {
edited.get('custom_excerpt').length.should.eql(299);
done();
}).catch(done);
});
it('can change title to number', function (done) {
var postId = testUtils.DataGenerator.Content.posts[0].id;
models.Post.findOne({id: postId}).then(function (results) {
should.exist(results);
var post = results.toJSON();
post.title.should.not.equal('123');
return models.Post.edit({title: 123}, _.extend({}, context, {id: postId}));
}).then(function (edited) {
should.exist(edited);
edited.attributes.title.should.equal('123');
done();
}).catch(done);
});
it('converts html to plaintext', function (done) {
var postId = testUtils.DataGenerator.Content.posts[0].id;
models.Post.findOne({id: postId}).then(function (results) {
should.exist(results);
results.attributes.html.should.match(/HTML Ipsum Presents/);
should.exist(results.attributes.plaintext);
return models.Post.edit({updated_at: results.attributes.updated_at}, _.extend({}, context, {id: postId}));
}).then(function (edited) {
should.exist(edited);
edited.attributes.html.should.match(/HTML Ipsum Presents/);
edited.attributes.plaintext.should.match(/HTML Ipsum Presents/);
done();
}).catch(done);
});
it('converts html to plaintext if html is null', function (done) {
var postId = testUtils.DataGenerator.Content.posts[0].id;
models.Post.findOne({id: postId}).then(function (results) {
should.exist(results);
results.attributes.html.should.match(/HTML Ipsum Presents/);
should.exist(results.attributes.plaintext);
return models.Post.edit({updated_at: results.attributes.updated_at}, _.extend({}, context, {id: postId}));
}).then(function (edited) {
should.exist(edited);
edited.attributes.html.should.match(/HTML Ipsum Presents/);
edited.attributes.plaintext.should.match(/HTML Ipsum Presents/);
return edited;
}).then(function (edited) {
return models.Post.edit({
mobiledoc: DataGenerator.markdownToMobiledoc(''),
updated_at: edited.attributes.updated_at
}, _.extend({}, context, {id: postId}));
}).then(function (edited) {
should.exist(edited);
should.not.exist(edited.attributes.html);
should.not.exist(edited.attributes.plaintext);
done();
}).catch(done);
});
it('can publish draft post', function (done) {
var postId = testUtils.DataGenerator.Content.posts[3].id;
@ -908,40 +668,6 @@ describe('Post Model', function () {
}).catch(done);
});
it('can save a draft without setting published_by or published_at', function (done) {
var newPost = testUtils.DataGenerator.forModel.posts[2],
postId;
models.Post.add(newPost, context).then(function (results) {
var post;
should.exist(results);
post = results.toJSON();
postId = post.id;
post.status.should.equal('draft');
should.not.exist(post.published_by);
should.not.exist(post.published_at);
// Test changing an unrelated property
return models.Post.edit({title: 'Hello World'}, _.extend({}, context, {id: postId}));
}).then(function (edited) {
should.exist(edited);
edited.attributes.status.should.equal('draft');
should.not.exist(edited.attributes.published_by);
should.not.exist(edited.attributes.published_at);
// Test changing status and published_by on its own
return models.Post.edit({published_by: 4}, _.extend({}, context, {id: postId}));
}).then(function (edited) {
should.exist(edited);
edited.attributes.status.should.equal('draft');
should.not.exist(edited.attributes.published_by);
should.not.exist(edited.attributes.published_at);
done();
}).catch(done);
});
it('cannot override the published_by setting', function (done) {
var postId = testUtils.DataGenerator.Content.posts[3].id;
@ -972,30 +698,6 @@ describe('Post Model', function () {
done();
}).catch(done);
});
it('send empty date', function (done) {
var postId = testUtils.DataGenerator.Content.posts[0].id;
models.Post
.findOne({
id: postId
})
.then(function (results) {
var post;
should.exist(results);
post = results.toJSON();
post.id.should.equal(postId);
return models.Post.edit({created_at: ''}, _.extend({}, context, {id: postId}));
})
.then(function () {
done(new Error('This test should fail.'));
})
.catch(function (err) {
err.statusCode.should.eql(422);
done();
});
});
});
describe('add', function () {
@ -1084,17 +786,6 @@ describe('Post Model', function () {
}).catch(done);
});
it('can add, with title being a number', function (done) {
var newPost = testUtils.DataGenerator.forModel.posts[2];
newPost.title = 123;
models.Post.add(newPost, context).then(function (createdPost) {
should.exist(createdPost);
done();
}).catch(done);
});
it('can add, with previous published_at date', function (done) {
var previousPublishedAtDate = new Date(2013, 8, 21, 12);
@ -1227,75 +918,6 @@ describe('Post Model', function () {
}).catch(done);
});
it('add scheduled page with published_at 10 minutes in future -> we expect success', function (done) {
models.Post.add({
status: 'scheduled',
page: 1,
published_at: moment().add(10, 'minute'),
title: 'scheduled 1',
mobiledoc: markdownToMobiledoc('This is some content')
}, context).then(function (post) {
should.exist(post);
Object.keys(eventsTriggered).length.should.eql(3);
should.exist(eventsTriggered['page.added']);
should.exist(eventsTriggered['page.scheduled']);
should.exist(eventsTriggered['user.attached']);
done();
}).catch(done);
});
it('can add default title, if it\'s missing', function (done) {
models.Post.add({
mobiledoc: markdownToMobiledoc('Content')
}, context).then(function (newPost) {
should.exist(newPost);
newPost.get('title').should.equal('(Untitled)');
done();
}).catch(done);
});
it('can trim title', function (done) {
var untrimmedCreateTitle = ' test trimmed create title ',
untrimmedUpdateTitle = ' test trimmed update title ',
newPost = {
title: untrimmedCreateTitle,
mobiledoc: markdownToMobiledoc('Test content')
};
models.Post.add(newPost, context).then(function (createdPost) {
return models.Post.findOne({id: createdPost.id, status: 'all'});
}).then(function (createdPost) {
should.exist(createdPost);
createdPost.get('title').should.equal(untrimmedCreateTitle.trim());
Object.keys(eventsTriggered).length.should.eql(2);
should.exist(eventsTriggered['post.added']);
should.exist(eventsTriggered['user.attached']);
return createdPost.save({title: untrimmedUpdateTitle}, context);
}).then(function (updatedPost) {
updatedPost.get('title').should.equal(untrimmedUpdateTitle.trim());
Object.keys(eventsTriggered).length.should.eql(3);
should.exist(eventsTriggered['post.edited']);
done();
}).catch(done);
});
it('can strip invisible unicode from slug', function (done) {
models.Post.add({
slug: 'abc\u0008',
}, context).then(function (newPost) {
should.exist(newPost);
newPost.get('slug').should.equal('abc');
done();
}).catch(done);
});
it('can generate a non conflicting slug', function (done) {
// Create 12 posts with the same title
sequence(_.times(12, function (i) {

View file

@ -1,175 +0,0 @@
var should = require('should'),
_ = require('lodash'),
sinon = require('sinon'),
testUtils = require('../../utils'),
SettingsModel = require('../../../server/models/settings').Settings,
db = require('../../../server/data/db'),
common = require('../../../server/lib/common'),
context = testUtils.context.admin;
describe('Settings Model', function () {
var eventSpy;
// Keep the DB clean
before(testUtils.teardown);
afterEach(testUtils.teardown);
beforeEach(testUtils.setup('settings'));
before(function () {
should.exist(SettingsModel);
});
afterEach(function () {
sinon.restore();
});
beforeEach(function () {
eventSpy = sinon.spy(common.events, 'emit');
});
describe('API', function () {
it('can edit single', function (done) {
SettingsModel.findAll().then(function (results) {
should.exist(results);
results.length.should.be.above(0);
return SettingsModel.edit({key: 'description', value: 'new value'}, context);
}).then(function (edited) {
should.exist(edited);
edited.length.should.equal(1);
edited = edited[0];
edited.attributes.key.should.equal('description');
edited.attributes.value.should.equal('new value');
eventSpy.calledTwice.should.be.true();
eventSpy.firstCall.calledWith('settings.edited').should.be.true();
eventSpy.secondCall.calledWith('settings.description.edited').should.be.true();
done();
}).catch(done);
});
it('can edit multiple', function (done) {
var model1,
model2,
editedModel;
SettingsModel.findAll().then(function (results) {
should.exist(results);
results.length.should.be.above(0);
model1 = {key: 'description', value: 'another new value'};
model2 = {key: 'title', value: 'new title'};
return SettingsModel.edit([model1, model2], context);
}).then(function (edited) {
should.exist(edited);
edited.length.should.equal(2);
editedModel = edited[0];
editedModel.attributes.key.should.equal(model1.key);
editedModel.attributes.value.should.equal(model1.value);
editedModel = edited[1];
editedModel.attributes.key.should.equal(model2.key);
editedModel.attributes.value.should.equal(model2.value);
eventSpy.callCount.should.equal(4);
// We can't rely on the order of updates.
// We can however expect the first and third call to
// to be `settings.edited`.
eventSpy.firstCall.calledWith('settings.edited').should.be.true();
eventSpy.thirdCall.calledWith('settings.edited').should.be.true();
eventSpy.calledWith('settings.description.edited').should.be.true();
eventSpy.calledWith('settings.title.edited').should.be.true();
done();
}).catch(done);
});
it('can add', function (done) {
var newSetting = {
key: 'TestSetting1',
value: 'Test Content 1'
};
SettingsModel.add(newSetting, context).then(function (createdSetting) {
should.exist(createdSetting);
createdSetting.has('uuid').should.equal(false);
createdSetting.attributes.key.should.equal(newSetting.key, 'key is correct');
createdSetting.attributes.value.should.equal(newSetting.value, 'value is correct');
createdSetting.attributes.type.should.equal('core');
eventSpy.calledTwice.should.be.true();
eventSpy.firstCall.calledWith('settings.added').should.be.true();
eventSpy.secondCall.calledWith('settings.TestSetting1.added').should.be.true();
done();
}).catch(done);
});
it('can destroy', function (done) {
SettingsModel.findAll().then(function (allSettings) {
SettingsModel.findOne({id: allSettings.models[1].id}).then(function (results) {
should.exist(results);
results.attributes.id.should.equal(allSettings.models[1].id);
return SettingsModel.destroy({id: allSettings.models[1].id});
}).then(function (response) {
response.toJSON().should.be.empty();
return SettingsModel.findOne({id: allSettings.models[1].id});
}).then(function (newResults) {
should.equal(newResults, null);
done();
}).catch(done);
}).catch(done);
});
});
describe('populating defaults from settings.json', function () {
beforeEach(function (done) {
db.knex('settings').truncate().then(function () {
done();
});
});
it('populates any unset settings from the JSON defaults', function (done) {
SettingsModel.findAll().then(function (allSettings) {
allSettings.length.should.equal(0);
return SettingsModel.populateDefaults();
}).then(function () {
return SettingsModel.findAll();
}).then(function (allSettings) {
allSettings.length.should.be.above(0);
return SettingsModel.findOne('description');
}).then(function (descriptionSetting) {
// Testing against the actual value in default-settings.json feels icky,
// but it's easier to fix the test if that ever changes than to mock out that behaviour
descriptionSetting.get('value').should.equal('The professional publishing platform');
done();
}).catch(done);
});
it('doesn\'t overwrite any existing settings', function (done) {
SettingsModel.add({key: 'description', value: 'Adam\'s Blog'}, context).then(function () {
return SettingsModel.populateDefaults();
}).then(function () {
return SettingsModel.findOne('description');
}).then(function (descriptionSetting) {
descriptionSetting.get('value').should.equal('Adam\'s Blog');
done();
}).catch(done);
});
});
});

View file

@ -208,17 +208,6 @@ describe('User Model', function run() {
});
});
it('can NOT findPage for a page that overflows the datatype', function (done) {
UserModel.findPage({page: 5700000000055345439587894375457849375284932759842375894372589243758947325894375894275894275894725897432859724309})
.then(function (paginationResult) {
should.exist(paginationResult.meta);
paginationResult.meta.pagination.page.should.be.a.Number();
done();
}).catch(done);
});
it('can findOne by role name', function () {
return testUtils.fixtures.createExtraUsers().then(function () {
return Promise.join(UserModel.findOne({role: 'Owner'}), UserModel.findOne({role: 'Editor'}));

View file

@ -1,11 +1,148 @@
const should = require('should');
const sinon = require('sinon');
const mockDb = require('mock-knex');
const models = require('../../../server/models');
const {knex} = require('../../../server/data/db');
const common = require('../../../server/lib/common');
describe('Unit: models/settings', function () {
before(function () {
models.init();
});
describe('events', function () {
let tracker;
let eventSpy;
beforeEach(function () {
mockDb.mock(knex);
tracker = mockDb.getTracker();
tracker.install();
});
afterEach(function () {
mockDb.unmock(knex);
});
beforeEach(function () {
eventSpy = sinon.spy(common.events, 'emit');
});
afterEach(function () {
sinon.restore();
});
it('emits add events', function () {
tracker.on('query', (query, step) => {
return [
function fetchAddQuery() {
query.response([{}]);
},
function addQuery() {
query.response([{
key: 'description',
value: 'added value'
}]);
}
][step - 1]();
});
return models.Settings.edit({
key: 'description',
value: 'added value'
})
.then(() => {
eventSpy.calledTwice.should.be.true();
eventSpy.firstCall.calledWith('settings.added').should.be.true();
eventSpy.secondCall.calledWith('settings.description.added').should.be.true();
});
});
it('emits edit events', function () {
tracker.on('query', (query, step) => {
return [
function fetchEditQuery() {
query.response([{
id: 1, // NOTE: `id` imitates existing value for 'edit' event
key: 'description',
value: 'db value'
}]);
}
][step - 1]();
});
return models.Settings.edit({
key: 'description',
value: 'edited value'
})
.then(() => {
eventSpy.calledTwice.should.be.true();
eventSpy.firstCall.calledWith('settings.edited').should.be.true();
eventSpy.secondCall.calledWith('settings.description.edited').should.be.true();
});
});
});
describe('defaults', function () {
let tracker;
let eventSpy;
beforeEach(function () {
mockDb.mock(knex);
tracker = mockDb.getTracker();
tracker.install();
});
afterEach(function () {
mockDb.unmock(knex);
tracker.uninstall();
});
beforeEach(function () {
eventSpy = sinon.spy(common.events, 'emit');
});
afterEach(function () {
sinon.restore();
});
it('populates unset defaults', function () {
tracker.on('query', (query) => {
return query.response([{}]);
});
return models.Settings.populateDefaults()
.then(() => {
eventSpy.callCount.should.equal(64);
eventSpy.args[1][0].should.equal('settings.db_hash.added');
eventSpy.args[1][1].attributes.type.should.equal('core');
eventSpy.args[11][0].should.equal('settings.description.added');
eventSpy.args[11][1].attributes.type.should.equal('blog');
eventSpy.args[11][1].attributes.value.should.equal('The professional publishing platform');
eventSpy.args[63][0].should.equal('settings.members_subscription_settings.added');
});
});
it('doesn\'t overwrite any existing settings', function () {
tracker.on('query', (query) => {
return query.response([{
key: 'description',
value: 'Adam\'s Blog'
}]);
});
return models.Settings.populateDefaults()
.then(() => {
eventSpy.callCount.should.equal(62);
eventSpy.args[11][0].should.equal('settings.logo.added');
});
});
});
describe('parse', function () {
it('ensure correct parsing when fetching from db', function () {
const setting = models.Settings.forge();