Ghost/ghost/admin/tests/acceptance/editor/publish-flow-test.js
Chris Raible 6b8f5fe7aa
🐛 Fixed UI bug when selecting specific recipients by label (#16543)
closes TryGhost/Team#2859

- when removing all selected labels/newsletters, the UI would uncheck
the Specific People checkbox and hide the label/newsletter selection
- this change forces the Specific People checkbox to be checked even if
no labels/newsletters are selected
- test enhanced to cover this specific edge case
2023-04-03 14:45:58 -07:00

650 lines
31 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import loginAsRole from '../../helpers/login-as-role';
import moment from 'moment-timezone';
import {blur, click, fillIn, find, findAll} from '@ember/test-helpers';
import {clickTrigger, removeMultipleOption, selectChoose} from 'ember-power-select/test-support/helpers';
import {disableMailgun, enableMailgun} from '../../helpers/mailgun';
import {disableMembers, enableMembers} from '../../helpers/members';
import {disableNewsletters, enableNewsletters} from '../../helpers/newsletters';
import {enableStripe} from '../../helpers/stripe';
import {expect} from 'chai';
import {setupApplicationTest} from 'ember-mocha';
import {setupMirage} from 'ember-cli-mirage/test-support';
import {visit} from '../../helpers/visit';
describe('Acceptance: Publish flow', function () {
let hooks = setupApplicationTest();
setupMirage(hooks);
beforeEach(function () {
this.server.loadFixtures();
});
it('has minimal features for contributors', async function () {
await loginAsRole('Contributor', this.server);
const post = this.server.create('post', {status: 'draft'});
await visit(`/editor/post/${post.id}`);
expect(find('[data-test-button="publish-flow"]'), 'publish button').to.not.exist;
expect(find('[data-test-button="contributor-preview"]'), 'contributor preview button').to.exist;
expect(find('[data-test-button="contributor-save"]'), 'contributor save button').to.exist;
await fillIn('[data-test-editor-title-input]', 'Contributor save test');
await click('[data-test-button="contributor-save"]');
expect(post.title, 'post title after save').to.equal('Contributor save test');
});
it('triggers post validation before opening', async function () {
await loginAsRole('Administrator', this.server);
const post = this.server.create('post', {status: 'draft'});
await visit(`/editor/post/${post.id}`);
await fillIn('[data-test-editor-title-input]', Array(260).join('a'));
await blur('[data-test-editor-title-input]');
await click('[data-test-button="publish-flow"]');
expect(find('.gh-alert'), 'validation shown in alert').to.exist;
expect(find('[data-test-modal="publish-flow"]'), 'publish flow modal').to.not.exist;
});
it('handles timezones correctly when scheduling');
// email unavailable state occurs when
// 1. members signup access is set to "none"
// 2. default newsletter recipients is set to "disabled"
async function testEmailUnavailableFlow() {
await loginAsRole('Administrator', this.server);
const post = this.server.create('post', {status: 'draft'});
await visit(`/editor/post/${post.id}`);
await fillIn('[data-test-editor-title-input]', 'Members disabled publish test');
await blur('[data-test-editor-title-input]');
await click('[data-test-button="publish-flow"]');
expect(find('[data-test-modal="publish-flow"]'), 'publish flow modal').to.exist;
expect(find('[data-test-publish-flow="options"]'), 'options step').to.exist;
// members/newsletters disabled =
// - fixed "Publish on site" publish type
// - no email options shown
// - standard publish time options
expect(find('[data-test-setting="publish-type"]'), 'publish type setting').to.exist;
expect(
find('[data-test-setting="publish-type"] [data-test-setting-title]'), 'publish type title'
).to.contain.trimmed.text('Publish on site');
expect(find('[data-test-setting="publish-type"] [data-test-setting-title]')).to.not.match('button');
expect(find('[data-test-setting="email-recipients"]')).to.not.exist;
expect(find('[data-test-setting="publish-at"]'), 'publish time setting').to.exist;
expect(
find('[data-test-setting="publish-at"] [data-test-setting-title]'), 'publish time title'
).to.contain.trimmed.text('Right now');
expect(find('[data-test-setting="publish-at"] [data-test-setting-title]')).to.match('button');
await click('[data-test-button="continue"]');
expect(find('[data-test-publish-flow="confirm"]'), 'confirm step').to.exist;
expect(find('[data-test-text="confirm-details"]'), 'confirmation text')
.to.have.rendered.text('Your post will be published on your site.');
expect(find('[data-test-button="confirm-publish"]'), 'publish button text')
.to.have.rendered.text('Publish post, right now');
await click('[data-test-button="confirm-publish"]');
expect(post.status, 'post status after publish').to.equal('published');
expect(find('[data-test-publish-flow="complete"]'), 'complete step').to.exist;
expect(find('[data-test-complete-title]'), 'complete title').to.have.rendered.text('Boom. Its out there. Thats 1 post published, keep going!');
expect(find('[data-test-complete-bookmark]'), 'bookmark card').to.exist;
// "revert to draft" only shown for scheduled posts
expect(find('[data-test-button="revert-to-draft"]'), 'revert-to-draft button').to.not.exist;
// publish/preview buttons are hidden on complete step
expect(find('[data-test-button="publish-flow-preview"]'), 'preview button on complete step').to.not.exist;
expect(find('[data-test-button="publish-flow-publish"]'), 'publish button on complete step').to.not.exist;
await click('[data-test-button="back-to-editor"]');
expect(find('[data-test-button="publish-flow"]'), 'publish button after publishing').to.not.exist;
expect(find('[data-test-button="update-flow"]'), 'update button after publishing').to.exist;
await click('[data-test-button="update-flow"]');
expect(find('[data-test-modal="update-flow"]'), 'update flow modal').to.exist;
expect(find('[data-test-update-flow-title]')).to.have.rendered.text('This post has been published');
expect(find('[data-test-update-flow-confirmation]')).to.contain.rendered.text('Your post was published on your site');
const savedPublishAt = moment(post.publishedAt).utc();
expect(find('[data-test-update-flow-confirmation]')).to.contain.rendered.text(`on ${savedPublishAt.format('D MMM YYYY')} at ${savedPublishAt.format('HH:mm')}`);
expect(find('[data-test-button="revert-to-draft"]')).to.exist;
expect(find('[data-test-button="revert-to-draft"]')).to.contain.rendered.text('Unpublish and revert to private draft');
await click('[data-test-button="revert-to-draft"]');
expect(post.status).to.equal('draft');
expect(find('[data-test-modal="update-flow"]')).to.not.exist;
expect(find('[data-test-button="publish-flow"]')).to.exist;
}
it('can publish with members disabled', async function () {
await disableMembers(this.server);
await testEmailUnavailableFlow.apply(this);
});
it('can publish with newsletters disabled', async function () {
await enableMembers(this.server);
await disableNewsletters(this.server);
await testEmailUnavailableFlow.apply(this);
});
describe('members enabled', function () {
beforeEach(async function () {
enableMembers(this.server);
enableMailgun(this.server);
enableNewsletters(this.server);
enableStripe(this.server);
// at least one member is required for publish+send to be available
const label = this.server.create('label');
this.server.createList('member', 3, {status: 'free', labels: [label]});
this.server.createList('member', 4, {status: 'paid'});
});
it('can publish+send with single newsletter', async function () {
await loginAsRole('Administrator', this.server);
const post = this.server.create('post', {status: 'draft'});
await visit(`/editor/post/${post.id}`);
await click('[data-test-button="publish-flow"]');
expect(
find('[data-test-setting="publish-type"] [data-test-setting-title]'), 'publish type title'
).to.have.trimmed.rendered.text('Publish and email');
// newsletter is not mentioned in the recipients title
expect(
find('[data-test-setting="email-recipients"] [data-test-setting-title]'), 'publish type title'
).to.have.trimmed.rendered.text('All 7 subscribers');
// newsletter select shouldn't exist
await click('[data-test-setting="email-recipients"] [data-test-setting-title]');
expect(find('[data-test-select="newsletter"]'), 'newsletter select').to.not.exist;
// check that the Free + Paid members toggle works properly
const freeCheckbox = find('[data-test-checkbox="free-members"]');
const paidCheckbox = find('[data-test-checkbox="paid-members"]');
// toggles exist
expect(freeCheckbox, 'free members checkbox').to.exist;
expect(paidCheckbox, 'paid members checkbox').to.exist;
// both toggles are checked by default
expect(freeCheckbox.checked, 'free members checkbox checked').to.be.true;
expect(paidCheckbox.checked, 'paid members checkbox checked').to.be.true;
// uncheck both and check that the title updates
await click(freeCheckbox);
await click(paidCheckbox);
expect(freeCheckbox.checked, 'free members checkbox checked').to.be.false;
expect(paidCheckbox.checked, 'paid members checkbox checked').to.be.false;
expect(
find('[data-test-setting="email-recipients"] [data-test-setting-title]')
).to.have.trimmed.rendered.text('Not sent as newsletter');
// check them both again
await click(freeCheckbox);
await click(paidCheckbox);
// check that specific filters work
// refs https://github.com/TryGhost/Team/issues/2859
// select the Specific people checkbox
const specificCheckbox = find('[data-test-checkbox="specific-members"]');
await click(specificCheckbox);
expect(specificCheckbox.checked, 'specific people checkbox checked').to.be.true;
// check that the select box is displayed
const specificSelect = find('.select-members-recipient');
expect(specificSelect, 'specific members select').to.exist;
// select a specific label to send the newsletter to
await clickTrigger('[data-test-select="specific-members"]');
await selectChoose('[data-test-select="specific-members"]', 'Label 0');
// uncheck everything, then recheck specific members
await click(freeCheckbox);
await click(paidCheckbox);
await click(specificCheckbox);
await click(specificCheckbox);
// Remove selected option and check that the select box is still visible
await removeMultipleOption('[data-test-select="specific-members"]', 'Label 0');
expect(specificCheckbox.checked, 'specific people checkbox checked').to.be.true;
// Uncheck specific and recheck free + paid
await click(freeCheckbox);
await click(paidCheckbox);
await click(specificCheckbox);
expect(freeCheckbox.checked, 'free members checkbox checked').to.be.true;
expect(paidCheckbox.checked, 'paid members checkbox checked').to.be.true;
await click('[data-test-button="continue"]');
// confirm text is correct
expect(find('[data-test-text="confirm-details"]')).to.contain.rendered
.text('will be published on your site, and delivered to all 7 subscribers.');
expect(find('[data-test-button="confirm-publish"]')).to.have.rendered
.text('Publish & send, right now');
await click('[data-test-button="confirm-publish"]');
// complete text has right count
expect(find('[data-test-complete-title]')).to.contain.rendered
.text('Thats 1 post published');
});
it('can publish+send with multiple newsletters', async function () {
const newsletter = this.server.create('newsletter', {
name: 'Second newsletter',
slug: 'second-newsletter',
status: 'active',
subscribeOnSignup: true
});
this.server.create('newsletter', {
name: 'Archived newsletter',
slug: 'archived-newsletter',
status: 'archived',
subscribeOnSignup: true
});
this.server.create('member', {newsletters: [newsletter], status: 'free'});
await loginAsRole('Administrator', this.server);
const post = this.server.create('post', {status: 'draft'});
await visit(`/editor/post/${post.id}`);
await click('[data-test-button="publish-flow"]');
// newsletter is mentioned in the recipients title
expect(
find('[data-test-setting="email-recipients"] [data-test-setting-title]'), 'publish type title'
).to.have.trimmed.rendered.text('All 8 subscribers of Default newsletter');
// newsletter select should exist with all active newsletters listed
await click('[data-test-setting="email-recipients"] [data-test-setting-title]');
expect(find('[data-test-select="newsletter"]'), 'newsletter select').to.exist;
await clickTrigger('[data-test-select="newsletter"]');
expect(findAll('.ember-power-select-dropdown [data-test-select-option]').length).to.equal(2);
// selecting a different newsletter updates recipient count
await selectChoose('[data-test-select="newsletter"]', 'Second newsletter');
expect(
find('[data-test-setting="email-recipients"] [data-test-setting-title]'), 'publish type title'
).to.have.trimmed.rendered.text('1 subscriber of Second newsletter');
await click('[data-test-button="continue"]');
// confirm text is correct
expect(find('[data-test-text="confirm-details"]')).to.contain.rendered
.text('will be published on your site, and delivered to all 1 subscriber of Second newsletter.');
expect(find('[data-test-button="confirm-publish"]')).to.have.rendered
.text('Publish & send, right now');
await click('[data-test-button="confirm-publish"]');
// saved with correct newsletter id
expect(post.newsletterId).to.equal(newsletter.id);
});
it('can schedule publish+send', async function () {
await loginAsRole('Administrator', this.server);
const post = this.server.create('post', {status: 'draft'});
await visit(`/editor/post/${post.id}`);
await click('[data-test-button="publish-flow"]');
expect(find('[data-test-setting="publish-at"] [data-test-setting-title]')).to.have.rendered
.text('Right now');
const siteTz = this.server.db.settings.findBy({key: 'timezone'}).value;
const plus10 = moment().tz(siteTz).add(10, 'minutes').set({});
await click('[data-test-setting="publish-at"] [data-test-setting-title]');
await click('[data-test-radio="schedule"]');
// date + time inputs are shown, defaults to now+5 mins
expect(find('[data-test-setting="publish-at"] [data-test-date-time-picker-datepicker]'), 'datepicker').to.exist;
expect(find('[data-test-setting="publish-at"] [data-test-date-time-picker-date-input]'), 'initial datepicker value')
.to.have.value(plus10.format('YYYY-MM-DD'));
expect(find('[data-test-setting="publish-at"] [data-test-date-time-picker-time-input]'), 'time input').to.exist;
expect(find('[data-test-setting="publish-at"] [data-test-date-time-picker-time-input]'), 'initial time input value')
.to.have.value(plus10.format('HH:mm'));
// can set a new date and time
const newDate = moment().tz(siteTz).add(4, 'days').add(5, 'hours').set('second', 0);
await fillIn('[data-test-setting="publish-at"] [data-test-date-time-picker-date-input]', newDate.format('YYYY-MM-DD'));
await blur('[data-test-setting="publish-at"] [data-test-date-time-picker-date-input]');
await fillIn('[data-test-setting="publish-at"] [data-test-date-time-picker-time-input]', newDate.format('HH:mm'));
await blur('[data-test-setting="publish-at"] [data-test-date-time-picker-time-input]');
expect(find('[data-test-setting="publish-at"] [data-test-date-time-picker-time-input]')).to.have.value(newDate.format('HH:mm'));
expect(find('[data-test-setting="publish-at"] [data-test-setting-title]'), 'publish-at title after change').to.have.rendered
.text('In 4 days');
await click('[data-test-button="continue"]');
// has correct confirm text
expect(find('[data-test-text="confirm-details"]')).to.have.rendered
.text(`On ${newDate.format('D MMM YYYY')} at ${newDate.format('HH:mm')} your post will be published on your site, and delivered to all 7 subscribers.`);
expect(find('[data-test-button="confirm-publish"]')).to.have.rendered
.text(`Publish & send, on ${newDate.format('MMMM Do')}`);
await click('[data-test-button="confirm-publish"]');
// saved with correct details
expect(post.status).to.equal('scheduled');
expect(moment.utc(post.publishedAt).format('YYYY-MM-DD HH:mm')).to.equal(moment(newDate).utc().format('YYYY-MM-DD HH:mm'));
expect(post.newsletterId).to.equal('1');
});
it('can send', async function () {
await loginAsRole('Administrator', this.server);
const post = this.server.create('post', {status: 'draft'});
await visit(`/editor/post/${post.id}`);
await click('[data-test-button="publish-flow"]');
await click('[data-test-setting="publish-type"] [data-test-setting-title]');
await click('[data-test-publish-type="send"]');
expect(find('[data-test-setting="publish-type"] [data-test-setting-title]')).to.have.rendered
.text('Email');
await click('[data-test-button="continue"]');
// has correct confirm text
expect(find('[data-test-text="confirm-details"]')).to.have.rendered
.text(`Your post will be delivered to all 7 subscribers, and will not be published on your site.`);
expect(find('[data-test-button="confirm-publish"]')).to.have.rendered
.text(`Send email, right now`);
await click('[data-test-button="confirm-publish"]');
expect(post.attrs.emailOnly).to.be.true;
});
it('can schedule send', async function () {
await loginAsRole('Administrator', this.server);
const post = this.server.create('post', {status: 'draft'});
await visit(`/editor/post/${post.id}`);
await click('[data-test-button="publish-flow"]');
await click('[data-test-setting="publish-type"] [data-test-setting-title]');
await click('[data-test-publish-type="send"]');
expect(find('[data-test-setting="publish-type"] [data-test-setting-title]')).to.have.rendered
.text('Email');
await click('[data-test-setting="publish-at"] [data-test-setting-title]');
await click('[data-test-setting="publish-at"] [data-test-radio="schedule"]');
const siteTz = this.server.db.settings.findBy({key: 'timezone'}).value;
const newDate = moment().tz(siteTz).add(4, 'days').add(5, 'hours').set('second', 0);
await fillIn('[data-test-setting="publish-at"] [data-test-date-time-picker-date-input]', newDate.format('YYYY-MM-DD'));
await blur('[data-test-setting="publish-at"] [data-test-date-time-picker-date-input]');
await fillIn('[data-test-setting="publish-at"] [data-test-date-time-picker-time-input]', newDate.format('HH:mm'));
await blur('[data-test-setting="publish-at"] [data-test-date-time-picker-time-input]');
expect(find('[data-test-setting="publish-at"] [data-test-date-time-picker-time-input]')).to.have.value(newDate.format('HH:mm'));
expect(find('[data-test-setting="publish-at"] [data-test-setting-title]'), 'publish-at title after change').to.have.rendered
.text('In 4 days');
await click('[data-test-button="continue"]');
// has correct confirm text
expect(find('[data-test-text="confirm-details"]')).to.have.rendered
.text(`On ${newDate.format('D MMM YYYY')} at ${newDate.format('HH:mm')} your post will be delivered to all 7 subscribers, and will not be published on your site.`);
expect(find('[data-test-button="confirm-publish"]')).to.have.rendered
.text(`Send email, on ${newDate.format('MMMM Do')}`);
await click('[data-test-button="confirm-publish"]');
expect(post.attrs.emailOnly).to.be.true;
});
it('can publish');
it('can schedule publish');
it('respects default recipient settings - usually nobody', async function () {
// switch to "usually nobody" setting
// - doing it this way so we're not testing potentially stale mocked setting keys/values
await loginAsRole('Administrator', this.server);
await visit('/settings/newsletters');
await click('[data-test-toggle-membersemail]');
await selectChoose('[data-test-select="default-recipients"]', 'Usually nobody');
await click('[data-test-button="save-members-settings"]');
const post = this.server.create('post', {status: 'draft'});
await visit(`/editor/post/${post.id}`);
await click('[data-test-button="publish-flow"]');
expect(
find('[data-test-setting="publish-type"] [data-test-setting-title]'), 'publish type title'
).to.have.trimmed.rendered.text('Publish');
expect(
find('[data-test-setting="email-recipients"] [data-test-setting-title]'), 'recipients title'
).to.have.trimmed.rendered.text('Not sent as newsletter');
await click('[data-test-setting="publish-type"] [data-test-setting-title]');
// email-related options are enabled
expect(find('[data-test-publish-type="publish+send"]')).to.not.have.attribute('disabled');
expect(find('[data-test-publish-type="send"]')).to.not.have.attribute('disabled');
await click('[data-test-publish-type="publish+send"]');
expect(
find('[data-test-setting="email-recipients"] [data-test-setting-title]'), 'recipients title'
).to.have.trimmed.rendered.text('All 7 subscribers');
});
it('handles Mailgun not being set up', async function () {
disableMailgun(this.server);
await loginAsRole('Administrator', this.server);
const post = this.server.create('post', {status: 'draft'});
await visit(`/editor/post/${post.id}`);
await click('[data-test-button="publish-flow"]');
expect(
find('[data-test-setting="publish-type"] [data-test-setting-title]'), 'publish type title'
).to.have.trimmed.rendered.text('Publish');
await click('[data-test-setting="publish-type"] [data-test-setting-title]');
// mailgun not set up notice is shown
expect(find('[data-test-publish-type-error]'), 'publish type error').to.exist;
expect(find('[data-test-publish-type-error="no-mailgun"]'), 'publish type error text').to.exist;
// email-related options are disabled
expect(find('[data-test-publish-type="publish+send"]')).to.have.attribute('disabled');
expect(find('[data-test-publish-type="send"]')).to.have.attribute('disabled');
});
it('handles no members present', async function () {
this.server.db.members.remove();
this.server.db.newsletters.update({memberIds: []});
await loginAsRole('Administrator', this.server);
const post = this.server.create('post', {status: 'draft'});
await visit(`/editor/post/${post.id}`);
await click('[data-test-button="publish-flow"]');
expect(
find('[data-test-setting="publish-type"] [data-test-setting-title]'), 'publish type title'
).to.have.trimmed.rendered.text('Publish');
await click('[data-test-setting="publish-type"] [data-test-setting-title]');
// no-members notice is shown
expect(find('[data-test-publish-type-error]'), 'publish type error').to.exist;
expect(find('[data-test-publish-type-error="no-members"]'), 'publish type error text').to.exist;
// email-related options are disabled
expect(find('[data-test-publish-type="publish+send"]')).to.have.attribute('disabled');
expect(find('[data-test-publish-type="send"]')).to.have.attribute('disabled');
});
it('handles over-member limit before publish', async function () {
// set members limit
const config = this.server.db.configs.find(1);
config.hostSettings = {
limits: {
members: {
max: 9,
error: 'Your plan supports up to {{max}} members. Please upgrade to reenable publishing.'
}
}
};
this.server.db.configs.update(1, config);
// go over limit (7 created by default in beforeEach)
this.server.createList('member', 3);
// simulate /members/stats/count/ endpoint that's used to get total member count
// TODO: can the default endpoint mock handle this?
this.server.get('/members/stats/count', function () {
return {
total: 10,
resource: 'members',
data: []
};
});
await loginAsRole('Administrator', this.server);
const post = this.server.create('post', {status: 'draft'});
// try to publish post
await visit(`/editor/post/${post.id}`);
await click('[data-test-button="publish-flow"]');
expect(find('[data-test-publish-type-error]'), 'publish disabled error').to.exist;
expect(find('[data-test-publish-type-error="publish-disabled"]'), 'publish disabled error')
.to.have.trimmed.text('Your plan supports up to 9 members. Please upgrade to reenable publishing.');
expect(find('[data-test-button="continue"]'), 'continue button').to.not.exist;
});
it('handles over-member limit when confirming', async function () {
await loginAsRole('Administrator', this.server);
const post = this.server.create('post', {status: 'draft'});
await visit(`/editor/post/${post.id}`);
await click('[data-test-button="publish-flow"]');
await click('[data-test-button="continue"]');
this.server.put('/posts/:id/', function () {
return {
errors: [
{
message: 'Host Limit error, cannot edit post.',
context: 'Your plan supports up to 1,000 members. Please upgrade to reenable publishing.',
type: 'HostLimitError',
details: {
name: 'members',
limit: 1000,
total: 37406
},
property: null,
help: 'https://ghost.org/help/',
code: null,
id: '212d9110-3db6-11ed-9651-e9a82ad49a7a',
ghostErrorCode: null
}
]
};
});
await click('[data-test-button="confirm-publish"]');
expect(find('[data-test-confirm-error]'), 'confirm error').to.exist;
expect(find('[data-test-confirm-error]'), 'confirm error')
.to.have.trimmed.text('Your plan supports up to 1,000 members. Please upgrade to reenable publishing.');
});
it('(as editor) handles over-member limits', async function () {
// set members limit
const config = this.server.db.configs.find(1);
config.hostSettings = {
limits: {
members: {
max: 9,
error: 'Your plan supports up to {{max}} members. Please upgrade to reenable publishing.'
}
}
};
this.server.db.configs.update(1, config);
// go over limit (7 created by default in beforeEach)
this.server.createList('member', 3);
await loginAsRole('Editor', this.server);
const post = this.server.create('post', {status: 'draft'});
// try to publish post
await visit(`/editor/post/${post.id}`);
await click('[data-test-button="publish-flow"]');
await click('[data-test-button="continue"]');
this.server.put('/posts/:id/', function () {
return {
errors: [
{
message: 'Host Limit error, cannot edit post.',
context: 'Your plan supports up to 1,000 members. Please upgrade to reenable publishing.',
type: 'HostLimitError',
details: {
name: 'members',
limit: 1000,
total: 37406
},
property: null,
help: 'https://ghost.org/help/',
code: null,
id: '212d9110-3db6-11ed-9651-e9a82ad49a7a',
ghostErrorCode: null
}
]
};
});
await click('[data-test-button="confirm-publish"]');
expect(find('[data-test-confirm-error]'), 'confirm error').to.exist;
expect(find('[data-test-confirm-error]'), 'confirm error')
.to.have.trimmed.text('Your plan supports up to 1,000 members. Please upgrade to reenable publishing.');
});
it('handles server error when confirming');
it('handles email sending error');
});
});