From 8fcd75de32a38cbf060c291c8a445fa5915bbe6e Mon Sep 17 00:00:00 2001 From: Moritz Schramm Date: Mon, 21 Jan 2019 12:44:30 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=A8=20Added=20post=20title=20to=20docu?= =?UTF-8?q?ment=20title=20for=20easier=20location=20with=20multiple=20edit?= =?UTF-8?q?or=20tabs=20(#1072)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closes https://github.com/tryghost/ghost/issues/10088 * added `updateDocumentTitle` action to base route and replace usage of `.send('collectTitleTokens, [])` * added `.titleToken()` method to editor route to add post title to document title * called `.send('updateDocumentTitle')` after saving post title in editor controller to keep document title in sync * updated editor controller test for latest ember-mocha and ember-test-helpers --- ghost/admin/app/controllers/editor.js | 2 + .../admin/app/controllers/settings/general.js | 2 +- ghost/admin/app/routes/editor.js | 5 +- ghost/admin/app/utils/document-title.js | 6 +- .../tests/unit/controllers/editor-test.js | 201 +++++++----------- 5 files changed, 89 insertions(+), 127 deletions(-) diff --git a/ghost/admin/app/controllers/editor.js b/ghost/admin/app/controllers/editor.js index d40b478a01..4536a6cd5a 100644 --- a/ghost/admin/app/controllers/editor.js +++ b/ghost/admin/app/controllers/editor.js @@ -474,6 +474,8 @@ export default Controller.extend({ if (this.get('post.isDraft')) { yield this.get('autosave').perform(); } + + this.send('updateDocumentTitle'); }), generateSlug: task(function* () { diff --git a/ghost/admin/app/controllers/settings/general.js b/ghost/admin/app/controllers/settings/general.js index da16652b5c..626c7d7864 100644 --- a/ghost/admin/app/controllers/settings/general.js +++ b/ghost/admin/app/controllers/settings/general.js @@ -274,7 +274,7 @@ export default Controller.extend({ // this forces the document title to recompute after // a blog title change - this.send('collectTitleTokens', []); + this.send('updateDocumentTitle'); return settings; } catch (error) { diff --git a/ghost/admin/app/routes/editor.js b/ghost/admin/app/routes/editor.js index 8b44390943..917856b9d5 100644 --- a/ghost/admin/app/routes/editor.js +++ b/ghost/admin/app/routes/editor.js @@ -17,7 +17,6 @@ export default AuthenticatedRoute.extend(ShortcutsRoute, { classNames: ['editor'], shortcuts: generalShortcuts, - titleToken: 'Editor', activate() { this._super(...arguments); @@ -82,6 +81,10 @@ export default AuthenticatedRoute.extend(ShortcutsRoute, { } }, + titleToken() { + return this.get('controller.post.title') || 'Editor'; + }, + _blurAndScheduleAction(func) { let selectedElement = $(document.activeElement); diff --git a/ghost/admin/app/utils/document-title.js b/ghost/admin/app/utils/document-title.js index 0f12405902..abfbb5b8c1 100644 --- a/ghost/admin/app/utils/document-title.js +++ b/ghost/admin/app/utils/document-title.js @@ -18,6 +18,10 @@ export default function () { title: null, actions: { + updateDocumentTitle() { + this.send('collectTitleTokens', []); + }, + collectTitleTokens(tokens) { let {titleToken} = this; let finalTitle; @@ -49,7 +53,7 @@ export default function () { Router.reopen({ updateTitle: on('didTransition', function () { - this.send('collectTitleTokens', []); + this.send('updateDocumentTitle'); }) }); } diff --git a/ghost/admin/tests/unit/controllers/editor-test.js b/ghost/admin/tests/unit/controllers/editor-test.js index bd628c6615..d3b00a8476 100644 --- a/ghost/admin/tests/unit/controllers/editor-test.js +++ b/ghost/admin/tests/unit/controllers/editor-test.js @@ -1,190 +1,143 @@ import EmberObject from '@ember/object'; import RSVP from 'rsvp'; -import wait from 'ember-test-helpers/wait'; import {describe, it} from 'mocha'; import {expect} from 'chai'; -import {run} from '@ember/runloop'; +import {settled} from '@ember/test-helpers'; import {setupTest} from 'ember-mocha'; import {task} from 'ember-concurrency'; describe('Unit: Controller: editor', function () { - setupTest('controller:editor', { - needs: [ - 'controller:application', - 'service:feature', - 'service:notifications', - // 'service:router', - 'service:slugGenerator', - 'service:session', - 'service:ui' - ] - }); + setupTest(); describe('generateSlug', function () { - it('should generate a slug and set it on the post', function (done) { - run(() => { - let controller = this.subject(); + it('should generate a slug and set it on the post', async function () { + let controller = this.owner.lookup('controller:editor'); - controller.set('slugGenerator', EmberObject.create({ - generateSlug(slugType, str) { - return RSVP.resolve(`${str}-slug`); - } - })); - controller.set('post', EmberObject.create({slug: ''})); + controller.set('slugGenerator', EmberObject.create({ + generateSlug(slugType, str) { + return RSVP.resolve(`${str}-slug`); + } + })); + controller.set('post', EmberObject.create({slug: ''})); - controller.set('post.titleScratch', 'title'); + controller.set('post.titleScratch', 'title'); + await settled(); - expect(controller.get('post.slug')).to.equal(''); + expect(controller.get('post.slug')).to.equal(''); - run(() => { - controller.get('generateSlug').perform(); - }); + await controller.get('generateSlug').perform(); - wait().then(() => { - expect(controller.get('post.slug')).to.equal('title-slug'); - done(); - }); - }); + expect(controller.get('post.slug')).to.equal('title-slug'); }); - it('should not set the destination if the title is "(Untitled)" and the post already has a slug', function (done) { - let controller = this.subject(); + it('should not set the destination if the title is "(Untitled)" and the post already has a slug', async function () { + let controller = this.owner.lookup('controller:editor'); - run(() => { - controller.set('slugGenerator', EmberObject.create({ - generateSlug(slugType, str) { - return RSVP.resolve(`${str}-slug`); - } - })); - controller.set('post', EmberObject.create({slug: 'whatever'})); - }); + controller.set('slugGenerator', EmberObject.create({ + generateSlug(slugType, str) { + return RSVP.resolve(`${str}-slug`); + } + })); + controller.set('post', EmberObject.create({slug: 'whatever'})); expect(controller.get('post.slug')).to.equal('whatever'); controller.set('post.titleScratch', '(Untitled)'); + await controller.get('generateSlug').perform(); - run(() => { - controller.get('generateSlug').perform(); - }); - - wait().then(() => { - expect(controller.get('post.slug')).to.equal('whatever'); - done(); - }); + expect(controller.get('post.slug')).to.equal('whatever'); }); }); describe('saveTitle', function () { - it('should invoke generateSlug if the post is new and a title has not been set', function (done) { - let controller = this.subject(); + beforeEach(function () { + this.controller = this.owner.lookup('controller:editor'); + this.controller.set('target', {send() {}}); + }); - run(() => { - controller.set('generateSlug', task(function * () { - this.set('post.slug', 'test-slug'); - yield RSVP.resolve(); - })); - controller.set('post', EmberObject.create({isNew: true})); - }); + it('should invoke generateSlug if the post is new and a title has not been set', async function () { + let {controller} = this; + + controller.set('target', {send() {}}); + controller.set('generateSlug', task(function * () { + this.set('post.slug', 'test-slug'); + yield RSVP.resolve(); + })); + controller.set('post', EmberObject.create({isNew: true})); expect(controller.get('post.isNew')).to.be.true; expect(controller.get('post.titleScratch')).to.not.be.ok; controller.set('post.titleScratch', 'test'); + await controller.get('saveTitle').perform(); - run(() => { - controller.get('saveTitle').perform(); - }); - - wait().then(() => { - expect(controller.get('post.titleScratch')).to.equal('test'); - expect(controller.get('post.slug')).to.equal('test-slug'); - done(); - }); + expect(controller.get('post.titleScratch')).to.equal('test'); + expect(controller.get('post.slug')).to.equal('test-slug'); }); - it('should invoke generateSlug if the post is not new and it\'s title is "(Untitled)"', function (done) { - let controller = this.subject(); + it('should invoke generateSlug if the post is not new and it\'s title is "(Untitled)"', async function () { + let {controller} = this; - run(() => { - controller.set('generateSlug', task(function * () { - this.set('post.slug', 'test-slug'); - yield RSVP.resolve(); - })); - controller.set('post', EmberObject.create({isNew: false, title: '(Untitled)'})); - }); + controller.set('target', {send() {}}); + controller.set('generateSlug', task(function * () { + this.set('post.slug', 'test-slug'); + yield RSVP.resolve(); + })); + controller.set('post', EmberObject.create({isNew: false, title: '(Untitled)'})); expect(controller.get('post.isNew')).to.be.false; expect(controller.get('post.titleScratch')).to.not.be.ok; controller.set('post.titleScratch', 'New Title'); - run(() => { - controller.get('saveTitle').perform(); - }); + await controller.get('saveTitle').perform(); - wait().then(() => { - expect(controller.get('post.titleScratch')).to.equal('New Title'); - expect(controller.get('post.slug')).to.equal('test-slug'); - done(); - }); + expect(controller.get('post.titleScratch')).to.equal('New Title'); + expect(controller.get('post.slug')).to.equal('test-slug'); }); - it('should not invoke generateSlug if the post is new but has a title', function (done) { - let controller = this.subject(); + it('should not invoke generateSlug if the post is new but has a title', async function () { + let {controller} = this; - run(() => { - controller.set('generateSlug', task(function * () { - expect(false, 'generateSlug should not be called').to.equal(true); - yield RSVP.resolve(); - })); - controller.set('post', EmberObject.create({ - isNew: true, - title: 'a title' - })); - }); + controller.set('target', {send() {}}); + controller.set('generateSlug', task(function * () { + expect(false, 'generateSlug should not be called').to.equal(true); + yield RSVP.resolve(); + })); + controller.set('post', EmberObject.create({ + isNew: true, + title: 'a title' + })); expect(controller.get('post.isNew')).to.be.true; expect(controller.get('post.title')).to.equal('a title'); expect(controller.get('post.titleScratch')).to.not.be.ok; controller.set('post.titleScratch', 'test'); + await controller.get('saveTitle').perform(); - run(() => { - controller.get('saveTitle').perform(); - }); - - wait().then(() => { - expect(controller.get('post.titleScratch')).to.equal('test'); - expect(controller.get('post.slug')).to.not.be.ok; - done(); - }); + expect(controller.get('post.titleScratch')).to.equal('test'); + expect(controller.get('post.slug')).to.not.be.ok; }); - it('should not invoke generateSlug if the post is not new and the title is not "(Untitled)"', function (done) { - let controller = this.subject(); + it('should not invoke generateSlug if the post is not new and the title is not "(Untitled)"', async function () { + let {controller} = this; - run(() => { - controller.set('generateSlug', task(function * () { - expect(false, 'generateSlug should not be called').to.equal(true); - yield RSVP.resolve(); - })); - controller.set('post', EmberObject.create({isNew: false})); - }); + controller.set('target', {send() {}}); + controller.set('generateSlug', task(function * () { + expect(false, 'generateSlug should not be called').to.equal(true); + yield RSVP.resolve(); + })); + controller.set('post', EmberObject.create({isNew: false})); expect(controller.get('post.isNew')).to.be.false; expect(controller.get('post.title')).to.not.be.ok; controller.set('post.titleScratch', 'title'); + await controller.get('saveTitle').perform(); - run(() => { - controller.get('saveTitle').perform(); - }); - - wait().then(() => { - expect(controller.get('post.titleScratch')).to.equal('title'); - expect(controller.get('post.slug')).to.not.be.ok; - done(); - }); + expect(controller.get('post.titleScratch')).to.equal('title'); + expect(controller.get('post.slug')).to.not.be.ok; }); }); });