2019-01-02 12:58:55 +03:00
|
|
|
import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
|
|
|
|
import {beforeEach, describe, it} from 'mocha';
|
2022-10-31 15:01:39 +03:00
|
|
|
import {blur, click, currentURL, fillIn, find, findAll, settled, visit} from '@ember/test-helpers';
|
2019-01-02 12:58:55 +03:00
|
|
|
import {clickTrigger, selectChoose} from 'ember-power-select/test-support/helpers';
|
2017-05-29 21:50:03 +03:00
|
|
|
import {expect} from 'chai';
|
2019-01-02 12:58:55 +03:00
|
|
|
import {setupApplicationTest} from 'ember-mocha';
|
2019-05-27 11:37:05 +03:00
|
|
|
import {setupMirage} from 'ember-cli-mirage/test-support';
|
2017-01-25 23:05:28 +03:00
|
|
|
|
2018-01-05 18:38:23 +03:00
|
|
|
describe('Acceptance: Content', function () {
|
2019-01-02 12:58:55 +03:00
|
|
|
let hooks = setupApplicationTest();
|
|
|
|
setupMirage(hooks);
|
2017-01-25 23:05:28 +03:00
|
|
|
|
2017-04-24 15:29:48 +03:00
|
|
|
it('redirects to signin when not authenticated', async function () {
|
2019-01-02 12:58:55 +03:00
|
|
|
await invalidateSession();
|
2019-03-21 12:33:14 +03:00
|
|
|
await visit('/posts');
|
2017-01-25 23:05:28 +03:00
|
|
|
|
2017-04-24 15:29:48 +03:00
|
|
|
expect(currentURL()).to.equal('/signin');
|
2017-01-25 23:05:28 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
describe('as admin', function () {
|
2019-02-22 06:17:33 +03:00
|
|
|
let admin, editor, publishedPost, scheduledPost, draftPost, authorPost;
|
2017-01-25 23:05:28 +03:00
|
|
|
|
2019-01-02 12:58:55 +03:00
|
|
|
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]});
|
2017-01-25 23:05:28 +03:00
|
|
|
|
2019-01-02 12:58:55 +03:00
|
|
|
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'});
|
2017-01-25 23:05:28 +03:00
|
|
|
|
2019-02-22 06:17:33 +03:00
|
|
|
// pages shouldn't appear in the list
|
|
|
|
this.server.create('page', {authors: [admin], status: 'published', title: 'Published Page'});
|
|
|
|
|
2019-01-02 12:58:55 +03:00
|
|
|
return await authenticateSession();
|
2017-01-25 23:05:28 +03:00
|
|
|
});
|
|
|
|
|
2021-01-28 18:25:21 +03:00
|
|
|
it.skip('displays and filters posts', async function () {
|
2019-03-21 12:33:14 +03:00
|
|
|
await visit('/posts');
|
2017-04-24 15:29:48 +03:00
|
|
|
// Not checking request here as it won't be the last request made
|
|
|
|
// Displays all posts + pages
|
2019-02-22 06:17:33 +03:00
|
|
|
expect(findAll('[data-test-post-id]').length, 'all posts count').to.equal(4);
|
2017-04-24 15:29:48 +03:00
|
|
|
|
2017-07-13 12:55:13 +03:00
|
|
|
// show draft posts
|
2017-08-11 18:28:05 +03:00
|
|
|
await selectChoose('[data-test-type-select]', 'Draft posts');
|
2017-04-24 15:29:48 +03:00
|
|
|
|
|
|
|
// API request is correct
|
2019-01-02 12:58:55 +03:00
|
|
|
let [lastRequest] = this.server.pretender.handledRequests.slice(-1);
|
2018-07-20 13:57:53 +03:00
|
|
|
expect(lastRequest.queryParams.filter, '"drafts" request status filter').to.have.string('status:draft');
|
2017-04-24 15:29:48 +03:00
|
|
|
// Displays draft post
|
2019-01-02 12:58:55 +03:00
|
|
|
expect(findAll('[data-test-post-id]').length, 'drafts count').to.equal(1);
|
2017-08-11 18:28:05 +03:00
|
|
|
expect(find(`[data-test-post-id="${draftPost.id}"]`), 'draft post').to.exist;
|
2017-04-24 15:29:48 +03:00
|
|
|
|
2017-07-13 12:55:13 +03:00
|
|
|
// show published posts
|
2017-08-11 18:28:05 +03:00
|
|
|
await selectChoose('[data-test-type-select]', 'Published posts');
|
2017-04-24 15:29:48 +03:00
|
|
|
|
|
|
|
// API request is correct
|
2019-01-02 12:58:55 +03:00
|
|
|
[lastRequest] = this.server.pretender.handledRequests.slice(-1);
|
2018-07-20 13:57:53 +03:00
|
|
|
expect(lastRequest.queryParams.filter, '"published" request status filter').to.have.string('status:published');
|
2017-04-24 15:29:48 +03:00
|
|
|
// Displays three published posts + pages
|
2019-01-02 12:58:55 +03:00
|
|
|
expect(findAll('[data-test-post-id]').length, 'published count').to.equal(2);
|
2017-08-11 18:28:05 +03:00
|
|
|
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;
|
2017-04-24 15:29:48 +03:00
|
|
|
|
2017-07-13 12:55:13 +03:00
|
|
|
// show scheduled posts
|
2017-08-11 18:28:05 +03:00
|
|
|
await selectChoose('[data-test-type-select]', 'Scheduled posts');
|
2017-04-24 15:29:48 +03:00
|
|
|
|
|
|
|
// API request is correct
|
2019-01-02 12:58:55 +03:00
|
|
|
[lastRequest] = this.server.pretender.handledRequests.slice(-1);
|
2018-07-20 13:57:53 +03:00
|
|
|
expect(lastRequest.queryParams.filter, '"scheduled" request status filter').to.have.string('status:scheduled');
|
2017-04-24 15:29:48 +03:00
|
|
|
// Displays scheduled post
|
2019-01-02 12:58:55 +03:00
|
|
|
expect(findAll('[data-test-post-id]').length, 'scheduled count').to.equal(1);
|
2017-08-11 18:28:05 +03:00
|
|
|
expect(find(`[data-test-post-id="${scheduledPost.id}"]`), 'scheduled post').to.exist;
|
2017-04-24 15:29:48 +03:00
|
|
|
|
2017-07-13 12:55:13 +03:00
|
|
|
// show all posts
|
2017-08-11 18:28:05 +03:00
|
|
|
await selectChoose('[data-test-type-select]', 'All posts');
|
2017-04-24 15:29:48 +03:00
|
|
|
|
|
|
|
// API request is correct
|
2019-01-02 12:58:55 +03:00
|
|
|
[lastRequest] = this.server.pretender.handledRequests.slice(-1);
|
2018-07-20 13:57:53 +03:00
|
|
|
expect(lastRequest.queryParams.filter, '"all" request status filter').to.have.string('status:[draft,scheduled,published]');
|
2017-04-24 15:29:48 +03:00
|
|
|
|
2017-07-13 12:55:13 +03:00
|
|
|
// show all posts by editor
|
2017-08-11 18:28:05 +03:00
|
|
|
await selectChoose('[data-test-author-select]', editor.name);
|
2017-04-24 15:29:48 +03:00
|
|
|
|
|
|
|
// API request is correct
|
2019-01-02 12:58:55 +03:00
|
|
|
[lastRequest] = this.server.pretender.handledRequests.slice(-1);
|
2020-06-09 14:19:25 +03:00
|
|
|
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+status:[draft,scheduled,published]');
|
2017-07-13 12:55:13 +03:00
|
|
|
|
2017-04-24 15:29:48 +03:00
|
|
|
// Displays editor post
|
|
|
|
// TODO: implement "filter" param support and fix mirage post->author association
|
2017-08-11 18:28:05 +03:00
|
|
|
// 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;
|
2017-03-02 21:35:09 +03:00
|
|
|
|
|
|
|
// TODO: test tags dropdown
|
2017-01-25 23:05:28 +03:00
|
|
|
});
|
2018-11-07 18:06:28 +03:00
|
|
|
|
2019-01-22 17:16:15 +03:00
|
|
|
// 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 () {
|
2019-01-02 12:58:55 +03:00
|
|
|
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'});
|
2018-11-07 18:06:28 +03:00
|
|
|
|
2019-03-21 12:33:14 +03:00
|
|
|
await visit('/posts');
|
2018-11-07 18:06:28 +03:00
|
|
|
await clickTrigger('[data-test-tag-select]');
|
|
|
|
|
2019-01-02 12:58:55 +03:00
|
|
|
let options = findAll('.ember-power-select-option');
|
2018-11-07 18:06:28 +03:00
|
|
|
|
|
|
|
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');
|
|
|
|
});
|
2020-01-30 18:35:36 +03:00
|
|
|
|
|
|
|
it('can add and edit custom views', async function () {
|
|
|
|
// actions are not visible when there's no filter
|
|
|
|
await visit('/posts');
|
2022-03-31 12:52:54 +03:00
|
|
|
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;
|
2020-01-30 18:35:36 +03:00
|
|
|
|
|
|
|
// add action is visible after filtering to a non-default filter
|
|
|
|
await selectChoose('[data-test-author-select]', admin.name);
|
2022-03-31 12:52:54 +03:00
|
|
|
expect(find('[data-test-button="add-view"]'), 'add-view button (with filter)').to.exist;
|
2020-01-30 18:35:36 +03:00
|
|
|
|
|
|
|
// adding view shows it in the sidebar
|
2022-03-31 12:52:54 +03:00
|
|
|
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;
|
2020-01-30 18:35:36 +03:00
|
|
|
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
|
2022-03-31 12:52:54 +03:00
|
|
|
expect(find('[data-test-modal="custom-view-form"]'), 'custom view modal (after add save)').to.not.exist;
|
2020-01-30 18:35:36 +03:00
|
|
|
// UI updates
|
2022-03-31 12:52:54 +03:00
|
|
|
expect(find('[data-test-nav-custom="posts-Test view"]'), 'new view nav').to.exist;
|
2020-01-30 18:35:36 +03:00
|
|
|
expect(find('[data-test-nav-custom="posts-Test view"]').textContent.trim()).to.equal('Test view');
|
2022-03-31 12:52:54 +03:00
|
|
|
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;
|
2020-01-30 18:35:36 +03:00
|
|
|
|
|
|
|
// editing view
|
2022-03-31 12:52:54 +03:00
|
|
|
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;
|
2020-01-30 18:35:36 +03:00
|
|
|
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
|
2022-03-31 12:52:54 +03:00
|
|
|
expect(find('[data-test-modal="custom-view-form"]'), 'custom view modal (after edit save)').to.not.exist;
|
2020-01-30 18:35:36 +03:00
|
|
|
// 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');
|
2022-03-31 12:52:54 +03:00
|
|
|
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;
|
2020-01-30 18:35:36 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
it('can navigate to custom views', async function () {
|
2020-06-04 23:43:54 +03:00
|
|
|
this.server.create('setting', {
|
2020-06-24 16:23:51 +03:00
|
|
|
group: 'site',
|
2020-06-04 23:43:54 +03:00
|
|
|
key: 'shared_views',
|
|
|
|
value: JSON.stringify([{
|
2020-01-30 18:35:36 +03:00
|
|
|
route: 'posts',
|
|
|
|
name: 'My posts',
|
|
|
|
filter: {
|
|
|
|
author: admin.slug
|
|
|
|
}
|
2020-06-04 23:43:54 +03:00
|
|
|
}])
|
2020-01-30 18:35:36 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
await visit('/posts');
|
|
|
|
|
|
|
|
// nav bar contains default + custom views
|
2021-07-15 17:27:29 +03:00
|
|
|
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;
|
2020-01-30 18:35:36 +03:00
|
|
|
|
|
|
|
// screen has default title and sidebar is showing inactive custom view
|
2022-09-01 12:01:23 +03:00
|
|
|
expect(find('[data-test-screen-title]')).to.have.rendered.text('Posts');
|
2021-07-15 17:27:29 +03:00
|
|
|
expect(find('[data-test-nav="posts"]')).to.have.class('active');
|
2020-01-30 18:35:36 +03:00
|
|
|
|
|
|
|
// clicking sidebar custom view link works
|
|
|
|
await click('[data-test-nav-custom="posts-Scheduled"]');
|
|
|
|
expect(currentURL()).to.equal('/posts?type=scheduled');
|
2022-10-04 08:35:29 +03:00
|
|
|
expect(find('[data-test-screen-title]').innerText).to.match(/Scheduled/);
|
2020-01-30 18:35:36 +03:00
|
|
|
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');
|
2022-09-01 12:01:23 +03:00
|
|
|
expect(find('[data-test-screen-title]')).to.have.rendered.text('Posts');
|
2020-01-30 18:35:36 +03:00
|
|
|
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');
|
2022-10-04 08:35:29 +03:00
|
|
|
expect(find('[data-test-screen-title]').innerText).to.match(/Scheduled/);
|
2020-01-30 18:35:36 +03:00
|
|
|
});
|
2017-01-25 23:05:28 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
describe('as author', function () {
|
|
|
|
let author, authorPost;
|
|
|
|
|
2019-01-02 12:58:55 +03:00
|
|
|
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]});
|
2017-01-25 23:05:28 +03:00
|
|
|
|
|
|
|
// create posts
|
2019-01-02 12:58:55 +03:00
|
|
|
authorPost = this.server.create('post', {authors: [author], status: 'published', title: 'Author Post'});
|
|
|
|
this.server.create('post', {authors: [admin], status: 'scheduled', title: 'Admin Post'});
|
2017-01-25 23:05:28 +03:00
|
|
|
|
2019-01-02 12:58:55 +03:00
|
|
|
return await authenticateSession();
|
2017-01-25 23:05:28 +03:00
|
|
|
});
|
|
|
|
|
2017-04-24 15:29:48 +03:00
|
|
|
it('only fetches the author\'s posts', async function () {
|
2019-03-21 12:33:14 +03:00
|
|
|
await visit('/posts');
|
2017-01-25 23:05:28 +03:00
|
|
|
// trigger a filter request so we can grab the posts API request easily
|
2017-08-11 18:28:05 +03:00
|
|
|
await selectChoose('[data-test-type-select]', 'Published posts');
|
2017-01-25 23:05:28 +03:00
|
|
|
|
2017-04-24 15:29:48 +03:00
|
|
|
// API request includes author filter
|
2019-01-02 12:58:55 +03:00
|
|
|
let [lastRequest] = this.server.pretender.handledRequests.slice(-1);
|
2018-07-20 13:57:53 +03:00
|
|
|
expect(lastRequest.queryParams.filter).to.have.string(`authors:${author.slug}`);
|
2017-01-25 23:05:28 +03:00
|
|
|
|
2017-04-24 15:29:48 +03:00
|
|
|
// only author's post is shown
|
2019-01-02 12:58:55 +03:00
|
|
|
expect(findAll('[data-test-post-id]').length, 'post count').to.equal(1);
|
2017-08-11 18:28:05 +03:00
|
|
|
expect(find(`[data-test-post-id="${authorPost.id}"]`), 'author post').to.exist;
|
2017-01-25 23:05:28 +03:00
|
|
|
});
|
|
|
|
});
|
2018-02-07 12:42:46 +03:00
|
|
|
|
|
|
|
describe('as contributor', function () {
|
2019-01-02 12:58:55 +03:00
|
|
|
beforeEach(async function () {
|
2022-10-31 15:01:39 +03:00
|
|
|
let contributorRole = this.server.create('role', {name: 'Contributor'});
|
2022-10-31 15:12:58 +03:00
|
|
|
this.server.create('user', {roles: [contributorRole]});
|
2018-02-07 12:42:46 +03:00
|
|
|
|
2019-01-02 12:58:55 +03:00
|
|
|
return await authenticateSession();
|
2018-02-07 12:42:46 +03:00
|
|
|
});
|
2022-10-31 15:01:39 +03:00
|
|
|
|
|
|
|
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;
|
|
|
|
});
|
2018-02-07 12:42:46 +03:00
|
|
|
});
|
2017-01-25 23:05:28 +03:00
|
|
|
});
|