diff --git a/ghost/admin/app/components/modals/newsletters/confirm-archive.hbs b/ghost/admin/app/components/modals/newsletters/confirm-archive.hbs
index 5983d0058e..ff19fafdd3 100644
--- a/ghost/admin/app/components/modals/newsletters/confirm-archive.hbs
+++ b/ghost/admin/app/components/modals/newsletters/confirm-archive.hbs
@@ -18,6 +18,7 @@
type="button"
class="gh-btn"
{{on "click" (fn @close false)}}
+ data-test-button="cancel-newsletter-archive"
>
Cancel
@@ -29,6 +30,7 @@
@task={{@data.archiveNewsletterTask}}
@taskArgs={{@data.newsletter}}
@class="gh-btn gh-btn-black gh-btn-icon"
+ data-test-button="confirm-newsletter-archive"
/>
-
\ No newline at end of file
+
diff --git a/ghost/admin/app/components/modals/newsletters/confirm-unarchive.hbs b/ghost/admin/app/components/modals/newsletters/confirm-unarchive.hbs
index fe365a743f..9d93f3ab8f 100644
--- a/ghost/admin/app/components/modals/newsletters/confirm-unarchive.hbs
+++ b/ghost/admin/app/components/modals/newsletters/confirm-unarchive.hbs
@@ -1,5 +1,5 @@
-
-
\ No newline at end of file
+
diff --git a/ghost/admin/app/components/settings/newsletters/newsletter-management.hbs b/ghost/admin/app/components/settings/newsletters/newsletter-management.hbs
index d4d26dd25a..002c5dd95a 100644
--- a/ghost/admin/app/components/settings/newsletters/newsletter-management.hbs
+++ b/ghost/admin/app/components/settings/newsletters/newsletter-management.hbs
@@ -3,7 +3,7 @@
Newsletters
{{#if this.archivedNewsletters}}
-
+
{{#if (eq newsletter.status "active")}}
-
+
Archive
{{/if}}
{{#if (eq newsletter.status "archived")}}
-
+
Reactivate
diff --git a/ghost/admin/tests/acceptance/settings/newsletters-test.js b/ghost/admin/tests/acceptance/settings/newsletters-test.js
index ed75d65889..7a4d5f785f 100644
--- a/ghost/admin/tests/acceptance/settings/newsletters-test.js
+++ b/ghost/admin/tests/acceptance/settings/newsletters-test.js
@@ -136,157 +136,55 @@ describe('Acceptance: Settings - Newsletters', function () {
await fillIn('input#newsletter-title', name);
}
- it('can create new newsletter', async function () {
- await visit('/settings/newsletters');
- await click('[data-test-button="add-newsletter"]');
+ describe('Creating newsletters', function () {
+ it('can create new newsletter', async function () {
+ await visit('/settings/newsletters');
+ await click('[data-test-button="add-newsletter"]');
- // Check if modal opens
- expect(find('[data-test-modal="create-newsletter"]'), 'Create newsletter modal').to.exist;
+ // Check if modal opens
+ expect(find('[data-test-modal="create-newsletter"]'), 'Create newsletter modal').to.exist;
- // Fill in the newsletter name
- await fillName('My new newsletter');
+ // Fill in the newsletter name
+ await fillName('My new newsletter');
- // Fill in the newsletter description
- await fillIn('textarea#newsletter-description', 'My newsletter description');
+ // Fill in the newsletter description
+ await fillIn('textarea#newsletter-description', 'My newsletter description');
- await checkSave({});
- });
-
- it('validates create newsletter before saving', async function () {
- await visit('/settings/newsletters');
- await click('[data-test-button="add-newsletter"]');
-
- // Check if modal opens
- expect(find('[data-test-modal="create-newsletter"]'), 'Create newsletter modal').to.exist;
-
- // Invalid name error when you try to save
- await checkValidationError({'input#newsletter-title': /Please enter a name./});
-
- // Fill in the newsletter name
- await fillName('My new newsletter');
-
- // Everything should be valid
- await checkSave({});
- });
-
- it('can edit via menu if multiple newsletters', async function () {
- // Create an extra newsletter
- this.server.create('newsletter', {status: 'active', name: 'test newsletter', slug: 'test-newsletter'});
- await visit('/settings/newsletters');
-
- await click('[data-test-newsletter-menu-trigger]');
- await click('[data-test-button="customize-newsletter"]');
-
- // Check if modal opens
- expect(find('[data-test-modal="edit-newsletter"]'), 'Edit newsletter modal').to.exist;
- });
-
- it('validates edit fields before saving', async function () {
- await visit('/settings/newsletters');
-
- // When we only have a single newsletter, the customize button is shown instead of the menu button
- await click('[data-test-button="customize-newsletter"]');
-
- // Check if modal opens
- expect(find('[data-test-modal="edit-newsletter"]'), 'Edit newsletter modal').to.exist;
-
- // Clear newsletter name
- await fillName('');
-
- // Invalid name error when you try to save
- await checkValidationError({'input#newsletter-title': /Please enter a name./});
-
- // Fill in the newsletter name
- await fillName('My new newsletter');
-
- // Enter an invalid email
- await openTab('general.email');
- await fillIn('input#newsletter-sender-email', 'invalid-email');
-
- // Check if it complains about the invalid email
- await checkValidationError({
- 'input#newsletter-sender-email': /Invalid email./
+ await checkSave({});
});
- await fillIn('input#newsletter-sender-email', 'valid-email@email.com');
+ it('validates create newsletter before saving', async function () {
+ await visit('/settings/newsletters');
+ await click('[data-test-button="add-newsletter"]');
- // Everything should be valid
- await checkSave({
- edit: true,
- verifyEmail: /default email address \(noreply/
+ // Check if modal opens
+ expect(find('[data-test-modal="create-newsletter"]'), 'Create newsletter modal').to.exist;
+
+ // Invalid name error when you try to save
+ await checkValidationError({'input#newsletter-title': /Please enter a name./});
+
+ // Fill in the newsletter name
+ await fillName('My new newsletter');
+
+ // Everything should be valid
+ await checkSave({});
});
});
- it('can open / close all tabs', async function () {
- await visit('/settings/newsletters');
+ describe('Editing newsletters', function () {
+ it('can edit via menu if multiple newsletters', async function () {
+ // Create an extra newsletter
+ this.server.create('newsletter', {status: 'active', name: 'test newsletter', slug: 'test-newsletter'});
+ await visit('/settings/newsletters');
- // When we only have a single newsletter, the customize button is shown instead of the menu button
- await click('[data-test-button="customize-newsletter"]');
+ await click('[data-test-newsletter-menu-trigger]');
+ await click('[data-test-button="customize-newsletter"]');
- // Check if modal opens
- expect(find('[data-test-modal="edit-newsletter"]'), 'Edit newsletter modal').to.exist;
-
- await openTab('general.name', false);
- await closeTab('general.name', false);
-
- await openTab('general.email', false);
- await closeTab('general.email', false);
-
- await openTab('general.member', false);
- await closeTab('general.member', false);
-
- await openTab('design.header', false);
- await closeTab('design.header', false);
-
- await openTab('design.body', false);
- await closeTab('design.body', false);
-
- await openTab('design.footer', false);
- await closeTab('design.footer', false);
- });
-
- it('shows current sender email in verify modal', async function () {
- this.server.create('newsletter', {status: 'active', name: 'test newsletter', slug: 'test-newsletter', senderEmail: 'test@example.com'});
-
- await visit('/settings/newsletters');
-
- // Edit the last newsletter
- await click('[data-test-newsletter="test-newsletter"] [data-test-newsletter-menu-trigger]');
- await click('[data-test-button="customize-newsletter"]');
-
- // Check if modal opens
- expect(find('[data-test-modal="edit-newsletter"]'), 'Edit newsletter modal').to.exist;
-
- await openTab('general.email');
- await fillIn('input#newsletter-sender-email', 'valid-email@email.com');
-
- // Everything should be valid
- await checkSave({
- edit: true,
- verifyEmail: /previous email address \(test@example\.com\)/
+ // Check if modal opens
+ expect(find('[data-test-modal="edit-newsletter"]'), 'Edit newsletter modal').to.exist;
});
- });
- it('does not ask to confirm saved changes', async function () {
- await visit('/settings/newsletters');
-
- // When we only have a single newsletter, the customize button is shown instead of the menu button
- await click('[data-test-button="customize-newsletter"]');
-
- // Check if modal opens
- expect(find('[data-test-modal="edit-newsletter"]'), 'Edit newsletter modal').to.exist;
-
- // Make no changes
-
- // Everything should be valid
- await checkCancel({
- edit: true,
- shouldConfirm: false
- });
- });
-
- it('asks to confirm unsaved changes', async function () {
- async function doCheck(tabName, field) {
+ it('validates edit fields before saving', async function () {
await visit('/settings/newsletters');
// When we only have a single newsletter, the customize button is shown instead of the menu button
@@ -295,84 +193,305 @@ describe('Acceptance: Settings - Newsletters', function () {
// Check if modal opens
expect(find('[data-test-modal="edit-newsletter"]'), 'Edit newsletter modal').to.exist;
- // Make a change
- await openTab(tabName, false);
- if (field.input) {
- await fillIn(field.input, field.value ?? 'my changed value');
- } else if (field.toggle) {
- await click(field.toggle);
- } else if (field.dropdown) {
- // Open dropdown
- await click(`${field.dropdown} .ember-basic-dropdown-trigger`);
+ // Clear newsletter name
+ await fillName('');
- // Click first not-selected option
- await click(`${field.dropdown} li.ember-power-select-option[aria-current="false"]`);
- }
+ // Invalid name error when you try to save
+ await checkValidationError({'input#newsletter-title': /Please enter a name./});
+
+ // Fill in the newsletter name
+ await fillName('My new newsletter');
+
+ // Enter an invalid email
+ await openTab('general.email');
+ await fillIn('input#newsletter-sender-email', 'invalid-email');
+
+ // Check if it complains about the invalid email
+ await checkValidationError({
+ 'input#newsletter-sender-email': /Invalid email./
+ });
+
+ await fillIn('input#newsletter-sender-email', 'valid-email@email.com');
+
+ // Everything should be valid
+ await checkSave({
+ edit: true,
+ verifyEmail: /default email address \(noreply/
+ });
+ });
+
+ it('can open / close all tabs', async function () {
+ await visit('/settings/newsletters');
+
+ // When we only have a single newsletter, the customize button is shown instead of the menu button
+ await click('[data-test-button="customize-newsletter"]');
+
+ // Check if modal opens
+ expect(find('[data-test-modal="edit-newsletter"]'), 'Edit newsletter modal').to.exist;
+
+ await openTab('general.name', false);
+ await closeTab('general.name', false);
+
+ await openTab('general.email', false);
+ await closeTab('general.email', false);
+
+ await openTab('general.member', false);
+ await closeTab('general.member', false);
+
+ await openTab('design.header', false);
+ await closeTab('design.header', false);
+
+ await openTab('design.body', false);
+ await closeTab('design.body', false);
+
+ await openTab('design.footer', false);
+ await closeTab('design.footer', false);
+ });
+
+ it('shows current sender email in verify modal', async function () {
+ this.server.create('newsletter', {status: 'active', name: 'test newsletter', slug: 'test-newsletter', senderEmail: 'test@example.com'});
+
+ await visit('/settings/newsletters');
+
+ // Edit the last newsletter
+ await click('[data-test-newsletter="test-newsletter"] [data-test-newsletter-menu-trigger]');
+ await click('[data-test-button="customize-newsletter"]');
+
+ // Check if modal opens
+ expect(find('[data-test-modal="edit-newsletter"]'), 'Edit newsletter modal').to.exist;
+
+ await openTab('general.email');
+ await fillIn('input#newsletter-sender-email', 'valid-email@email.com');
+
+ // Everything should be valid
+ await checkSave({
+ edit: true,
+ verifyEmail: /previous email address \(test@example\.com\)/
+ });
+ });
+
+ it('does not ask to confirm saved changes', async function () {
+ await visit('/settings/newsletters');
+
+ // When we only have a single newsletter, the customize button is shown instead of the menu button
+ await click('[data-test-button="customize-newsletter"]');
+
+ // Check if modal opens
+ expect(find('[data-test-modal="edit-newsletter"]'), 'Edit newsletter modal').to.exist;
+
+ // Make no changes
// Everything should be valid
await checkCancel({
edit: true,
- shouldConfirm: true
+ shouldConfirm: false
});
- }
-
- // General name
- await doCheck('general.name', {
- input: '#newsletter-title'
});
- await doCheck('general.name', {
- input: '#newsletter-description'
+ it('asks to confirm unsaved changes', async function () {
+ async function doCheck(tabName, field) {
+ await visit('/settings/newsletters');
+
+ // When we only have a single newsletter, the customize button is shown instead of the menu button
+ await click('[data-test-button="customize-newsletter"]');
+
+ // Check if modal opens
+ expect(find('[data-test-modal="edit-newsletter"]'), 'Edit newsletter modal').to.exist;
+
+ // Make a change
+ await openTab(tabName, false);
+ if (field.input) {
+ await fillIn(field.input, field.value ?? 'my changed value');
+ } else if (field.toggle) {
+ await click(field.toggle);
+ } else if (field.dropdown) {
+ // Open dropdown
+ await click(`${field.dropdown} .ember-basic-dropdown-trigger`);
+
+ // Click first not-selected option
+ await click(`${field.dropdown} li.ember-power-select-option[aria-current="false"]`);
+ }
+
+ // Everything should be valid
+ await checkCancel({
+ edit: true,
+ shouldConfirm: true
+ });
+ }
+
+ // General name
+ await doCheck('general.name', {
+ input: '#newsletter-title'
+ });
+
+ await doCheck('general.name', {
+ input: '#newsletter-description'
+ });
+
+ // General email
+ await doCheck('general.email', {
+ input: '#newsletter-sender-name'
+ });
+
+ await doCheck('general.email', {
+ input: '#newsletter-sender-email'
+ });
+
+ await doCheck('general.email', {
+ input: '#newsletter-reply-to',
+ value: 'support'
+ });
+
+ // Member settings
+ await doCheck.call(this, 'general.member', {
+ toggle: '[data-test-toggle="subscribeOnSignup"]'
+ });
+
+ // Design header
+ await doCheck.call(this, 'design.header', {
+ toggle: '[data-test-toggle="showHeaderTitle"]'
+ });
+
+ await doCheck.call(this, 'design.header', {
+ toggle: '[data-test-toggle="showHeaderName"]'
+ });
+
+ // Design body
+ await doCheck.call(this, 'design.body', {
+ dropdown: '[data-test-input="titleFontCategory"]'
+ });
+
+ await doCheck.call(this, 'design.body', {
+ toggle: '#newsletter-title-alignment button:not(.gh-btn-group-selected)'
+ });
+
+ await doCheck.call(this, 'design.body', {
+ dropdown: '[data-test-input="bodyFontCategory"]'
+ });
+
+ await doCheck.call(this, 'design.body', {
+ toggle: '#show-feature-image'
+ });
+
+ // Design footer
+ await doCheck('design.footer', {
+ input: '[contenteditable="true"]'
+ });
+ });
+ });
+
+ describe('Archiving newsletters', function () {
+ it('can archive newsletters', async function () {
+ // Create an extra newsletter, because we cannot archive the last one
+ this.server.create('newsletter', {status: 'active', name: 'test newsletter', slug: 'test-newsletter'});
+ await visit('/settings/newsletters');
+
+ // Check total newsletters shown
+ expect(findAll('[data-test-newsletter]').length, 'Total newsletters shown').to.equal(2);
+
+ // Toggle is hidden
+ expect(find('[data-test-dropdown="newsletter-status-filter"] .ember-power-select-trigger')).not.to.exist;
+
+ await click('[data-test-newsletter-menu-trigger]');
+ await click('[data-test-button="archive-newsletter"]');
+
+ // Check if confimation modal opens
+ expect(find('[data-test-modal="confirm-newsletter-archive"]'), 'Archive newsletter modal').to.exist;
+
+ // Confirm archive
+ await click('[data-test-button="confirm-newsletter-archive"]');
+
+ // Check total newsletters equals 1
+ expect(findAll('[data-test-newsletter]').length, 'Total newsletters shown').to.equal(1);
+
+ // Toggle is shown now
+ expect(find('[data-test-dropdown="newsletter-status-filter"] .ember-power-select-trigger')).to.exist;
});
- // General email
- await doCheck('general.email', {
- input: '#newsletter-sender-name'
+ it('can reactivate newsletters if only archived newsletter left', async function () {
+ // Create an extra newsletter, to check counts
+ this.server.create('newsletter', {status: 'active', name: 'test newsletter', slug: 'test-newsletter'});
+
+ // Create an archived newsletter, beacuse the toggle is invisible otherwise
+ this.server.create('newsletter', {status: 'archived', name: 'test newsletter 2', slug: 'test-newsletter2'});
+ await visit('/settings/newsletters');
+
+ // Check total newsletters shown
+ expect(findAll('[data-test-newsletter]').length, 'Total newsletters shown').to.equal(2);
+
+ // Go to archived newsletters
+ await click('[data-test-dropdown="newsletter-status-filter"] .ember-power-select-trigger');
+ await click('.ember-power-select-option[aria-selected="false"]');
+
+ // Check title okay
+ expect(find('.gh-newsletters .gh-expandable-title').textContent.trim(), 'Title').to.equal('Archived newsletters');
+
+ // Check total newsletters shown
+ expect(findAll('[data-test-newsletter]').length, 'Total archived newsletters shown').to.equal(1);
+
+ // Reactivate the newsletter
+ await click('[data-test-newsletter-menu-trigger]');
+ await click('[data-test-button="reactivate-newsletter"]');
+
+ // Check if confimation modal opens
+ expect(find('[data-test-modal="confirm-newsletter-reactivate"]'), 'Reactivate newsletter modal').to.exist;
+
+ // Confirm archive
+ await click('[data-test-button="confirm-newsletter-reactivate"]');
+
+ // Check automatically went back to all (because no newsletters archived)
+ // Check title okay
+ expect(find('.gh-newsletters .gh-expandable-title').textContent.trim(), 'Title').to.equal('Active newsletters');
+
+ // Check total newsletters shown
+ expect(findAll('[data-test-newsletter]').length, 'Total newsletters shown').to.equal(3);
});
- await doCheck('general.email', {
- input: '#newsletter-sender-email'
- });
+ it('can reactivate newsletters', async function () {
+ // Create an extra newsletter, to check counts
+ this.server.create('newsletter', {status: 'active', name: 'test newsletter', slug: 'test-newsletter'});
- await doCheck('general.email', {
- input: '#newsletter-reply-to',
- value: 'support'
- });
+ // Create an archived newsletter, beacuse the toggle is invisible otherwise
+ this.server.create('newsletter', {status: 'archived', name: 'test newsletter 2', slug: 'test-newsletter2'});
+ this.server.create('newsletter', {status: 'archived', name: 'test newsletter 3', slug: 'test-newsletter3'});
+ await visit('/settings/newsletters');
- // Member settings
- await doCheck.call(this, 'general.member', {
- toggle: '[data-test-toggle="subscribeOnSignup"]'
- });
+ // Check total newsletters shown
+ expect(findAll('[data-test-newsletter]').length, 'Total newsletters shown').to.equal(2);
- // Design header
- await doCheck.call(this, 'design.header', {
- toggle: '[data-test-toggle="showHeaderTitle"]'
- });
+ // Go to archived newsletters
+ await click('[data-test-dropdown="newsletter-status-filter"] .ember-power-select-trigger');
+ await click('.ember-power-select-option[aria-selected="false"]');
- await doCheck.call(this, 'design.header', {
- toggle: '[data-test-toggle="showHeaderName"]'
- });
+ // Check title okay
+ expect(find('.gh-newsletters .gh-expandable-title').textContent.trim(), 'Title').to.equal('Archived newsletters');
- // Design body
- await doCheck.call(this, 'design.body', {
- dropdown: '[data-test-input="titleFontCategory"]'
- });
+ // Check total newsletters shown
+ expect(findAll('[data-test-newsletter]').length, 'Total archived newsletters shown').to.equal(2);
- await doCheck.call(this, 'design.body', {
- toggle: '#newsletter-title-alignment button:not(.gh-btn-group-selected)'
- });
+ // Reactivate the newsletter
+ await click('[data-test-newsletter-menu-trigger]');
+ await click('[data-test-button="reactivate-newsletter"]');
- await doCheck.call(this, 'design.body', {
- dropdown: '[data-test-input="bodyFontCategory"]'
- });
+ // Check if confimation modal opens
+ expect(find('[data-test-modal="confirm-newsletter-reactivate"]'), 'Reactivate newsletter modal').to.exist;
- await doCheck.call(this, 'design.body', {
- toggle: '#show-feature-image'
- });
+ // Confirm archive
+ await click('[data-test-button="confirm-newsletter-reactivate"]');
- // Design footer
- await doCheck('design.footer', {
- input: '[contenteditable="true"]'
+ // Check still showing archived newsletters
+ expect(find('.gh-newsletters .gh-expandable-title').textContent.trim(), 'Title').to.equal('Archived newsletters');
+
+ // Go to active newsletters
+ await click('[data-test-dropdown="newsletter-status-filter"] .ember-power-select-trigger');
+ await click('.ember-power-select-option[aria-selected="false"]');
+
+ // Check automatically went back to all (because no newsletters archived)
+ // Check title okay
+ expect(find('.gh-newsletters .gh-expandable-title').textContent.trim(), 'Title').to.equal('Active newsletters');
+
+ // Check total newsletters shown
+ expect(findAll('[data-test-newsletter]').length, 'Total newsletters shown').to.equal(3);
});
});
});