Ghost/ghost/admin/tests/unit/controllers/post-settings-menu-test.js
Austin Burdine cf36851265 deps: grunt-jscs,ember-suave@3.0.0
replaces #41, #60
- update ember-suave and grunt-jscs to 3.0
- standardize Ember global de-structuring rules across app & tests
2016-06-11 13:39:31 -06:00

718 lines
27 KiB
JavaScript

/* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
import Ember from 'ember';
import {
describeModule,
it
} from 'ember-mocha';
import sinon from 'sinon';
const {
run,
Object: EmberObject,
RSVP
} = Ember;
function K() {
return this;
}
describeModule(
'controller:post-settings-menu',
'Unit: Controller: post-settings-menu',
{
needs: ['controller:application', 'service:notifications', 'service:slug-generator', 'service:timeZone']
},
function () {
it('slugValue is one-way bound to model.slug', function () {
let controller = this.subject({
model: EmberObject.create({
slug: 'a-slug'
})
});
expect(controller.get('model.slug')).to.equal('a-slug');
expect(controller.get('slugValue')).to.equal('a-slug');
run(function () {
controller.set('model.slug', 'changed-slug');
expect(controller.get('slugValue')).to.equal('changed-slug');
});
run(function () {
controller.set('slugValue', 'changed-directly');
expect(controller.get('model.slug')).to.equal('changed-slug');
expect(controller.get('slugValue')).to.equal('changed-directly');
});
run(function () {
// test that the one-way binding is still in place
controller.set('model.slug', 'should-update');
expect(controller.get('slugValue')).to.equal('should-update');
});
});
it('metaTitleScratch is one-way bound to model.metaTitle', function () {
let controller = this.subject({
model: EmberObject.create({
metaTitle: 'a title'
})
});
expect(controller.get('model.metaTitle')).to.equal('a title');
expect(controller.get('metaTitleScratch')).to.equal('a title');
run(function () {
controller.set('model.metaTitle', 'a different title');
expect(controller.get('metaTitleScratch')).to.equal('a different title');
});
run(function () {
controller.set('metaTitleScratch', 'changed directly');
expect(controller.get('model.metaTitle')).to.equal('a different title');
expect(controller.get('metaTitleScratch')).to.equal('changed directly');
});
run(function () {
// test that the one-way binding is still in place
controller.set('model.metaTitle', 'should update');
expect(controller.get('metaTitleScratch')).to.equal('should update');
});
});
it('metaDescriptionScratch is one-way bound to model.metaDescription', function () {
let controller = this.subject({
model: EmberObject.create({
metaDescription: 'a description'
})
});
expect(controller.get('model.metaDescription')).to.equal('a description');
expect(controller.get('metaDescriptionScratch')).to.equal('a description');
run(function () {
controller.set('model.metaDescription', 'a different description');
expect(controller.get('metaDescriptionScratch')).to.equal('a different description');
});
run(function () {
controller.set('metaDescriptionScratch', 'changed directly');
expect(controller.get('model.metaDescription')).to.equal('a different description');
expect(controller.get('metaDescriptionScratch')).to.equal('changed directly');
});
run(function () {
// test that the one-way binding is still in place
controller.set('model.metaDescription', 'should update');
expect(controller.get('metaDescriptionScratch')).to.equal('should update');
});
});
describe('seoTitle', function () {
it('should be the metaTitle if one exists', function () {
let controller = this.subject({
model: EmberObject.create({
metaTitle: 'a meta-title',
titleScratch: 'should not be used'
})
});
expect(controller.get('seoTitle')).to.equal('a meta-title');
});
it('should default to the title if an explicit meta-title does not exist', function () {
let controller = this.subject({
model: EmberObject.create({
titleScratch: 'should be the meta-title'
})
});
expect(controller.get('seoTitle')).to.equal('should be the meta-title');
});
it('should be the metaTitle if both title and metaTitle exist', function () {
let controller = this.subject({
model: EmberObject.create({
metaTitle: 'a meta-title',
titleScratch: 'a title'
})
});
expect(controller.get('seoTitle')).to.equal('a meta-title');
});
it('should revert to the title if explicit metaTitle is removed', function () {
let controller = this.subject({
model: EmberObject.create({
metaTitle: 'a meta-title',
titleScratch: 'a title'
})
});
expect(controller.get('seoTitle')).to.equal('a meta-title');
run(function () {
controller.set('model.metaTitle', '');
expect(controller.get('seoTitle')).to.equal('a title');
});
});
it('should truncate to 70 characters with an appended ellipsis', function () {
let longTitle = new Array(100).join('a');
let controller = this.subject({
model: EmberObject.create()
});
expect(longTitle.length).to.equal(99);
run(function () {
let expected = `${longTitle.substr(0, 70)}…`;
controller.set('metaTitleScratch', longTitle);
expect(controller.get('seoTitle').toString().length).to.equal(78);
expect(controller.get('seoTitle').toString()).to.equal(expected);
});
});
});
describe('seoDescription', function () {
it('should be the metaDescription if one exists', function () {
let controller = this.subject({
model: EmberObject.create({
metaDescription: 'a description'
})
});
expect(controller.get('seoDescription')).to.equal('a description');
});
it.skip('should be generated from the rendered markdown if not explicitly set', function () {
// can't test right now because the rendered markdown is being pulled
// from the DOM via jquery
});
it('should truncate to 156 characters with an appended ellipsis', function () {
let longDescription = new Array(200).join('a');
let controller = this.subject({
model: EmberObject.create()
});
expect(longDescription.length).to.equal(199);
run(function () {
let expected = `${longDescription.substr(0, 156)}…`;
controller.set('metaDescriptionScratch', longDescription);
expect(controller.get('seoDescription').toString().length).to.equal(164);
expect(controller.get('seoDescription').toString()).to.equal(expected);
});
});
});
describe('seoURL', function () {
it('should be the URL of the blog if no post slug exists', function () {
let controller = this.subject({
config: EmberObject.create({blogUrl: 'http://my-ghost-blog.com'}),
model: EmberObject.create()
});
expect(controller.get('seoURL')).to.equal('http://my-ghost-blog.com/');
});
it('should be the URL of the blog plus the post slug', function () {
let controller = this.subject({
config: EmberObject.create({blogUrl: 'http://my-ghost-blog.com'}),
model: EmberObject.create({slug: 'post-slug'})
});
expect(controller.get('seoURL')).to.equal('http://my-ghost-blog.com/post-slug/');
});
it('should update when the post slug changes', function () {
let controller = this.subject({
config: EmberObject.create({blogUrl: 'http://my-ghost-blog.com'}),
model: EmberObject.create({slug: 'post-slug'})
});
expect(controller.get('seoURL')).to.equal('http://my-ghost-blog.com/post-slug/');
run(function () {
controller.set('model.slug', 'changed-slug');
expect(controller.get('seoURL')).to.equal('http://my-ghost-blog.com/changed-slug/');
});
});
it('should truncate a long URL to 70 characters with an appended ellipsis', function () {
let blogURL = 'http://my-ghost-blog.com';
let longSlug = new Array(75).join('a');
let controller = this.subject({
config: EmberObject.create({blogUrl: blogURL}),
model: EmberObject.create({slug: longSlug})
});
let expected;
expect(longSlug.length).to.equal(74);
expected = `${blogURL}/${longSlug}/`;
expected = `${expected.substr(0, 70)}…`;
expect(controller.get('seoURL').toString().length).to.equal(78);
expect(controller.get('seoURL').toString()).to.equal(expected);
});
});
describe('togglePage', function () {
it('should toggle the page property', function () {
let controller = this.subject({
model: EmberObject.create({
page: false,
isNew: true
})
});
expect(controller.get('model.page')).to.not.be.ok;
run(function () {
controller.send('togglePage');
expect(controller.get('model.page')).to.be.ok;
});
});
it('should not save the post if it is still new', function () {
let controller = this.subject({
model: EmberObject.create({
page: false,
isNew: true,
save() {
this.incrementProperty('saved');
return RSVP.resolve();
}
})
});
run(function () {
controller.send('togglePage');
expect(controller.get('model.page')).to.be.ok;
expect(controller.get('model.saved')).to.not.be.ok;
});
});
it('should save the post if it is not new', function () {
let controller = this.subject({
model: EmberObject.create({
page: false,
isNew: false,
save() {
this.incrementProperty('saved');
return RSVP.resolve();
}
})
});
run(function () {
controller.send('togglePage');
expect(controller.get('model.page')).to.be.ok;
expect(controller.get('model.saved')).to.equal(1);
});
});
});
describe('toggleFeatured', function () {
it('should toggle the featured property', function () {
let controller = this.subject({
model: EmberObject.create({
featured: false,
isNew: true
})
});
run(function () {
controller.send('toggleFeatured');
expect(controller.get('model.featured')).to.be.ok;
});
});
it('should not save the post if it is still new', function () {
let controller = this.subject({
model: EmberObject.create({
featured: false,
isNew: true,
save() {
this.incrementProperty('saved');
return RSVP.resolve();
}
})
});
run(function () {
controller.send('toggleFeatured');
expect(controller.get('model.featured')).to.be.ok;
expect(controller.get('model.saved')).to.not.be.ok;
});
});
it('should save the post if it is not new', function () {
let controller = this.subject({
model: EmberObject.create({
featured: false,
isNew: false,
save() {
this.incrementProperty('saved');
return RSVP.resolve();
}
})
});
run(function () {
controller.send('toggleFeatured');
expect(controller.get('model.featured')).to.be.ok;
expect(controller.get('model.saved')).to.equal(1);
});
});
});
describe('generateAndSetSlug', function () {
it('should generate a slug and set it on the destination', function (done) {
let controller = this.subject({
slugGenerator: EmberObject.create({
generateSlug(slugType, str) {
return RSVP.resolve(`${str}-slug`);
}
}),
model: EmberObject.create({slug: ''})
});
run(function () {
controller.set('model.titleScratch', 'title');
controller.generateAndSetSlug('model.slug');
expect(controller.get('model.slug')).to.equal('');
RSVP.resolve(controller.get('lastPromise')).then(function () {
expect(controller.get('model.slug')).to.equal('title-slug');
done();
}).catch(done);
});
});
it('should not set the destination if the title is "(Untitled)" and the post already has a slug', function (done) {
let controller = this.subject({
slugGenerator: EmberObject.create({
generateSlug(slugType, str) {
return RSVP.resolve(`${str}-slug`);
}
}),
model: EmberObject.create({
slug: 'whatever'
})
});
expect(controller.get('model.slug')).to.equal('whatever');
run(function () {
controller.set('model.titleScratch', 'title');
RSVP.resolve(controller.get('lastPromise')).then(function () {
expect(controller.get('model.slug')).to.equal('whatever');
done();
}).catch(done);
});
});
});
describe('titleObserver', function () {
it('should invoke generateAndSetSlug if the post is new and a title has not been set', function (done) {
let controller = this.subject({
model: EmberObject.create({isNew: true}),
invoked: 0,
generateAndSetSlug() {
this.incrementProperty('invoked');
}
});
expect(controller.get('invoked')).to.equal(0);
expect(controller.get('model.title')).to.not.be.ok;
run(function () {
controller.set('model.titleScratch', 'test');
controller.titleObserver();
// since titleObserver invokes generateAndSetSlug with a delay of 700ms
// we need to make sure this assertion runs after that.
// probably a better way to handle this?
run.later(function () {
expect(controller.get('invoked')).to.equal(1);
done();
}, 800);
});
});
it('should invoke generateAndSetSlug if the post title is "(Untitled)"', function (done) {
let controller = this.subject({
model: EmberObject.create({
isNew: false,
title: '(Untitled)'
}),
invoked: 0,
generateAndSetSlug() {
this.incrementProperty('invoked');
}
});
expect(controller.get('invoked')).to.equal(0);
expect(controller.get('model.title')).to.equal('(Untitled)');
run(function () {
controller.set('model.titleScratch', 'test');
controller.titleObserver();
// since titleObserver invokes generateAndSetSlug with a delay of 700ms
// we need to make sure this assertion runs after that.
// probably a better way to handle this?
run.later(function () {
expect(controller.get('invoked')).to.equal(1);
done();
}, 800);
});
});
it('should not invoke generateAndSetSlug if the post is new but has a title', function (done) {
let controller = this.subject({
model: EmberObject.create({
isNew: true,
title: 'a title'
}),
invoked: 0,
generateAndSetSlug() {
this.incrementProperty('invoked');
}
});
expect(controller.get('invoked')).to.equal(0);
expect(controller.get('model.title')).to.equal('a title');
run(function () {
controller.set('model.titleScratch', 'test');
controller.titleObserver();
// since titleObserver invokes generateAndSetSlug with a delay of 700ms
// we need to make sure this assertion runs after that.
// probably a better way to handle this?
run.later(function () {
expect(controller.get('invoked')).to.equal(0);
done();
}, 800);
});
});
});
describe('updateSlug', function () {
it('should reset slugValue to the previous slug when the new slug is blank or unchanged', function () {
let controller = this.subject({
model: EmberObject.create({
slug: 'slug'
})
});
run(function () {
// unchanged
controller.set('slugValue', 'slug');
controller.send('updateSlug', controller.get('slugValue'));
expect(controller.get('model.slug')).to.equal('slug');
expect(controller.get('slugValue')).to.equal('slug');
});
run(function () {
// unchanged after trim
controller.set('slugValue', 'slug ');
controller.send('updateSlug', controller.get('slugValue'));
expect(controller.get('model.slug')).to.equal('slug');
expect(controller.get('slugValue')).to.equal('slug');
});
run(function () {
// blank
controller.set('slugValue', '');
controller.send('updateSlug', controller.get('slugValue'));
expect(controller.get('model.slug')).to.equal('slug');
expect(controller.get('slugValue')).to.equal('slug');
});
});
it('should not set a new slug if the server-generated slug matches existing slug', function (done) {
let controller = this.subject({
slugGenerator: EmberObject.create({
generateSlug(slugType, str) {
let promise = RSVP.resolve(str.split('#')[0]);
this.set('lastPromise', promise);
return promise;
}
}),
model: EmberObject.create({
slug: 'whatever'
})
});
run(function () {
controller.set('slugValue', 'whatever#slug');
controller.send('updateSlug', controller.get('slugValue'));
RSVP.resolve(controller.get('lastPromise')).then(function () {
expect(controller.get('model.slug')).to.equal('whatever');
done();
}).catch(done);
});
});
it('should not set a new slug if the only change is to the appended increment value', function (done) {
let controller = this.subject({
slugGenerator: EmberObject.create({
generateSlug(slugType, str) {
let sanitizedStr = str.replace(/[^a-zA-Z]/g, '');
let promise = RSVP.resolve(`${sanitizedStr}-2`);
this.set('lastPromise', promise);
return promise;
}
}),
model: EmberObject.create({
slug: 'whatever'
})
});
run(function () {
controller.set('slugValue', 'whatever!');
controller.send('updateSlug', controller.get('slugValue'));
RSVP.resolve(controller.get('lastPromise')).then(function () {
expect(controller.get('model.slug')).to.equal('whatever');
done();
}).catch(done);
});
});
it('should set the slug if the new slug is different', function (done) {
let controller = this.subject({
slugGenerator: EmberObject.create({
generateSlug(slugType, str) {
let promise = RSVP.resolve(str);
this.set('lastPromise', promise);
return promise;
}
}),
model: EmberObject.create({
slug: 'whatever',
save: K
})
});
run(function () {
controller.set('slugValue', 'changed');
controller.send('updateSlug', controller.get('slugValue'));
RSVP.resolve(controller.get('lastPromise')).then(function () {
expect(controller.get('model.slug')).to.equal('changed');
done();
}).catch(done);
});
});
it('should save the post when the slug changes and the post is not new', function (done) {
let controller = this.subject({
slugGenerator: EmberObject.create({
generateSlug(slugType, str) {
let promise = RSVP.resolve(str);
this.set('lastPromise', promise);
return promise;
}
}),
model: EmberObject.create({
slug: 'whatever',
saved: 0,
isNew: false,
save() {
this.incrementProperty('saved');
}
})
});
run(function () {
controller.set('slugValue', 'changed');
controller.send('updateSlug', controller.get('slugValue'));
RSVP.resolve(controller.get('lastPromise')).then(function () {
expect(controller.get('model.slug')).to.equal('changed');
expect(controller.get('model.saved')).to.equal(1);
done();
}).catch(done);
});
});
it('should not save the post when the slug changes and the post is new', function (done) {
let controller = this.subject({
slugGenerator: EmberObject.create({
generateSlug(slugType, str) {
let promise = RSVP.resolve(str);
this.set('lastPromise', promise);
return promise;
}
}),
model: EmberObject.create({
slug: 'whatever',
saved: 0,
isNew: true,
save() {
this.incrementProperty('saved');
}
})
});
run(function () {
controller.set('slugValue', 'changed');
controller.send('updateSlug', controller.get('slugValue'));
RSVP.resolve(controller.get('lastPromise')).then(function () {
expect(controller.get('model.slug')).to.equal('changed');
expect(controller.get('model.saved')).to.equal(0);
done();
}).catch(done);
});
});
});
}
);