refactor slug-generator object into a service

refs #6243
This commit is contained in:
Austin Burdine 2016-01-15 09:43:16 -06:00
parent 749bd29e12
commit 4862a9051c
6 changed files with 100 additions and 65 deletions

View File

@ -1,7 +1,6 @@
import Ember from 'ember';
import {parseDateString} from 'ghost/utils/date-formatting';
import SettingsMenuMixin from 'ghost/mixins/settings-menu-controller';
import SlugGenerator from 'ghost/models/slug-generator';
import boundOneWay from 'ghost/utils/bound-one-way';
import isNumber from 'ghost/utils/isNumber';
@ -18,6 +17,7 @@ export default Controller.extend(SettingsMenuMixin, {
ghostPaths: inject.service('ghost-paths'),
notifications: inject.service(),
session: inject.service(),
slugGenerator: inject.service('slug-generator'),
initializeSelectedAuthor: observer('model', function () {
return this.get('model.author').then((author) => {
@ -45,14 +45,6 @@ export default Controller.extend(SettingsMenuMixin, {
slugValue: boundOneWay('model.slug'),
// Lazy load the slug generator
slugGenerator: computed(function () {
return SlugGenerator.create({
ghostPaths: this.get('ghostPaths'),
slugType: 'post'
});
}),
// Requests slug from title
generateAndSetSlug(destination) {
let title = this.get('model.titleScratch');
@ -65,7 +57,7 @@ export default Controller.extend(SettingsMenuMixin, {
}
promise = RSVP.resolve(afterSave).then(() => {
return this.get('slugGenerator').generateSlug(title).then((slug) => {
return this.get('slugGenerator').generateSlug('post', title).then((slug) => {
if (!isBlank(slug)) {
this.set(destination, slug);
}
@ -232,7 +224,7 @@ export default Controller.extend(SettingsMenuMixin, {
return;
}
this.get('slugGenerator').generateSlug(newSlug).then((serverSlug) => {
this.get('slugGenerator').generateSlug('post', newSlug).then((serverSlug) => {
// If after getting the sanitized and unique slug back from the API
// we end up with a slug that matches the existing slug, abort the change
if (serverSlug === slug) {

View File

@ -1,6 +1,5 @@
import Ember from 'ember';
import {request as ajax} from 'ic-ajax';
import SlugGenerator from 'ghost/models/slug-generator';
import isNumber from 'ghost/utils/isNumber';
import boundOneWay from 'ghost/utils/bound-one-way';
import ValidationEngine from 'ghost/mixins/validation-engine';
@ -22,6 +21,7 @@ export default Controller.extend(ValidationEngine, {
ghostPaths: inject.service('ghost-paths'),
notifications: inject.service(),
session: inject.service(),
slugGenerator: inject.service('slug-generator'),
user: alias('model'),
currentUser: alias('session.user'),
@ -74,14 +74,6 @@ export default Controller.extend(ValidationEngine, {
return `${this.get('user.name')}'s Cover Image`;
}),
// Lazy load the slug generator for slugPlaceholder
slugGenerator: computed(function () {
return SlugGenerator.create({
ghostPaths: this.get('ghostPaths'),
slugType: 'user'
});
}),
roles: computed(function () {
return this.store.query('role', {permissions: 'assign'});
}),
@ -210,7 +202,7 @@ export default Controller.extend(ValidationEngine, {
return;
}
return this.get('slugGenerator').generateSlug(newSlug).then((serverSlug) => {
return this.get('slugGenerator').generateSlug('user', newSlug).then((serverSlug) => {
// If after getting the sanitized and unique slug back from the API
// we end up with a slug that matches the existing slug, abort the change
if (serverSlug === slug) {

View File

@ -1,36 +0,0 @@
import Ember from 'ember';
import {request as ajax} from 'ic-ajax';
const {RSVP, inject} = Ember;
export default Ember.Object.extend({
slugType: null,
value: null,
ghostPaths: inject.service('ghost-paths'),
toString() {
return this.get('value');
},
generateSlug(textToSlugify) {
let url;
if (!textToSlugify) {
return RSVP.resolve('');
}
url = this.get('ghostPaths.url').api('slugs', this.get('slugType'), encodeURIComponent(textToSlugify));
return ajax(url, {
type: 'GET'
}).then((response) => {
let [firstSlug] = response.slugs;
let {slug} = firstSlug;
this.set('value', slug);
return slug;
});
}
});

View File

@ -0,0 +1,25 @@
import Ember from 'ember';
import {request as ajax} from 'ic-ajax';
const {RSVP, inject, Service} = Ember;
export default Service.extend({
ghostPaths: inject.service('ghost-paths'),
generateSlug(slugType, textToSlugify) {
let url;
if (!textToSlugify) {
return RSVP.resolve('');
}
url = this.get('ghostPaths.url').api('slugs', slugType, encodeURIComponent(textToSlugify));
return ajax(url).then((response) => {
let [firstSlug] = response.slugs;
let {slug} = firstSlug;
return slug;
});
}
});

View File

@ -0,0 +1,62 @@
import { expect } from 'chai';
import {
describeModule,
it
} from 'ember-mocha';
import Pretender from 'pretender';
import Ember from 'ember';
const {dasherize} = Ember.String;
function stubSlugEndpoint(server, type, slug) {
server.get('/ghost/api/v0.1/slugs/:type/:slug/', function (request) {
expect(request.params.type).to.equal(type);
expect(request.params.slug).to.equal(slug);
return [
200,
{'Content-Type': 'application/json'},
JSON.stringify({slugs: [{slug: dasherize(slug)}]})
];
});
}
describeModule(
'service:slug-generator',
'Integration: Service: slug-generator',
{
integration: true
},
function () {
let server;
beforeEach(function () {
server = new Pretender();
});
afterEach(function () {
server.shutdown();
});
it('returns empty if no slug is provided', function (done) {
let service = this.subject();
service.generateSlug('post', '').then(function (slug) {
expect(slug).to.equal('');
done();
});
});
it('calls correct endpoint and returns correct data', function (done) {
let rawSlug = 'a test post';
stubSlugEndpoint(server, 'post', rawSlug);
let service = this.subject();
service.generateSlug('post', rawSlug).then(function (slug) {
expect(slug).to.equal(dasherize(rawSlug));
done();
});
});
}
);

View File

@ -15,7 +15,7 @@ describeModule(
'controller:post-settings-menu',
'Unit: Controller: post-settings-menu',
{
needs: ['controller:application', 'service:notifications']
needs: ['controller:application', 'service:notifications', 'service:slug-generator']
},
function () {
@ -389,7 +389,7 @@ describeModule(
it('should generate a slug and set it on the destination', function (done) {
let controller = this.subject({
slugGenerator: Ember.Object.create({
generateSlug(str) {
generateSlug(slugType, str) {
return Ember.RSVP.resolve(`${str}-slug`);
}
}),
@ -413,7 +413,7 @@ describeModule(
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: Ember.Object.create({
generateSlug(str) {
generateSlug(slugType, str) {
return Ember.RSVP.resolve(`${str}-slug`);
}
}),
@ -567,7 +567,7 @@ describeModule(
it('should not set a new slug if the server-generated slug matches existing slug', function (done) {
let controller = this.subject({
slugGenerator: Ember.Object.create({
generateSlug(str) {
generateSlug(slugType, str) {
let promise = Ember.RSVP.resolve(str.split('#')[0]);
this.set('lastPromise', promise);
return promise;
@ -593,7 +593,7 @@ describeModule(
it('should not set a new slug if the only change is to the appended increment value', function (done) {
let controller = this.subject({
slugGenerator: Ember.Object.create({
generateSlug(str) {
generateSlug(slugType, str) {
let sanitizedStr = str.replace(/[^a-zA-Z]/g, '');
let promise = Ember.RSVP.resolve(`${sanitizedStr}-2`);
this.set('lastPromise', promise);
@ -620,7 +620,7 @@ describeModule(
it('should set the slug if the new slug is different', function (done) {
let controller = this.subject({
slugGenerator: Ember.Object.create({
generateSlug(str) {
generateSlug(slugType, str) {
let promise = Ember.RSVP.resolve(str);
this.set('lastPromise', promise);
return promise;
@ -647,7 +647,7 @@ describeModule(
it('should save the post when the slug changes and the post is not new', function (done) {
let controller = this.subject({
slugGenerator: Ember.Object.create({
generateSlug(str) {
generateSlug(slugType, str) {
let promise = Ember.RSVP.resolve(str);
this.set('lastPromise', promise);
return promise;
@ -679,7 +679,7 @@ describeModule(
it('should not save the post when the slug changes and the post is new', function (done) {
let controller = this.subject({
slugGenerator: Ember.Object.create({
generateSlug(str) {
generateSlug(slugType, str) {
let promise = Ember.RSVP.resolve(str);
this.set('lastPromise', promise);
return promise;