From f1b82363eda7fb47a4272fd5b72d656330a6df92 Mon Sep 17 00:00:00 2001 From: Paul Slaughter <pslaughter@gitlab.com> Date: Wed, 17 Mar 2021 14:27:08 -0500 Subject: [PATCH] Refactor UserInternalRegexHandler to own module - Also removes jquery usage --- app/assets/javascripts/admin/users/new.js | 55 ++++++++++++++ .../pages/admin/users/new/index.js | 50 +----------- ...s-refactor-user-internal-regex-handler.yml | 5 ++ spec/frontend/admin/users/new_spec.js | 76 +++++++++++++++++++ .../pages/admin/users/new/index_spec.js | 41 ---------- 5 files changed, 138 insertions(+), 89 deletions(-) create mode 100644 app/assets/javascripts/admin/users/new.js create mode 100644 changelogs/unreleased/ps-refactor-user-internal-regex-handler.yml create mode 100644 spec/frontend/admin/users/new_spec.js delete mode 100644 spec/frontend/pages/admin/users/new/index_spec.js diff --git a/app/assets/javascripts/admin/users/new.js b/app/assets/javascripts/admin/users/new.js new file mode 100644 index 00000000000..33565bfc14f --- /dev/null +++ b/app/assets/javascripts/admin/users/new.js @@ -0,0 +1,55 @@ +const DATA_ATTR_REGEX_PATTERN = 'data-user-internal-regex-pattern'; +const DATA_ATTR_REGEX_OPTIONS = 'data-user-internal-regex-options'; +export const ID_USER_EXTERNAL = 'user_external'; +export const ID_WARNING = 'warning_external_automatically_set'; +export const ID_USER_EMAIL = 'user_email'; + +const getAttributeValue = (attr) => document.querySelector(`[${attr}]`)?.getAttribute(attr); + +const getRegexPattern = () => getAttributeValue(DATA_ATTR_REGEX_PATTERN); + +const getRegexOptions = () => getAttributeValue(DATA_ATTR_REGEX_OPTIONS); + +export const setupInternalUserRegexHandler = () => { + const regexPattern = getRegexPattern(); + + if (!regexPattern) { + return; + } + + const regexOptions = getRegexOptions(); + const elExternal = document.getElementById(ID_USER_EXTERNAL); + const elWarningMessage = document.getElementById(ID_WARNING); + const elUserEmail = document.getElementById(ID_USER_EMAIL); + + const isEmailInternal = (email) => { + const regex = new RegExp(regexPattern, regexOptions); + return regex.test(email); + }; + + const setExternalCheckbox = (email) => { + const isChecked = elExternal.checked; + + if (isEmailInternal(email)) { + if (isChecked) { + elExternal.checked = false; + elWarningMessage.classList.remove('hidden'); + } + } else if (!isChecked) { + elExternal.checked = true; + elWarningMessage.classList.add('hidden'); + } + }; + + const setupListeners = () => { + elUserEmail.addEventListener('input', (event) => { + setExternalCheckbox(event.target.value); + }); + + elExternal.addEventListener('change', () => { + elWarningMessage.classList.add('hidden'); + }); + }; + + setupListeners(); +}; diff --git a/app/assets/javascripts/pages/admin/users/new/index.js b/app/assets/javascripts/pages/admin/users/new/index.js index 01710246c86..34c10e44f4c 100644 --- a/app/assets/javascripts/pages/admin/users/new/index.js +++ b/app/assets/javascripts/pages/admin/users/new/index.js @@ -1,49 +1,3 @@ -import $ from 'jquery'; +import { setupInternalUserRegexHandler } from '~/admin/users/new'; -export default class UserInternalRegexHandler { - constructor() { - this.regexPattern = $('[data-user-internal-regex-pattern]').data('user-internal-regex-pattern'); - if (this.regexPattern && this.regexPattern !== '') { - this.regexOptions = $('[data-user-internal-regex-options]').data( - 'user-internal-regex-options', - ); - this.external = $('#user_external'); - this.warningMessage = $('#warning_external_automatically_set'); - this.addListenerToEmailField(); - this.addListenerToUserExternalCheckbox(); - } - } - - addListenerToEmailField() { - $('#user_email').on('input', (event) => { - this.setExternalCheckbox(event.currentTarget.value); - }); - } - - addListenerToUserExternalCheckbox() { - this.external.on('click', () => { - this.warningMessage.addClass('hidden'); - }); - } - - isEmailInternal(email) { - const regex = new RegExp(this.regexPattern, this.regexOptions); - return regex.test(email); - } - - setExternalCheckbox(email) { - const isChecked = this.external.prop('checked'); - if (this.isEmailInternal(email)) { - if (isChecked) { - this.external.prop('checked', false); - this.warningMessage.removeClass('hidden'); - } - } else if (!isChecked) { - this.external.prop('checked', true); - this.warningMessage.addClass('hidden'); - } - } -} - -// eslint-disable-next-line no-new -new UserInternalRegexHandler(); +setupInternalUserRegexHandler(); diff --git a/changelogs/unreleased/ps-refactor-user-internal-regex-handler.yml b/changelogs/unreleased/ps-refactor-user-internal-regex-handler.yml new file mode 100644 index 00000000000..156861328e1 --- /dev/null +++ b/changelogs/unreleased/ps-refactor-user-internal-regex-handler.yml @@ -0,0 +1,5 @@ +--- +title: In admin new user page, fix external checkbox warning hide with keyboard interaction +merge_request: 56896 +author: +type: fixed diff --git a/spec/frontend/admin/users/new_spec.js b/spec/frontend/admin/users/new_spec.js new file mode 100644 index 00000000000..692c583dca8 --- /dev/null +++ b/spec/frontend/admin/users/new_spec.js @@ -0,0 +1,76 @@ +import { + setupInternalUserRegexHandler, + ID_USER_EMAIL, + ID_USER_EXTERNAL, + ID_WARNING, +} from '~/admin/users/new'; + +describe('admin/users/new', () => { + const FIXTURE = 'admin/users/new_with_internal_user_regex.html'; + + let elExternal; + let elUserEmail; + let elWarningMessage; + + beforeEach(() => { + loadFixtures(FIXTURE); + setupInternalUserRegexHandler(); + + elExternal = document.getElementById(ID_USER_EXTERNAL); + elUserEmail = document.getElementById(ID_USER_EMAIL); + elWarningMessage = document.getElementById(ID_WARNING); + + elExternal.checked = true; + }); + + const changeEmail = (val) => { + elUserEmail.value = val; + elUserEmail.dispatchEvent(new Event('input')); + }; + + const hasHiddenWarning = () => elWarningMessage.classList.contains('hidden'); + + describe('Behaviour of userExternal checkbox', () => { + it('hides warning by default', () => { + expect(hasHiddenWarning()).toBe(true); + }); + + describe('when matches email as internal', () => { + beforeEach(() => { + changeEmail('test@'); + }); + + it('has external unchecked', () => { + expect(elExternal.checked).toBe(false); + }); + + it('shows warning', () => { + expect(hasHiddenWarning()).toBe(false); + }); + + describe('when external is checked again', () => { + beforeEach(() => { + elExternal.dispatchEvent(new Event('change')); + }); + + it('hides warning', () => { + expect(hasHiddenWarning()).toBe(true); + }); + }); + }); + + describe('when matches emails as external', () => { + beforeEach(() => { + changeEmail('test.ext@'); + }); + + it('has external checked', () => { + expect(elExternal.checked).toBe(true); + }); + + it('hides warning', () => { + expect(hasHiddenWarning()).toBe(true); + }); + }); + }); +}); diff --git a/spec/frontend/pages/admin/users/new/index_spec.js b/spec/frontend/pages/admin/users/new/index_spec.js deleted file mode 100644 index ec9fe487030..00000000000 --- a/spec/frontend/pages/admin/users/new/index_spec.js +++ /dev/null @@ -1,41 +0,0 @@ -import $ from 'jquery'; -import UserInternalRegexHandler from '~/pages/admin/users/new/index'; - -describe('UserInternalRegexHandler', () => { - const FIXTURE = 'admin/users/new_with_internal_user_regex.html'; - let $userExternal; - let $userEmail; - let $warningMessage; - - beforeEach(() => { - loadFixtures(FIXTURE); - // eslint-disable-next-line no-new - new UserInternalRegexHandler(); - $userExternal = $('#user_external'); - $userEmail = $('#user_email'); - $warningMessage = $('#warning_external_automatically_set'); - if (!$userExternal.prop('checked')) $userExternal.prop('checked', 'checked'); - }); - - describe('Behaviour of userExternal checkbox when', () => { - it('matches email as internal', (done) => { - expect($warningMessage.hasClass('hidden')).toBeTruthy(); - - $userEmail.val('test@').trigger('input'); - - expect($userExternal.prop('checked')).toBeFalsy(); - expect($warningMessage.hasClass('hidden')).toBeFalsy(); - done(); - }); - - it('matches email as external', (done) => { - expect($warningMessage.hasClass('hidden')).toBeTruthy(); - - $userEmail.val('test.ext@').trigger('input'); - - expect($userExternal.prop('checked')).toBeTruthy(); - expect($warningMessage.hasClass('hidden')).toBeTruthy(); - done(); - }); - }); -}); -- 2.30.9