diff --git a/app/assets/javascripts/ci_variable_list/components/ci_variable_modal.vue b/app/assets/javascripts/ci_variable_list/components/ci_variable_modal.vue index be2366108b3..eb2b1fc501c 100644 --- a/app/assets/javascripts/ci_variable_list/components/ci_variable_modal.vue +++ b/app/assets/javascripts/ci_variable_list/components/ci_variable_modal.vue @@ -109,7 +109,7 @@ export default { return regex.test(this.variable.secret_value); }, containsVariableReference() { - const regex = RegExp(/\$/); + const regex = /\$/; return regex.test(this.variable.secret_value); }, displayMaskedError() { diff --git a/app/assets/javascripts/editor/extensions/source_editor_extension_base.js b/app/assets/javascripts/editor/extensions/source_editor_extension_base.js index 3aa19df964c..49b9a74fdb2 100644 --- a/app/assets/javascripts/editor/extensions/source_editor_extension_base.js +++ b/app/assets/javascripts/editor/extensions/source_editor_extension_base.js @@ -5,7 +5,7 @@ import { EXTENSION_BASE_LINE_NUMBERS_CLASS, } from '../constants'; -const hashRegexp = new RegExp('#?L', 'g'); +const hashRegexp = /#?L/g; const createAnchor = (href) => { const fragment = new DocumentFragment(); diff --git a/app/assets/javascripts/filtered_search/filtered_search_manager.js b/app/assets/javascripts/filtered_search/filtered_search_manager.js index 27a55250355..07f2c75f00a 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_manager.js +++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js @@ -581,7 +581,7 @@ export default class FilteredSearchManager { * Eg. not[foo]=%bar * key = foo; value = %bar */ - const notKeyValueRegex = new RegExp(/not\[(\w+)\]\[?\]?=(.*)/); + const notKeyValueRegex = /not\[(\w+)\]\[?\]?=(.*)/; return params.map((query) => { // Check if there are matches for `not` operator diff --git a/app/assets/javascripts/gfm_auto_complete.js b/app/assets/javascripts/gfm_auto_complete.js index 8cb2e9e249b..b1af1ad797b 100644 --- a/app/assets/javascripts/gfm_auto_complete.js +++ b/app/assets/javascripts/gfm_auto_complete.js @@ -844,7 +844,7 @@ class GfmAutoComplete { } } -GfmAutoComplete.regexSubtext = new RegExp(/\s+/g); +GfmAutoComplete.regexSubtext = /\s+/g; GfmAutoComplete.defaultLoadingData = ['loading']; diff --git a/app/assets/javascripts/issues/create_merge_request_dropdown.js b/app/assets/javascripts/issues/create_merge_request_dropdown.js index c96af6da720..3ea70c07058 100644 --- a/app/assets/javascripts/issues/create_merge_request_dropdown.js +++ b/app/assets/javascripts/issues/create_merge_request_dropdown.js @@ -69,12 +69,12 @@ export default class CreateMergeRequestDropdown { // with user's inputs. this.regexps = { branch: { - createBranchPath: new RegExp('(branch_name=)(.+?)(?=&issue)'), - createMrPath: new RegExp('(source_branch%5D=)(.+?)(?=&)'), + createBranchPath: /(branch_name=)(.+?)(?=&issue)/, + createMrPath: /(source_branch%5D=)(.+?)(?=&)/, }, ref: { - createBranchPath: new RegExp('(ref=)(.+?)$'), - createMrPath: new RegExp('(target_branch%5D=)(.+?)$'), + createBranchPath: /(ref=)(.+?)$/, + createMrPath: /(target_branch%5D=)(.+?)$/, }, }; diff --git a/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue b/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue index e5ddfe82e3b..05c1f2d4a1e 100644 --- a/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue +++ b/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue @@ -128,7 +128,7 @@ export default { this.selectedTemplate = selectedTemplate; }, validateProjectKey() { - if (this.projectKey && !new RegExp(/^[a-z0-9_]+$/).test(this.projectKey)) { + if (this.projectKey && !/^[a-z0-9_]+$/.test(this.projectKey)) { this.projectKeyError = __('Only use lowercase letters, numbers, and underscores.'); return; } diff --git a/app/assets/javascripts/vue_shared/components/confirm_danger/confirm_danger_modal.stories.js b/app/assets/javascripts/vue_shared/components/confirm_danger/confirm_danger_modal.stories.js index 6629b293eb9..8481280f25f 100644 --- a/app/assets/javascripts/vue_shared/components/confirm_danger/confirm_danger_modal.stories.js +++ b/app/assets/javascripts/vue_shared/components/confirm_danger/confirm_danger_modal.stories.js @@ -14,6 +14,8 @@ const Template = (args, { argTypes }) => ({ additionalInformation: args.additionalInformation || null, confirmDangerMessage: args.confirmDangerMessage || 'You require more Vespene Gas', htmlConfirmationMessage: args.confirmDangerMessage || false, + confirmButtonText: args.confirmButtonText || 'Cancel', + cancelButtonText: args.cancelButtonText || 'Confirm', }, }); diff --git a/app/assets/javascripts/vue_shared/components/confirm_danger/confirm_danger_modal.vue b/app/assets/javascripts/vue_shared/components/confirm_danger/confirm_danger_modal.vue index 88890b3332d..37e480f7e41 100644 --- a/app/assets/javascripts/vue_shared/components/confirm_danger/confirm_danger_modal.vue +++ b/app/assets/javascripts/vue_shared/components/confirm_danger/confirm_danger_modal.vue @@ -12,7 +12,7 @@ import { CONFIRM_DANGER_MODAL_TITLE, CONFIRM_DANGER_PHRASE_TEXT, CONFIRM_DANGER_WARNING, - CONFIRM_DANGER_MODAL_ERROR, + CONFIRM_DANGER_MODAL_CANCEL, } from './constants'; export default { @@ -40,6 +40,9 @@ export default { additionalInformation: { default: CONFIRM_DANGER_WARNING, }, + cancelButtonText: { + default: CONFIRM_DANGER_MODAL_CANCEL, + }, }, props: { modalId: { @@ -66,6 +69,11 @@ export default { attributes: [{ variant: 'danger', disabled: !this.isValid, class: 'qa-confirm-button' }], }; }, + actionCancel() { + return { + text: this.cancelButtonText, + }; + }, }, methods: { equalString(a, b) { @@ -77,7 +85,6 @@ export default { CONFIRM_DANGER_MODAL_TITLE, CONFIRM_DANGER_WARNING, CONFIRM_DANGER_PHRASE_TEXT, - CONFIRM_DANGER_MODAL_ERROR, }, }; @@ -88,6 +95,7 @@ export default { :data-testid="modalId" :title="$options.i18n.CONFIRM_DANGER_MODAL_TITLE" :action-primary="actionPrimary" + :action-cancel="actionCancel" @primary="$emit('confirm')" >

- + { const url = axios.get.mock.calls[0][0]; expect(url).toMatch(new RegExp(`^${dummyEndpointUrl}/render?`)); - expect(url).toMatch( - new RegExp('\\?link_url=%3Cscript%3EI%20am%20dangerous!%3C%2Fscript%3E&'), - ); - expect(url).toMatch(new RegExp('&image_url=%26make-sandwich%3Dtrue$')); + expect(url).toMatch(/\\?link_url=%3Cscript%3EI%20am%20dangerous!%3C%2Fscript%3E&/); + expect(url).toMatch(/&image_url=%26make-sandwich%3Dtrue$/); }); it('dispatches requestRenderedBadge and receiveRenderedBadge for successful response', async () => { diff --git a/spec/frontend/vue_shared/components/confirm_danger/confirm_danger_modal_spec.js b/spec/frontend/vue_shared/components/confirm_danger/confirm_danger_modal_spec.js index f75694bd504..a660643d74f 100644 --- a/spec/frontend/vue_shared/components/confirm_danger/confirm_danger_modal_spec.js +++ b/spec/frontend/vue_shared/components/confirm_danger/confirm_danger_modal_spec.js @@ -3,6 +3,7 @@ import { CONFIRM_DANGER_WARNING, CONFIRM_DANGER_MODAL_BUTTON, CONFIRM_DANGER_MODAL_ID, + CONFIRM_DANGER_MODAL_CANCEL, } from '~/vue_shared/components/confirm_danger/constants'; import ConfirmDangerModal from '~/vue_shared/components/confirm_danger/confirm_danger_modal.vue'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; @@ -10,6 +11,7 @@ import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; describe('Confirm Danger Modal', () => { const confirmDangerMessage = 'This is a dangerous activity'; const confirmButtonText = 'Confirm button text'; + const cancelButtonText = 'Cancel button text'; const phrase = 'You must construct additional pylons'; const modalId = CONFIRM_DANGER_MODAL_ID; @@ -21,6 +23,7 @@ describe('Confirm Danger Modal', () => { const findDefaultWarning = () => wrapper.findByTestId('confirm-danger-warning'); const findAdditionalMessage = () => wrapper.findByTestId('confirm-danger-message'); const findPrimaryAction = () => findModal().props('actionPrimary'); + const findCancelAction = () => findModal().props('actionCancel'); const findPrimaryActionAttributes = (attr) => findPrimaryAction().attributes[0][attr]; const createComponent = ({ provide = {} } = {}) => @@ -34,7 +37,9 @@ describe('Confirm Danger Modal', () => { }); beforeEach(() => { - wrapper = createComponent({ provide: { confirmDangerMessage, confirmButtonText } }); + wrapper = createComponent({ + provide: { confirmDangerMessage, confirmButtonText, cancelButtonText }, + }); }); afterEach(() => { @@ -54,6 +59,10 @@ describe('Confirm Danger Modal', () => { expect(findPrimaryActionAttributes('variant')).toBe('danger'); }); + it('renders the cancel button', () => { + expect(findCancelAction().text).toBe(cancelButtonText); + }); + it('renders the correct confirmation phrase', () => { expect(findConfirmationPhrase().text()).toBe( `Please type ${phrase} to proceed or close this modal to cancel.`, @@ -72,6 +81,10 @@ describe('Confirm Danger Modal', () => { it('renders the default confirm button', () => { expect(findPrimaryAction().text).toBe(CONFIRM_DANGER_MODAL_BUTTON); }); + + it('renders the default cancel button', () => { + expect(findCancelAction().text).toBe(CONFIRM_DANGER_MODAL_CANCEL); + }); }); describe('with a valid confirmation phrase', () => { diff --git a/spec/lib/gitlab/zentao/client_spec.rb b/spec/lib/gitlab/zentao/client_spec.rb index 86b310fe417..135f13e6265 100644 --- a/spec/lib/gitlab/zentao/client_spec.rb +++ b/spec/lib/gitlab/zentao/client_spec.rb @@ -130,4 +130,36 @@ RSpec.describe Gitlab::Zentao::Client do end end end + + describe '#url' do + context 'api url' do + shared_examples 'joins api_url correctly' do + it 'verify url' do + expect(integration.send(:url, "products/1").to_s) + .to eq("https://jihudemo.zentao.net/zentao/api.php/v1/products/1") + end + end + + context 'no ends slash' do + let(:zentao_integration) { create(:zentao_integration, api_url: 'https://jihudemo.zentao.net/zentao') } + + include_examples 'joins api_url correctly' + end + + context 'ends slash' do + let(:zentao_integration) { create(:zentao_integration, api_url: 'https://jihudemo.zentao.net/zentao/') } + + include_examples 'joins api_url correctly' + end + end + + context 'no api url' do + let(:zentao_integration) { create(:zentao_integration, url: 'https://jihudemo.zentao.net') } + + it 'joins url correctly' do + expect(integration.send(:url, "products/1").to_s) + .to eq("https://jihudemo.zentao.net/api.php/v1/products/1") + end + end + end end