From c219446f85a82ea4e5a8344e564f7025129452c0 Mon Sep 17 00:00:00 2001 From: Naz Gargol Date: Tue, 26 Mar 2019 11:37:32 +0800 Subject: [PATCH] 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 --- .../regression/api/v2/admin/posts_spec.js | 118 +++++- .../regression/models/model_posts_spec.js | 378 ------------------ .../regression/models/model_settings_spec.js | 175 -------- .../regression/models/model_users_spec.js | 11 - core/test/unit/models/settings_spec.js | 137 +++++++ 5 files changed, 249 insertions(+), 570 deletions(-) delete mode 100644 core/test/regression/models/model_settings_spec.js diff --git a/core/test/regression/api/v2/admin/posts_spec.js b/core/test/regression/api/v2/admin/posts_spec.js index 2b60691c5e..effa7b2d88 100644 --- a/core/test/regression/api/v2/admin/posts_spec.js +++ b/core/test/regression/api/v2/admin/posts_spec.js @@ -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: '

HTML Ipsum presents

', + 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() + '/')) diff --git a/core/test/regression/models/model_posts_spec.js b/core/test/regression/models/model_posts_spec.js index 0b18e71a11..1829ab2a3b 100644 --- a/core/test/regression/models/model_posts_spec.js +++ b/core/test/regression/models/model_posts_spec.js @@ -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) { diff --git a/core/test/regression/models/model_settings_spec.js b/core/test/regression/models/model_settings_spec.js deleted file mode 100644 index 1cfd444423..0000000000 --- a/core/test/regression/models/model_settings_spec.js +++ /dev/null @@ -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); - }); - }); -}); diff --git a/core/test/regression/models/model_users_spec.js b/core/test/regression/models/model_users_spec.js index 3c99647ba8..ac63ef2466 100644 --- a/core/test/regression/models/model_users_spec.js +++ b/core/test/regression/models/model_users_spec.js @@ -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'})); diff --git a/core/test/unit/models/settings_spec.js b/core/test/unit/models/settings_spec.js index 013e32df0b..1ea2bd1ad1 100644 --- a/core/test/unit/models/settings_spec.js +++ b/core/test/unit/models/settings_spec.js @@ -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();