0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-01-20 22:42:53 -05:00

🐛 Fixed errors creating new posts after a post access change via context menu

ref https://linear.app/tryghost/issue/ONC-323

After changing a post's access via the posts list context menu, creating new posts or members would not work correctly.

- the issue stemmed from `this.post.set('currentState.parentState.isNew', false);` that was called when changing a post's access level, after that all Ember Data models created from the store would have `isNew: false` causing Ember Data to attempt a PUT request to update the not-yet-created model rather than a POST request to create it
- we were only using a real post model instance in order to run validations against the post access level settings but we can do that just as easily by creating a new object and injecting our validation mixin
This commit is contained in:
Kevin Ansfield 2024-10-01 14:27:00 +01:00
parent 4679bbb10b
commit 86d61304b1
2 changed files with 27 additions and 12 deletions

View file

@ -1,15 +1,23 @@
import Component from '@glimmer/component';
import EmberObject from '@ember/object';
import ValidationEngine from 'ghost-admin/mixins/validation-engine';
import {action} from '@ember/object';
import {inject as service} from '@ember/service';
import {task} from 'ember-concurrency';
import {tracked} from '@glimmer/tracking';
const PostValidatorProxy = EmberObject.extend(ValidationEngine, {
validationType: 'post',
isNew: false // required for our visibility and tiers validations to work
});
export default class EditPostsAccessModal extends Component {
@service store;
@service settings;
// We createa new post model to use the same validations as the post model
@tracked post = this.store.createRecord('post', {});
// We use a simulated post model to use the same validations as the post model without
// putting any dummy records in the store and needing to force an "isNew: false" state
@tracked post = PostValidatorProxy.create();
get selectionList() {
return this.args.data.selectionList;
@ -18,29 +26,27 @@ export default class EditPostsAccessModal extends Component {
@action
setup() {
if (this.selectionList.first && this.selectionList.isSingle) {
this.post.set('visibility', this.selectionList.first.visibility);
this.post.set('tiers', this.selectionList.first.tiers);
this.post.visibility = this.selectionList.first.visibility;
this.post.tiers = this.selectionList.first.tiers;
} else {
// Use default
this.post.set('visibility', this.settings.defaultContentVisibility);
this.post.set('tiers', this.settings.defaultContentVisibilityTiers.map((tier) => {
this.post.visibility = this.settings.defaultContentVisibility;
this.post.tiers = this.settings.defaultContentVisibilityTiers.map((tier) => {
return {
id: tier
};
}));
});
}
}
async validate() {
// Mark as not new
this.post.set('currentState.parentState.isNew', false);
await this.post.validate({property: 'visibility'});
await this.post.validate({property: 'tiers'});
}
@action
async setVisibility(segment) {
this.post.set('tiers', segment);
this.post.tiers = segment;
try {
await this.validate();
} catch (e) {

View file

@ -1,5 +1,6 @@
import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
import sinon from 'sinon';
import windowProxy from 'ghost-admin/utils/window-proxy';
import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
import {beforeEach, describe, it} from 'mocha';
import {blur, click, currentURL, fillIn, find, findAll, triggerEvent, triggerKeyEvent, visit} from '@ember/test-helpers';
@ -447,8 +448,7 @@ describe('Acceptance: Posts / Pages', function () {
expect(JSON.parse(lastRequest.requestBody).bulk.action, 'add tag request action').to.equal('addTag');
});
// TODO: Skip for now. This causes the member creation test to fail ('New member' text doesn't show... ???).
it.skip('can change access', async function () {
it('can change access', async function () {
await visit('/posts');
// get all posts
@ -493,6 +493,15 @@ describe('Acceptance: Posts / Pages', function () {
let [lastRequest] = this.server.pretender.handledRequests.slice(-1);
expect(lastRequest.queryParams.filter, 'change access request id').to.equal(`id:['${publishedPost.id}','${authorPost.id}']`);
expect(JSON.parse(lastRequest.requestBody).bulk.action, 'change access request action').to.equal('access');
// ensure creating new posts still works
// (we had a bug where newly created records in the store had `isNew: false` set meaning any saves failed
// because Ember Data attempted a PUT with no id)
sinon.stub(windowProxy, 'reload'); // we had a force-reload in place to workaround the bug
await visit('/editor/post');
await fillIn('[data-test-editor-title-input]', 'New post');
await blur('[data-test-editor-title-input]');
expect(this.server.db.posts.length, 'posts count after new post save').to.equal(5);
});
it('can unpublish', async function () {