Ghost/ghost/admin/tests/acceptance/content-test.js
Steve Larson 8bc653802d
Released new editor (#18422)
Promoted our beta editor to the default editor. Keep an eye on (or subscribe to) https://ghost.org/changelog/ for release announcements with full details.

- moved the beta editor (Lexical-based editor) to the default editor; all pages and posts will now use it
- all mobiledoc (previous editor) posts will remain mobiledoc until opened in the editor at which point will be converted to Lexical on the fly and open in the new editor
2023-10-04 12:22:54 +01:00

284 lines
14 KiB
JavaScript

import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
import {beforeEach, describe, it} from 'mocha';
import {blur, click, currentURL, fillIn, find, findAll, settled, visit} from '@ember/test-helpers';
import {clickTrigger, selectChoose} from 'ember-power-select/test-support/helpers';
import {expect} from 'chai';
import {setupApplicationTest} from 'ember-mocha';
import {setupMirage} from 'ember-cli-mirage/test-support';
describe('Acceptance: Content', function () {
let hooks = setupApplicationTest();
setupMirage(hooks);
beforeEach(async function () {
this.server.loadFixtures('configs');
});
it('redirects to signin when not authenticated', async function () {
await invalidateSession();
await visit('/posts');
expect(currentURL()).to.equal('/signin');
});
describe('as admin', function () {
let admin, editor, publishedPost, scheduledPost, draftPost, authorPost;
beforeEach(async function () {
let adminRole = this.server.create('role', {name: 'Administrator'});
admin = this.server.create('user', {roles: [adminRole]});
let editorRole = this.server.create('role', {name: 'Editor'});
editor = this.server.create('user', {roles: [editorRole]});
publishedPost = this.server.create('post', {authors: [admin], status: 'published', title: 'Published Post'});
scheduledPost = this.server.create('post', {authors: [admin], status: 'scheduled', title: 'Scheduled Post'});
draftPost = this.server.create('post', {authors: [admin], status: 'draft', title: 'Draft Post'});
authorPost = this.server.create('post', {authors: [editor], status: 'published', title: 'Editor Published Post'});
// pages shouldn't appear in the list
this.server.create('page', {authors: [admin], status: 'published', title: 'Published Page'});
return await authenticateSession();
});
it.skip('displays and filters posts', async function () {
await visit('/posts');
// Not checking request here as it won't be the last request made
// Displays all posts + pages
expect(findAll('[data-test-post-id]').length, 'all posts count').to.equal(4);
// show draft posts
await selectChoose('[data-test-type-select]', 'Draft posts');
// API request is correct
let [lastRequest] = this.server.pretender.handledRequests.slice(-1);
expect(lastRequest.queryParams.filter, '"drafts" request status filter').to.have.string('status:draft');
// Displays draft post
expect(findAll('[data-test-post-id]').length, 'drafts count').to.equal(1);
expect(find(`[data-test-post-id="${draftPost.id}"]`), 'draft post').to.exist;
// show published posts
await selectChoose('[data-test-type-select]', 'Published posts');
// API request is correct
[lastRequest] = this.server.pretender.handledRequests.slice(-1);
expect(lastRequest.queryParams.filter, '"published" request status filter').to.have.string('status:published');
// Displays three published posts + pages
expect(findAll('[data-test-post-id]').length, 'published count').to.equal(2);
expect(find(`[data-test-post-id="${publishedPost.id}"]`), 'admin published post').to.exist;
expect(find(`[data-test-post-id="${authorPost.id}"]`), 'author published post').to.exist;
// show scheduled posts
await selectChoose('[data-test-type-select]', 'Scheduled posts');
// API request is correct
[lastRequest] = this.server.pretender.handledRequests.slice(-1);
expect(lastRequest.queryParams.filter, '"scheduled" request status filter').to.have.string('status:scheduled');
// Displays scheduled post
expect(findAll('[data-test-post-id]').length, 'scheduled count').to.equal(1);
expect(find(`[data-test-post-id="${scheduledPost.id}"]`), 'scheduled post').to.exist;
// show all posts
await selectChoose('[data-test-type-select]', 'All posts');
// API request is correct
[lastRequest] = this.server.pretender.handledRequests.slice(-1);
expect(lastRequest.queryParams.filter, '"all" request status filter').to.have.string('status:[draft,scheduled,published]');
// show all posts by editor
await selectChoose('[data-test-author-select]', editor.name);
// API request is correct
[lastRequest] = this.server.pretender.handledRequests.slice(-1);
expect(lastRequest.queryParams.filter, '"editor" request status filter')
.to.have.string('status:[draft,scheduled,published]');
expect(lastRequest.queryParams.filter, '"editor" request filter param')
.to.have.string(`authors:${editor.slug}`);
// Post status is only visible when members is enabled
expect(find('[data-test-visibility-select]'), 'access dropdown before members enabled').to.not.exist;
let featureService = this.owner.lookup('service:feature');
featureService.set('members', true);
await settled();
expect(find('[data-test-visibility-select]'), 'access dropdown after members enabled').to.exist;
await selectChoose('[data-test-visibility-select]', 'Paid members-only');
[lastRequest] = this.server.pretender.handledRequests.slice(-1);
expect(lastRequest.queryParams.filter, '"visibility" request filter param')
.to.have.string('visibility:[paid,tiers]+status:[draft,scheduled,published]');
// Displays editor post
// TODO: implement "filter" param support and fix mirage post->author association
// expect(find('[data-test-post-id]').length, 'editor post count').to.equal(1);
// expect(find(`[data-test-post-id="${authorPost.id}"]`), 'author post').to.exist;
// TODO: test tags dropdown
});
// TODO: skipped due to consistently random failures on Travis
// options[0] is undefined
// https://github.com/TryGhost/Ghost/issues/10308
it.skip('sorts tags filter alphabetically', async function () {
this.server.create('tag', {name: 'B - Second', slug: 'second'});
this.server.create('tag', {name: 'Z - Last', slug: 'last'});
this.server.create('tag', {name: 'A - First', slug: 'first'});
await visit('/posts');
await clickTrigger('[data-test-tag-select]');
let options = findAll('.ember-power-select-option');
expect(options[0].textContent.trim()).to.equal('All tags');
expect(options[1].textContent.trim()).to.equal('A - First');
expect(options[2].textContent.trim()).to.equal('B - Second');
expect(options[3].textContent.trim()).to.equal('Z - Last');
});
it('can add and edit custom views', async function () {
// actions are not visible when there's no filter
await visit('/posts');
expect(find('[data-test-button="edit-view"]'), 'edit-view button (no filter)').to.not.exist;
expect(find('[data-test-button="add-view"]'), 'add-view button (no filter)').to.not.exist;
// add action is visible after filtering to a non-default filter
await selectChoose('[data-test-author-select]', admin.name);
expect(find('[data-test-button="add-view"]'), 'add-view button (with filter)').to.exist;
// adding view shows it in the sidebar
await click('[data-test-button="add-view"]'), 'add-view button';
expect(find('[data-test-modal="custom-view-form"]'), 'custom view modal (on add)').to.exist;
expect(find('[data-test-modal="custom-view-form"] h1').textContent.trim()).to.equal('New view');
await fillIn('[data-test-input="custom-view-name"]', 'Test view');
await click('[data-test-button="save-custom-view"]');
// modal closes on save
expect(find('[data-test-modal="custom-view-form"]'), 'custom view modal (after add save)').to.not.exist;
// UI updates
expect(find('[data-test-nav-custom="posts-Test view"]'), 'new view nav').to.exist;
expect(find('[data-test-nav-custom="posts-Test view"]').textContent.trim()).to.equal('Test view');
expect(find('[data-test-button="add-view"]'), 'add-view button (on existing view)').to.not.exist;
expect(find('[data-test-button="edit-view"]'), 'edit-view button (on existing view)').to.exist;
// editing view
await click('[data-test-button="edit-view"]'), 'edit-view button';
expect(find('[data-test-modal="custom-view-form"]'), 'custom view modal (on edit)').to.exist;
expect(find('[data-test-modal="custom-view-form"] h1').textContent.trim()).to.equal('Edit view');
await fillIn('[data-test-input="custom-view-name"]', 'Updated view');
await click('[data-test-button="save-custom-view"]');
// modal closes on save
expect(find('[data-test-modal="custom-view-form"]'), 'custom view modal (after edit save)').to.not.exist;
// UI updates
expect(find('[data-test-nav-custom="posts-Updated view"]')).to.exist;
expect(find('[data-test-nav-custom="posts-Updated view"]').textContent.trim()).to.equal('Updated view');
expect(find('[data-test-button="add-view"]'), 'add-view button (after edit)').to.not.exist;
expect(find('[data-test-button="edit-view"]'), 'edit-view button (after edit)').to.exist;
});
it('can navigate to custom views', async function () {
this.server.create('setting', {
group: 'site',
key: 'shared_views',
value: JSON.stringify([{
route: 'posts',
name: 'My posts',
filter: {
author: admin.slug
}
}])
});
await visit('/posts');
// nav bar contains default + custom views
expect(find('[data-test-nav-custom="posts-Drafts"]')).to.exist;
expect(find('[data-test-nav-custom="posts-Scheduled"]')).to.exist;
expect(find('[data-test-nav-custom="posts-Published"]')).to.exist;
expect(find('[data-test-nav-custom="posts-My posts"]')).to.exist;
// screen has default title and sidebar is showing inactive custom view
expect(find('[data-test-screen-title]')).to.have.rendered.text('Posts');
expect(find('[data-test-nav="posts"]')).to.have.class('active');
// clicking sidebar custom view link works
await click('[data-test-nav-custom="posts-Scheduled"]');
expect(currentURL()).to.equal('/posts?type=scheduled');
expect(find('[data-test-screen-title]').innerText).to.match(/Scheduled/);
expect(find('[data-test-nav-custom="posts-Scheduled"]')).to.have.class('active');
// clicking the main posts link resets
await click('[data-test-nav="posts"]');
expect(currentURL()).to.equal('/posts');
expect(find('[data-test-screen-title]')).to.have.rendered.text('Posts');
expect(find('[data-test-nav-custom="posts-Scheduled"]')).to.not.have.class('active');
// changing a filter to match a custom view shows custom view
await selectChoose('[data-test-type-select]', 'Scheduled posts');
expect(currentURL()).to.equal('/posts?type=scheduled');
expect(find('[data-test-nav-custom="posts-Scheduled"]')).to.have.class('active');
expect(find('[data-test-screen-title]').innerText).to.match(/Scheduled/);
});
});
describe('as author', function () {
let author, authorPost;
beforeEach(async function () {
let authorRole = this.server.create('role', {name: 'Author'});
author = this.server.create('user', {roles: [authorRole]});
let adminRole = this.server.create('role', {name: 'Administrator'});
let admin = this.server.create('user', {roles: [adminRole]});
// create posts
authorPost = this.server.create('post', {authors: [author], status: 'published', title: 'Author Post'});
this.server.create('post', {authors: [admin], status: 'scheduled', title: 'Admin Post'});
return await authenticateSession();
});
it('only fetches the author\'s posts', async function () {
await visit('/posts');
// trigger a filter request so we can grab the posts API request easily
await selectChoose('[data-test-type-select]', 'Published posts');
// API request includes author filter
let [lastRequest] = this.server.pretender.handledRequests.slice(-1);
expect(lastRequest.queryParams.filter).to.have.string(`authors:${author.slug}`);
// only author's post is shown
expect(findAll('[data-test-post-id]').length, 'post count').to.equal(1);
expect(find(`[data-test-post-id="${authorPost.id}"]`), 'author post').to.exist;
});
});
describe('as contributor', function () {
beforeEach(async function () {
let contributorRole = this.server.create('role', {name: 'Contributor'});
this.server.create('user', {roles: [contributorRole]});
return await authenticateSession();
});
it('shows posts list and allows post creation', async function () {
await visit('/posts');
// has an empty state
expect(findAll('[data-test-post-id]')).to.have.length(0);
expect(find('[data-test-no-posts-box]')).to.exist;
expect(find('[data-test-link="write-a-new-post"]')).to.exist;
await click('[data-test-link="write-a-new-post"]');
expect(currentURL()).to.equal('/editor/post');
await fillIn('[data-test-editor-title-input]', 'First contributor post');
await blur('[data-test-editor-title-input]');
expect(currentURL()).to.equal('/editor/post/1');
await click('[data-test-link="posts"]');
expect(findAll('[data-test-post-id]')).to.have.length(1);
expect(find('[data-test-no-posts-box]')).to.not.exist;
});
});
});