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

🐛 Fixed infinite loops in setFeatureImageCaption for deleted posts (#21081)

ref ONC-364

- Adds a condition to check whether the record is deleted or if deleting
is in progress before firing the `setFeatureImageCaption`.
- Adds tests. Managed to reproduce the issue using tests.
This commit is contained in:
Ronald Langeveld 2024-09-25 17:02:38 +09:00 committed by GitHub
parent 0187d6b6a2
commit 052ef6971f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 45 additions and 1 deletions

View file

@ -498,7 +498,9 @@ export default class LexicalEditorController extends Controller {
@action
setFeatureImageCaption(html) {
this.post.set('featureImageCaption', html);
if (!this.post.isDestroyed || !this.post.isDestroying) {
this.post.set('featureImageCaption', html);
}
}
@action
@ -1161,6 +1163,11 @@ export default class LexicalEditorController extends Controller {
let hasDirtyAttributes = this.hasDirtyAttributes;
let state = post.getProperties('isDeleted', 'isSaving', 'hasDirtyAttributes', 'isNew');
if (state.isDeleted) {
// if the post is deleted, we don't need to save it
hasDirtyAttributes = false;
}
// Check if anything has changed since the last revision
let postRevisions = post.get('postRevisions').toArray();
let latestRevision = postRevisions[postRevisions.length - 1];

View file

@ -0,0 +1,37 @@
import loginAsRole from '../../helpers/login-as-role';
import {click, currentURL, find} from '@ember/test-helpers';
import {expect} from 'chai';
import {setupApplicationTest} from 'ember-mocha';
import {setupMirage} from 'ember-cli-mirage/test-support';
import {visit} from '../../helpers/visit';
describe('Acceptance: Feature Image', function () {
let hooks = setupApplicationTest();
setupMirage(hooks);
beforeEach(async function () {
this.server.loadFixtures();
await loginAsRole('Administrator', this.server);
});
it('can display feature image with caption', async function () {
const post = this.server.create('post', {status: 'published', featureImage: 'https://static.ghost.org/v4.0.0/images/feature-image.jpg', featureImageCaption: '<span style="white-space: pre-wrap;">Hello dogggos</span>'});
await visit(`/editor/post/${post.id}`);
expect(await find('.gh-editor-feature-image img').src).to.equal('https://static.ghost.org/v4.0.0/images/feature-image.jpg');
expect(await find('.gh-editor-feature-image-caption').textContent).to.contain('Hello dogggos');
});
it('does not attempt to save if already deleted and goes back to posts', async function () {
// avoids an infinite loop when the post is deleted and the save button is clicked, potential race condition
const post = this.server.create('post', {status: 'published', featureImage: 'https://static.ghost.org/v4.0.0/images/feature-image.jpg', featureImageCaption: '<span style="white-space: pre-wrap;">Hello dogggos</span>'});
await visit(`/editor/post/${post.id}`);
this.server.db.posts.update(post.id, {isDeleted: true});
await click('[data-test-psm-trigger]');
await click('[data-test-button="delete-post"]');
await click('[data-test-button="delete-post-confirm"]');
expect(currentURL()).to.equal('/posts');
});
});