Use preact-modal in adminModal (#18613)

* Commented test

* Removed User subscription related modal code

* Fixed test case

* Updated tests

* Added more tests
This commit is contained in:
Rajat Talesra 2022-10-29 23:58:28 +05:30 committed by GitHub
parent e9d4f18f1e
commit cc4f3556cf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 219 additions and 81 deletions

View file

@ -1,34 +0,0 @@
import { Application } from '@hotwired/stimulus';
import ConfigController from '../../controllers/config_controller';
describe('ConfigController', () => {
beforeEach(() => {
document.body.innerHTML = `
<div data-controller="config">
<button data-action="click->config#activateEmailAuthModal">
Disable
</button>
<div data-config-target="configModalAnchor"></div>
</div>`;
global.scrollTo = jest.fn();
const application = Application.start();
application.register('config', ConfigController);
});
describe('#activateEmailAuthModal', () => {
it('builds and adds a Modal to the page', () => {
const button = document.getElementsByTagName('button')[0];
const modalAnchor = document.querySelector(
'[data-config-target="configModalAnchor"]',
);
button.click();
expect(
modalAnchor.firstElementChild.classList.contains('crayons-modal'),
).toBe(true);
});
});
});

View file

@ -1,16 +1,17 @@
import { closeWindowModal, showWindowModal } from '@utilities/showModal';
/**
* A function to generate the HTML for a Crayons modal within the /admin/ space.
*
* @function adminModal
* @param {Object} modalProps Properties of the Modal
* @param {string} modalProps.title The title of the modal.
* @param {string} modalProps.controllerName The name of the controller activating the modal.
* @param {string} modalProps.closeModalFunction The name of the function that closes the modal.
* @param {function} modalProps.closeModalFunction The name of the function that closes the modal.
* @param {string} modalProps.body The modal's content. May use HTML tags for styling.
* @param {string} modalProps.leftBtnText The text for the modal's left button.
* @param {string} modalProps.leftBtnAction The function that fires when left button is clicked.
* @param {function} modalProps.leftBtnAction The function that fires when left button is clicked.
* @param {string} modalProps.rightBtnText The text for the modal's right button.
* @param {string} modalProps.rightBtnAction The function that fires when right button is clicked.
* @param {function} modalProps.rightBtnAction The function that fires when right button is clicked.
* @param {string} modalProps.leftBtnClasses Classes applied to left button.
* @param {string} modalProps.rightBtnClasses Classes applied to right button.
* @param {string} modalProps.leftCustomDataAttr A custom data attribute for the left button.
@ -18,7 +19,6 @@
*/
export const adminModal = function ({
title,
controllerName,
closeModalFunction,
body,
leftBtnText,
@ -30,36 +30,51 @@ export const adminModal = function ({
leftCustomDataAttr = null,
rightCustomDataAttr = null,
}) {
return `
<div class="crayons-modal crayons-modal--small">
<div class="crayons-modal__box">
<header class="crayons-modal__box__header">
<p class="fw-bold fs-l">${title}</p>
<button type="button" class="crayons-btn crayons-btn--icon crayons-btn--ghost" data-action="click->${controllerName}#${closeModalFunction}">
<svg width="24" height="24" viewBox="0 0 24 24" class="crayons-icon" xmlns="http://www.w3.org/2000/svg">
<path d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636l4.95 4.95z" />
</svg>
</button>
</header>
<div class="crayons-modal__box__body grid gap-4">
${body}
<div class="crayons-btn-actions">
<button
class="crayons-btn ${leftBtnClasses}"
data-action="click->${controllerName}#${leftBtnAction}"
${leftCustomDataAttr}>
${leftBtnText}
</button>
<button
class="crayons-btn ${rightBtnClasses}"
data-action="click->${controllerName}#${rightBtnAction}"
${rightCustomDataAttr}>
${rightBtnText}
</button>
</div>
</div>
const content = `
<div class="admin-modal-content grid gap-4">
${body}
<div class="crayons-btn-actions">
<button
id="left-btn"
class="crayons-btn ${leftBtnClasses}"
${leftCustomDataAttr}>
${leftBtnText}
</button>
<button
id="right-btn"
class="crayons-btn ${rightBtnClasses}"
${rightCustomDataAttr}>
${rightBtnText}
</button>
</div>
<div class="crayons-modal__overlay"></div>
</div>
`;
return showWindowModal({
document: window.document,
title,
modalContent: content,
size: 'small',
onOpen: () => {
window.document
.getElementById(`left-btn`)
.addEventListener('click', (event) => {
closeWindowModal();
leftBtnAction(event);
});
window.document
.getElementById(`right-btn`)
.addEventListener('click', (event) => {
closeWindowModal();
rightBtnAction(event);
});
window.document
.querySelector(`.crayons-modal__dismiss`)
.addEventListener('click', (event) => {
closeModalFunction(event);
});
},
});
};

View file

@ -180,13 +180,12 @@ export default class ConfigController extends Controller {
event.preventDefault();
this.configModalAnchorTarget.innerHTML = adminModal({
title: emailAuthModalTitle,
controllerName: 'config',
closeModalFunction: 'closeAdminModal',
closeModalFunction: this.closeAdminModal.bind(this),
body: emailAuthModalBody,
leftBtnText: 'Confirm disable',
leftBtnAction: 'disableEmailAuthFromModal',
leftBtnAction: this.disableEmailAuthFromModal.bind(this),
rightBtnText: 'Cancel',
rightBtnAction: 'closeAdminModal',
rightBtnAction: this.closeAdminModal.bind(this),
leftBtnClasses: 'crayons-btn--danger',
rightBtnClasses: 'crayons-btn--secondary',
});
@ -260,13 +259,12 @@ export default class ConfigController extends Controller {
const { providerOfficialName } = event.target.dataset;
this.configModalAnchorTarget.innerHTML = adminModal({
title: this.authProviderModalTitle(providerOfficialName),
controllerName: 'config',
closeModalFunction: 'closeAdminModal',
closeModalFunction: this.closeAdminModal.bind(this),
body: this.authProviderModalBody(providerOfficialName),
leftBtnText: 'Confirm disable',
leftBtnAction: 'disableAuthProviderFromModal',
leftBtnAction: this.disableAuthProviderFromModal.bind(this),
rightBtnText: 'Cancel',
rightBtnAction: 'closeAdminModal',
rightBtnAction: this.closeAdminModal.bind(this),
leftBtnClasses: 'crayons-btn--danger',
rightBtnClasses: 'crayons-btn--secondary',
leftCustomDataAttr: `data-provider-name=${providerName}`,
@ -399,13 +397,12 @@ export default class ConfigController extends Controller {
activateMissingKeysModal(providers) {
this.configModalAnchorTarget.innerHTML = adminModal({
title: 'Setup not complete',
controllerName: 'config',
closeModalFunction: 'closeAdminModal',
closeModalFunction: this.closeAdminModal.bind(this),
body: this.missingAuthKeysModalBody(providers),
leftBtnText: 'Continue editing',
leftBtnAction: 'closeAdminModal',
leftBtnAction: this.closeAdminModal.bind(this),
rightBtnText: 'Cancel',
rightBtnAction: 'cancelAuthProviderEnable',
rightBtnAction: this.cancelAuthProviderEnable.bind(this),
rightBtnClasses: 'crayons-btn--secondary',
});
}

View file

@ -83,12 +83,100 @@ describe('Authentication Section', () => {
cy.get('@authSectionForm').findByText('Update Settings').click();
cy.get('.crayons-modal__box__body > ul > li')
cy.findByTestId('modal-container').as('modal');
cy.get('@modal')
.get('.admin-modal-content > ul > li')
.contains('facebook')
.should('be.visible');
});
});
it('should display warning modal with multiple providers if keys are missing', () => {
cy.fixture('users/adminUser.json').as('user');
cy.get('@user').then(() => {
cy.visit('/admin/customization/config');
cy.findByTestId('authSectionForm').as('authSectionForm');
cy.get('@authSectionForm').findByText('Authentication').click();
cy.get('#apple-auth-btn').click();
cy.get('#facebook-auth-btn').click();
cy.get('@authSectionForm').findByText('Update Settings').click();
cy.findByTestId('modal-container').as('modal');
cy.get('@modal')
.get('.admin-modal-content > ul > li')
.contains('facebook')
.should('be.visible');
cy.get('@modal')
.get('.admin-modal-content > ul > li')
.contains('apple')
.should('be.visible');
});
});
it('closing warning modal should keep provider enabled', () => {
cy.fixture('users/adminUser.json').as('user');
cy.get('@user').then(() => {
cy.visit('/admin/customization/config');
cy.findByTestId('authSectionForm').as('authSectionForm');
cy.get('@authSectionForm').findByText('Authentication').click();
cy.get('#facebook-auth-btn').click();
cy.get('@authSectionForm').findByText('Update Settings').click();
cy.findByTestId('modal-container').as('modal');
cy.get('@modal').findByRole('button', { name: /Close/ }).click();
cy.get('@modal').should('not.exist');
cy.get('@authSectionForm').findByText('Facebook key').should('exist');
});
});
it('continue editing button of modal should keep provider enabled', () => {
cy.fixture('users/adminUser.json').as('user');
cy.get('@user').then(() => {
cy.visit('/admin/customization/config');
cy.findByTestId('authSectionForm').as('authSectionForm');
cy.get('@authSectionForm').findByText('Authentication').click();
cy.get('#facebook-auth-btn').click();
cy.get('@authSectionForm').findByText('Update Settings').click();
cy.findByTestId('modal-container').as('modal');
cy.get('@modal').findByText('Continue editing').click();
cy.get('@modal').should('not.exist');
cy.get('@authSectionForm').findByText('Facebook key').should('exist');
});
});
it('cancelling modal should reset providers', () => {
cy.fixture('users/adminUser.json').as('user');
cy.get('@user').then(() => {
cy.visit('/admin/customization/config');
cy.findByTestId('authSectionForm').as('authSectionForm');
cy.get('@authSectionForm').findByText('Authentication').click();
cy.get('#facebook-auth-btn').click();
cy.get('@authSectionForm').findByText('Update Settings').click();
cy.findByTestId('modal-container').as('modal');
cy.get('@modal').findByText('Cancel').click();
cy.get('@modal').should('not.exist');
cy.get('@authSectionForm')
.findAllByRole('button', { name: 'Enable' })
.should('have.length', 6);
});
});
it('should not display warning modal if provider keys present', () => {
cy.fixture('users/adminUser.json').as('user');
@ -132,5 +220,77 @@ describe('Authentication Section', () => {
});
});
});
it('should display warning modal when disabling a provider', () => {
cy.fixture('users/adminUser.json').as('user');
cy.get('@user').then(() => {
cy.visit('/admin/customization/config');
cy.findByTestId('authSectionForm').as('authSectionForm');
cy.get('@authSectionForm').findByText('Authentication').click();
cy.get('#email-auth-enable-edit-btn').click();
cy.get('@authSectionForm').findByText('Disable').click();
cy.findByTestId('modal-container').as('modal');
cy.get('@modal').should('exist');
});
});
it('email-auth disable modal has correct header', () => {
cy.fixture('users/adminUser.json').as('user');
cy.get('@user').then(() => {
cy.visit('/admin/customization/config');
cy.findByTestId('authSectionForm').as('authSectionForm');
cy.get('@authSectionForm').findByText('Authentication').click();
cy.get('#email-auth-enable-edit-btn').click();
cy.get('@authSectionForm').findByText('Disable').click();
cy.findByTestId('modal-container').as('modal');
cy.get('@modal')
.findByText('Disable Email address registration')
.should('exist');
});
});
it('cancelling email-auth disable modal should close the modal', () => {
cy.fixture('users/adminUser.json').as('user');
cy.get('@user').then(() => {
cy.visit('/admin/customization/config');
cy.findByTestId('authSectionForm').as('authSectionForm');
cy.get('@authSectionForm').findByText('Authentication').click();
cy.get('#email-auth-enable-edit-btn').click();
cy.get('@authSectionForm').findByText('Disable').click();
cy.findByTestId('modal-container').as('modal');
cy.get('@modal').findByText('Cancel').click();
cy.get('@modal').should('not.exist');
cy.get('@authSectionForm').findByText('Disable').should('exist');
});
});
it('confirm disable button of email-auth disable modal should disable the auth', () => {
cy.fixture('users/adminUser.json').as('user');
cy.get('@user').then(() => {
cy.visit('/admin/customization/config');
cy.findByTestId('authSectionForm').as('authSectionForm');
cy.get('@authSectionForm').findByText('Authentication').click();
cy.get('#email-auth-enable-edit-btn').click();
cy.get('@authSectionForm').findByText('Disable').click();
cy.findByTestId('modal-container').as('modal');
cy.get('@modal').findByText('Confirm disable').click();
cy.get('@modal').should('not.exist');
cy.get('@authSectionForm')
.findAllByRole('button', { name: 'Enable' })
.should('have.length', 7);
});
});
});
});