0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-03-11 02:12:21 -05:00

New posts pass PostsController sorting function at the top

- PostsController orderBy function sorts posts with isNew to the top, otherwise their undefined dates fail to compare
- also catch when `updated_at` is undefined, happens when model is being written with results from the server
- catch objects of type Error in validation engine, helps catching client errors
- join server errors with BR tag in ajax util
- add `emberBuild` task to `grunt test-functional`
- add a test helper, `thenTransitionAndWaitForScreenLoad`, to test transitioning to major parts of the app
- add a test that transitions from Content to the Editor, and back to Content
This commit is contained in:
David Arvelo 2014-06-27 23:50:31 -04:00
parent 7eab416d01
commit a958a66c4c
6 changed files with 79 additions and 6 deletions

View file

@ -807,7 +807,7 @@ var path = require('path'),
// The purpose of the functional tests is to ensure that Ghost is working as is expected from a user perspective
// including buttons and other important interactions in the admin UI.
grunt.registerTask('test-functional', 'Run functional interface tests (CasperJS)',
['clean:test', 'setTestEnv', 'loadConfig', 'copy:dev', 'express:test', 'spawnCasperJS', 'express:test:stop']
['clean:test', 'emberBuild', 'setTestEnv', 'loadConfig', 'copy:dev', 'express:test', 'spawnCasperJS', 'express:test:stop']
);
// ### Coverage

View file

@ -15,7 +15,6 @@ var PostsController = Ember.ArrayController.extend({
// published_at: DESC
// updated_at: DESC
orderBy: function (item1, item2) {
function publishedAtCompare() {
var published1 = item1.get('published_at'),
published2 = item2.get('published_at');
@ -35,9 +34,25 @@ var PostsController = Ember.ArrayController.extend({
return Ember.compare(item1.get('published_at').valueOf(), item2.get('published_at').valueOf());
}
var statusResult = Ember.compare(item1.get('status'), item2.get('status')),
updatedAtResult = Ember.compare(item1.get('updated_at').valueOf(), item2.get('updated_at').valueOf()),
publishedAtResult = publishedAtCompare();
var updated1 = item1.get('updated_at'),
updated2 = item2.get('updated_at'),
statusResult,
updatedAtResult,
publishedAtResult;
// when `updated_at` is undefined, the model is still
// being written to with the results from the server
if (item1.get('isNew') || !updated1) {
return -1;
}
if (item2.get('isNew') || !updated2) {
return 1;
}
statusResult = Ember.compare(item1.get('status'), item2.get('status'));
updatedAtResult = Ember.compare(updated1.valueOf(), updated2.valueOf());
publishedAtResult = publishedAtCompare();
if (statusResult === 0) {
if (publishedAtResult === 0) {

View file

@ -54,6 +54,9 @@ var ValidationEngine = Ember.Mixin.create({
if (Ember.isArray(errors)) {
// get validation error messages
message = errors.mapBy('message').join('<br />');
} else if (errors instanceof Error) {
// we got some kind of error in Ember
message += ': ' + errors.message;
} else if (typeof errors === 'object') {
// Get messages from server response
message += ': ' + getRequestErrorMessage(errors);

View file

@ -26,7 +26,7 @@ var getRequestErrorMessage = function (request) {
message = request.responseJSON.errors.map(function (errorItem) {
return errorItem.message;
}).join('; ');
}).join('<br />');
} else {
message = request.responseJSON.error || 'Unknown Error';
}

View file

@ -151,6 +151,44 @@ casper.thenOpenAndWaitForPageLoad = function (screen, then, timeout) {
});
};
casper.thenTransitionAndWaitForScreenLoad = function (screen, then, timeout) {
then = then || function () {};
timeout = timeout || casper.failOnTimeout(casper.test, 'Unable to load ' + screen);
var screens = {
'root': {
linkSelector: '#main-menu > li.content a',
selector: '#main-menu .content.active'
},
'content': {
linkSelector: '#main-menu > li.content a',
selector: '#main-menu .content.active'
},
'editor': {
linkSelector: '#main-menu > li.editor a',
selector: '#entry-title'
},
'settings': {
linkSelector: '#main-menu > li.settings a',
selector: '.settings-content'
},
'settings.user': {
linkSelector: '#user-menu li.usermenu-profile a',
selector: '.settings-content .settings-user'
},
'signout': {
linkSelector: '#user-menu li.usermenu-signout a',
// When no user exists we get redirected to setup which has button-add
selector: '.button-save, .button-add'
},
};
return casper.thenClick(screens[screen].linkSelector).then(function () {
// Some screens fade in
return casper.waitForOpaque(screens[screen].selector, then, timeout, 10000);
});
};
casper.failOnTimeout = function (test, message) {
return function onTimeout() {
test.fail(message);

View file

@ -65,3 +65,20 @@ CasperTest.begin('Admin navigation bar is correct', 28, function suite(test) {
test.assertEquals(signoutHref, '/ghost/ember/signout/', 'Sign Out href is correct');
}, casper.failOnTimeout(test, 'WaitForSelector #usermenu ul.overlay failed'));
});
CasperTest.begin('Can transition to the editor and back', 6, function suite(test) {
casper.thenOpenAndWaitForPageLoad('root', function testTitleAndUrl() {
test.assertTitle('Ghost Admin', 'Ghost admin has no title');
test.assertUrlMatch(/ghost\/ember\/\d+\/$/, 'Landed on the correct URL');
});
casper.thenTransitionAndWaitForScreenLoad('editor', function testTransitionToEditor() {
test.assertUrlMatch(/ghost\/ember\/editor\/$/, 'Landed on the correct URL');
test.assertExists('.entry-markdown', 'Ghost editor is present');
test.assertExists('.entry-preview', 'Ghost preview is present');
});
casper.thenTransitionAndWaitForScreenLoad('content', function testTransitionToContent() {
test.assertUrlMatch(/ghost\/ember\/\d+\/$/, 'Landed on the correct URL');
});
});