mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-10 23:36:14 -05:00
Merge pull request #3766 from jaswilli/user-slug
Correct behavior on updating user slug.
This commit is contained in:
commit
02ca955a00
3 changed files with 124 additions and 37 deletions
|
@ -2,16 +2,14 @@ import SlugGenerator from 'ghost/models/slug-generator';
|
||||||
|
|
||||||
var SettingsUserController = Ember.ObjectController.extend({
|
var SettingsUserController = Ember.ObjectController.extend({
|
||||||
|
|
||||||
_lastSlug: null,
|
|
||||||
|
|
||||||
updateLastSlug: Ember.observer(function () {
|
|
||||||
this.set('_lastSlug', this.get('user.slug'));
|
|
||||||
}),
|
|
||||||
|
|
||||||
user: Ember.computed.alias('model'),
|
user: Ember.computed.alias('model'),
|
||||||
|
|
||||||
email: Ember.computed.readOnly('user.email'),
|
email: Ember.computed.readOnly('user.email'),
|
||||||
|
|
||||||
|
slugValue: Ember.computed.oneWay('user.slug'),
|
||||||
|
|
||||||
|
lastPromise: null,
|
||||||
|
|
||||||
coverDefault: function () {
|
coverDefault: function () {
|
||||||
return this.get('ghostPaths.url').asset('/shared/img/user-cover.png');
|
return this.get('ghostPaths.url').asset('/shared/img/user-cover.png');
|
||||||
}.property('ghostPaths'),
|
}.property('ghostPaths'),
|
||||||
|
@ -106,15 +104,43 @@ var SettingsUserController = Ember.ObjectController.extend({
|
||||||
|
|
||||||
save: function () {
|
save: function () {
|
||||||
var user = this.get('user'),
|
var user = this.get('user'),
|
||||||
|
slugValue = this.get('slugValue'),
|
||||||
|
afterUpdateSlug = this.get('lastPromise'),
|
||||||
|
promise,
|
||||||
|
slugChanged,
|
||||||
self = this;
|
self = this;
|
||||||
|
|
||||||
user.save({ format: false }).then(function (model) {
|
if (user.get('slug') !== slugValue) {
|
||||||
|
slugChanged = true;
|
||||||
|
user.set('slug', slugValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
promise = Ember.RSVP.resolve(afterUpdateSlug).then(function () {
|
||||||
|
return user.save({ format: false });
|
||||||
|
}).then(function (model) {
|
||||||
|
var currentPath,
|
||||||
|
newPath;
|
||||||
|
|
||||||
self.notifications.showSuccess('Settings successfully saved.');
|
self.notifications.showSuccess('Settings successfully saved.');
|
||||||
|
|
||||||
|
// If the user's slug has changed, change the URL and replace
|
||||||
|
// the history so refresh and back button still work
|
||||||
|
if (slugChanged) {
|
||||||
|
currentPath = window.history.state.path;
|
||||||
|
|
||||||
|
newPath = currentPath.split('/');
|
||||||
|
newPath[newPath.length - 2] = model.get('slug');
|
||||||
|
newPath = newPath.join('/');
|
||||||
|
|
||||||
|
window.history.replaceState({ path: newPath }, '', newPath);
|
||||||
|
}
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
}).catch(function (errors) {
|
}).catch(function (errors) {
|
||||||
self.notifications.showErrors(errors);
|
self.notifications.showErrors(errors);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.set('lastPromise', promise);
|
||||||
},
|
},
|
||||||
|
|
||||||
password: function () {
|
password: function () {
|
||||||
|
@ -143,8 +169,12 @@ var SettingsUserController = Ember.ObjectController.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
updateSlug: function (newSlug) {
|
updateSlug: function (newSlug) {
|
||||||
var slug = this.get('_lastSlug'),
|
var self = this,
|
||||||
self = this;
|
afterSave = this.get('lastPromise'),
|
||||||
|
promise;
|
||||||
|
|
||||||
|
promise = Ember.RSVP.resolve(afterSave).then(function () {
|
||||||
|
var slug = self.get('slug');
|
||||||
|
|
||||||
newSlug = newSlug || slug;
|
newSlug = newSlug || slug;
|
||||||
|
|
||||||
|
@ -152,10 +182,12 @@ var SettingsUserController = Ember.ObjectController.extend({
|
||||||
|
|
||||||
// Ignore unchanged slugs or candidate slugs that are empty
|
// Ignore unchanged slugs or candidate slugs that are empty
|
||||||
if (!newSlug || slug === newSlug) {
|
if (!newSlug || slug === newSlug) {
|
||||||
|
self.set('slugValue', slug);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.get('slugGenerator').generateSlug(newSlug).then(function (serverSlug) {
|
return self.get('slugGenerator').generateSlug(newSlug).then(function (serverSlug) {
|
||||||
|
|
||||||
// If after getting the sanitized and unique slug back from the API
|
// 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
|
// we end up with a slug that matches the existing slug, abort the change
|
||||||
|
@ -177,12 +209,17 @@ var SettingsUserController = Ember.ObjectController.extend({
|
||||||
// for the incrementor then the existing slug should be used
|
// for the incrementor then the existing slug should be used
|
||||||
if (_.isNumber(check) && check > 0) {
|
if (_.isNumber(check) && check > 0) {
|
||||||
if (slug === slugTokens.join('-') && serverSlug !== newSlug) {
|
if (slug === slugTokens.join('-') && serverSlug !== newSlug) {
|
||||||
|
self.set('slugValue', slug);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.set('_lastSlug', serverSlug);
|
self.set('slugValue', serverSlug);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
this.set('lastPromise', promise);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -52,9 +52,8 @@
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="user-slug">Slug</label>
|
<label for="user-slug">Slug</label>
|
||||||
{{!-- {{input value=user.slug id="user-slug" placeholder="Slug" autocorrect="off"}} --}}
|
{{gh-blur-input class="user-name" id="user-slug" value=slugValue name="user" action="updateSlug" placeholder="Slug" selectOnClick="true" autocorrect="off"}}
|
||||||
{{gh-blur-input class="user-name" id="user-slug" value=user.slug name="user" action="updateSlug" placeholder="Slug" selectOnClick="true" autocorrect="off"}}
|
<p>{{gh-blog-url}}/author/{{slugValue}}</p>
|
||||||
<p>{{gh-blog-url}}/author/{{user.slug}}</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
|
@ -283,6 +283,57 @@ CasperTest.begin('Can save settings', 7, function suite(test) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
CasperTest.begin('User settings screen resets all whitespace slug to original value', 3, function suite(test) {
|
||||||
|
var slug;
|
||||||
|
|
||||||
|
casper.thenOpenAndWaitForPageLoad('settings.users.user', function testTitleAndUrl() {
|
||||||
|
test.assertTitle('Ghost Admin', 'Ghost admin has no title');
|
||||||
|
test.assertUrlMatch(/ghost\/settings\/users\/test-user\/$/, 'Ghost doesn\'t require login this time');
|
||||||
|
});
|
||||||
|
|
||||||
|
casper.then(function setSlugToAllWhitespace() {
|
||||||
|
slug = casper.getElementInfo('#user-slug').attributes.value;
|
||||||
|
|
||||||
|
casper.fillSelectors('.user-profile', {
|
||||||
|
'#user-slug': ' '
|
||||||
|
}, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
casper.thenClick('.content.settings-user');
|
||||||
|
|
||||||
|
casper.then(function checkSlugInputValue() {
|
||||||
|
casper.wait(250);
|
||||||
|
test.assertField('user', slug);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
CasperTest.begin('User settings screen change slug handles duplicate slug', 4, function suite(test) {
|
||||||
|
var slug;
|
||||||
|
|
||||||
|
casper.thenOpenAndWaitForPageLoad('settings.users.user', function testTitleAndUrl() {
|
||||||
|
test.assertTitle('Ghost Admin', 'Ghost admin has no title');
|
||||||
|
test.assertUrlMatch(/ghost\/settings\/users\/test-user\/$/, 'Ghost doesn\'t require login this time');
|
||||||
|
});
|
||||||
|
|
||||||
|
casper.then(function changeSlug() {
|
||||||
|
slug = casper.getElementInfo('#user-slug').attributes.value;
|
||||||
|
|
||||||
|
casper.fillSelectors('.user-profile', {
|
||||||
|
'#user-slug': slug + '!'
|
||||||
|
}, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
casper.thenClick('.content.settings-user');
|
||||||
|
|
||||||
|
casper.waitForResource(/\/slugs\/user\//, function testGoodResponse(resource) {
|
||||||
|
test.assert(400 > resource.status);
|
||||||
|
});
|
||||||
|
|
||||||
|
casper.then(function checkSlugInputValue() {
|
||||||
|
test.assertField('user', slug);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
CasperTest.begin('User settings screen validates email', 6, function suite(test) {
|
CasperTest.begin('User settings screen validates email', 6, function suite(test) {
|
||||||
var email, brokenEmail;
|
var email, brokenEmail;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue