mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-24 06:35:49 +03:00
commit
53dc1b4466
@ -817,7 +817,7 @@ var path = require('path'),
|
||||
grunt.registerTask('init', ['shell:bourbon', 'default']);
|
||||
|
||||
// Run unit tests
|
||||
grunt.registerTask('test-unit', ['setTestEnv', 'loadConfig', 'mochacli:all']);
|
||||
grunt.registerTask('test-unit', ['setTestEnv', 'loadConfig', 'express:test', 'mochacli:all']);
|
||||
|
||||
// Run casperjs tests only
|
||||
grunt.registerTask('test-functional', ['setTestEnv', 'express:test', 'spawn-casperjs']);
|
||||
|
@ -1,12 +1,31 @@
|
||||
/*globals casper, __utils__, url, testPost */
|
||||
|
||||
casper.test.begin("Content screen is correct", 17, function suite(test) {
|
||||
test.filename = "content_test.png";
|
||||
CasperTest.begin("Content screen is correct", 20, function suite(test) {
|
||||
// Create a sample post
|
||||
casper.thenOpen(url + 'ghost/editor/', function testTitleAndUrl() {
|
||||
test.assertTitle('Ghost Admin', 'Ghost admin has no title');
|
||||
});
|
||||
|
||||
casper.start(url + "ghost/content/", function testTitleAndUrl() {
|
||||
casper.then(function createTestPost() {
|
||||
casper.sendKeys('#entry-title', testPost.title);
|
||||
casper.writeContentToCodeMirror(testPost.html);
|
||||
});
|
||||
|
||||
casper.waitForSelectorTextChange('.entry-preview .rendered-markdown', function onSuccess() {
|
||||
test.assertSelectorHasText('.entry-preview .rendered-markdown', 'test', 'Editor value is correct');
|
||||
});
|
||||
|
||||
casper.thenClick('.js-publish-button');
|
||||
|
||||
casper.waitForResource(/posts/, function checkPostWasCreated() {
|
||||
test.assertExists('.notification-success', 'got success notification');
|
||||
});
|
||||
|
||||
// Begin test
|
||||
casper.thenOpen(url + "ghost/content/", function testTitleAndUrl() {
|
||||
test.assertTitle("Ghost Admin", "Ghost admin has no title");
|
||||
test.assertUrlMatch(/ghost\/content\/$/, "Ghost doesn't require login this time");
|
||||
}).viewport(1280, 1024);
|
||||
});
|
||||
|
||||
casper.then(function testMenus() {
|
||||
test.assertExists("#main-menu", "Main menu is present");
|
||||
@ -25,40 +44,25 @@ casper.test.begin("Content screen is correct", 17, function suite(test) {
|
||||
test.assertExists(".content-list-content", "Content list view is present");
|
||||
test.assertExists(".content-list-content li .entry-title", "Content list view has at least one item");
|
||||
test.assertExists(".content-preview", "Content preview is present");
|
||||
test.assertSelectorHasText(".content-list-content li:first-child h3", testPost.title, "first item is the post we created");
|
||||
test.assertSelectorHasText(".content-list-content li:first-child h3", testPost.title, "item is present and has content");
|
||||
});
|
||||
|
||||
casper.then(function testActiveItem() {
|
||||
casper.test.assertEvalEquals(function () {
|
||||
test.assertEvalEquals(function () {
|
||||
return document.querySelector('.content-list-content li').className;
|
||||
}, "active", "first item is active");
|
||||
|
||||
}).thenClick(".content-list-content li:nth-child(2) a", function then() {
|
||||
casper.test.assertEvalEquals(function () {
|
||||
test.assertEvalEquals(function () {
|
||||
return document.querySelectorAll('.content-list-content li')[1].className;
|
||||
}, "active", "second item is active");
|
||||
});
|
||||
|
||||
// TODO: finish testing delete
|
||||
// casper.then(function testDeletePost() {
|
||||
// casper.clickLabel(testPost.title, "h3");
|
||||
// });
|
||||
|
||||
casper.run(function () {
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
|
||||
casper.test.begin('Infinite scrolling', 1, function suite(test) {
|
||||
test.filename = 'content_infinite_scrolling_test.png';
|
||||
|
||||
CasperTest.begin('Infinite scrolling', 1, function suite(test) {
|
||||
// Placeholder for infinite scrolling/pagination tests (will need to setup 16+ posts).
|
||||
|
||||
casper.start(url + "ghost/content/", function testTitleAndUrl() {
|
||||
test.assertTitle("Ghost Admin", "Ghost admin has no title");
|
||||
}).viewport(1280, 1024);
|
||||
|
||||
casper.run(function () {
|
||||
test.done();
|
||||
casper.thenOpen(url + 'ghost/content/', function testTitleAndUrl() {
|
||||
test.assertTitle('Ghost Admin', 'Ghost admin has no title');
|
||||
});
|
||||
});
|
@ -1,15 +1,12 @@
|
||||
/*globals casper, __utils__, url, testPost */
|
||||
|
||||
casper.test.begin("Ghost editor is correct", 9, function suite(test) {
|
||||
test.filename = "editor_test.png";
|
||||
|
||||
casper.start(url + "ghost/editor/", function testTitleAndUrl() {
|
||||
CasperTest.begin("Ghost editor is correct", 10, function suite(test) {
|
||||
casper.thenOpen(url + "ghost/editor/", function testTitleAndUrl() {
|
||||
test.assertTitle("Ghost Admin", "Ghost admin has no title");
|
||||
test.assertUrlMatch(/ghost\/editor\/$/, "Ghost doesn't require login this time");
|
||||
test.assertExists(".entry-markdown", "Ghost editor is present");
|
||||
test.assertExists(".entry-preview", "Ghost preview is present");
|
||||
}).viewport(1280, 1024);
|
||||
|
||||
});
|
||||
|
||||
// test saving with no data
|
||||
casper.thenClick('.js-publish-button');
|
||||
@ -26,9 +23,8 @@ casper.test.begin("Ghost editor is correct", 9, function suite(test) {
|
||||
casper.writeContentToCodeMirror(testPost.html);
|
||||
});
|
||||
|
||||
// We must wait after sending keys to CodeMirror
|
||||
casper.wait(1000, function doneWait() {
|
||||
this.echo("I've waited for 1 seconds.");
|
||||
casper.waitForSelectorTextChange('.entry-preview .rendered-markdown', function onSuccess() {
|
||||
test.assertSelectorHasText('.entry-preview .rendered-markdown', 'test', 'Editor value is correct.');
|
||||
});
|
||||
|
||||
casper.thenClick('.js-publish-button');
|
||||
@ -40,54 +36,31 @@ casper.test.begin("Ghost editor is correct", 9, function suite(test) {
|
||||
test.assertEvalEquals(function () {
|
||||
return document.querySelector('#entry-title').value;
|
||||
}, testPost.title, 'Title is correct');
|
||||
|
||||
// TODO: make this work - spaces & newlines are problematic
|
||||
// test.assertTextExists(testPost.html, 'Post html exists');
|
||||
});
|
||||
|
||||
casper.run(function () {
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
casper.test.begin("Haunted markdown in editor works", 3, function suite(test) {
|
||||
test.filename = "markdown_test.png";
|
||||
|
||||
casper.start(url + "ghost/editor/", function testTitleAndUrl() {
|
||||
CasperTest.begin("Haunted markdown in editor works", 3, function suite(test) {
|
||||
casper.thenOpen(url + "ghost/editor/", function testTitleAndUrl() {
|
||||
test.assertTitle("Ghost Admin", "Ghost admin has no title");
|
||||
}).viewport(1280, 1024);
|
||||
});
|
||||
|
||||
casper.then(function testImage() {
|
||||
casper.writeContentToCodeMirror("![sometext]()");
|
||||
});
|
||||
|
||||
// We must wait after sending keys to CodeMirror
|
||||
casper.wait(1000, function doneWait() {
|
||||
this.echo("I've waited for 1 seconds.");
|
||||
// bind to resource events so we can get the API response
|
||||
});
|
||||
|
||||
casper.then(function checkPostWasCreated() {
|
||||
|
||||
casper.waitForSelectorTextChange('.entry-preview .rendered-markdown', function onSuccess() {
|
||||
test.assertEvalEquals(function () {
|
||||
return document.querySelector('.CodeMirror-wrap textarea').value;
|
||||
}, "![sometext]()", 'Editor value is correct');
|
||||
}, '![sometext]()', 'Editor value is correct');
|
||||
|
||||
test.assertSelectorHasText('.entry-preview .rendered-markdown', 'Add image of sometext', 'Editor value is correct');
|
||||
});
|
||||
|
||||
casper.run(function () {
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
|
||||
casper.test.begin("Word count and plurality", 4, function suite(test) {
|
||||
test.filename = "editor_plurality_test.png";
|
||||
|
||||
casper.start(url + "ghost/editor/", function testTitleAndUrl() {
|
||||
CasperTest.begin("Word count and plurality", 4, function suite(test) {
|
||||
casper.thenOpen(url + "ghost/editor/", function testTitleAndUrl() {
|
||||
test.assertTitle("Ghost Admin", "Ghost admin has no title");
|
||||
}).viewport(1280, 1024);
|
||||
});
|
||||
|
||||
casper.then(function checkZeroPlural() {
|
||||
test.assertSelectorHasText('.entry-word-count', '0 words', 'count of 0 produces plural "words".');
|
||||
@ -97,42 +70,26 @@ casper.test.begin("Word count and plurality", 4, function suite(test) {
|
||||
casper.writeContentToCodeMirror('test');
|
||||
});
|
||||
|
||||
// We must wait after sending keys to CodeMirror
|
||||
casper.wait(1000, function doneWait() {
|
||||
this.echo('I\'ve waited for 1 seconds.');
|
||||
});
|
||||
|
||||
casper.then(function checkSinglular() {
|
||||
casper.waitForSelectorTextChange('.entry-word-count', function onSuccess() {
|
||||
test.assertSelectorHasText('.entry-word-count', '1 word', 'count of 1 produces singular "word".');
|
||||
});
|
||||
})
|
||||
|
||||
casper.then(function () {
|
||||
casper.writeContentToCodeMirror('test'); // append another word, assumes newline
|
||||
});
|
||||
|
||||
// We must wait after sending keys to CodeMirror
|
||||
casper.wait(1000, function doneWait() {
|
||||
this.echo('I\'ve waited for 1 seconds.');
|
||||
});
|
||||
|
||||
casper.then(function checkPlural() {
|
||||
casper.waitForSelectorTextChange('.entry-word-count', function onSuccess() {
|
||||
test.assertSelectorHasText('.entry-word-count', '2 words', 'count of 2 produces plural "words".');
|
||||
});
|
||||
|
||||
casper.run(function () {
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
|
||||
casper.test.begin('Title Trimming', function suite(test) {
|
||||
CasperTest.begin('Title Trimming', 2, function suite(test) {
|
||||
var untrimmedTitle = ' test title ',
|
||||
trimmedTitle = 'test title';
|
||||
|
||||
test.filename = 'editor_title_trimming_test.png';
|
||||
|
||||
casper.start(url + 'ghost/editor/', function testTitleAndUrl() {
|
||||
casper.thenOpen(url + 'ghost/editor/', function testTitleAndUrl() {
|
||||
test.assertTitle("Ghost Admin", 'Ghost admin has no title');
|
||||
}).viewport(1280, 1024);
|
||||
});
|
||||
|
||||
casper.then(function populateTitle() {
|
||||
casper.sendKeys('#entry-title', untrimmedTitle);
|
||||
@ -143,18 +100,12 @@ casper.test.begin('Title Trimming', function suite(test) {
|
||||
|
||||
}, trimmedTitle, 'Entry title should match expected value.');
|
||||
});
|
||||
|
||||
casper.run(function () {
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
|
||||
casper.test.begin('Publish menu - new post', function suite(test) {
|
||||
test.filename = 'publish_menu_new_post.png';
|
||||
|
||||
casper.start(url + 'ghost/editor/', function testTitleAndUrl() {
|
||||
CasperTest.begin('Publish menu - new post', 11, function suite(test) {
|
||||
casper.thenOpen(url + 'ghost/editor/', function testTitleAndUrl() {
|
||||
test.assertTitle("Ghost Admin", 'Ghost admin has no title');
|
||||
}).viewport(1280, 1024);
|
||||
});
|
||||
|
||||
// ... check default option status, label, class
|
||||
casper.then(function () {
|
||||
@ -184,28 +135,21 @@ casper.test.begin('Publish menu - new post', function suite(test) {
|
||||
return (__utils__.findOne('.js-publish-button').getAttribute('data-status') === 'published');
|
||||
}, 'Publish button\'s updated status should be "published"');
|
||||
});
|
||||
|
||||
casper.run(function () {
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
|
||||
casper.test.begin('Publish menu - existing post', function suite(test) {
|
||||
test.filename = 'publish_menu_existing_post.png';
|
||||
|
||||
CasperTest.begin('Publish menu - existing post', 24, function suite(test) {
|
||||
// Create a post, save it and test refreshed editor
|
||||
casper.start(url + 'ghost/editor/', function testTitleAndUrl() {
|
||||
casper.thenOpen(url + 'ghost/editor/', function testTitleAndUrl() {
|
||||
test.assertTitle("Ghost Admin", 'Ghost admin has no title');
|
||||
}).viewport(1280, 1024);
|
||||
});
|
||||
|
||||
casper.then(function createTestPost() {
|
||||
casper.sendKeys('#entry-title', testPost.title);
|
||||
casper.writeContentToCodeMirror(testPost.html);
|
||||
});
|
||||
|
||||
// We must wait after sending keys to CodeMirror
|
||||
casper.wait(1000, function doneWait() {
|
||||
this.echo("I've waited for 1 seconds.");
|
||||
casper.waitForSelectorTextChange('.entry-preview .rendered-markdown', function onSuccess() {
|
||||
test.assertSelectorHasText('.entry-preview .rendered-markdown', 'test', 'Editor value is correct');
|
||||
});
|
||||
|
||||
// Create a post in draft status
|
||||
@ -279,8 +223,4 @@ casper.test.begin('Publish menu - existing post', function suite(test) {
|
||||
return (__utils__.findOne('.js-publish-button').getAttribute('data-status') === 'draft');
|
||||
}, 'Publish button\'s updated status should be "draft"');
|
||||
});
|
||||
|
||||
casper.run(function () {
|
||||
test.done();
|
||||
});
|
||||
});
|
@ -3,22 +3,18 @@
|
||||
*/
|
||||
|
||||
/*globals casper, __utils__, url, testPost */
|
||||
casper.test.begin("Ghost edit draft flow works correctly", 7, function suite(test) {
|
||||
test.filename = "flow_test.png";
|
||||
|
||||
casper.start(url + "ghost/editor/", function then() {
|
||||
CasperTest.begin("Ghost edit draft flow works correctly", 8, function suite(test) {
|
||||
casper.thenOpen(url + "ghost/editor/", function then() {
|
||||
test.assertUrlMatch(/ghost\/editor\/$/, "Ghost doesn't require login this time");
|
||||
}).viewport(1280, 1024);
|
||||
|
||||
// First, create a new draft post
|
||||
casper.then(function createTestPost() {
|
||||
casper.sendKeys('#entry-title', 'Test Draft Post');
|
||||
casper.writeContentToCodeMirror('I am a draft');
|
||||
});
|
||||
|
||||
// We must wait after sending keys to CodeMirror
|
||||
casper.wait(1000, function doneWait() {
|
||||
this.echo("I've waited for 1 seconds.");
|
||||
casper.then(function createTestPost() {
|
||||
casper.sendKeys('#entry-title', testPost.title);
|
||||
casper.writeContentToCodeMirror(testPost.html);
|
||||
});
|
||||
|
||||
casper.waitForSelectorTextChange('.entry-preview .rendered-markdown', function onSuccess() {
|
||||
test.assertSelectorHasText('.entry-preview .rendered-markdown', 'test', 'Editor value is correct');
|
||||
});
|
||||
|
||||
casper.thenClick('.js-publish-button');
|
||||
@ -39,7 +35,7 @@ casper.test.begin("Ghost edit draft flow works correctly", 7, function suite(tes
|
||||
return document.querySelector('.content-list-content li').className;
|
||||
}, "active", "first item is active");
|
||||
|
||||
test.assertSelectorHasText(".content-list-content li:first-child h3", 'Test Draft Post', "first item is the post we created");
|
||||
test.assertSelectorHasText(".content-list-content li:first-child h3", testPost.title, "first item is the post we created");
|
||||
});
|
||||
|
||||
casper.thenClick('.post-edit').waitForResource(/editor/, function then() {
|
||||
@ -54,16 +50,11 @@ casper.test.begin("Ghost edit draft flow works correctly", 7, function suite(tes
|
||||
}, function onTimeout() {
|
||||
test.assert(false, 'No success notification :(');
|
||||
});
|
||||
|
||||
casper.run(function () {
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
|
||||
// TODO: test publishing, editing, republishing, unpublishing etc
|
||||
//casper.test.begin("Ghost edit published flow works correctly", 6, function suite(test) {
|
||||
//CasperTest.begin("Ghost edit published flow works correctly", 6, function suite(test) {
|
||||
//
|
||||
// test.filename = "flow_test.png";
|
||||
//
|
||||
//
|
||||
//});
|
@ -1,21 +1,13 @@
|
||||
/*globals casper, __utils__, url, user, falseUser */
|
||||
|
||||
casper.test.begin('Ensure Session is Killed', 1, function suite(test) {
|
||||
test.filename = 'login_logout_test.png';
|
||||
|
||||
casper.start(url + 'logout/', function (response) {
|
||||
CasperTest.begin('Ensure Session is Killed', 1, function suite(test) {
|
||||
casper.thenOpen(url + 'logout/', function (response) {
|
||||
test.assertUrlMatch(/ghost\/sign/, 'We got redirected to signin or signup page');
|
||||
});
|
||||
}, true);
|
||||
|
||||
casper.run(function () {
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
|
||||
casper.test.begin('Ensure a User is Registered', 2, function suite(test) {
|
||||
test.filename = 'login_user_registered_test.png';
|
||||
|
||||
casper.start(url + 'ghost/signup/').viewport(1280, 1024);
|
||||
CasperTest.begin('Ensure a User is Registered', 2, function suite(test) {
|
||||
casper.thenOpen(url + 'ghost/signup/');
|
||||
|
||||
casper.waitForOpaque(".signup-box",
|
||||
function then() {
|
||||
@ -28,61 +20,35 @@ casper.test.begin('Ensure a User is Registered', 2, function suite(test) {
|
||||
casper.waitForSelectorTextChange('.notification-error', function onSuccess() {
|
||||
test.assertSelectorHasText('.notification-error', 'already registered');
|
||||
// If the previous assert succeeds, then we should skip the next check and just pass.
|
||||
test.pass('Already registered!');
|
||||
casper.echo('Already registered!');
|
||||
}, function onTimeout() {
|
||||
test.assertUrlMatch(/\/ghost\/$/, 'If we\'re not already registered, we should be logged in.');
|
||||
test.pass('Successfully registered.');
|
||||
casper.echo('Successfully registered.');
|
||||
}, 2000);
|
||||
|
||||
casper.run(function () {
|
||||
test.done();
|
||||
casper.thenOpen(url + 'logout/', function then() {
|
||||
test.assertUrlMatch(/ghost\/signin/, 'We got redirected to signin page.');
|
||||
});
|
||||
});
|
||||
}, true);
|
||||
|
||||
casper.test.begin('Ensure Session is Killed after Registration', 1, function suite(test) {
|
||||
test.filename = 'login_logout2_test.png';
|
||||
|
||||
casper.start(url + 'logout/', function then() {
|
||||
test.assertUrlMatch(/ghost\/signin/, 'We got redirected to signin page');
|
||||
});
|
||||
|
||||
casper.run(function () {
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
|
||||
casper.test.begin("Ghost admin will load login page", 2, function suite(test) {
|
||||
test.filename = "admin_test.png";
|
||||
|
||||
casper.start(url + "ghost", function testTitleAndUrl() {
|
||||
CasperTest.begin("Ghost admin will load login page", 2, function suite(test) {
|
||||
casper.thenOpen(url + "ghost", function testTitleAndUrl() {
|
||||
test.assertTitle("Ghost Admin", "Ghost admin has no title");
|
||||
test.assertUrlMatch(/ghost\/signin\/$/, 'If we\'re not already registered, we should be logged in.');
|
||||
}).viewport(1280, 1024);
|
||||
|
||||
casper.run(function () {
|
||||
test.done();
|
||||
test.assertUrlMatch(/ghost\/signin\/$/, 'We should be presented with the signin page.');
|
||||
});
|
||||
});
|
||||
|
||||
casper.test.begin('Redirects to signin', 2, function suite(test) {
|
||||
test.filename = 'login_redirect_test.png';
|
||||
}, true);
|
||||
|
||||
CasperTest.begin('Redirects login to signin', 2, function suite(test) {
|
||||
casper.start(url + 'ghost/login/', function testRedirect(response) {
|
||||
test.assertEqual(response.status, 200, 'Response status should be 200.');
|
||||
test.assertUrlMatch(/ghost\/signin\/$/, 'Should be redirected to /signin/.');
|
||||
});
|
||||
}, true);
|
||||
|
||||
casper.run(function () {
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
|
||||
casper.test.begin("Can't spam it", 4, function suite(test) {
|
||||
test.filename = "login_spam_test.png";
|
||||
|
||||
casper.start(url + "ghost/signin/", function testTitle() {
|
||||
CasperTest.begin("Can't spam it", 4, function suite(test) {
|
||||
casper.thenOpen(url + "ghost/signin/", function testTitle() {
|
||||
test.assertTitle("Ghost Admin", "Ghost admin has no title");
|
||||
}).viewport(1280, 1024);
|
||||
});
|
||||
|
||||
casper.waitForOpaque(".login-box",
|
||||
function then() {
|
||||
@ -107,18 +73,12 @@ casper.test.begin("Can't spam it", 4, function suite(test) {
|
||||
// This test causes the spam notification
|
||||
// add a wait to ensure future tests don't get tripped up by this.
|
||||
casper.wait(1000);
|
||||
}, true);
|
||||
|
||||
casper.run(function () {
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
|
||||
casper.test.begin("Can login to Ghost", 4, function suite(test) {
|
||||
test.filename = "login_test.png";
|
||||
|
||||
casper.start(url + "ghost/login/", function testTitle() {
|
||||
CasperTest.begin("Can login to Ghost", 4, function suite(test) {
|
||||
casper.thenOpen(url + "ghost/login/", function testTitle() {
|
||||
test.assertTitle("Ghost Admin", "Ghost admin has no title");
|
||||
}).viewport(1280, 1024);
|
||||
});
|
||||
|
||||
casper.waitForOpaque(".login-box",
|
||||
function then() {
|
||||
@ -132,8 +92,4 @@ casper.test.begin("Can login to Ghost", 4, function suite(test) {
|
||||
}, function onTimeOut() {
|
||||
test.fail('Failed to load ghost/ resource');
|
||||
});
|
||||
|
||||
casper.run(function () {
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
}, true);
|
@ -3,12 +3,12 @@
|
||||
*/
|
||||
|
||||
/*globals casper, __utils__, url, testPost, falseUser, email */
|
||||
casper.test.begin("Ghost logout works correctly", 2, function suite(test) {
|
||||
test.filename = "logout_test.png";
|
||||
CasperTest.begin("Ghost logout works correctly", 2, function suite(test) {
|
||||
CasperTest.Routines.login.run(test);
|
||||
|
||||
casper.start(url + "ghost/", function then() {
|
||||
casper.thenOpen(url + "ghost/", function then() {
|
||||
test.assertEquals(casper.getCurrentUrl(), url + "ghost/", "Ghost doesn't require login this time");
|
||||
}).viewport(1280, 1024);
|
||||
});
|
||||
|
||||
casper.thenClick('#usermenu a').waitFor(function checkOpaque() {
|
||||
return this.evaluate(function () {
|
||||
@ -26,19 +26,13 @@ casper.test.begin("Ghost logout works correctly", 2, function suite(test) {
|
||||
}, function onTimeout() {
|
||||
test.assert(false, 'No success notification :(');
|
||||
});
|
||||
|
||||
casper.run(function () {
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
}, true);
|
||||
|
||||
// has to be done after signing out
|
||||
casper.test.begin("Can't spam signin", 3, function suite(test) {
|
||||
test.filename = "spam_test.png";
|
||||
|
||||
casper.start(url + "ghost/signin/", function testTitle() {
|
||||
CasperTest.begin("Can't spam signin", 3, function suite(test) {
|
||||
casper.thenOpen(url + "ghost/signin/", function testTitle() {
|
||||
test.assertTitle("Ghost Admin", "Ghost admin has no title");
|
||||
}).viewport(1280, 1024);
|
||||
});
|
||||
|
||||
casper.waitFor(function checkOpaque() {
|
||||
return this.evaluate(function () {
|
||||
@ -60,18 +54,12 @@ casper.test.begin("Can't spam signin", 3, function suite(test) {
|
||||
}, function onTimeout() {
|
||||
test.assert(false, 'No error notification :(');
|
||||
});
|
||||
}, true);
|
||||
|
||||
casper.run(function () {
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
|
||||
casper.test.begin("Ghost signup fails properly", 5, function suite(test) {
|
||||
test.filename = "signup_test.png";
|
||||
|
||||
casper.start(url + "ghost/signup/", function then() {
|
||||
CasperTest.begin("Ghost signup fails properly", 5, function suite(test) {
|
||||
casper.thenOpen(url + "ghost/signup/", function then() {
|
||||
test.assertEquals(casper.getCurrentUrl(), url + "ghost/signup/", "Reached signup page");
|
||||
}).viewport(1280, 1024);
|
||||
});
|
||||
|
||||
casper.then(function signupWithShortPassword() {
|
||||
this.fill("#signup", {email: email, password: 'test'}, true);
|
||||
@ -98,8 +86,4 @@ casper.test.begin("Ghost signup fails properly", 5, function suite(test) {
|
||||
}, function onTimeout() {
|
||||
test.assert(false, 'No error notification :(');
|
||||
});
|
||||
|
||||
casper.run(function () {
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
}, true);
|
@ -1,12 +1,10 @@
|
||||
/*globals casper, __utils__, url */
|
||||
|
||||
casper.test.begin("Settings screen is correct", 15, function suite(test) {
|
||||
test.filename = "settings_test.png";
|
||||
|
||||
casper.start(url + "ghost/settings/", function testTitleAndUrl() {
|
||||
CasperTest.begin("Settings screen is correct", 15, function suite(test) {
|
||||
casper.thenOpen(url + "ghost/settings/", function testTitleAndUrl() {
|
||||
test.assertTitle("Ghost Admin", "Ghost admin has no title");
|
||||
test.assertUrlMatch(/ghost\/settings\/general\/$/, "Ghost doesn't require login this time");
|
||||
}).viewport(1280, 1024);
|
||||
});
|
||||
|
||||
casper.then(function testViews() {
|
||||
test.assertExists(".wrapper", "Settings main view is present");
|
||||
@ -41,14 +39,14 @@ casper.test.begin("Settings screen is correct", 15, function suite(test) {
|
||||
function handleUserRequest(requestData, request) {
|
||||
// make sure we only get requests from the user pane
|
||||
if (requestData.url.indexOf('settings/') !== -1) {
|
||||
casper.test.fail("Saving the user pane triggered another settings pane to save");
|
||||
test.fail("Saving the user pane triggered another settings pane to save");
|
||||
}
|
||||
}
|
||||
|
||||
function handleSettingsRequest(requestData, request) {
|
||||
// make sure we only get requests from the user pane
|
||||
if (requestData.url.indexOf('users/') !== -1) {
|
||||
casper.test.fail("Saving a settings pane triggered the user pane to save");
|
||||
test.fail("Saving a settings pane triggered the user pane to save");
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,7 +62,7 @@ casper.test.begin("Settings screen is correct", 15, function suite(test) {
|
||||
}, function doneWaiting() {
|
||||
|
||||
}, function waitTimeout() {
|
||||
casper.test.fail("Saving the user pane did not result in a notification");
|
||||
test.fail("Saving the user pane did not result in a notification");
|
||||
});
|
||||
|
||||
casper.then(function checkUserWasSaved() {
|
||||
@ -92,7 +90,7 @@ casper.test.begin("Settings screen is correct", 15, function suite(test) {
|
||||
}, function doneWaiting() {
|
||||
|
||||
}, function waitTimeout() {
|
||||
casper.test.fail("Saving the general pane did not result in a notification");
|
||||
test.fail("Saving the general pane did not result in a notification");
|
||||
});
|
||||
|
||||
casper.then(function checkSettingsWereSaved() {
|
||||
@ -105,22 +103,19 @@ casper.test.begin("Settings screen is correct", 15, function suite(test) {
|
||||
test.assert(false, 'No success notification :(');
|
||||
});
|
||||
|
||||
casper.run(function () {
|
||||
CasperTest.beforeDone(function () {
|
||||
casper.removeListener('resource.requested', handleUserRequest);
|
||||
casper.removeListener('resource.requested', handleSettingsRequest);
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
|
||||
casper.test.begin("User settings screen validates email", 6, function suite(test) {
|
||||
CasperTest.begin("User settings screen validates email", 6, function suite(test) {
|
||||
var email, brokenEmail;
|
||||
|
||||
test.filename = "user_settings_test.png";
|
||||
|
||||
casper.start(url + "ghost/settings/user/", function testTitleAndUrl() {
|
||||
casper.thenOpen(url + "ghost/settings/user/", function testTitleAndUrl() {
|
||||
test.assertTitle("Ghost Admin", "Ghost admin has no title");
|
||||
test.assertUrlMatch(/ghost\/settings\/user\/$/, "Ghost doesn't require login this time");
|
||||
}).viewport(1280, 1024);
|
||||
});
|
||||
|
||||
casper.then(function setEmailToInvalid() {
|
||||
email = casper.getElementInfo('#user-email').attributes.value;
|
||||
@ -158,8 +153,4 @@ casper.test.begin("User settings screen validates email", 6, function suite(test
|
||||
}, function onTimeout() {
|
||||
test.assert(false, 'No success notification :(');
|
||||
});
|
||||
|
||||
casper.run(function () {
|
||||
test.done();
|
||||
});
|
||||
});
|
@ -83,4 +83,141 @@ casper.on("page.error", function (msg, trace) {
|
||||
casper.test.on("fail", function captureFailure() {
|
||||
var filename = casper.test.filename || "casper_test_fail.png";
|
||||
casper.capture(new Date().getTime() + '_' + filename);
|
||||
});
|
||||
});
|
||||
|
||||
var CasperTest = (function() {
|
||||
|
||||
var _beforeDoneHandler,
|
||||
_noop = function noop() { },
|
||||
_isUserRegistered = false;
|
||||
|
||||
// Always log out at end of test.
|
||||
casper.test.tearDown(function (done) {
|
||||
casper.then(_beforeDoneHandler);
|
||||
|
||||
casper.thenOpen(url + 'signout/');
|
||||
|
||||
casper.waitForResource(/ghost\/sign/);
|
||||
|
||||
casper.run(done);
|
||||
});
|
||||
|
||||
// Wrapper around `casper.test.begin`
|
||||
function begin(testName, expect, suite, doNotAutoLogin) {
|
||||
_beforeDoneHandler = _noop;
|
||||
|
||||
var runTest = function (test) {
|
||||
test.filename = testName.toLowerCase().replace(/ /g, '-').concat('.png');
|
||||
|
||||
casper.start().viewport(1280, 1024);
|
||||
|
||||
if (!doNotAutoLogin) {
|
||||
// Only call register once for the lifetime of Mindless
|
||||
if (!_isUserRegistered) {
|
||||
CasperTest.Routines.logout.run(test);
|
||||
CasperTest.Routines.register.run(test);
|
||||
|
||||
_isUserRegistered = true;
|
||||
}
|
||||
|
||||
/* Ensure we're logged out at the start of every test or we may get
|
||||
unexpected failures. */
|
||||
CasperTest.Routines.logout.run(test);
|
||||
CasperTest.Routines.login.run(test);
|
||||
}
|
||||
|
||||
suite.call(casper, test);
|
||||
|
||||
casper.run(function () {
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
|
||||
if (typeof expect === 'function') {
|
||||
doNotAutoLogin = suite;
|
||||
suite = expect;
|
||||
|
||||
casper.test.begin(testName, runTest);
|
||||
}
|
||||
else {
|
||||
casper.test.begin(testName, expect, runTest);
|
||||
}
|
||||
}
|
||||
|
||||
// Sets a handler to be invoked right before `test.done` is invoked
|
||||
function beforeDone(fn) {
|
||||
if (fn) {
|
||||
_beforeDoneHandler = fn;
|
||||
}
|
||||
else {
|
||||
_beforeDoneHandler = _noop;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
begin: begin,
|
||||
beforeDone: beforeDone
|
||||
};
|
||||
|
||||
}());
|
||||
|
||||
CasperTest.Routines = (function () {
|
||||
|
||||
function register(test) {
|
||||
casper.thenOpen(url + 'ghost/signup/').viewport(1280, 1024);
|
||||
|
||||
casper.waitForOpaque('.signup-box', function then() {
|
||||
this.fill('#signup', newUser, true);
|
||||
});
|
||||
|
||||
casper.waitForSelectorTextChange('.notification-error', function onSuccess() {
|
||||
this.echo('It appears as though a user is already registered.');
|
||||
}, function onTimeout() {
|
||||
this.echo('It appears as though a user was not already registered.');
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
function login(test) {
|
||||
casper.thenOpen(url + 'ghost/signin/');
|
||||
|
||||
casper.waitForOpaque('.login-box', function then() {
|
||||
this.fill("#login", user, true);
|
||||
});
|
||||
|
||||
casper.waitForResource(/ghost\/$/);
|
||||
}
|
||||
|
||||
function logout(test) {
|
||||
casper.thenOpen(url + 'signout/');
|
||||
// Wait for signin or signup
|
||||
casper.waitForResource(/ghost\/sign/);
|
||||
}
|
||||
|
||||
function deletePost(id) {
|
||||
casper.thenOpen(url + 'ghost/');
|
||||
|
||||
casper.thenEvaluate(function (id) {
|
||||
return __utils__.sendAJAX(Ghost.settings.apiRoot + '/posts/' + id, 'DELETE');
|
||||
}, id);
|
||||
}
|
||||
|
||||
function _createRunner(fn) {
|
||||
fn.run = function run(test) {
|
||||
var routine = this;
|
||||
|
||||
casper.then(function () {
|
||||
routine.call(casper, test);
|
||||
});
|
||||
};
|
||||
|
||||
return fn;
|
||||
}
|
||||
|
||||
return {
|
||||
register: _createRunner(register),
|
||||
login: _createRunner(login),
|
||||
logout: _createRunner(logout),
|
||||
deletePost: _createRunner(deletePost)
|
||||
};
|
||||
|
||||
}());
|
@ -1,16 +0,0 @@
|
||||
/**
|
||||
* Tests logging out and attempting to sign up
|
||||
*/
|
||||
|
||||
/*globals casper, __utils__, url, testPost, falseUser, email */
|
||||
casper.test.begin('Redirects page 1 request', 1, function suite(test) {
|
||||
test.filename = '01_route_test_redirects_page_1.png';
|
||||
|
||||
casper.start(url + 'page/1/', function then(response) {
|
||||
test.assertEqual(casper.getCurrentUrl().indexOf('page/'), -1, 'Should be redirected to "/".');
|
||||
}).viewport(1280, 1024);
|
||||
|
||||
casper.run(function () {
|
||||
test.done();
|
||||
});
|
||||
});
|
10
core/test/functional/frontend/route_test.js
Normal file
10
core/test/functional/frontend/route_test.js
Normal file
@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Tests logging out and attempting to sign up
|
||||
*/
|
||||
|
||||
/*globals casper, __utils__, url, testPost, falseUser, email */
|
||||
CasperTest.begin('Redirects page 1 request', 1, function suite(test) {
|
||||
casper.thenOpen(url + 'page/1/', function then(response) {
|
||||
test.assertEqual(casper.getCurrentUrl().indexOf('page/'), -1, 'Should be redirected to "/".');
|
||||
});
|
||||
}, true);
|
@ -1,16 +1,10 @@
|
||||
/**
|
||||
* Tests if RSS exists and is working
|
||||
*/
|
||||
casper.test.begin('Ensure that RSS is available', 3, function suite(test) {
|
||||
test.filename = 'rss_test.png';
|
||||
|
||||
casper.start(url + 'rss/', function (response) {
|
||||
CasperTest.begin('Ensure that RSS is available', 3, function suite(test) {
|
||||
casper.thenOpen(url + 'rss/', function (response) {
|
||||
test.assertEqual(response.status, 200, 'Response status should be 200.');
|
||||
test.assert(this.getPageContent().indexOf('<rss') >= 0, 'Feed should contain <rss');
|
||||
test.assert(this.getPageContent().indexOf('</rss>') >= 0, 'Feed should contain </rss>');
|
||||
});
|
||||
|
||||
casper.run(function () {
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
}, true);
|
@ -1,36 +1,32 @@
|
||||
/*globals describe, before, beforeEach, afterEach, it */
|
||||
var testUtils = require('./testUtils'),
|
||||
should = require('should'),
|
||||
_ = require('underscore'),
|
||||
when = require('when'),
|
||||
sequence = require('when/sequence'),
|
||||
_ = require('underscore');
|
||||
|
||||
// Stuff we are testing
|
||||
Models = require('../../server/models');
|
||||
describe('Post API', function () {
|
||||
|
||||
describe('Post Model', function () {
|
||||
|
||||
var PostModel = Models.Post,
|
||||
UserModel = Models.User,
|
||||
userData = {
|
||||
password: 'testpass1',
|
||||
email: 'test@test1.com',
|
||||
name: 'Mr Biscuits'
|
||||
};
|
||||
var user = testUtils.DataGenerator.forModel.users[0],
|
||||
authCookie;
|
||||
|
||||
before(function (done) {
|
||||
testUtils.clearData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
testUtils.clearData()
|
||||
.then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
beforeEach(function (done) {
|
||||
this.timeout(5000);
|
||||
testUtils.initData()
|
||||
.then(function () {
|
||||
return UserModel.add(userData);
|
||||
return testUtils.insertDefaultFixtures();
|
||||
})
|
||||
.then(function () {
|
||||
return testUtils.API.login(user.email, user.password);
|
||||
})
|
||||
.then(function (authResponse) {
|
||||
authCookie = authResponse;
|
||||
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
@ -41,330 +37,13 @@ describe('Post Model', function () {
|
||||
}, done);
|
||||
});
|
||||
|
||||
it('can browse', function (done) {
|
||||
PostModel.browse().then(function (results) {
|
||||
should.exist(results);
|
||||
results.length.should.equal(1);
|
||||
|
||||
// should be in published_at, DESC order
|
||||
// model and API differ here - need to fix
|
||||
//results.models[0].attributes.published_at.should.be.above(results.models[1].attributes.published_at);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can read', function (done) {
|
||||
var firstPost;
|
||||
|
||||
PostModel.browse().then(function (results) {
|
||||
should.exist(results);
|
||||
results.length.should.be.above(0);
|
||||
firstPost = results.models[0];
|
||||
|
||||
return PostModel.read({slug: firstPost.attributes.slug});
|
||||
}).then(function (found) {
|
||||
should.exist(found);
|
||||
found.attributes.title.should.equal(firstPost.attributes.title);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can findAll, returning author and user data', function (done) {
|
||||
var firstPost;
|
||||
|
||||
PostModel.findAll({}).then(function (results) {
|
||||
should.exist(results);
|
||||
results.length.should.be.above(0);
|
||||
firstPost = results.models[0].toJSON();
|
||||
|
||||
firstPost.author.should.be.a('object');
|
||||
firstPost.user.should.be.a('object');
|
||||
firstPost.author.name.should.equal('Mr Biscuits');
|
||||
firstPost.user.name.should.equal('Mr Biscuits');
|
||||
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
it('can findOne, returning author and user data', function (done) {
|
||||
var firstPost;
|
||||
|
||||
PostModel.findOne({}).then(function (result) {
|
||||
it('can retrieve a post', function (done) {
|
||||
testUtils.API.get(testUtils.API.ApiRouteBase + 'posts/?status=all', authCookie).then(function (result) {
|
||||
should.exist(result);
|
||||
firstPost = result.toJSON();
|
||||
|
||||
firstPost.author.should.be.a('object');
|
||||
firstPost.user.should.be.a('object');
|
||||
firstPost.author.name.should.equal('Mr Biscuits');
|
||||
firstPost.user.name.should.equal('Mr Biscuits');
|
||||
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
it('can edit', function (done) {
|
||||
var firstPost;
|
||||
|
||||
PostModel.browse().then(function (results) {
|
||||
should.exist(results);
|
||||
results.length.should.be.above(0);
|
||||
firstPost = results.models[0];
|
||||
|
||||
return PostModel.edit({id: firstPost.id, title: 'new title'});
|
||||
}).then(function (edited) {
|
||||
should.exist(edited);
|
||||
edited.attributes.title.should.equal('new title');
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can add, defaulting as a draft', function (done) {
|
||||
var createdPostUpdatedDate,
|
||||
newPost = {
|
||||
title: 'Test Title 1',
|
||||
markdown: 'Test Content 1'
|
||||
};
|
||||
|
||||
PostModel.add(newPost).then(function (createdPost) {
|
||||
return new PostModel({id: createdPost.id}).fetch();
|
||||
}).then(function (createdPost) {
|
||||
should.exist(createdPost);
|
||||
createdPost.has('uuid').should.equal(true);
|
||||
createdPost.get('status').should.equal('draft');
|
||||
createdPost.get('title').should.equal(newPost.title, 'title is correct');
|
||||
createdPost.get('markdown').should.equal(newPost.markdown, 'markdown is correct');
|
||||
createdPost.has('html').should.equal(true);
|
||||
createdPost.get('html').should.equal('<p>' + newPost.markdown + '</p>');
|
||||
createdPost.get('slug').should.equal('test-title-1');
|
||||
createdPost.get('created_at').should.be.above(new Date(0).getTime());
|
||||
createdPost.get('created_by').should.equal(1);
|
||||
createdPost.get('author_id').should.equal(1);
|
||||
createdPost.get('created_by').should.equal(createdPost.get('author_id'));
|
||||
createdPost.get('updated_at').should.be.above(new Date(0).getTime());
|
||||
createdPost.get('updated_by').should.equal(1);
|
||||
should.equal(createdPost.get('published_at'), null);
|
||||
should.equal(createdPost.get('published_by'), null);
|
||||
|
||||
createdPostUpdatedDate = createdPost.get('updated_at');
|
||||
|
||||
// Set the status to published to check that `published_at` is set.
|
||||
return createdPost.save({status: 'published'});
|
||||
}).then(function (publishedPost) {
|
||||
publishedPost.get('published_at').should.be.instanceOf(Date);
|
||||
publishedPost.get('published_by').should.equal(1);
|
||||
publishedPost.get('updated_at').should.be.instanceOf(Date);
|
||||
publishedPost.get('updated_by').should.equal(1);
|
||||
publishedPost.get('updated_at').should.not.equal(createdPostUpdatedDate);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
|
||||
});
|
||||
|
||||
it('can trim title', function (done) {
|
||||
var untrimmedCreateTitle = ' test trimmed create title ',
|
||||
untrimmedUpdateTitle = ' test trimmed update title ',
|
||||
newPost = {
|
||||
title: untrimmedCreateTitle,
|
||||
markdown: 'Test Content'
|
||||
};
|
||||
|
||||
PostModel.add(newPost).then(function (createdPost) {
|
||||
return new PostModel({ id: createdPost.id }).fetch();
|
||||
}).then(function (createdPost) {
|
||||
should.exist(createdPost);
|
||||
createdPost.get('title').should.equal(untrimmedCreateTitle.trim());
|
||||
|
||||
return createdPost.save({ title: untrimmedUpdateTitle });
|
||||
}).then(function (updatedPost) {
|
||||
updatedPost.get('title').should.equal(untrimmedUpdateTitle.trim());
|
||||
|
||||
should.exist(result.response);
|
||||
result.response.posts.length.should.be.above(1);
|
||||
done();
|
||||
}).otherwise(done);
|
||||
});
|
||||
|
||||
it('can generate a non conflicting slug', function (done) {
|
||||
var newPost = {
|
||||
title: 'Test Title',
|
||||
markdown: 'Test Content 1'
|
||||
};
|
||||
|
||||
this.timeout(5000); // this is a patch to ensure it doesn't timeout.
|
||||
|
||||
// Create 12 posts with the same title
|
||||
sequence(_.times(12, function (i) {
|
||||
return function () {
|
||||
return PostModel.add({
|
||||
title: 'Test Title',
|
||||
markdown: 'Test Content ' + (i+1)
|
||||
});
|
||||
};
|
||||
})).then(function (createdPosts) {
|
||||
// Should have created 12 posts
|
||||
createdPosts.length.should.equal(12);
|
||||
|
||||
// Should have unique slugs and contents
|
||||
_(createdPosts).each(function (post, i) {
|
||||
var num = i + 1;
|
||||
|
||||
// First one has normal title
|
||||
if (num === 1) {
|
||||
post.get('slug').should.equal('test-title');
|
||||
return;
|
||||
}
|
||||
|
||||
post.get('slug').should.equal('test-title-' + num);
|
||||
post.get('markdown').should.equal('Test Content ' + num);
|
||||
});
|
||||
|
||||
done();
|
||||
}).otherwise(done);
|
||||
});
|
||||
|
||||
it('can generate slugs without duplicate hyphens', function (done) {
|
||||
var newPost = {
|
||||
title: 'apprehensive titles have too many spaces ',
|
||||
markdown: 'Test Content 1'
|
||||
};
|
||||
|
||||
PostModel.add(newPost).then(function (createdPost) {
|
||||
|
||||
createdPost.get('slug').should.equal('apprehensive-titles-have-too-many-spaces');
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('detects duplicate slugs before saving', function (done) {
|
||||
var firstPost = {
|
||||
title: 'First post',
|
||||
markdown: 'First content 1'
|
||||
},
|
||||
secondPost = {
|
||||
title: 'Second post',
|
||||
markdown: 'Second content 1'
|
||||
};
|
||||
|
||||
// Create the first post
|
||||
PostModel.add(firstPost)
|
||||
.then(function (createdFirstPost) {
|
||||
// Store the slug for later
|
||||
firstPost.slug = createdFirstPost.get('slug');
|
||||
|
||||
// Create the second post
|
||||
return PostModel.add(secondPost);
|
||||
}).then(function (createdSecondPost) {
|
||||
// Store the slug for comparison later
|
||||
secondPost.slug = createdSecondPost.get('slug');
|
||||
|
||||
// Update with a conflicting slug from the first post
|
||||
return createdSecondPost.save({
|
||||
slug: firstPost.slug
|
||||
});
|
||||
}).then(function (updatedSecondPost) {
|
||||
|
||||
// Should have updated from original
|
||||
updatedSecondPost.get('slug').should.not.equal(secondPost.slug);
|
||||
// Should not have a conflicted slug from the first
|
||||
updatedSecondPost.get('slug').should.not.equal(firstPost.slug);
|
||||
|
||||
return PostModel.read({
|
||||
id: updatedSecondPost.id
|
||||
});
|
||||
}).then(function (foundPost) {
|
||||
|
||||
// Should have updated from original
|
||||
foundPost.get('slug').should.not.equal(secondPost.slug);
|
||||
// Should not have a conflicted slug from the first
|
||||
foundPost.get('slug').should.not.equal(firstPost.slug);
|
||||
|
||||
done();
|
||||
}).otherwise(done);
|
||||
});
|
||||
|
||||
it('can delete', function (done) {
|
||||
var firstPostId;
|
||||
PostModel.browse().then(function (results) {
|
||||
should.exist(results);
|
||||
results.length.should.be.above(0);
|
||||
firstPostId = results.models[0].id;
|
||||
|
||||
return PostModel.destroy(firstPostId);
|
||||
}).then(function () {
|
||||
return PostModel.browse();
|
||||
}).then(function (newResults) {
|
||||
var ids, hasDeletedId;
|
||||
|
||||
ids = _.pluck(newResults.models, 'id');
|
||||
hasDeletedId = _.any(ids, function (id) {
|
||||
return id === firstPostId;
|
||||
});
|
||||
hasDeletedId.should.equal(false);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can create a new Post with a previous published_at date', function (done) {
|
||||
var previousPublishedAtDate = new Date(2013, 8, 21, 12);
|
||||
|
||||
PostModel.add({
|
||||
status: 'published',
|
||||
published_at: previousPublishedAtDate,
|
||||
title: 'published_at test',
|
||||
markdown: 'This is some content'
|
||||
}).then(function (newPost) {
|
||||
|
||||
should.exist(newPost);
|
||||
|
||||
newPost.get('published_at').should.equal(previousPublishedAtDate);
|
||||
|
||||
done();
|
||||
|
||||
}).otherwise(done);
|
||||
});
|
||||
|
||||
it('can fetch a paginated set, with various options', function (done) {
|
||||
this.timeout(10000); // this is a patch to ensure it doesn't timeout.
|
||||
|
||||
testUtils.insertMorePosts().then(function () {
|
||||
|
||||
return PostModel.findPage({page: 2});
|
||||
}).then(function (paginationResult) {
|
||||
paginationResult.page.should.equal(2);
|
||||
paginationResult.limit.should.equal(15);
|
||||
paginationResult.posts.length.should.equal(15);
|
||||
paginationResult.pages.should.equal(4);
|
||||
|
||||
return PostModel.findPage({page: 5});
|
||||
}).then(function (paginationResult) {
|
||||
paginationResult.page.should.equal(5);
|
||||
paginationResult.limit.should.equal(15);
|
||||
paginationResult.posts.length.should.equal(0);
|
||||
paginationResult.pages.should.equal(4);
|
||||
|
||||
return PostModel.findPage({limit: 30});
|
||||
}).then(function (paginationResult) {
|
||||
paginationResult.page.should.equal(1);
|
||||
paginationResult.limit.should.equal(30);
|
||||
paginationResult.posts.length.should.equal(30);
|
||||
paginationResult.pages.should.equal(2);
|
||||
|
||||
return PostModel.findPage({limit: 10, page: 2, where: {language: 'fr'}});
|
||||
}).then(function (paginationResult) {
|
||||
paginationResult.page.should.equal(2);
|
||||
paginationResult.limit.should.equal(10);
|
||||
paginationResult.posts.length.should.equal(10);
|
||||
paginationResult.pages.should.equal(3);
|
||||
|
||||
return PostModel.findPage({limit: 10, page: 2, status: 'all'});
|
||||
}).then(function (paginationResult) {
|
||||
paginationResult.pages.should.equal(11);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
});
|
||||
|
217
core/test/unit/fixtures/data-generator.js
Normal file
217
core/test/unit/fixtures/data-generator.js
Normal file
File diff suppressed because one or more lines are too long
@ -22,6 +22,7 @@ describe("Ghost API", function () {
|
||||
});
|
||||
|
||||
beforeEach(function (done) {
|
||||
this.timeout(5000);
|
||||
sandbox = sinon.sandbox.create();
|
||||
|
||||
testUtils.initData().then(function () {
|
||||
|
@ -6,100 +6,6 @@ var testUtils = require('./testUtils'),
|
||||
// Stuff we are testing
|
||||
Models = require('../../server/models');
|
||||
|
||||
describe("Role Model", function () {
|
||||
|
||||
var RoleModel = Models.Role;
|
||||
|
||||
should.exist(RoleModel);
|
||||
|
||||
before(function (done) {
|
||||
testUtils.clearData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
beforeEach(function (done) {
|
||||
this.timeout(5000);
|
||||
testUtils.initData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
afterEach(function (done) {
|
||||
testUtils.clearData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
it("can browse roles", function (done) {
|
||||
RoleModel.browse().then(function (foundRoles) {
|
||||
should.exist(foundRoles);
|
||||
|
||||
foundRoles.models.length.should.be.above(0);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it("can read roles", function (done) {
|
||||
RoleModel.read({id: 1}).then(function (foundRole) {
|
||||
should.exist(foundRole);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it("can edit roles", function (done) {
|
||||
RoleModel.read({id: 1}).then(function (foundRole) {
|
||||
should.exist(foundRole);
|
||||
|
||||
return foundRole.set({name: "updated"}).save();
|
||||
}).then(function () {
|
||||
return RoleModel.read({id: 1});
|
||||
}).then(function (updatedRole) {
|
||||
should.exist(updatedRole);
|
||||
|
||||
updatedRole.get("name").should.equal("updated");
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it("can add roles", function (done) {
|
||||
var newRole = {
|
||||
name: "test1",
|
||||
description: "test1 description"
|
||||
};
|
||||
|
||||
RoleModel.add(newRole).then(function (createdRole) {
|
||||
should.exist(createdRole);
|
||||
|
||||
createdRole.attributes.name.should.equal(newRole.name);
|
||||
createdRole.attributes.description.should.equal(newRole.description);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it("can delete roles", function (done) {
|
||||
RoleModel.read({id: 1}).then(function (foundRole) {
|
||||
should.exist(foundRole);
|
||||
|
||||
return RoleModel['delete'](1);
|
||||
}).then(function () {
|
||||
return RoleModel.browse();
|
||||
}).then(function (foundRoles) {
|
||||
var hasRemovedId = foundRoles.any(function (role) {
|
||||
return role.id === 1;
|
||||
});
|
||||
|
||||
hasRemovedId.should.equal(false);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Permission Model", function () {
|
||||
|
||||
var PermissionModel = Models.Permission;
|
364
core/test/unit/model_posts_spec.js
Normal file
364
core/test/unit/model_posts_spec.js
Normal file
@ -0,0 +1,364 @@
|
||||
/*globals describe, before, beforeEach, afterEach, it */
|
||||
var testUtils = require('./testUtils'),
|
||||
should = require('should'),
|
||||
_ = require('underscore'),
|
||||
when = require('when'),
|
||||
sequence = require('when/sequence'),
|
||||
|
||||
// Stuff we are testing
|
||||
Models = require('../../server/models');
|
||||
|
||||
describe('Post Model', function () {
|
||||
|
||||
var PostModel = Models.Post,
|
||||
UserModel = Models.User;
|
||||
|
||||
before(function (done) {
|
||||
testUtils.clearData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
beforeEach(function (done) {
|
||||
this.timeout(5000);
|
||||
testUtils.initData()
|
||||
.then(function () {
|
||||
return testUtils.insertDefaultFixtures();
|
||||
})
|
||||
.then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
afterEach(function (done) {
|
||||
testUtils.clearData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
it('can browse', function (done) {
|
||||
PostModel.browse().then(function (results) {
|
||||
should.exist(results);
|
||||
results.length.should.be.above(1);
|
||||
|
||||
// should be in published_at, DESC order
|
||||
// model and API differ here - need to fix
|
||||
//results.models[0].attributes.published_at.should.be.above(results.models[1].attributes.published_at);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can read', function (done) {
|
||||
var firstPost;
|
||||
|
||||
PostModel.browse().then(function (results) {
|
||||
should.exist(results);
|
||||
results.length.should.be.above(0);
|
||||
firstPost = results.models[0];
|
||||
|
||||
return PostModel.read({slug: firstPost.attributes.slug});
|
||||
}).then(function (found) {
|
||||
should.exist(found);
|
||||
found.attributes.title.should.equal(firstPost.attributes.title);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can findAll, returning author and user data', function (done) {
|
||||
var firstPost;
|
||||
|
||||
PostModel.findAll({}).then(function (results) {
|
||||
should.exist(results);
|
||||
results.length.should.be.above(0);
|
||||
firstPost = results.models[0].toJSON();
|
||||
|
||||
firstPost.author.should.be.a('object');
|
||||
firstPost.user.should.be.a('object');
|
||||
firstPost.author.name.should.equal(DataGenerator.Content.users[0].name);
|
||||
firstPost.user.name.should.equal(DataGenerator.Content.users[0].name);
|
||||
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
it('can findOne, returning author and user data', function (done) {
|
||||
this.timeout(5000);
|
||||
var firstPost;
|
||||
|
||||
PostModel.findOne({}).then(function (result) {
|
||||
should.exist(result);
|
||||
firstPost = result.toJSON();
|
||||
|
||||
firstPost.author.should.be.a('object');
|
||||
firstPost.user.should.be.a('object');
|
||||
firstPost.author.name.should.equal(testUtils.DataGenerator.Content.users[0].name);
|
||||
firstPost.user.name.should.equal(testUtils.DataGenerator.Content.users[0].name);
|
||||
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
it('can edit', function (done) {
|
||||
var firstPost;
|
||||
|
||||
PostModel.browse().then(function (results) {
|
||||
should.exist(results);
|
||||
results.length.should.be.above(0);
|
||||
firstPost = results.models[0];
|
||||
|
||||
return PostModel.edit({id: firstPost.id, title: 'new title'});
|
||||
}).then(function (edited) {
|
||||
should.exist(edited);
|
||||
edited.attributes.title.should.equal('new title');
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can add, defaulting as a draft', function (done) {
|
||||
var createdPostUpdatedDate,
|
||||
newPost = testUtils.DataGenerator.forModel.posts[2],
|
||||
newPostDB = testUtils.DataGenerator.Content.posts[2];
|
||||
|
||||
PostModel.add(newPost).then(function (createdPost) {
|
||||
return new PostModel({id: createdPost.id}).fetch();
|
||||
}).then(function (createdPost) {
|
||||
should.exist(createdPost);
|
||||
createdPost.has('uuid').should.equal(true);
|
||||
createdPost.get('status').should.equal('draft');
|
||||
createdPost.get('title').should.equal(newPost.title, 'title is correct');
|
||||
createdPost.get('markdown').should.equal(newPost.markdown, 'markdown is correct');
|
||||
createdPost.has('html').should.equal(true);
|
||||
createdPost.get('html').should.equal(newPostDB.html);
|
||||
createdPost.get('slug').should.equal(newPostDB.slug + '-2');
|
||||
createdPost.get('created_at').should.be.above(new Date(0).getTime());
|
||||
createdPost.get('created_by').should.equal(1);
|
||||
createdPost.get('author_id').should.equal(1);
|
||||
createdPost.get('created_by').should.equal(createdPost.get('author_id'));
|
||||
createdPost.get('updated_at').should.be.above(new Date(0).getTime());
|
||||
createdPost.get('updated_by').should.equal(1);
|
||||
should.equal(createdPost.get('published_at'), null);
|
||||
should.equal(createdPost.get('published_by'), null);
|
||||
|
||||
createdPostUpdatedDate = createdPost.get('updated_at');
|
||||
|
||||
// Set the status to published to check that `published_at` is set.
|
||||
return createdPost.save({status: 'published'});
|
||||
}).then(function (publishedPost) {
|
||||
publishedPost.get('published_at').should.be.instanceOf(Date);
|
||||
publishedPost.get('published_by').should.equal(1);
|
||||
publishedPost.get('updated_at').should.be.instanceOf(Date);
|
||||
publishedPost.get('updated_by').should.equal(1);
|
||||
publishedPost.get('updated_at').should.not.equal(createdPostUpdatedDate);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
|
||||
});
|
||||
|
||||
it('can trim title', function (done) {
|
||||
var untrimmedCreateTitle = ' test trimmed create title ',
|
||||
untrimmedUpdateTitle = ' test trimmed update title ',
|
||||
newPost = {
|
||||
title: untrimmedCreateTitle,
|
||||
markdown: 'Test Content'
|
||||
};
|
||||
|
||||
PostModel.add(newPost).then(function (createdPost) {
|
||||
return new PostModel({ id: createdPost.id }).fetch();
|
||||
}).then(function (createdPost) {
|
||||
should.exist(createdPost);
|
||||
createdPost.get('title').should.equal(untrimmedCreateTitle.trim());
|
||||
|
||||
return createdPost.save({ title: untrimmedUpdateTitle });
|
||||
}).then(function (updatedPost) {
|
||||
updatedPost.get('title').should.equal(untrimmedUpdateTitle.trim());
|
||||
|
||||
done();
|
||||
}).otherwise(done);
|
||||
});
|
||||
|
||||
it('can generate a non conflicting slug', function (done) {
|
||||
var newPost = {
|
||||
title: 'Test Title',
|
||||
markdown: 'Test Content 1'
|
||||
};
|
||||
|
||||
this.timeout(5000); // this is a patch to ensure it doesn't timeout.
|
||||
|
||||
// Create 12 posts with the same title
|
||||
sequence(_.times(12, function (i) {
|
||||
return function () {
|
||||
return PostModel.add({
|
||||
title: 'Test Title',
|
||||
markdown: 'Test Content ' + (i+1)
|
||||
});
|
||||
};
|
||||
})).then(function (createdPosts) {
|
||||
// Should have created 12 posts
|
||||
createdPosts.length.should.equal(12);
|
||||
|
||||
// Should have unique slugs and contents
|
||||
_(createdPosts).each(function (post, i) {
|
||||
var num = i + 1;
|
||||
|
||||
// First one has normal title
|
||||
if (num === 1) {
|
||||
post.get('slug').should.equal('test-title');
|
||||
return;
|
||||
}
|
||||
|
||||
post.get('slug').should.equal('test-title-' + num);
|
||||
post.get('markdown').should.equal('Test Content ' + num);
|
||||
});
|
||||
|
||||
done();
|
||||
}).otherwise(done);
|
||||
});
|
||||
|
||||
it('can generate slugs without duplicate hyphens', function (done) {
|
||||
var newPost = {
|
||||
title: 'apprehensive titles have too many spaces ',
|
||||
markdown: 'Test Content 1'
|
||||
};
|
||||
|
||||
PostModel.add(newPost).then(function (createdPost) {
|
||||
|
||||
createdPost.get('slug').should.equal('apprehensive-titles-have-too-many-spaces');
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('detects duplicate slugs before saving', function (done) {
|
||||
var firstPost = {
|
||||
title: 'First post',
|
||||
markdown: 'First content 1'
|
||||
},
|
||||
secondPost = {
|
||||
title: 'Second post',
|
||||
markdown: 'Second content 1'
|
||||
};
|
||||
|
||||
// Create the first post
|
||||
PostModel.add(firstPost)
|
||||
.then(function (createdFirstPost) {
|
||||
// Store the slug for later
|
||||
firstPost.slug = createdFirstPost.get('slug');
|
||||
|
||||
// Create the second post
|
||||
return PostModel.add(secondPost);
|
||||
}).then(function (createdSecondPost) {
|
||||
// Store the slug for comparison later
|
||||
secondPost.slug = createdSecondPost.get('slug');
|
||||
|
||||
// Update with a conflicting slug from the first post
|
||||
return createdSecondPost.save({
|
||||
slug: firstPost.slug
|
||||
});
|
||||
}).then(function (updatedSecondPost) {
|
||||
|
||||
// Should have updated from original
|
||||
updatedSecondPost.get('slug').should.not.equal(secondPost.slug);
|
||||
// Should not have a conflicted slug from the first
|
||||
updatedSecondPost.get('slug').should.not.equal(firstPost.slug);
|
||||
|
||||
return PostModel.read({
|
||||
id: updatedSecondPost.id
|
||||
});
|
||||
}).then(function (foundPost) {
|
||||
|
||||
// Should have updated from original
|
||||
foundPost.get('slug').should.not.equal(secondPost.slug);
|
||||
// Should not have a conflicted slug from the first
|
||||
foundPost.get('slug').should.not.equal(firstPost.slug);
|
||||
|
||||
done();
|
||||
}).otherwise(done);
|
||||
});
|
||||
|
||||
it('can delete', function (done) {
|
||||
var firstPostId;
|
||||
PostModel.browse().then(function (results) {
|
||||
should.exist(results);
|
||||
results.length.should.be.above(0);
|
||||
firstPostId = results.models[0].id;
|
||||
|
||||
return PostModel.destroy(firstPostId);
|
||||
}).then(function () {
|
||||
return PostModel.browse();
|
||||
}).then(function (newResults) {
|
||||
var ids, hasDeletedId;
|
||||
|
||||
ids = _.pluck(newResults.models, 'id');
|
||||
hasDeletedId = _.any(ids, function (id) {
|
||||
return id === firstPostId;
|
||||
});
|
||||
hasDeletedId.should.equal(false);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can create a new Post with a previous published_at date', function (done) {
|
||||
var previousPublishedAtDate = new Date(2013, 8, 21, 12);
|
||||
|
||||
PostModel.add({
|
||||
status: 'published',
|
||||
published_at: previousPublishedAtDate,
|
||||
title: 'published_at test',
|
||||
markdown: 'This is some content'
|
||||
}).then(function (newPost) {
|
||||
|
||||
should.exist(newPost);
|
||||
|
||||
newPost.get('published_at').should.equal(previousPublishedAtDate);
|
||||
|
||||
done();
|
||||
|
||||
}).otherwise(done);
|
||||
});
|
||||
|
||||
it('can fetch a paginated set, with various options', function (done) {
|
||||
this.timeout(10000); // this is a patch to ensure it doesn't timeout.
|
||||
|
||||
testUtils.insertMorePosts().then(function () {
|
||||
|
||||
return PostModel.findPage({page: 2});
|
||||
}).then(function (paginationResult) {
|
||||
paginationResult.page.should.equal(2);
|
||||
paginationResult.limit.should.equal(15);
|
||||
paginationResult.posts.length.should.equal(15);
|
||||
paginationResult.pages.should.equal(4);
|
||||
|
||||
return PostModel.findPage({page: 5});
|
||||
}).then(function (paginationResult) {
|
||||
paginationResult.page.should.equal(5);
|
||||
paginationResult.limit.should.equal(15);
|
||||
paginationResult.posts.length.should.equal(0);
|
||||
paginationResult.pages.should.equal(4);
|
||||
|
||||
return PostModel.findPage({limit: 30});
|
||||
}).then(function (paginationResult) {
|
||||
paginationResult.page.should.equal(1);
|
||||
paginationResult.limit.should.equal(30);
|
||||
paginationResult.posts.length.should.equal(30);
|
||||
paginationResult.pages.should.equal(2);
|
||||
|
||||
return PostModel.findPage({limit: 10, page: 2, where: {language: 'fr'}});
|
||||
}).then(function (paginationResult) {
|
||||
paginationResult.page.should.equal(2);
|
||||
paginationResult.limit.should.equal(10);
|
||||
paginationResult.posts.length.should.equal(10);
|
||||
paginationResult.pages.should.equal(3);
|
||||
|
||||
return PostModel.findPage({limit: 10, page: 2, status: 'all'});
|
||||
}).then(function (paginationResult) {
|
||||
paginationResult.pages.should.equal(11);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
});
|
101
core/test/unit/model_roles_spec.js
Normal file
101
core/test/unit/model_roles_spec.js
Normal file
@ -0,0 +1,101 @@
|
||||
/*globals describe, it, before, beforeEach, afterEach */
|
||||
var testUtils = require('./testUtils'),
|
||||
should = require('should'),
|
||||
errors = require('../../server/errorHandling'),
|
||||
|
||||
// Stuff we are testing
|
||||
Models = require('../../server/models');
|
||||
|
||||
describe("Role Model", function () {
|
||||
|
||||
var RoleModel = Models.Role;
|
||||
|
||||
should.exist(RoleModel);
|
||||
|
||||
before(function (done) {
|
||||
testUtils.clearData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
beforeEach(function (done) {
|
||||
this.timeout(5000);
|
||||
testUtils.initData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
afterEach(function (done) {
|
||||
testUtils.clearData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
it("can browse roles", function (done) {
|
||||
RoleModel.browse().then(function (foundRoles) {
|
||||
should.exist(foundRoles);
|
||||
|
||||
foundRoles.models.length.should.be.above(0);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it("can read roles", function (done) {
|
||||
RoleModel.read({id: 1}).then(function (foundRole) {
|
||||
should.exist(foundRole);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it("can edit roles", function (done) {
|
||||
RoleModel.read({id: 1}).then(function (foundRole) {
|
||||
should.exist(foundRole);
|
||||
|
||||
return foundRole.set({name: "updated"}).save();
|
||||
}).then(function () {
|
||||
return RoleModel.read({id: 1});
|
||||
}).then(function (updatedRole) {
|
||||
should.exist(updatedRole);
|
||||
|
||||
updatedRole.get("name").should.equal("updated");
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it("can add roles", function (done) {
|
||||
var newRole = {
|
||||
name: "test1",
|
||||
description: "test1 description"
|
||||
};
|
||||
|
||||
RoleModel.add(newRole).then(function (createdRole) {
|
||||
should.exist(createdRole);
|
||||
|
||||
createdRole.attributes.name.should.equal(newRole.name);
|
||||
createdRole.attributes.description.should.equal(newRole.description);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it("can delete roles", function (done) {
|
||||
RoleModel.read({id: 1}).then(function (foundRole) {
|
||||
should.exist(foundRole);
|
||||
|
||||
return RoleModel['delete'](1);
|
||||
}).then(function () {
|
||||
return RoleModel.browse();
|
||||
}).then(function (foundRoles) {
|
||||
var hasRemovedId = foundRoles.any(function (role) {
|
||||
return role.id === 1;
|
||||
});
|
||||
|
||||
hasRemovedId.should.equal(false);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
});
|
@ -36,8 +36,8 @@ describe('Tag Model', function () {
|
||||
var PostModel = Models.Post;
|
||||
|
||||
it('can add a tag', function (done) {
|
||||
var newPost = {title: 'Test Title 1', markdown: 'Test Content 1'},
|
||||
newTag = {name: 'tag1'},
|
||||
var newPost = testUtils.DataGenerator.forModel.posts[0],
|
||||
newTag = testUtils.DataGenerator.forModel.tags[0],
|
||||
createdPostID;
|
||||
|
||||
when.all([
|
||||
@ -62,8 +62,8 @@ describe('Tag Model', function () {
|
||||
// The majority of this test is ripped from above, which is obviously a Bad Thing.
|
||||
// Would be nice to find a way to seed data with relations for cases like this,
|
||||
// because there are more DB hits than needed
|
||||
var newPost = {title: 'Test Title 1', markdown: 'Test Content 1'},
|
||||
newTag = {name: 'tag1'},
|
||||
var newPost = testUtils.DataGenerator.forModel.posts[0],
|
||||
newTag = testUtils.DataGenerator.forModel.tags[0],
|
||||
createdTagID,
|
||||
createdPostID;
|
||||
|
||||
@ -96,13 +96,12 @@ describe('Tag Model', function () {
|
||||
|
||||
function seedTags(tagNames) {
|
||||
var createOperations = [
|
||||
PostModel.add({title: 'title', markdown: 'content'})
|
||||
PostModel.add(testUtils.DataGenerator.forModel.posts[0])
|
||||
];
|
||||
|
||||
var tagModels = tagNames.map(function (tagName) { return TagModel.add({name: tagName}); });
|
||||
createOperations = createOperations.concat(tagModels);
|
||||
|
||||
|
||||
return when.all(createOperations).then(function (models) {
|
||||
var postModel = models[0],
|
||||
attachOperations;
|
||||
@ -209,7 +208,7 @@ describe('Tag Model', function () {
|
||||
|
||||
|
||||
it('can add a tag to a post on creation', function (done) {
|
||||
var newPost = {title: 'Test Title 1', markdown: 'Test Content 1', tags: [{name: 'test_tag_1'}]};
|
||||
var newPost = _.extend(testUtils.DataGenerator.forModel.posts[0], {tags: [{name: 'test_tag_1'}]})
|
||||
|
||||
PostModel.add(newPost).then(function (createdPost) {
|
||||
return PostModel.read({id: createdPost.id}, { withRelated: ['tags']});
|
@ -33,11 +33,7 @@ describe('User Model', function run() {
|
||||
});
|
||||
|
||||
it('can add first', function (done) {
|
||||
var userData = {
|
||||
name: 'test',
|
||||
password: 'testpass1',
|
||||
email: "test@test1.com"
|
||||
};
|
||||
var userData = testUtils.DataGenerator.forModel.users[0];
|
||||
|
||||
UserModel.add(userData).then(function (createdUser) {
|
||||
should.exist(createdUser);
|
||||
@ -64,11 +60,7 @@ describe('User Model', function run() {
|
||||
});
|
||||
|
||||
it('can\'t add second', function (done) {
|
||||
var userData = {
|
||||
name: 'test',
|
||||
password: 'testpass3',
|
||||
email: "test3@test1.com"
|
||||
};
|
||||
var userData = testUtils.DataGenerator.forModel.users[1];
|
||||
|
||||
return UserModel.add(userData).then(done, function (failure) {
|
||||
failure.message.should.eql('A user is already registered. Only one user for now!');
|
@ -13,7 +13,7 @@ var testUtils = require('./testUtils'),
|
||||
PermissionsProvider = Models.Permission,
|
||||
PostProvider = Models.Post;
|
||||
|
||||
describe('permissions', function () {
|
||||
describe('Permissions', function () {
|
||||
|
||||
before(function (done) {
|
||||
testUtils.clearData()
|
||||
|
File diff suppressed because one or more lines are too long
118
core/test/unit/utils/api.js
Normal file
118
core/test/unit/utils/api.js
Normal file
@ -0,0 +1,118 @@
|
||||
var _ = require('underscore'),
|
||||
when = require('when'),
|
||||
http = require('http'),
|
||||
HttpMethods,
|
||||
ApiRouteBase = '/api/v0.1/';
|
||||
|
||||
HttpMethods = {
|
||||
GET: 'GET',
|
||||
POST: 'POST',
|
||||
PUT: 'PUT',
|
||||
DELETE: 'DELETE'
|
||||
};
|
||||
|
||||
function createRequest(httpMethod, overrides) {
|
||||
return _.defaults(overrides, {
|
||||
'host': 'localhost',
|
||||
'port': '2369',
|
||||
'method': httpMethod
|
||||
});
|
||||
}
|
||||
|
||||
function post(route, data, authCookie) {
|
||||
var jsonData = JSON.stringify(data),
|
||||
options = createRequest(HttpMethods.POST, {
|
||||
path: route,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': jsonData.length
|
||||
}
|
||||
}),
|
||||
req,
|
||||
response = '',
|
||||
deferred = when.defer();
|
||||
|
||||
if (authCookie) {
|
||||
options.headers['Cookie'] = authCookie;
|
||||
}
|
||||
|
||||
req = http.request(options, function (res) {
|
||||
res.setEncoding('utf-8');
|
||||
|
||||
if (res.statusCode === 401) {
|
||||
return deferred.resolver.reject(new Error('401 Unauthorized.'));
|
||||
}
|
||||
|
||||
res.on('data', function (chunk) {
|
||||
response += chunk;
|
||||
});
|
||||
|
||||
res.on('end', function () {
|
||||
deferred.resolver.resolve({
|
||||
headers: res.headers,
|
||||
response: JSON.parse(response)
|
||||
});
|
||||
});
|
||||
}).on('error', deferred.resolver.reject);
|
||||
|
||||
req.write(jsonData);
|
||||
req.end();
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function get(route, authCookie) {
|
||||
var options = createRequest(HttpMethods.GET, {
|
||||
path: route,
|
||||
headers: {}
|
||||
}),
|
||||
response = '',
|
||||
deferred = when.defer();
|
||||
|
||||
if (authCookie) {
|
||||
options.headers['Cookie'] = authCookie;
|
||||
}
|
||||
|
||||
http.get(options, function (res) {
|
||||
res.setEncoding('utf-8');
|
||||
|
||||
if (res.statusCode === 401) {
|
||||
return deferred.resolver.reject(new Error('401 Unauthorized.'));
|
||||
}
|
||||
|
||||
res.on('data', function (chunk) {
|
||||
response += chunk;
|
||||
});
|
||||
|
||||
res.on('end', function () {
|
||||
deferred.resolve({
|
||||
headers: res.headers,
|
||||
response: JSON.parse(response)
|
||||
});
|
||||
});
|
||||
}).on('error', deferred.resolver.reject);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function login(email, password) {
|
||||
var data = {
|
||||
email: email,
|
||||
password: password
|
||||
};
|
||||
|
||||
return post('/ghost/signin/', data).then(function (response) {
|
||||
return response.headers['set-cookie'];
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
HttpMethods: HttpMethods,
|
||||
ApiRouteBase: ApiRouteBase,
|
||||
|
||||
createRequest: createRequest,
|
||||
post: post,
|
||||
get: get,
|
||||
|
||||
login: login
|
||||
};
|
Loading…
Reference in New Issue
Block a user