diff options
Diffstat (limited to 'spec/frontend/projects/settings')
3 files changed, 133 insertions, 27 deletions
diff --git a/spec/frontend/projects/settings/components/new_access_dropdown_spec.js b/spec/frontend/projects/settings/components/new_access_dropdown_spec.js index 4e3554131c6..75b239d2d94 100644 --- a/spec/frontend/projects/settings/components/new_access_dropdown_spec.js +++ b/spec/frontend/projects/settings/components/new_access_dropdown_spec.js @@ -74,20 +74,14 @@ describe('Access Level Dropdown', () => { const createComponent = ({ accessLevelsData = mockAccessLevelsData, accessLevel = ACCESS_LEVELS.PUSH, - hasLicense, - label, - disabled, - preselectedItems, stubs = {}, + ...optionalProps } = {}) => { wrapper = shallowMountExtended(AccessDropdown, { propsData: { accessLevelsData, accessLevel, - hasLicense, - label, - disabled, - preselectedItems, + ...optionalProps, }, stubs: { GlSprintf, @@ -114,10 +108,19 @@ describe('Access Level Dropdown', () => { it('should make an api call for users, groups && deployKeys when user has a license', () => { createComponent(); expect(getUsers).toHaveBeenCalled(); - expect(getGroups).toHaveBeenCalled(); + expect(getGroups).toHaveBeenCalledWith({ withProjectAccess: false }); expect(getDeployKeys).toHaveBeenCalled(); }); + describe('withProjectAccess', () => { + it('should make an api call for users, groups && deployKeys when user has a license', () => { + createComponent({ groupsWithProjectAccess: true }); + expect(getUsers).toHaveBeenCalled(); + expect(getGroups).toHaveBeenCalledWith({ withProjectAccess: true }); + expect(getDeployKeys).toHaveBeenCalled(); + }); + }); + it('should make an api call for deployKeys but not for users or groups when user does not have a license', () => { createComponent({ hasLicense: false }); expect(getUsers).not.toHaveBeenCalled(); @@ -132,7 +135,7 @@ describe('Access Level Dropdown', () => { findSearchBox().vm.$emit('input', query); await nextTick(); expect(getUsers).toHaveBeenCalledWith(query); - expect(getGroups).toHaveBeenCalled(); + expect(getGroups).toHaveBeenCalledWith({ withProjectAccess: false }); expect(getDeployKeys).toHaveBeenCalledWith(query); }); }); diff --git a/spec/frontend/projects/settings/repository/branch_rules/app_spec.js b/spec/frontend/projects/settings/repository/branch_rules/app_spec.js index dd534bec25d..e86759ec6ca 100644 --- a/spec/frontend/projects/settings/repository/branch_rules/app_spec.js +++ b/spec/frontend/projects/settings/repository/branch_rules/app_spec.js @@ -1,16 +1,21 @@ -import Vue from 'vue'; +import Vue, { nextTick } from 'vue'; import VueApollo from 'vue-apollo'; -import { GlModal } from '@gitlab/ui'; +import { GlModal, GlCollapsibleListbox, GlDisclosureDropdown } from '@gitlab/ui'; +import setWindowLocation from 'helpers/set_window_location_helper'; +import { TEST_HOST } from 'helpers/test_constants'; import createMockApollo from 'helpers/mock_apollo_helper'; import waitForPromises from 'helpers/wait_for_promises'; import { mountExtended } from 'helpers/vue_test_utils_helper'; import BranchRules from '~/projects/settings/repository/branch_rules/app.vue'; import BranchRule from '~/projects/settings/repository/branch_rules/components/branch_rule.vue'; import branchRulesQuery from 'ee_else_ce/projects/settings/repository/branch_rules/graphql/queries/branch_rules.query.graphql'; +import createBranchRuleMutation from '~/projects/settings/repository/branch_rules/graphql/mutations/create_branch_rule.mutation.graphql'; + import { createAlert } from '~/alert'; import { branchRulesMockResponse, appProvideMock, + createBranchRuleMockResponse, } from 'ee_else_ce_jest/projects/settings/repository/branch_rules/mock_data'; import { I18N, @@ -31,16 +36,33 @@ Vue.use(VueApollo); describe('Branch rules app', () => { let wrapper; let fakeApollo; - + const openBranches = [ + { text: 'branch1', id: 'branch1', title: 'branch1' }, + { text: 'branch2', id: 'branch2', title: 'branch2' }, + ]; const branchRulesQuerySuccessHandler = jest.fn().mockResolvedValue(branchRulesMockResponse); - - const createComponent = async ({ queryHandler = branchRulesQuerySuccessHandler } = {}) => { - fakeApollo = createMockApollo([[branchRulesQuery, queryHandler]]); + const addRuleMutationSuccessHandler = jest.fn().mockResolvedValue(createBranchRuleMockResponse); + + const createComponent = async ({ + glFeatures = { addBranchRule: true }, + queryHandler = branchRulesQuerySuccessHandler, + mutationHandler = addRuleMutationSuccessHandler, + } = {}) => { + fakeApollo = createMockApollo([ + [branchRulesQuery, queryHandler], + [createBranchRuleMutation, mutationHandler], + ]); wrapper = mountExtended(BranchRules, { apolloProvider: fakeApollo, - provide: appProvideMock, - stubs: { GlModal: stubComponent(GlModal, { template: RENDER_ALL_SLOTS_TEMPLATE }) }, + provide: { + ...appProvideMock, + glFeatures, + }, + stubs: { + GlDisclosureDropdown, + GlModal: stubComponent(GlModal, { template: RENDER_ALL_SLOTS_TEMPLATE }), + }, directives: { GlModal: createMockDirective('gl-modal') }, }); @@ -51,9 +73,32 @@ describe('Branch rules app', () => { const findEmptyState = () => wrapper.findByTestId('empty'); const findAddBranchRuleButton = () => wrapper.findByRole('button', I18N.addBranchRule); const findModal = () => wrapper.findComponent(GlModal); + const findAddBranchRuleDropdown = () => wrapper.findComponent(GlDisclosureDropdown); + const findCreateBranchRuleListbox = () => wrapper.findComponent(GlCollapsibleListbox); + + beforeEach(() => { + window.gon = { + open_branches: openBranches, + }; + setWindowLocation(TEST_HOST); + }); beforeEach(() => createComponent()); + it('renders branch rules', () => { + const { nodes } = branchRulesMockResponse.data.project.branchRules; + + expect(findAllBranchRules().length).toBe(nodes.length); + + expect(findAllBranchRules().at(0).props('name')).toBe(nodes[0].name); + + expect(findAllBranchRules().at(0).props('branchProtection')).toEqual(nodes[0].branchProtection); + + expect(findAllBranchRules().at(1).props('name')).toBe(nodes[1].name); + + expect(findAllBranchRules().at(1).props('branchProtection')).toEqual(nodes[1].branchProtection); + }); + it('displays an error if branch rules query fails', async () => { await createComponent({ queryHandler: jest.fn().mockRejectedValue() }); expect(createAlert).toHaveBeenCalledWith({ message: I18N.queryError }); @@ -64,21 +109,65 @@ describe('Branch rules app', () => { expect(findEmptyState().text()).toBe(I18N.emptyState); }); - it('renders branch rules', () => { - const { nodes } = branchRulesMockResponse.data.project.branchRules; - - expect(findAllBranchRules().length).toBe(nodes.length); + describe('Add branch rule', () => { + it('renders an Add branch rule dropdown', () => { + expect(findAddBranchRuleDropdown().props('toggleText')).toBe('Add branch rule'); + }); - expect(findAllBranchRules().at(0).props('name')).toBe(nodes[0].name); + it('renders a modal with correct props/attributes', () => { + expect(findModal().props()).toMatchObject({ + title: I18N.createBranchRule, + modalId: BRANCH_PROTECTION_MODAL_ID, + actionCancel: { + text: 'Create branch rule', + }, + actionPrimary: { + attributes: { + disabled: true, + variant: 'confirm', + }, + text: 'Create protected branch', + }, + }); + }); - expect(findAllBranchRules().at(0).props('branchProtection')).toEqual(nodes[0].branchProtection); + it('renders listbox with branch names', () => { + expect(findCreateBranchRuleListbox().exists()).toBe(true); + expect(findCreateBranchRuleListbox().props('items')).toHaveLength(openBranches.length); + expect(findCreateBranchRuleListbox().props('toggleText')).toBe( + 'Select Branch or create wildcard', + ); + }); - expect(findAllBranchRules().at(1).props('name')).toBe(nodes[1].name); + it('when the primary modal action is clicked it calls create rule mutation', async () => { + findCreateBranchRuleListbox().vm.$emit('select', openBranches[0].text); + await nextTick(); + findModal().vm.$emit('primary'); + await nextTick(); + await nextTick(); + expect(addRuleMutationSuccessHandler).toHaveBeenCalledWith({ + name: 'branch1', + projectPath: 'some/project/path', + }); + }); - expect(findAllBranchRules().at(1).props('branchProtection')).toEqual(nodes[1].branchProtection); + it('shows alert when mutation fails', async () => { + createComponent({ mutationHandler: jest.fn().mockRejectedValue() }); + findCreateBranchRuleListbox().vm.$emit('select', openBranches[0].text); + await nextTick(); + findModal().vm.$emit('primary'); + await waitForPromises(); + expect(createAlert).toHaveBeenCalledWith({ + message: 'Something went wrong while creating branch rule.', + }); + }); }); - describe('Add branch rule', () => { + describe('Add branch rule when addBranchRule FF disabled', () => { + beforeEach(() => { + window.gon.open_branches = openBranches; + createComponent({ glFeatures: { addBranchRule: false } }); + }); it('renders an Add branch rule button', () => { expect(findAddBranchRuleButton().exists()).toBe(true); }); diff --git a/spec/frontend/projects/settings/repository/branch_rules/mock_data.js b/spec/frontend/projects/settings/repository/branch_rules/mock_data.js index d169397241d..5981647ce38 100644 --- a/spec/frontend/projects/settings/repository/branch_rules/mock_data.js +++ b/spec/frontend/projects/settings/repository/branch_rules/mock_data.js @@ -65,8 +65,22 @@ export const branchRulesMockResponse = { }, }; +export const createBranchRuleMockResponse = { + data: { + branchRuleCreate: { + errors: [], + branchRule: { + name: '*dkd', + __typename: 'BranchRule', + }, + __typename: 'BranchRuleCreatePayload', + }, + }, +}; + export const appProvideMock = { projectPath: 'some/project/path', + branchRulesPath: 'settings/repository/branch_rules', }; export const branchRuleProvideMock = { |