From 6a7cc8c14727f6fac64a5be6838764d8d5d41468 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Thu, 5 Dec 2019 18:07:51 +0000 Subject: Add latest changes from gitlab-org/gitlab@master --- .../projects/merge_requests_controller_spec.rb | 4 +- spec/features/projects/pipelines/pipelines_spec.rb | 2 +- .../projects/wiki/markdown_preview_spec.rb | 60 +-- .../projects/wiki/user_creates_wiki_page_spec.rb | 2 +- spec/frontend/boards/boards_store_spec.js | 549 ++++++++++++++++++++ .../frontend/boards/services/board_service_spec.js | 552 --------------------- spec/frontend/gfm_auto_complete_spec.js | 3 +- spec/frontend/notes/components/note_app_spec.js | 15 +- spec/helpers/search_helper_spec.rb | 4 +- spec/helpers/wiki_helper_spec.rb | 2 +- spec/javascripts/boards/boards_store_spec.js | 1 - spec/javascripts/boards/issue_spec.js | 1 - spec/javascripts/boards/list_spec.js | 1 - spec/javascripts/vue_mr_widget/mock_data.js | 1 + .../vue_mr_widget/mr_widget_options_spec.js | 97 ++-- spec/lib/banzai/pipeline/wiki_pipeline_spec.rb | 34 +- spec/lib/gitlab/chat/command_spec.rb | 2 +- spec/lib/gitlab/ci/pipeline/chain/build_spec.rb | 2 +- .../ci/pipeline/chain/config/content_spec.rb | 221 +++++++++ spec/models/project_wiki_spec.rb | 4 +- spec/requests/api/pipelines_spec.rb | 2 +- spec/routing/project_routing_spec.rb | 8 +- ...merge_request_poll_cached_widget_entity_spec.rb | 202 ++++++++ .../merge_request_poll_widget_entity_spec.rb | 180 +++++++ .../merge_request_widget_entity_spec.rb | 332 ------------- spec/services/ci/create_pipeline_service_spec.rb | 4 +- spec/support/helpers/stub_gitlab_calls.rb | 18 +- spec/views/search/_results.html.haml_spec.rb | 2 +- 28 files changed, 1306 insertions(+), 999 deletions(-) create mode 100644 spec/frontend/boards/boards_store_spec.js delete mode 100644 spec/frontend/boards/services/board_service_spec.js create mode 100644 spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb create mode 100644 spec/serializers/merge_request_poll_cached_widget_entity_spec.rb create mode 100644 spec/serializers/merge_request_poll_widget_entity_spec.rb (limited to 'spec') diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb index 4519cd014a1..ef5f286502b 100644 --- a/spec/controllers/projects/merge_requests_controller_spec.rb +++ b/spec/controllers/projects/merge_requests_controller_spec.rb @@ -1073,7 +1073,7 @@ describe Projects::MergeRequestsController do end it 'renders MergeRequest as JSON' do - expect(json_response.keys).to include('id', 'iid', 'description') + expect(json_response.keys).to include('id', 'iid') end end @@ -1107,7 +1107,7 @@ describe Projects::MergeRequestsController do it 'renders MergeRequest as JSON' do subject - expect(json_response.keys).to include('id', 'iid', 'description') + expect(json_response.keys).to include('id', 'iid') end end diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index f6eeb8d7065..f5558a1f2ec 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -706,7 +706,7 @@ describe 'Pipelines', :js do click_on 'Run Pipeline' end - it { expect(page).to have_content('Missing .gitlab-ci.yml file') } + it { expect(page).to have_content('Missing CI config file') } it 'creates a pipeline after first request failed and a valid gitlab-ci.yml file is available when trying again' do click_button project.default_branch diff --git a/spec/features/projects/wiki/markdown_preview_spec.rb b/spec/features/projects/wiki/markdown_preview_spec.rb index 5c6b04a7141..331ba58d067 100644 --- a/spec/features/projects/wiki/markdown_preview_spec.rb +++ b/spec/features/projects/wiki/markdown_preview_spec.rb @@ -29,11 +29,11 @@ describe 'Projects > Wiki > User previews markdown changes', :js do expect(page).to have_content("regular link") - expect(page.html).to include("regular link") - expect(page.html).to include("relative link 1") - expect(page.html).to include("relative link 2") - expect(page.html).to include("relative link 3") - expect(page.html).to include("spaced link") + expect(page.html).to include("regular link") + expect(page.html).to include("relative link 1") + expect(page.html).to include("relative link 2") + expect(page.html).to include("relative link 3") + expect(page.html).to include("spaced link") end end @@ -43,11 +43,11 @@ describe 'Projects > Wiki > User previews markdown changes', :js do expect(page).to have_content("regular link") - expect(page.html).to include("regular link") - expect(page.html).to include("relative link 1") - expect(page.html).to include("relative link 2") - expect(page.html).to include("relative link 3") - expect(page.html).to include("spaced link") + expect(page.html).to include("regular link") + expect(page.html).to include("relative link 1") + expect(page.html).to include("relative link 2") + expect(page.html).to include("relative link 3") + expect(page.html).to include("spaced link") end end @@ -57,11 +57,11 @@ describe 'Projects > Wiki > User previews markdown changes', :js do expect(page).to have_content("regular link") - expect(page.html).to include("regular link") - expect(page.html).to include("relative link 1") - expect(page.html).to include("relative link 2") - expect(page.html).to include("relative link 3") - expect(page.html).to include("spaced link") + expect(page.html).to include("regular link") + expect(page.html).to include("relative link 1") + expect(page.html).to include("relative link 2") + expect(page.html).to include("relative link 3") + expect(page.html).to include("spaced link") end end end @@ -77,11 +77,11 @@ describe 'Projects > Wiki > User previews markdown changes', :js do expect(page).to have_content("regular link") - expect(page.html).to include("regular link") - expect(page.html).to include("relative link 1") - expect(page.html).to include("relative link 2") - expect(page.html).to include("relative link 3") - expect(page.html).to include("spaced link") + expect(page.html).to include("regular link") + expect(page.html).to include("relative link 1") + expect(page.html).to include("relative link 2") + expect(page.html).to include("relative link 3") + expect(page.html).to include("spaced link") end end @@ -95,11 +95,11 @@ describe 'Projects > Wiki > User previews markdown changes', :js do expect(page).to have_content("regular link") - expect(page.html).to include("regular link") - expect(page.html).to include("relative link 1") - expect(page.html).to include("relative link 2") - expect(page.html).to include("relative link 3") - expect(page.html).to include("spaced link") + expect(page.html).to include("regular link") + expect(page.html).to include("relative link 1") + expect(page.html).to include("relative link 2") + expect(page.html).to include("relative link 3") + expect(page.html).to include("spaced link") end end @@ -113,11 +113,11 @@ describe 'Projects > Wiki > User previews markdown changes', :js do expect(page).to have_content("regular link") - expect(page.html).to include("regular link") - expect(page.html).to include("relative link 1") - expect(page.html).to include("relative link 2") - expect(page.html).to include("relative link 3") - expect(page.html).to include("spaced link") + expect(page.html).to include("regular link") + expect(page.html).to include("relative link 1") + expect(page.html).to include("relative link 2") + expect(page.html).to include("relative link 3") + expect(page.html).to include("spaced link") end end diff --git a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb index 56d0518015d..499c459621a 100644 --- a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb +++ b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb @@ -55,7 +55,7 @@ describe "User creates wiki page" do end expect(current_path).to include("one/two/three-test") - expect(page).to have_xpath("//a[@href='/#{project.full_path}/wikis/one/two/three-test']") + expect(page).to have_xpath("//a[@href='/#{project.full_path}/-/wikis/one/two/three-test']") end it "has `Create home` as a commit message", :js do diff --git a/spec/frontend/boards/boards_store_spec.js b/spec/frontend/boards/boards_store_spec.js new file mode 100644 index 00000000000..f8e5873c87b --- /dev/null +++ b/spec/frontend/boards/boards_store_spec.js @@ -0,0 +1,549 @@ +import { TEST_HOST } from 'helpers/test_constants'; +import AxiosMockAdapter from 'axios-mock-adapter'; +import axios from '~/lib/utils/axios_utils'; +import boardsStore from '~/boards/stores/boards_store'; + +describe('boardsStore', () => { + const dummyResponse = "without type checking this doesn't matter"; + const boardId = 'dummy-board-id'; + const endpoints = { + boardsEndpoint: `${TEST_HOST}/boards`, + listsEndpoint: `${TEST_HOST}/lists`, + bulkUpdatePath: `${TEST_HOST}/bulk/update`, + recentBoardsEndpoint: `${TEST_HOST}/recent/boards`, + }; + + let axiosMock; + + beforeEach(() => { + axiosMock = new AxiosMockAdapter(axios); + boardsStore.setEndpoints({ + ...endpoints, + boardId, + }); + }); + + describe('all', () => { + it('makes a request to fetch lists', () => { + axiosMock.onGet(endpoints.listsEndpoint).replyOnce(200, dummyResponse); + const expectedResponse = expect.objectContaining({ data: dummyResponse }); + + return expect(boardsStore.all()).resolves.toEqual(expectedResponse); + }); + + it('fails for error response', () => { + axiosMock.onGet(endpoints.listsEndpoint).replyOnce(500); + + return expect(boardsStore.all()).rejects.toThrow(); + }); + }); + + describe('generateDefaultLists', () => { + const listsEndpointGenerate = `${endpoints.listsEndpoint}/generate.json`; + + it('makes a request to generate default lists', () => { + axiosMock.onPost(listsEndpointGenerate).replyOnce(200, dummyResponse); + const expectedResponse = expect.objectContaining({ data: dummyResponse }); + + return expect(boardsStore.generateDefaultLists()).resolves.toEqual(expectedResponse); + }); + + it('fails for error response', () => { + axiosMock.onPost(listsEndpointGenerate).replyOnce(500); + + return expect(boardsStore.generateDefaultLists()).rejects.toThrow(); + }); + }); + + describe('createList', () => { + const entityType = 'moorhen'; + const entityId = 'quack'; + const expectedRequest = expect.objectContaining({ + data: JSON.stringify({ list: { [entityType]: entityId } }), + }); + + let requestSpy; + + beforeEach(() => { + requestSpy = jest.fn(); + axiosMock.onPost(endpoints.listsEndpoint).replyOnce(config => requestSpy(config)); + }); + + it('makes a request to create a list', () => { + requestSpy.mockReturnValue([200, dummyResponse]); + const expectedResponse = expect.objectContaining({ data: dummyResponse }); + + return expect(boardsStore.createList(entityId, entityType)) + .resolves.toEqual(expectedResponse) + .then(() => { + expect(requestSpy).toHaveBeenCalledWith(expectedRequest); + }); + }); + + it('fails for error response', () => { + requestSpy.mockReturnValue([500]); + + return expect(boardsStore.createList(entityId, entityType)) + .rejects.toThrow() + .then(() => { + expect(requestSpy).toHaveBeenCalledWith(expectedRequest); + }); + }); + }); + + describe('updateList', () => { + const id = 'David Webb'; + const position = 'unknown'; + const collapsed = false; + const expectedRequest = expect.objectContaining({ + data: JSON.stringify({ list: { position, collapsed } }), + }); + + let requestSpy; + + beforeEach(() => { + requestSpy = jest.fn(); + axiosMock.onPut(`${endpoints.listsEndpoint}/${id}`).replyOnce(config => requestSpy(config)); + }); + + it('makes a request to update a list position', () => { + requestSpy.mockReturnValue([200, dummyResponse]); + const expectedResponse = expect.objectContaining({ data: dummyResponse }); + + return expect(boardsStore.updateList(id, position, collapsed)) + .resolves.toEqual(expectedResponse) + .then(() => { + expect(requestSpy).toHaveBeenCalledWith(expectedRequest); + }); + }); + + it('fails for error response', () => { + requestSpy.mockReturnValue([500]); + + return expect(boardsStore.updateList(id, position, collapsed)) + .rejects.toThrow() + .then(() => { + expect(requestSpy).toHaveBeenCalledWith(expectedRequest); + }); + }); + }); + + describe('destroyList', () => { + const id = '-42'; + + let requestSpy; + + beforeEach(() => { + requestSpy = jest.fn(); + axiosMock + .onDelete(`${endpoints.listsEndpoint}/${id}`) + .replyOnce(config => requestSpy(config)); + }); + + it('makes a request to delete a list', () => { + requestSpy.mockReturnValue([200, dummyResponse]); + const expectedResponse = expect.objectContaining({ data: dummyResponse }); + + return expect(boardsStore.destroyList(id)) + .resolves.toEqual(expectedResponse) + .then(() => { + expect(requestSpy).toHaveBeenCalled(); + }); + }); + + it('fails for error response', () => { + requestSpy.mockReturnValue([500]); + + return expect(boardsStore.destroyList(id)) + .rejects.toThrow() + .then(() => { + expect(requestSpy).toHaveBeenCalled(); + }); + }); + }); + + describe('getIssuesForList', () => { + const id = 'TOO-MUCH'; + const url = `${endpoints.listsEndpoint}/${id}/issues?id=${id}`; + + it('makes a request to fetch list issues', () => { + axiosMock.onGet(url).replyOnce(200, dummyResponse); + const expectedResponse = expect.objectContaining({ data: dummyResponse }); + + return expect(boardsStore.getIssuesForList(id)).resolves.toEqual(expectedResponse); + }); + + it('makes a request to fetch list issues with filter', () => { + const filter = { algal: 'scrubber' }; + axiosMock.onGet(`${url}&algal=scrubber`).replyOnce(200, dummyResponse); + const expectedResponse = expect.objectContaining({ data: dummyResponse }); + + return expect(boardsStore.getIssuesForList(id, filter)).resolves.toEqual(expectedResponse); + }); + + it('fails for error response', () => { + axiosMock.onGet(url).replyOnce(500); + + return expect(boardsStore.getIssuesForList(id)).rejects.toThrow(); + }); + }); + + describe('moveIssue', () => { + const urlRoot = 'potato'; + const id = 'over 9000'; + const fromListId = 'left'; + const toListId = 'right'; + const moveBeforeId = 'up'; + const moveAfterId = 'down'; + const expectedRequest = expect.objectContaining({ + data: JSON.stringify({ + from_list_id: fromListId, + to_list_id: toListId, + move_before_id: moveBeforeId, + move_after_id: moveAfterId, + }), + }); + + let requestSpy; + + beforeAll(() => { + global.gon.relative_url_root = urlRoot; + }); + + afterAll(() => { + delete global.gon.relative_url_root; + }); + + beforeEach(() => { + requestSpy = jest.fn(); + axiosMock + .onPut(`${urlRoot}/-/boards/${boardId}/issues/${id}`) + .replyOnce(config => requestSpy(config)); + }); + + it('makes a request to move an issue between lists', () => { + requestSpy.mockReturnValue([200, dummyResponse]); + const expectedResponse = expect.objectContaining({ data: dummyResponse }); + + return expect(boardsStore.moveIssue(id, fromListId, toListId, moveBeforeId, moveAfterId)) + .resolves.toEqual(expectedResponse) + .then(() => { + expect(requestSpy).toHaveBeenCalledWith(expectedRequest); + }); + }); + + it('fails for error response', () => { + requestSpy.mockReturnValue([500]); + + return expect(boardsStore.moveIssue(id, fromListId, toListId, moveBeforeId, moveAfterId)) + .rejects.toThrow() + .then(() => { + expect(requestSpy).toHaveBeenCalledWith(expectedRequest); + }); + }); + }); + + describe('newIssue', () => { + const id = 'not-creative'; + const issue = { some: 'issue data' }; + const url = `${endpoints.listsEndpoint}/${id}/issues`; + const expectedRequest = expect.objectContaining({ + data: JSON.stringify({ + issue, + }), + }); + + let requestSpy; + + beforeEach(() => { + requestSpy = jest.fn(); + axiosMock.onPost(url).replyOnce(config => requestSpy(config)); + }); + + it('makes a request to create a new issue', () => { + requestSpy.mockReturnValue([200, dummyResponse]); + const expectedResponse = expect.objectContaining({ data: dummyResponse }); + + return expect(boardsStore.newIssue(id, issue)) + .resolves.toEqual(expectedResponse) + .then(() => { + expect(requestSpy).toHaveBeenCalledWith(expectedRequest); + }); + }); + + it('fails for error response', () => { + requestSpy.mockReturnValue([500]); + + return expect(boardsStore.newIssue(id, issue)) + .rejects.toThrow() + .then(() => { + expect(requestSpy).toHaveBeenCalledWith(expectedRequest); + }); + }); + }); + + describe('getBacklog', () => { + const urlRoot = 'deep'; + const url = `${urlRoot}/-/boards/${boardId}/issues.json?not=relevant`; + const requestParams = { + not: 'relevant', + }; + + beforeAll(() => { + global.gon.relative_url_root = urlRoot; + }); + + afterAll(() => { + delete global.gon.relative_url_root; + }); + + it('makes a request to fetch backlog', () => { + axiosMock.onGet(url).replyOnce(200, dummyResponse); + const expectedResponse = expect.objectContaining({ data: dummyResponse }); + + return expect(boardsStore.getBacklog(requestParams)).resolves.toEqual(expectedResponse); + }); + + it('fails for error response', () => { + axiosMock.onGet(url).replyOnce(500); + + return expect(boardsStore.getBacklog(requestParams)).rejects.toThrow(); + }); + }); + + describe('bulkUpdate', () => { + const issueIds = [1, 2, 3]; + const extraData = { moar: 'data' }; + const expectedRequest = expect.objectContaining({ + data: JSON.stringify({ + update: { + ...extraData, + issuable_ids: '1,2,3', + }, + }), + }); + + let requestSpy; + + beforeEach(() => { + requestSpy = jest.fn(); + axiosMock.onPost(endpoints.bulkUpdatePath).replyOnce(config => requestSpy(config)); + }); + + it('makes a request to create a list', () => { + requestSpy.mockReturnValue([200, dummyResponse]); + const expectedResponse = expect.objectContaining({ data: dummyResponse }); + + return expect(boardsStore.bulkUpdate(issueIds, extraData)) + .resolves.toEqual(expectedResponse) + .then(() => { + expect(requestSpy).toHaveBeenCalledWith(expectedRequest); + }); + }); + + it('fails for error response', () => { + requestSpy.mockReturnValue([500]); + + return expect(boardsStore.bulkUpdate(issueIds, extraData)) + .rejects.toThrow() + .then(() => { + expect(requestSpy).toHaveBeenCalledWith(expectedRequest); + }); + }); + }); + + describe('getIssueInfo', () => { + const dummyEndpoint = `${TEST_HOST}/some/where`; + + it('makes a request to the given endpoint', () => { + axiosMock.onGet(dummyEndpoint).replyOnce(200, dummyResponse); + const expectedResponse = expect.objectContaining({ data: dummyResponse }); + + return expect(boardsStore.getIssueInfo(dummyEndpoint)).resolves.toEqual(expectedResponse); + }); + + it('fails for error response', () => { + axiosMock.onGet(dummyEndpoint).replyOnce(500); + + return expect(boardsStore.getIssueInfo(dummyEndpoint)).rejects.toThrow(); + }); + }); + + describe('toggleIssueSubscription', () => { + const dummyEndpoint = `${TEST_HOST}/some/where`; + + it('makes a request to the given endpoint', () => { + axiosMock.onPost(dummyEndpoint).replyOnce(200, dummyResponse); + const expectedResponse = expect.objectContaining({ data: dummyResponse }); + + return expect(boardsStore.toggleIssueSubscription(dummyEndpoint)).resolves.toEqual( + expectedResponse, + ); + }); + + it('fails for error response', () => { + axiosMock.onPost(dummyEndpoint).replyOnce(500); + + return expect(boardsStore.toggleIssueSubscription(dummyEndpoint)).rejects.toThrow(); + }); + }); + + describe('allBoards', () => { + const url = `${endpoints.boardsEndpoint}.json`; + + it('makes a request to fetch all boards', () => { + axiosMock.onGet(url).replyOnce(200, dummyResponse); + const expectedResponse = expect.objectContaining({ data: dummyResponse }); + + return expect(boardsStore.allBoards()).resolves.toEqual(expectedResponse); + }); + + it('fails for error response', () => { + axiosMock.onGet(url).replyOnce(500); + + return expect(boardsStore.allBoards()).rejects.toThrow(); + }); + }); + + describe('recentBoards', () => { + const url = `${endpoints.recentBoardsEndpoint}.json`; + + it('makes a request to fetch all boards', () => { + axiosMock.onGet(url).replyOnce(200, dummyResponse); + const expectedResponse = expect.objectContaining({ data: dummyResponse }); + + return expect(boardsStore.recentBoards()).resolves.toEqual(expectedResponse); + }); + + it('fails for error response', () => { + axiosMock.onGet(url).replyOnce(500); + + return expect(boardsStore.recentBoards()).rejects.toThrow(); + }); + }); + + describe('createBoard', () => { + const labelIds = ['first label', 'second label']; + const assigneeId = 'as sign ee'; + const milestoneId = 'vegetable soup'; + const board = { + labels: labelIds.map(id => ({ id })), + assignee: { id: assigneeId }, + milestone: { id: milestoneId }, + }; + + describe('for existing board', () => { + const id = 'skate-board'; + const url = `${endpoints.boardsEndpoint}/${id}.json`; + const expectedRequest = expect.objectContaining({ + data: JSON.stringify({ + board: { + ...board, + id, + label_ids: labelIds, + assignee_id: assigneeId, + milestone_id: milestoneId, + }, + }), + }); + + let requestSpy; + + beforeEach(() => { + requestSpy = jest.fn(); + axiosMock.onPut(url).replyOnce(config => requestSpy(config)); + }); + + it('makes a request to update the board', () => { + requestSpy.mockReturnValue([200, dummyResponse]); + const expectedResponse = expect.objectContaining({ data: dummyResponse }); + + return expect( + boardsStore.createBoard({ + ...board, + id, + }), + ) + .resolves.toEqual(expectedResponse) + .then(() => { + expect(requestSpy).toHaveBeenCalledWith(expectedRequest); + }); + }); + + it('fails for error response', () => { + requestSpy.mockReturnValue([500]); + + return expect( + boardsStore.createBoard({ + ...board, + id, + }), + ) + .rejects.toThrow() + .then(() => { + expect(requestSpy).toHaveBeenCalledWith(expectedRequest); + }); + }); + }); + + describe('for new board', () => { + const url = `${endpoints.boardsEndpoint}.json`; + const expectedRequest = expect.objectContaining({ + data: JSON.stringify({ + board: { + ...board, + label_ids: labelIds, + assignee_id: assigneeId, + milestone_id: milestoneId, + }, + }), + }); + + let requestSpy; + + beforeEach(() => { + requestSpy = jest.fn(); + axiosMock.onPost(url).replyOnce(config => requestSpy(config)); + }); + + it('makes a request to create a new board', () => { + requestSpy.mockReturnValue([200, dummyResponse]); + const expectedResponse = expect.objectContaining({ data: dummyResponse }); + + return expect(boardsStore.createBoard(board)) + .resolves.toEqual(expectedResponse) + .then(() => { + expect(requestSpy).toHaveBeenCalledWith(expectedRequest); + }); + }); + + it('fails for error response', () => { + requestSpy.mockReturnValue([500]); + + return expect(boardsStore.createBoard(board)) + .rejects.toThrow() + .then(() => { + expect(requestSpy).toHaveBeenCalledWith(expectedRequest); + }); + }); + }); + }); + + describe('deleteBoard', () => { + const id = 'capsized'; + const url = `${endpoints.boardsEndpoint}/${id}.json`; + + it('makes a request to delete a boards', () => { + axiosMock.onDelete(url).replyOnce(200, dummyResponse); + const expectedResponse = expect.objectContaining({ data: dummyResponse }); + + return expect(boardsStore.deleteBoard({ id })).resolves.toEqual(expectedResponse); + }); + + it('fails for error response', () => { + axiosMock.onDelete(url).replyOnce(500); + + return expect(boardsStore.deleteBoard({ id })).rejects.toThrow(); + }); + }); +}); diff --git a/spec/frontend/boards/services/board_service_spec.js b/spec/frontend/boards/services/board_service_spec.js deleted file mode 100644 index 86f49f63f4e..00000000000 --- a/spec/frontend/boards/services/board_service_spec.js +++ /dev/null @@ -1,552 +0,0 @@ -import BoardService from '~/boards/services/board_service'; -import { TEST_HOST } from 'helpers/test_constants'; -import AxiosMockAdapter from 'axios-mock-adapter'; -import axios from '~/lib/utils/axios_utils'; -import boardsStore from '~/boards/stores/boards_store'; - -describe('BoardService', () => { - const dummyResponse = "without type checking this doesn't matter"; - const boardId = 'dummy-board-id'; - const endpoints = { - boardsEndpoint: `${TEST_HOST}/boards`, - listsEndpoint: `${TEST_HOST}/lists`, - bulkUpdatePath: `${TEST_HOST}/bulk/update`, - recentBoardsEndpoint: `${TEST_HOST}/recent/boards`, - }; - - let service; - let axiosMock; - - beforeEach(() => { - axiosMock = new AxiosMockAdapter(axios); - boardsStore.setEndpoints({ - ...endpoints, - boardId, - }); - service = new BoardService(); - }); - - describe('all', () => { - it('makes a request to fetch lists', () => { - axiosMock.onGet(endpoints.listsEndpoint).replyOnce(200, dummyResponse); - const expectedResponse = expect.objectContaining({ data: dummyResponse }); - - return expect(service.all()).resolves.toEqual(expectedResponse); - }); - - it('fails for error response', () => { - axiosMock.onGet(endpoints.listsEndpoint).replyOnce(500); - - return expect(service.all()).rejects.toThrow(); - }); - }); - - describe('generateDefaultLists', () => { - const listsEndpointGenerate = `${endpoints.listsEndpoint}/generate.json`; - - it('makes a request to generate default lists', () => { - axiosMock.onPost(listsEndpointGenerate).replyOnce(200, dummyResponse); - const expectedResponse = expect.objectContaining({ data: dummyResponse }); - - return expect(service.generateDefaultLists()).resolves.toEqual(expectedResponse); - }); - - it('fails for error response', () => { - axiosMock.onPost(listsEndpointGenerate).replyOnce(500); - - return expect(service.generateDefaultLists()).rejects.toThrow(); - }); - }); - - describe('createList', () => { - const entityType = 'moorhen'; - const entityId = 'quack'; - const expectedRequest = expect.objectContaining({ - data: JSON.stringify({ list: { [entityType]: entityId } }), - }); - - let requestSpy; - - beforeEach(() => { - requestSpy = jest.fn(); - axiosMock.onPost(endpoints.listsEndpoint).replyOnce(config => requestSpy(config)); - }); - - it('makes a request to create a list', () => { - requestSpy.mockReturnValue([200, dummyResponse]); - const expectedResponse = expect.objectContaining({ data: dummyResponse }); - - return expect(service.createList(entityId, entityType)) - .resolves.toEqual(expectedResponse) - .then(() => { - expect(requestSpy).toHaveBeenCalledWith(expectedRequest); - }); - }); - - it('fails for error response', () => { - requestSpy.mockReturnValue([500]); - - return expect(service.createList(entityId, entityType)) - .rejects.toThrow() - .then(() => { - expect(requestSpy).toHaveBeenCalledWith(expectedRequest); - }); - }); - }); - - describe('updateList', () => { - const id = 'David Webb'; - const position = 'unknown'; - const collapsed = false; - const expectedRequest = expect.objectContaining({ - data: JSON.stringify({ list: { position, collapsed } }), - }); - - let requestSpy; - - beforeEach(() => { - requestSpy = jest.fn(); - axiosMock.onPut(`${endpoints.listsEndpoint}/${id}`).replyOnce(config => requestSpy(config)); - }); - - it('makes a request to update a list position', () => { - requestSpy.mockReturnValue([200, dummyResponse]); - const expectedResponse = expect.objectContaining({ data: dummyResponse }); - - return expect(service.updateList(id, position, collapsed)) - .resolves.toEqual(expectedResponse) - .then(() => { - expect(requestSpy).toHaveBeenCalledWith(expectedRequest); - }); - }); - - it('fails for error response', () => { - requestSpy.mockReturnValue([500]); - - return expect(service.updateList(id, position, collapsed)) - .rejects.toThrow() - .then(() => { - expect(requestSpy).toHaveBeenCalledWith(expectedRequest); - }); - }); - }); - - describe('destroyList', () => { - const id = '-42'; - - let requestSpy; - - beforeEach(() => { - requestSpy = jest.fn(); - axiosMock - .onDelete(`${endpoints.listsEndpoint}/${id}`) - .replyOnce(config => requestSpy(config)); - }); - - it('makes a request to delete a list', () => { - requestSpy.mockReturnValue([200, dummyResponse]); - const expectedResponse = expect.objectContaining({ data: dummyResponse }); - - return expect(service.destroyList(id)) - .resolves.toEqual(expectedResponse) - .then(() => { - expect(requestSpy).toHaveBeenCalled(); - }); - }); - - it('fails for error response', () => { - requestSpy.mockReturnValue([500]); - - return expect(service.destroyList(id)) - .rejects.toThrow() - .then(() => { - expect(requestSpy).toHaveBeenCalled(); - }); - }); - }); - - describe('getIssuesForList', () => { - const id = 'TOO-MUCH'; - const url = `${endpoints.listsEndpoint}/${id}/issues?id=${id}`; - - it('makes a request to fetch list issues', () => { - axiosMock.onGet(url).replyOnce(200, dummyResponse); - const expectedResponse = expect.objectContaining({ data: dummyResponse }); - - return expect(service.getIssuesForList(id)).resolves.toEqual(expectedResponse); - }); - - it('makes a request to fetch list issues with filter', () => { - const filter = { algal: 'scrubber' }; - axiosMock.onGet(`${url}&algal=scrubber`).replyOnce(200, dummyResponse); - const expectedResponse = expect.objectContaining({ data: dummyResponse }); - - return expect(service.getIssuesForList(id, filter)).resolves.toEqual(expectedResponse); - }); - - it('fails for error response', () => { - axiosMock.onGet(url).replyOnce(500); - - return expect(service.getIssuesForList(id)).rejects.toThrow(); - }); - }); - - describe('moveIssue', () => { - const urlRoot = 'potato'; - const id = 'over 9000'; - const fromListId = 'left'; - const toListId = 'right'; - const moveBeforeId = 'up'; - const moveAfterId = 'down'; - const expectedRequest = expect.objectContaining({ - data: JSON.stringify({ - from_list_id: fromListId, - to_list_id: toListId, - move_before_id: moveBeforeId, - move_after_id: moveAfterId, - }), - }); - - let requestSpy; - - beforeAll(() => { - global.gon.relative_url_root = urlRoot; - }); - - afterAll(() => { - delete global.gon.relative_url_root; - }); - - beforeEach(() => { - requestSpy = jest.fn(); - axiosMock - .onPut(`${urlRoot}/-/boards/${boardId}/issues/${id}`) - .replyOnce(config => requestSpy(config)); - }); - - it('makes a request to move an issue between lists', () => { - requestSpy.mockReturnValue([200, dummyResponse]); - const expectedResponse = expect.objectContaining({ data: dummyResponse }); - - return expect(service.moveIssue(id, fromListId, toListId, moveBeforeId, moveAfterId)) - .resolves.toEqual(expectedResponse) - .then(() => { - expect(requestSpy).toHaveBeenCalledWith(expectedRequest); - }); - }); - - it('fails for error response', () => { - requestSpy.mockReturnValue([500]); - - return expect(service.moveIssue(id, fromListId, toListId, moveBeforeId, moveAfterId)) - .rejects.toThrow() - .then(() => { - expect(requestSpy).toHaveBeenCalledWith(expectedRequest); - }); - }); - }); - - describe('newIssue', () => { - const id = 'not-creative'; - const issue = { some: 'issue data' }; - const url = `${endpoints.listsEndpoint}/${id}/issues`; - const expectedRequest = expect.objectContaining({ - data: JSON.stringify({ - issue, - }), - }); - - let requestSpy; - - beforeEach(() => { - requestSpy = jest.fn(); - axiosMock.onPost(url).replyOnce(config => requestSpy(config)); - }); - - it('makes a request to create a new issue', () => { - requestSpy.mockReturnValue([200, dummyResponse]); - const expectedResponse = expect.objectContaining({ data: dummyResponse }); - - return expect(service.newIssue(id, issue)) - .resolves.toEqual(expectedResponse) - .then(() => { - expect(requestSpy).toHaveBeenCalledWith(expectedRequest); - }); - }); - - it('fails for error response', () => { - requestSpy.mockReturnValue([500]); - - return expect(service.newIssue(id, issue)) - .rejects.toThrow() - .then(() => { - expect(requestSpy).toHaveBeenCalledWith(expectedRequest); - }); - }); - }); - - describe('getBacklog', () => { - const urlRoot = 'deep'; - const url = `${urlRoot}/-/boards/${boardId}/issues.json?not=relevant`; - const requestParams = { - not: 'relevant', - }; - - beforeAll(() => { - global.gon.relative_url_root = urlRoot; - }); - - afterAll(() => { - delete global.gon.relative_url_root; - }); - - it('makes a request to fetch backlog', () => { - axiosMock.onGet(url).replyOnce(200, dummyResponse); - const expectedResponse = expect.objectContaining({ data: dummyResponse }); - - return expect(service.getBacklog(requestParams)).resolves.toEqual(expectedResponse); - }); - - it('fails for error response', () => { - axiosMock.onGet(url).replyOnce(500); - - return expect(service.getBacklog(requestParams)).rejects.toThrow(); - }); - }); - - describe('bulkUpdate', () => { - const issueIds = [1, 2, 3]; - const extraData = { moar: 'data' }; - const expectedRequest = expect.objectContaining({ - data: JSON.stringify({ - update: { - ...extraData, - issuable_ids: '1,2,3', - }, - }), - }); - - let requestSpy; - - beforeEach(() => { - requestSpy = jest.fn(); - axiosMock.onPost(endpoints.bulkUpdatePath).replyOnce(config => requestSpy(config)); - }); - - it('makes a request to create a list', () => { - requestSpy.mockReturnValue([200, dummyResponse]); - const expectedResponse = expect.objectContaining({ data: dummyResponse }); - - return expect(service.bulkUpdate(issueIds, extraData)) - .resolves.toEqual(expectedResponse) - .then(() => { - expect(requestSpy).toHaveBeenCalledWith(expectedRequest); - }); - }); - - it('fails for error response', () => { - requestSpy.mockReturnValue([500]); - - return expect(service.bulkUpdate(issueIds, extraData)) - .rejects.toThrow() - .then(() => { - expect(requestSpy).toHaveBeenCalledWith(expectedRequest); - }); - }); - }); - - describe('getIssueInfo', () => { - const dummyEndpoint = `${TEST_HOST}/some/where`; - - it('makes a request to the given endpoint', () => { - axiosMock.onGet(dummyEndpoint).replyOnce(200, dummyResponse); - const expectedResponse = expect.objectContaining({ data: dummyResponse }); - - return expect(BoardService.getIssueInfo(dummyEndpoint)).resolves.toEqual(expectedResponse); - }); - - it('fails for error response', () => { - axiosMock.onGet(dummyEndpoint).replyOnce(500); - - return expect(BoardService.getIssueInfo(dummyEndpoint)).rejects.toThrow(); - }); - }); - - describe('toggleIssueSubscription', () => { - const dummyEndpoint = `${TEST_HOST}/some/where`; - - it('makes a request to the given endpoint', () => { - axiosMock.onPost(dummyEndpoint).replyOnce(200, dummyResponse); - const expectedResponse = expect.objectContaining({ data: dummyResponse }); - - return expect(BoardService.toggleIssueSubscription(dummyEndpoint)).resolves.toEqual( - expectedResponse, - ); - }); - - it('fails for error response', () => { - axiosMock.onPost(dummyEndpoint).replyOnce(500); - - return expect(BoardService.toggleIssueSubscription(dummyEndpoint)).rejects.toThrow(); - }); - }); - - describe('allBoards', () => { - const url = `${endpoints.boardsEndpoint}.json`; - - it('makes a request to fetch all boards', () => { - axiosMock.onGet(url).replyOnce(200, dummyResponse); - const expectedResponse = expect.objectContaining({ data: dummyResponse }); - - return expect(service.allBoards()).resolves.toEqual(expectedResponse); - }); - - it('fails for error response', () => { - axiosMock.onGet(url).replyOnce(500); - - return expect(service.allBoards()).rejects.toThrow(); - }); - }); - - describe('recentBoards', () => { - const url = `${endpoints.recentBoardsEndpoint}.json`; - - it('makes a request to fetch all boards', () => { - axiosMock.onGet(url).replyOnce(200, dummyResponse); - const expectedResponse = expect.objectContaining({ data: dummyResponse }); - - return expect(service.recentBoards()).resolves.toEqual(expectedResponse); - }); - - it('fails for error response', () => { - axiosMock.onGet(url).replyOnce(500); - - return expect(service.recentBoards()).rejects.toThrow(); - }); - }); - - describe('createBoard', () => { - const labelIds = ['first label', 'second label']; - const assigneeId = 'as sign ee'; - const milestoneId = 'vegetable soup'; - const board = { - labels: labelIds.map(id => ({ id })), - assignee: { id: assigneeId }, - milestone: { id: milestoneId }, - }; - - describe('for existing board', () => { - const id = 'skate-board'; - const url = `${endpoints.boardsEndpoint}/${id}.json`; - const expectedRequest = expect.objectContaining({ - data: JSON.stringify({ - board: { - ...board, - id, - label_ids: labelIds, - assignee_id: assigneeId, - milestone_id: milestoneId, - }, - }), - }); - - let requestSpy; - - beforeEach(() => { - requestSpy = jest.fn(); - axiosMock.onPut(url).replyOnce(config => requestSpy(config)); - }); - - it('makes a request to update the board', () => { - requestSpy.mockReturnValue([200, dummyResponse]); - const expectedResponse = expect.objectContaining({ data: dummyResponse }); - - return expect( - service.createBoard({ - ...board, - id, - }), - ) - .resolves.toEqual(expectedResponse) - .then(() => { - expect(requestSpy).toHaveBeenCalledWith(expectedRequest); - }); - }); - - it('fails for error response', () => { - requestSpy.mockReturnValue([500]); - - return expect( - service.createBoard({ - ...board, - id, - }), - ) - .rejects.toThrow() - .then(() => { - expect(requestSpy).toHaveBeenCalledWith(expectedRequest); - }); - }); - }); - - describe('for new board', () => { - const url = `${endpoints.boardsEndpoint}.json`; - const expectedRequest = expect.objectContaining({ - data: JSON.stringify({ - board: { - ...board, - label_ids: labelIds, - assignee_id: assigneeId, - milestone_id: milestoneId, - }, - }), - }); - - let requestSpy; - - beforeEach(() => { - requestSpy = jest.fn(); - axiosMock.onPost(url).replyOnce(config => requestSpy(config)); - }); - - it('makes a request to create a new board', () => { - requestSpy.mockReturnValue([200, dummyResponse]); - const expectedResponse = expect.objectContaining({ data: dummyResponse }); - - return expect(service.createBoard(board)) - .resolves.toEqual(expectedResponse) - .then(() => { - expect(requestSpy).toHaveBeenCalledWith(expectedRequest); - }); - }); - - it('fails for error response', () => { - requestSpy.mockReturnValue([500]); - - return expect(service.createBoard(board)) - .rejects.toThrow() - .then(() => { - expect(requestSpy).toHaveBeenCalledWith(expectedRequest); - }); - }); - }); - }); - - describe('deleteBoard', () => { - const id = 'capsized'; - const url = `${endpoints.boardsEndpoint}/${id}.json`; - - it('makes a request to delete a boards', () => { - axiosMock.onDelete(url).replyOnce(200, dummyResponse); - const expectedResponse = expect.objectContaining({ data: dummyResponse }); - - return expect(service.deleteBoard({ id })).resolves.toEqual(expectedResponse); - }); - - it('fails for error response', () => { - axiosMock.onDelete(url).replyOnce(500); - - return expect(service.deleteBoard({ id })).rejects.toThrow(); - }); - }); -}); diff --git a/spec/frontend/gfm_auto_complete_spec.js b/spec/frontend/gfm_auto_complete_spec.js index 28ab2f2d6c4..99869c46f3f 100644 --- a/spec/frontend/gfm_auto_complete_spec.js +++ b/spec/frontend/gfm_auto_complete_spec.js @@ -1,8 +1,7 @@ /* eslint no-param-reassign: "off" */ import $ from 'jquery'; -import { membersBeforeSave } from '~/gfm_auto_complete'; -import GfmAutoComplete from 'ee_else_ce/gfm_auto_complete'; +import GfmAutoComplete, { membersBeforeSave } from 'ee_else_ce/gfm_auto_complete'; import 'jquery.caret'; import 'at.js'; diff --git a/spec/frontend/notes/components/note_app_spec.js b/spec/frontend/notes/components/note_app_spec.js index 3716b349210..3c960adb698 100644 --- a/spec/frontend/notes/components/note_app_spec.js +++ b/spec/frontend/notes/components/note_app_spec.js @@ -1,13 +1,13 @@ import $ from 'helpers/jquery'; import AxiosMockAdapter from 'axios-mock-adapter'; -import axios from '~/lib/utils/axios_utils'; import Vue from 'vue'; import { mount, createLocalVue } from '@vue/test-utils'; +import { setTestTimeout } from 'helpers/timeout'; +import axios from '~/lib/utils/axios_utils'; import NotesApp from '~/notes/components/notes_app.vue'; import service from '~/notes/services/notes_service'; import createStore from '~/notes/stores'; import '~/behaviors/markdown/render_gfm'; -import { setTestTimeout } from 'helpers/timeout'; // TODO: use generated fixture (https://gitlab.com/gitlab-org/gitlab-foss/issues/62491) import * as mockData from '../../notes/mock_data'; import * as urlUtility from '~/lib/utils/url_utility'; @@ -77,6 +77,8 @@ describe('note_app', () => { describe('set data', () => { beforeEach(() => { + setFixtures('
'); + axiosMock.onAny().reply(200, []); wrapper = mountComponent(); return waitForDiscussionsRequest(); @@ -97,6 +99,10 @@ describe('note_app', () => { it('should fetch discussions', () => { expect(store.state.discussions).toEqual([]); }); + + it('updates discussions badge', () => { + expect(document.querySelector('.js-discussions-count').textContent).toEqual('0'); + }); }); describe('render', () => { @@ -161,6 +167,7 @@ describe('note_app', () => { describe('while fetching data', () => { beforeEach(() => { + setFixtures('
'); axiosMock.onAny().reply(200, []); wrapper = mountComponent(); }); @@ -177,6 +184,10 @@ describe('note_app', () => { 'Write a comment or drag your files hereā€¦', ); }); + + it('should not update discussions badge (it should be blank)', () => { + expect(document.querySelector('.js-discussions-count').textContent).toEqual(''); + }); }); describe('update note', () => { diff --git a/spec/helpers/search_helper_spec.rb b/spec/helpers/search_helper_spec.rb index bef6fbe3d5f..18c94602596 100644 --- a/spec/helpers/search_helper_spec.rb +++ b/spec/helpers/search_helper_spec.rb @@ -122,13 +122,13 @@ describe SearchHelper do it 'uses the correct singular label' do collection = Kaminari.paginate_array([:foo]).page(1).per(10) - expect(search_entries_info(collection, scope, 'foo')).to eq("Showing 1 #{label} for \"foo\"") + expect(search_entries_info(collection, scope, 'foo')).to eq("Showing 1 #{label} for foo ") end it 'uses the correct plural label' do collection = Kaminari.paginate_array([:foo] * 23).page(1).per(10) - expect(search_entries_info(collection, scope, 'foo')).to eq("Showing 1 - 10 of 23 #{label.pluralize} for \"foo\"") + expect(search_entries_info(collection, scope, 'foo')).to eq("Showing 1 - 10 of 23 #{label.pluralize} for foo ") end end diff --git a/spec/helpers/wiki_helper_spec.rb b/spec/helpers/wiki_helper_spec.rb index bcc2bd71da1..1aab01281c6 100644 --- a/spec/helpers/wiki_helper_spec.rb +++ b/spec/helpers/wiki_helper_spec.rb @@ -27,7 +27,7 @@ describe WikiHelper do let(:classes) { "btn btn-default has-tooltip reverse-sort-btn qa-reverse-sort rspec-reverse-sort" } def expected_link(sort, direction, icon_class) - path = "/#{project.full_path}/wikis/pages?direction=#{direction}&sort=#{sort}" + path = "/#{project.full_path}/-/wikis/pages?direction=#{direction}&sort=#{sort}" helper.link_to(path, type: 'button', class: classes, title: 'Sort direction') do helper.sprite_icon("sort-#{icon_class}", size: 16) diff --git a/spec/javascripts/boards/boards_store_spec.js b/spec/javascripts/boards/boards_store_spec.js index 292fa745fe8..278930789e1 100644 --- a/spec/javascripts/boards/boards_store_spec.js +++ b/spec/javascripts/boards/boards_store_spec.js @@ -8,7 +8,6 @@ import '~/boards/models/label'; import '~/boards/models/assignee'; import '~/boards/models/issue'; import '~/boards/models/list'; -import '~/boards/services/board_service'; import boardsStore from '~/boards/stores/boards_store'; import eventHub from '~/boards/eventhub'; import { listObj, listObjDuplicate, boardsMockInterceptor } from './mock_data'; diff --git a/spec/javascripts/boards/issue_spec.js b/spec/javascripts/boards/issue_spec.js index 890a47c189a..181e7af7451 100644 --- a/spec/javascripts/boards/issue_spec.js +++ b/spec/javascripts/boards/issue_spec.js @@ -5,7 +5,6 @@ import '~/boards/models/label'; import '~/boards/models/assignee'; import '~/boards/models/issue'; import '~/boards/models/list'; -import '~/boards/services/board_service'; import boardsStore from '~/boards/stores/boards_store'; import { setMockEndpoints } from './mock_data'; diff --git a/spec/javascripts/boards/list_spec.js b/spec/javascripts/boards/list_spec.js index 1fcd7958bc5..374e7d76b1c 100644 --- a/spec/javascripts/boards/list_spec.js +++ b/spec/javascripts/boards/list_spec.js @@ -10,7 +10,6 @@ import '~/boards/models/label'; import '~/boards/models/assignee'; import '~/boards/models/issue'; import '~/boards/models/list'; -import '~/boards/services/board_service'; import boardsStore from '~/boards/stores/boards_store'; import { listObj, listObjDuplicate, boardsMockInterceptor } from './mock_data'; diff --git a/spec/javascripts/vue_mr_widget/mock_data.js b/spec/javascripts/vue_mr_widget/mock_data.js index ff34dafa660..ba999adb2a9 100644 --- a/spec/javascripts/vue_mr_widget/mock_data.js +++ b/spec/javascripts/vue_mr_widget/mock_data.js @@ -222,6 +222,7 @@ export default { plain_diff_path: '/root/acets-app/merge_requests/22.diff', merge_request_basic_path: '/root/acets-app/merge_requests/22.json?serializer=basic', merge_request_widget_path: '/root/acets-app/merge_requests/22/widget.json', + merge_request_cached_widget_path: '/cached.json', merge_check_path: '/root/acets-app/merge_requests/22/merge_check', ci_environments_status_url: '/root/acets-app/merge_requests/22/ci_environments_status', project_archived: false, diff --git a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js index 604b21e77fe..36e4ce7177f 100644 --- a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js +++ b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js @@ -1,4 +1,6 @@ import Vue from 'vue'; +import MockAdapter from 'axios-mock-adapter'; +import axios from '~/lib/utils/axios_utils'; import mrWidgetOptions from '~/vue_merge_request_widget/mr_widget_options.vue'; import eventHub from '~/vue_merge_request_widget/event_hub'; import notify from '~/lib/utils/notify'; @@ -17,6 +19,7 @@ const returnPromise = data => describe('mrWidgetOptions', () => { let vm; + let mock; let MrWidgetOptions; const COLLABORATION_MESSAGE = 'Allows commits from members who can merge to the target branch'; @@ -25,6 +28,13 @@ describe('mrWidgetOptions', () => { // Prevent component mounting delete mrWidgetOptions.el; + gl.mrWidgetData = { ...mockData }; + gon.features = { asyncMrWidget: true }; + + mock = new MockAdapter(axios); + mock.onGet(mockData.merge_request_widget_path).reply(() => [200, { ...mockData }]); + mock.onGet(mockData.merge_request_cached_widget_path).reply(() => [200, { ...mockData }]); + MrWidgetOptions = Vue.extend(mrWidgetOptions); vm = mountComponent(MrWidgetOptions, { mrData: { ...mockData }, @@ -33,6 +43,9 @@ describe('mrWidgetOptions', () => { afterEach(() => { vm.$destroy(); + mock.restore(); + gl.mrWidgetData = {}; + gon.features = {}; }); describe('data', () => { @@ -308,59 +321,61 @@ describe('mrWidgetOptions', () => { }); describe('bindEventHubListeners', () => { - it('should bind eventHub listeners', () => { + it('should bind eventHub listeners', done => { spyOn(vm, 'checkStatus').and.returnValue(() => {}); spyOn(vm.service, 'checkStatus').and.returnValue(returnPromise(mockData)); spyOn(vm, 'fetchActionsContent'); spyOn(vm.mr, 'setData'); spyOn(vm, 'resumePolling'); spyOn(vm, 'stopPolling'); - spyOn(eventHub, '$on'); + spyOn(eventHub, '$on').and.callThrough(); - vm.bindEventHubListeners(); + setTimeout(() => { + eventHub.$emit('SetBranchRemoveFlag', ['flag']); - eventHub.$emit('SetBranchRemoveFlag', ['flag']); + expect(vm.mr.isRemovingSourceBranch).toEqual('flag'); - expect(vm.mr.isRemovingSourceBranch).toEqual('flag'); + eventHub.$emit('FailedToMerge'); - eventHub.$emit('FailedToMerge'); + expect(vm.mr.state).toEqual('failedToMerge'); - expect(vm.mr.state).toEqual('failedToMerge'); + eventHub.$emit('UpdateWidgetData', mockData); - eventHub.$emit('UpdateWidgetData', mockData); + expect(vm.mr.setData).toHaveBeenCalledWith(mockData); - expect(vm.mr.setData).toHaveBeenCalledWith(mockData); + eventHub.$emit('EnablePolling'); - eventHub.$emit('EnablePolling'); + expect(vm.resumePolling).toHaveBeenCalled(); - expect(vm.resumePolling).toHaveBeenCalled(); + eventHub.$emit('DisablePolling'); - eventHub.$emit('DisablePolling'); + expect(vm.stopPolling).toHaveBeenCalled(); - expect(vm.stopPolling).toHaveBeenCalled(); + const listenersWithServiceRequest = { + MRWidgetUpdateRequested: true, + FetchActionsContent: true, + }; - const listenersWithServiceRequest = { - MRWidgetUpdateRequested: true, - FetchActionsContent: true, - }; + const allArgs = eventHub.$on.calls.allArgs(); + allArgs.forEach(params => { + const eventName = params[0]; + const callback = params[1]; - const allArgs = eventHub.$on.calls.allArgs(); - allArgs.forEach(params => { - const eventName = params[0]; - const callback = params[1]; + if (listenersWithServiceRequest[eventName]) { + listenersWithServiceRequest[eventName] = callback; + } + }); - if (listenersWithServiceRequest[eventName]) { - listenersWithServiceRequest[eventName] = callback; - } - }); + listenersWithServiceRequest.MRWidgetUpdateRequested(); - listenersWithServiceRequest.MRWidgetUpdateRequested(); + expect(vm.checkStatus).toHaveBeenCalled(); - expect(vm.checkStatus).toHaveBeenCalled(); + listenersWithServiceRequest.FetchActionsContent(); - listenersWithServiceRequest.FetchActionsContent(); + expect(vm.fetchActionsContent).toHaveBeenCalled(); - expect(vm.fetchActionsContent).toHaveBeenCalled(); + done(); + }); }); }); @@ -451,22 +466,30 @@ describe('mrWidgetOptions', () => { }); describe('resumePolling', () => { - it('should call stopTimer on pollingInterval', () => { - spyOn(vm.pollingInterval, 'resume'); + it('should call stopTimer on pollingInterval', done => { + setTimeout(() => { + spyOn(vm.pollingInterval, 'resume'); + + vm.resumePolling(); - vm.resumePolling(); + expect(vm.pollingInterval.resume).toHaveBeenCalled(); - expect(vm.pollingInterval.resume).toHaveBeenCalled(); + done(); + }); }); }); describe('stopPolling', () => { - it('should call stopTimer on pollingInterval', () => { - spyOn(vm.pollingInterval, 'stopTimer'); + it('should call stopTimer on pollingInterval', done => { + setTimeout(() => { + spyOn(vm.pollingInterval, 'stopTimer'); + + vm.stopPolling(); - vm.stopPolling(); + expect(vm.pollingInterval.stopTimer).toHaveBeenCalled(); - expect(vm.pollingInterval.stopTimer).toHaveBeenCalled(); + done(); + }); }); }); }); diff --git a/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb b/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb index 26f2b0b0acf..e1814ea403e 100644 --- a/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb +++ b/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb @@ -72,14 +72,14 @@ describe Banzai::Pipeline::WikiPipeline do markdown = "[Page](./page)" output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) - expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/twice/page\"") + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/-/wikis/nested/twice/page\"") end it "rewrites file links to be at the scope of the current directory" do markdown = "[Link to Page](./page.md)" output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) - expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/twice/page.md\"") + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/-/wikis/nested/twice/page.md\"") end end @@ -88,14 +88,14 @@ describe Banzai::Pipeline::WikiPipeline do markdown = "[Link to Page](../page)" output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) - expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/page\"") + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/-/wikis/nested/page\"") end it "rewrites file links to be at the scope of the parent directory" do markdown = "[Link to Page](../page.md)" output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) - expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/page.md\"") + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/-/wikis/nested/page.md\"") end end @@ -104,14 +104,14 @@ describe Banzai::Pipeline::WikiPipeline do markdown = "[Link to Page](./subdirectory/page)" output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) - expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/twice/subdirectory/page\"") + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/-/wikis/nested/twice/subdirectory/page\"") end it "rewrites file links to be at the scope of the sub-directory" do markdown = "[Link to Page](./subdirectory/page.md)" output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) - expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/twice/subdirectory/page.md\"") + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/-/wikis/nested/twice/subdirectory/page.md\"") end end @@ -120,35 +120,35 @@ describe Banzai::Pipeline::WikiPipeline do markdown = "[Link to Page](page)" output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) - expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/page\"") + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/-/wikis/page\"") end it 'rewrites non-file links (with spaces) to be at the scope of the wiki root' do markdown = "[Link to Page](page slug)" output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) - expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/page%20slug\"") + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/-/wikis/page%20slug\"") end it "rewrites file links to be at the scope of the current directory" do markdown = "[Link to Page](page.md)" output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) - expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/twice/page.md\"") + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/-/wikis/nested/twice/page.md\"") end it 'rewrites links with anchor' do markdown = '[Link to Header](start-page#title)' output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) - expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/start-page#title\"") + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/-/wikis/start-page#title\"") end it 'rewrites links (with spaces) with anchor' do markdown = '[Link to Header](start page#title)' output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) - expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/start%20page#title\"") + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/-/wikis/start%20page#title\"") end end @@ -157,14 +157,14 @@ describe Banzai::Pipeline::WikiPipeline do markdown = "[Link to Page](/page)" output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) - expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/page\"") + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/-/wikis/page\"") end it 'rewrites file links to be at the scope of the wiki root' do markdown = "[Link to Page](/page.md)" output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) - expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/page.md\"") + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/-/wikis/page.md\"") end end end @@ -270,28 +270,28 @@ describe Banzai::Pipeline::WikiPipeline do markdown = "![video_file](video_file_name.mp4)" output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) - expect(output).to include('