mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-04-15 03:01:37 -05:00
Prevent editor title from being overwritten
Closes #3955 - Change titleScratch from being bound to the title to being set when entering the editor so it is not overwritten on a model refresh. - Ensure that the "unsaved content" dialog is shown when there are changes to the "scratch" fields after a post-settings-menu change. - Add tests to prevent regression.
This commit is contained in:
parent
af7743f935
commit
1d6b1f9667
4 changed files with 111 additions and 4 deletions
core
client
test/functional/client
|
@ -5,7 +5,7 @@ import boundOneWay from 'ghost/utils/bound-one-way';
|
|||
|
||||
// this array will hold properties we need to watch
|
||||
// to know if the model has been changed (`controller.isDirty`)
|
||||
var watchedProps = ['scratch', 'model.isDirty'];
|
||||
var watchedProps = ['scratch', 'titleScratch', 'model.isDirty'];
|
||||
|
||||
Ember.get(PostModel, 'attributes').forEach(function (name) {
|
||||
watchedProps.push('model.' + name);
|
||||
|
@ -76,7 +76,14 @@ var EditorControllerMixin = Ember.Mixin.create(MarkerManager, {
|
|||
|
||||
// `updateTags` triggers `isDirty => true`.
|
||||
// for a saved model it would otherwise be false.
|
||||
this.set('isDirty', false);
|
||||
|
||||
// if the two "scratch" properties (title and content) match the model, then
|
||||
// it's ok to set isDirty to false
|
||||
if (this.get('titleScratch') === model.get('title') &&
|
||||
this.get('scratch') === model.get('markdown')) {
|
||||
|
||||
this.set('isDirty', false);
|
||||
}
|
||||
},
|
||||
|
||||
// an ugly hack, but necessary to watch all the model's properties
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import ValidationEngine from 'ghost/mixins/validation-engine';
|
||||
import boundOneWay from 'ghost/utils/bound-one-way';
|
||||
import NProgressSaveMixin from 'ghost/mixins/nprogress-save';
|
||||
|
||||
var Post = DS.Model.extend(NProgressSaveMixin, ValidationEngine, {
|
||||
|
@ -23,7 +22,6 @@ var Post = DS.Model.extend(NProgressSaveMixin, ValidationEngine, {
|
|||
published_at: DS.attr('moment-date'),
|
||||
published_by: DS.belongsTo('user', { async: true }),
|
||||
tags: DS.hasMany('tag', { embedded: 'always' }),
|
||||
titleScratch: boundOneWay('title'),
|
||||
//## Computed post properties
|
||||
isPublished: Ember.computed.equal('status', 'published'),
|
||||
isDraft: Ember.computed.equal('status', 'draft'),
|
||||
|
|
|
@ -55,7 +55,11 @@ var EditorEditRoute = Ember.Route.extend(SimpleAuth.AuthenticatedRouteMixin, bas
|
|||
|
||||
setupController: function (controller, model) {
|
||||
this._super(controller, model);
|
||||
|
||||
controller.set('scratch', model.get('markdown'));
|
||||
|
||||
controller.set('titleScratch', model.get('title'));
|
||||
|
||||
// used to check if anything has changed in the editor
|
||||
controller.set('previousTagNames', model.get('tags').mapBy('name'));
|
||||
|
||||
|
|
|
@ -542,3 +542,101 @@ CasperTest.begin('Markdown help modal', 5, function suite(test) {
|
|||
test.assert(true, 'clicking close should remove the markdown help modal');
|
||||
});
|
||||
});
|
||||
|
||||
// test editor title input is correct after changing a post attribute in the post-settings-menu
|
||||
CasperTest.begin('Title input is set correctly after using the Post-Settings-Menu', function suite(test) {
|
||||
casper.thenOpenAndWaitForPageLoad('editor', function testTitleAndUrl() {
|
||||
test.assertTitle('Ghost Admin', 'Ghost admin has no title');
|
||||
test.assertUrlMatch(/ghost\/editor\/$/, 'Landed on the correct URL');
|
||||
});
|
||||
|
||||
// add a new post
|
||||
casper.then(function fillContent() {
|
||||
casper.sendKeys('#entry-title', 'post title');
|
||||
casper.writeContentToCodeMirror('Just a bit of test text');
|
||||
});
|
||||
|
||||
// save draft
|
||||
casper.thenClick('.js-publish-button');
|
||||
|
||||
casper.waitForSelector('.notification-success');
|
||||
|
||||
// change the title
|
||||
casper.then(function updateTitle() {
|
||||
casper.sendKeys('#entry-title', 'changed post title');
|
||||
casper.click('#entry-markdown-content');
|
||||
});
|
||||
|
||||
// change a post attribute via the post-settings-menu
|
||||
|
||||
casper.thenClick('.post-settings');
|
||||
casper.waitForOpaque('.post-settings-menu.open');
|
||||
|
||||
casper.then(function () {
|
||||
this.fillSelectors('.post-settings-menu form', {
|
||||
'#url': 'changed-slug'
|
||||
}, false);
|
||||
|
||||
this.click('.post-settings');
|
||||
});
|
||||
|
||||
casper.waitForResource(/\/posts\/\d+\/\?include=tags/, function testGoodResponse(resource) {
|
||||
test.assert(400 > resource.status);
|
||||
});
|
||||
|
||||
casper.then(function checkTitleInput() {
|
||||
test.assertEvalEquals(function () {
|
||||
return $('#entry-title').val();
|
||||
}, 'changed post title', 'Title input should match expected value.');
|
||||
});
|
||||
});
|
||||
|
||||
// test editor content input is correct after changing a post attribute in the post-settings-menu
|
||||
CasperTest.begin('Editor content is set correctly after using the Post-Settings-Menu', function suite(test) {
|
||||
casper.thenOpenAndWaitForPageLoad('editor', function testTitleAndUrl() {
|
||||
test.assertTitle('Ghost Admin', 'Ghost admin has no title');
|
||||
test.assertUrlMatch(/ghost\/editor\/$/, 'Landed on the correct URL');
|
||||
});
|
||||
|
||||
// add a new post
|
||||
casper.then(function fillContent() {
|
||||
casper.sendKeys('#entry-title', 'post title');
|
||||
casper.writeContentToCodeMirror('Just a bit of test text');
|
||||
});
|
||||
|
||||
// save draft
|
||||
casper.thenClick('.js-publish-button');
|
||||
|
||||
casper.waitForSelector('.notification-success');
|
||||
|
||||
// change the content
|
||||
casper.then(function updateContent() {
|
||||
casper.writeContentToCodeMirror('updated content');
|
||||
casper.click('#entry-title');
|
||||
});
|
||||
|
||||
// change a post attribute via the post-settings-menu
|
||||
|
||||
casper.thenClick('.post-settings');
|
||||
casper.waitForOpaque('.post-settings-menu.open');
|
||||
|
||||
casper.then(function () {
|
||||
this.fillSelectors('.post-settings-menu form', {
|
||||
'#url': 'changed-slug-after-update'
|
||||
}, false);
|
||||
|
||||
this.click('.post-settings');
|
||||
});
|
||||
|
||||
casper.waitForResource(/\/posts\/\d+\/\?include=tags/, function testGoodResponse(resource) {
|
||||
test.assert(400 > resource.status);
|
||||
});
|
||||
|
||||
casper.waitForSelectorTextChange('.entry-preview .rendered-markdown', function onSuccess() {
|
||||
test.assertSelectorHasText(
|
||||
'.entry-preview .rendered-markdown',
|
||||
'updated content',
|
||||
'Editor has correct content.'
|
||||
);
|
||||
}, casper.failOnTimeout(test, 'markdown was not available'));
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue