cb59388c5b
no issue - adds `eslint-plugin-sort-imports-es6-autofix` dependency - implements ESLint's base `sort-imports` rule but has a distinction in that `import {foo} from 'bar';` is considered `multiple` rather than `single` - fixes ESLint's autofix behaviour so `eslint --fix` will actually fix the sort order - updates all unordered import rules by using `eslint --fix` With the increased number of `import` statements since Ember+ecosystem started moving towards es6 modules I've found it frustrating at times trying to search through randomly ordered import statements. Recently I've been sorting imports manually when I've added new code or touched old code so I thought I'd add an ESLint rule to codify it.
244 lines
10 KiB
JavaScript
244 lines
10 KiB
JavaScript
/* jshint expr:true */
|
|
import destroyApp from '../helpers/destroy-app';
|
|
import startApp from '../helpers/start-app';
|
|
import testSelector from 'ember-test-selectors';
|
|
import {afterEach, beforeEach, describe, it} from 'mocha';
|
|
import {authenticateSession, invalidateSession} from 'ghost-admin/tests/helpers/ember-simple-auth';
|
|
import {expect} from 'chai';
|
|
|
|
describe('Acceptance: Subscribers', function() {
|
|
let application;
|
|
|
|
beforeEach(function() {
|
|
application = startApp();
|
|
});
|
|
|
|
afterEach(function() {
|
|
destroyApp(application);
|
|
});
|
|
|
|
it('redirects to signin when not authenticated', async function () {
|
|
invalidateSession(application);
|
|
await visit('/subscribers');
|
|
|
|
expect(currentURL()).to.equal('/signin');
|
|
});
|
|
|
|
it('redirects editors to posts', async function () {
|
|
let role = server.create('role', {name: 'Editor'});
|
|
server.create('user', {roles: [role]});
|
|
|
|
authenticateSession(application);
|
|
await visit('/subscribers');
|
|
|
|
expect(currentURL()).to.equal('/');
|
|
expect(find('.gh-nav-main a:contains("Subscribers")').length, 'sidebar link is visible')
|
|
.to.equal(0);
|
|
});
|
|
|
|
it('redirects authors to posts', async function () {
|
|
let role = server.create('role', {name: 'Author'});
|
|
server.create('user', {roles: [role]});
|
|
|
|
authenticateSession(application);
|
|
await visit('/subscribers');
|
|
|
|
expect(currentURL()).to.equal('/');
|
|
expect(find('.gh-nav-main a:contains("Subscribers")').length, 'sidebar link is visible')
|
|
.to.equal(0);
|
|
});
|
|
|
|
describe('an admin', function () {
|
|
beforeEach(function () {
|
|
let role = server.create('role', {name: 'Administrator'});
|
|
server.create('user', {roles: [role]});
|
|
|
|
return authenticateSession(application);
|
|
});
|
|
|
|
it('can manage subscribers', async function () {
|
|
server.createList('subscriber', 40);
|
|
|
|
authenticateSession(application);
|
|
await visit('/');
|
|
await click('.gh-nav-main a:contains("Subscribers")');
|
|
|
|
// it navigates to the correct page
|
|
expect(currentPath()).to.equal('subscribers.index');
|
|
|
|
// it has correct page title
|
|
expect(document.title, 'page title')
|
|
.to.equal('Subscribers - Test Blog');
|
|
|
|
// it loads the first page
|
|
expect(find('.subscribers-table .lt-body .lt-row').length, 'number of subscriber rows')
|
|
.to.equal(30);
|
|
|
|
// it shows the total number of subscribers
|
|
expect(find(testSelector('total-subscribers')).text().trim(), 'displayed subscribers total')
|
|
.to.equal('(40)');
|
|
|
|
// it defaults to sorting by created_at desc
|
|
let [lastRequest] = server.pretender.handledRequests.slice(-1);
|
|
expect(lastRequest.queryParams.order).to.equal('created_at desc');
|
|
|
|
let createdAtHeader = find('.subscribers-table th:contains("Subscription Date")');
|
|
expect(createdAtHeader.hasClass('is-sorted'), 'createdAt column is sorted')
|
|
.to.be.true;
|
|
expect(createdAtHeader.find('.gh-icon-descending').length, 'createdAt column has descending icon')
|
|
.to.equal(1);
|
|
|
|
// click the column to re-order
|
|
await click('th:contains("Subscription Date")');
|
|
|
|
// it flips the directions and re-fetches
|
|
[lastRequest] = server.pretender.handledRequests.slice(-1);
|
|
expect(lastRequest.queryParams.order).to.equal('created_at asc');
|
|
|
|
createdAtHeader = find('.subscribers-table th:contains("Subscription Date")');
|
|
expect(createdAtHeader.find('.gh-icon-ascending').length, 'createdAt column has ascending icon')
|
|
.to.equal(1);
|
|
|
|
// TODO: scroll test disabled as ember-light-table doesn't calculate
|
|
// the scroll trigger element's positioning against the scroll
|
|
// container - https://github.com/offirgolan/ember-light-table/issues/201
|
|
//
|
|
// // scroll to the bottom of the table to simulate infinite scroll
|
|
// await find('.subscribers-table').scrollTop(find('.subscribers-table .ember-light-table').height() - 50);
|
|
//
|
|
// // trigger infinite scroll
|
|
// await triggerEvent('.subscribers-table tbody', 'scroll');
|
|
//
|
|
// // it loads the next page
|
|
// expect(find('.subscribers-table .lt-body .lt-row').length, 'number of subscriber rows after infinite-scroll')
|
|
// .to.equal(40);
|
|
|
|
// click the add subscriber button
|
|
await click('.gh-btn:contains("Add Subscriber")');
|
|
|
|
// it displays the add subscriber modal
|
|
expect(find('.fullscreen-modal').length, 'add subscriber modal displayed')
|
|
.to.equal(1);
|
|
|
|
// cancel the modal
|
|
await click('.fullscreen-modal .gh-btn:contains("Cancel")');
|
|
|
|
// it closes the add subscriber modal
|
|
expect(find('.fullscreen-modal').length, 'add subscriber modal displayed after cancel')
|
|
.to.equal(0);
|
|
|
|
// save a new subscriber
|
|
await click('.gh-btn:contains("Add Subscriber")');
|
|
await fillIn('.fullscreen-modal input[name="email"]', 'test@example.com');
|
|
await click('.fullscreen-modal .gh-btn:contains("Add")');
|
|
|
|
// the add subscriber modal is closed
|
|
expect(find('.fullscreen-modal').length, 'add subscriber modal displayed after save')
|
|
.to.equal(0);
|
|
|
|
// the subscriber is added to the table
|
|
expect(find('.subscribers-table .lt-body .lt-row:first-of-type .lt-cell:first-of-type').text().trim(), 'first email in list after addition')
|
|
.to.equal('test@example.com');
|
|
|
|
// the table is scrolled to the top
|
|
// TODO: implement scroll to new record after addition
|
|
// expect(find('.subscribers-table').scrollTop(), 'scroll position after addition')
|
|
// .to.equal(0);
|
|
|
|
// the subscriber total is updated
|
|
expect(find(testSelector('total-subscribers')).text().trim(), 'subscribers total after addition')
|
|
.to.equal('(41)');
|
|
|
|
// saving a duplicate subscriber
|
|
await click('.gh-btn:contains("Add Subscriber")');
|
|
await fillIn('.fullscreen-modal input[name="email"]', 'test@example.com');
|
|
await click('.fullscreen-modal .gh-btn:contains("Add")');
|
|
|
|
// the validation error is displayed
|
|
expect(find('.fullscreen-modal .error .response').text().trim(), 'duplicate email validation')
|
|
.to.equal('Email already exists.');
|
|
|
|
// the subscriber is not added to the table
|
|
expect(find('.lt-cell:contains(test@example.com)').length, 'number of "test@example.com rows"')
|
|
.to.equal(1);
|
|
|
|
// the subscriber total is unchanged
|
|
expect(find(testSelector('total-subscribers')).text().trim(), 'subscribers total after failed add')
|
|
.to.equal('(41)');
|
|
|
|
// deleting a subscriber
|
|
await click('.fullscreen-modal .gh-btn:contains("Cancel")');
|
|
await click('.subscribers-table tbody tr:first-of-type button:last-of-type');
|
|
|
|
// it displays the delete subscriber modal
|
|
expect(find('.fullscreen-modal').length, 'delete subscriber modal displayed')
|
|
.to.equal(1);
|
|
|
|
// cancel the modal
|
|
await click('.fullscreen-modal .gh-btn:contains("Cancel")');
|
|
|
|
// it closes the add subscriber modal
|
|
expect(find('.fullscreen-modal').length, 'delete subscriber modal displayed after cancel')
|
|
.to.equal(0);
|
|
|
|
await click('.subscribers-table tbody tr:first-of-type button:last-of-type');
|
|
await click('.fullscreen-modal .gh-btn:contains("Delete")');
|
|
|
|
// the add subscriber modal is closed
|
|
expect(find('.fullscreen-modal').length, 'delete subscriber modal displayed after confirm')
|
|
.to.equal(0);
|
|
|
|
// the subscriber is removed from the table
|
|
expect(find('.subscribers-table .lt-body .lt-row:first-of-type .lt-cell:first-of-type').text().trim(), 'first email in list after addition')
|
|
.to.not.equal('test@example.com');
|
|
|
|
// the subscriber total is updated
|
|
expect(find(testSelector('total-subscribers')).text().trim(), 'subscribers total after addition')
|
|
.to.equal('(40)');
|
|
|
|
// click the import subscribers button
|
|
await click('.gh-btn:contains("Import CSV")');
|
|
|
|
// it displays the import subscribers modal
|
|
expect(find('.fullscreen-modal').length, 'import subscribers modal displayed')
|
|
.to.equal(1);
|
|
expect(find('.fullscreen-modal input[type="file"]').length, 'import modal contains file input')
|
|
.to.equal(1);
|
|
|
|
// cancel the modal
|
|
await click('.fullscreen-modal .gh-btn:contains("Cancel")');
|
|
|
|
// it closes the import subscribers modal
|
|
expect(find('.fullscreen-modal').length, 'import subscribers modal displayed after cancel')
|
|
.to.equal(0);
|
|
|
|
await click('.gh-btn:contains("Import CSV")');
|
|
await fileUpload('.fullscreen-modal input[type="file"]', ['test'], {name: 'test.csv'});
|
|
|
|
// modal title changes
|
|
expect(find('.fullscreen-modal h1').text().trim(), 'import modal title after import')
|
|
.to.equal('Import Successful');
|
|
|
|
// modal button changes
|
|
expect(find('.fullscreen-modal .modal-footer button').text().trim(), 'import modal button text after import')
|
|
.to.equal('Close');
|
|
|
|
// subscriber total is updated
|
|
expect(find(testSelector('total-subscribers')).text().trim(), 'subscribers total after import')
|
|
.to.equal('(90)');
|
|
|
|
// table is reset
|
|
[lastRequest] = server.pretender.handledRequests.slice(-1);
|
|
expect(lastRequest.url, 'endpoint requested after import')
|
|
.to.match(/\/subscribers\/\?/);
|
|
expect(lastRequest.queryParams.page, 'page requested after import')
|
|
.to.equal('1');
|
|
|
|
expect(find('.subscribers-table .lt-body .lt-row').length, 'number of rows in table after import')
|
|
.to.equal(30);
|
|
|
|
// close modal
|
|
});
|
|
});
|
|
});
|