diff --git a/app/assets/javascripts/boards/components/board_form.vue b/app/assets/javascripts/boards/components/board_form.vue index 88bd1b0eaf0ecd77170820ada62ee63c560e8a76..e939f0c0ebe03909ffa2222df538766d66a171e7 100644 --- a/app/assets/javascripts/boards/components/board_form.vue +++ b/app/assets/javascripts/boards/components/board_form.vue @@ -1,7 +1,7 @@ <script> import { GlModal, GlAlert } from '@gitlab/ui'; import { mapGetters, mapActions, mapState } from 'vuex'; -import { TYPE_ITERATION, TYPE_MILESTONE } from '~/graphql_shared/constants'; +import { TYPE_USER, TYPE_ITERATION, TYPE_MILESTONE } from '~/graphql_shared/constants'; import { convertToGraphQLId } from '~/graphql_shared/utils'; import { getParameterByName, visitUrl } from '~/lib/utils/url_utility'; import { __, s__ } from '~/locale'; @@ -188,7 +188,9 @@ export default { issueBoardScopeMutationVariables() { return { weight: this.board.weight, - assigneeId: this.board.assignee?.id || null, + assigneeId: this.board.assignee?.id + ? convertToGraphQLId(TYPE_USER, this.board.assignee.id) + : null, milestoneId: this.board.milestone?.id ? convertToGraphQLId(TYPE_MILESTONE, this.board.milestone.id) : null, diff --git a/ee/spec/frontend/boards/components/board_form_spec.js b/ee/spec/frontend/boards/components/board_form_spec.js index 85bde5dfb5110f2975fc61758da9bae7d3ac056b..3b5ed65a6d249edb79cce3f464d19ff04cbc4408 100644 --- a/ee/spec/frontend/boards/components/board_form_spec.js +++ b/ee/spec/frontend/boards/components/board_form_spec.js @@ -12,11 +12,13 @@ import { TEST_HOST } from 'helpers/test_constants'; import waitForPromises from 'helpers/wait_for_promises'; import { formType } from '~/boards/constants'; +import updateBoardMutation from '~/boards/graphql/board_update.mutation.graphql'; import { visitUrl } from '~/lib/utils/url_utility'; jest.mock('~/lib/utils/url_utility', () => ({ visitUrl: jest.fn().mockName('visitUrlMock'), stripFinalUrlSegment: jest.requireActual('~/lib/utils/url_utility').stripFinalUrlSegment, + getParameterByName: jest.fn().mockName('getParameterByName'), })); Vue.use(Vuex); @@ -44,6 +46,7 @@ const defaultProps = { describe('BoardForm', () => { let wrapper; let mutate; + let store; const findModal = () => wrapper.findComponent(GlModal); const findModalActionPrimary = () => findModal().props('actionPrimary'); @@ -51,19 +54,18 @@ describe('BoardForm', () => { const findDeleteConfirmation = () => wrapper.find('[data-testid="delete-confirmation-message"]'); const findInput = () => wrapper.find('#board-new-name'); - const createStore = () => { - return new Vuex.Store({ + const createStore = ({ getters = {} } = {}) => { + store = new Vuex.Store({ getters: { isIssueBoard: () => false, isEpicBoard: () => true, isGroupBoard: () => true, isProjectBoard: () => false, + ...getters, }, }); }; - const store = createStore(); - const createComponent = (props) => { wrapper = shallowMount(BoardForm, { propsData: { ...defaultProps, ...props }, @@ -84,9 +86,14 @@ describe('BoardForm', () => { wrapper.destroy(); wrapper = null; mutate = null; + store = null; }); describe('when creating a new epic board', () => { + beforeEach(() => { + createStore(); + }); + describe('on non-scoped-board', () => { beforeEach(() => { createComponent({ canAdminBoard: true, currentPage: formType.new }); @@ -176,7 +183,62 @@ describe('BoardForm', () => { }); }); + describe('when editing a scoped issue board', () => { + beforeEach(() => { + createStore({ + getters: { + isIssueBoard: () => true, + isEpicBoard: () => false, + }, + }); + }); + + it('should use global ids for assignee, milestone and iteration when calling GraphQL mutation', async () => { + mutate = jest.fn().mockResolvedValue({ + data: { + updateBoard: { board: { id: 'gid://gitlab/Board/321' } }, + }, + }); + + createComponent({ + currentBoard: { + ...currentBoard, + assignee: { + id: 1, + }, + milestone: { + id: 2, + }, + iteration_id: 3, + }, + canAdminBoard: true, + currentPage: formType.edit, + scopedIssueBoardFeatureEnabled: true, + }); + + findInput().trigger('keyup.enter', { metaKey: true }); + + await waitForPromises(); + + expect(mutate).toHaveBeenCalledWith({ + mutation: updateBoardMutation, + variables: { + input: expect.objectContaining({ + id: `gid://gitlab/Board/${currentBoard.id}`, + assigneeId: 'gid://gitlab/User/1', + milestoneId: 'gid://gitlab/Milestone/2', + iterationId: 'gid://gitlab/Iteration/3', + }), + }, + }); + }); + }); + describe('when editing an epic board', () => { + beforeEach(() => { + createStore(); + }); + it('calls GraphQL mutation with correct parameters', async () => { mutate = jest.fn().mockResolvedValue({ data: { @@ -221,6 +283,10 @@ describe('BoardForm', () => { }); describe('when deleting an epic board', () => { + beforeEach(() => { + createStore(); + }); + it('passes correct primary action text and variant', () => { createComponent({ canAdminBoard: true, currentPage: formType.delete }); expect(findModalActionPrimary().text).toBe('Delete');