diff options
author | Kushal Pandya <kushalspandya@gmail.com> | 2019-04-07 02:36:21 +0000 |
---|---|---|
committer | Kushal Pandya <kushalspandya@gmail.com> | 2019-04-07 02:36:21 +0000 |
commit | 8f372152774119440ba41f2603eac4f475a601f6 (patch) | |
tree | c89f98207d31ee7ec53f403f3b2dd368f6d84a99 /spec | |
parent | 302dbfff2a298a2683997feca98589aff33228fb (diff) | |
parent | 7650677d3d832f9d65c8d38a2485ca60b97731c4 (diff) | |
download | gitlab-ce-8f372152774119440ba41f2603eac4f475a601f6.tar.gz |
Merge branch '_acet-related-mrs-widget-rewrite' into 'master'
Rewrite related MRs widget with Vue
Closes #58926 and #57662
See merge request gitlab-org/gitlab-ce!27027
Diffstat (limited to 'spec')
5 files changed, 307 insertions, 1 deletions
diff --git a/spec/features/issuables/markdown_references/internal_references_spec.rb b/spec/features/issuables/markdown_references/internal_references_spec.rb index 23385ba65fc..870e92b8de8 100644 --- a/spec/features/issuables/markdown_references/internal_references_spec.rb +++ b/spec/features/issuables/markdown_references/internal_references_spec.rb @@ -70,7 +70,7 @@ describe "Internal references", :js do page.within("#merge-requests ul") do expect(page).to have_content(private_project_merge_request.title) - expect(page).to have_css(".merge-request-status") + expect(page).to have_css(".ic-issue-open-m") end expect(page).to have_content("mentioned in merge request #{private_project_merge_request.to_reference(public_project)}") diff --git a/spec/javascripts/fixtures/issues.rb b/spec/javascripts/fixtures/issues.rb index 645b3aa788a..0f3f9a10f94 100644 --- a/spec/javascripts/fixtures/issues.rb +++ b/spec/javascripts/fixtures/issues.rb @@ -65,3 +65,61 @@ describe Projects::IssuesController, '(JavaScript fixtures)', type: :controller store_frontend_fixture(response, fixture_file_name) end end + +describe API::Issues, '(JavaScript fixtures)', type: :request do + include ApiHelpers + include JavaScriptFixturesHelpers + + def get_related_merge_requests(project_id, issue_iid, user = nil) + get api("/projects/#{project_id}/issues/#{issue_iid}/related_merge_requests", user) + end + + def create_referencing_mr(user, project, issue) + attributes = { + author: user, + source_project: project, + target_project: project, + source_branch: "master", + target_branch: "test", + assignee: user, + description: "See #{issue.to_reference}" + } + create(:merge_request, attributes).tap do |merge_request| + create(:note, :system, project: issue.project, noteable: issue, author: user, note: merge_request.to_reference(full: true)) + end + end + + it 'issues/related_merge_requests.json' do |example| + user = create(:user) + project = create(:project, :public, creator_id: user.id, namespace: user.namespace) + issue_title = 'foo' + issue_description = 'closed' + milestone = create(:milestone, title: '1.0.0', project: project) + issue = create :issue, + author: user, + assignees: [user], + project: project, + milestone: milestone, + created_at: generate(:past_time), + updated_at: 1.hour.ago, + title: issue_title, + description: issue_description + + project.add_reporter(user) + create_referencing_mr(user, project, issue) + + create(:merge_request, + :simple, + author: user, + source_project: project, + target_project: project, + description: "Some description") + project2 = create(:project, :public, creator_id: user.id, namespace: user.namespace) + create_referencing_mr(user, project2, issue).update!(head_pipeline: create(:ci_pipeline)) + + get_related_merge_requests(project.id, issue.iid, user) + + expect(response).to be_success + store_frontend_fixture(response, example.description) + end +end diff --git a/spec/javascripts/related_merge_requests/components/related_merge_requests_spec.js b/spec/javascripts/related_merge_requests/components/related_merge_requests_spec.js new file mode 100644 index 00000000000..29760f79c3c --- /dev/null +++ b/spec/javascripts/related_merge_requests/components/related_merge_requests_spec.js @@ -0,0 +1,89 @@ +import { mount, createLocalVue } from '@vue/test-utils'; +import MockAdapter from 'axios-mock-adapter'; +import axios from '~/lib/utils/axios_utils'; +import RelatedIssuableItem from '~/vue_shared/components/issue/related_issuable_item.vue'; +import RelatedMergeRequests from '~/related_merge_requests/components/related_merge_requests.vue'; +import createStore from '~/related_merge_requests/store/index'; + +const FIXTURE_PATH = 'issues/related_merge_requests.json'; +const API_ENDPOINT = '/api/v4/projects/2/issues/33/related_merge_requests'; +const localVue = createLocalVue(); + +describe('RelatedMergeRequests', () => { + let wrapper; + let mock; + let mockData; + + beforeEach(done => { + loadFixtures(FIXTURE_PATH); + mockData = getJSONFixture(FIXTURE_PATH); + mock = new MockAdapter(axios); + mock.onGet(`${API_ENDPOINT}?per_page=100`).reply(200, mockData, { 'x-total': 2 }); + + wrapper = mount(RelatedMergeRequests, { + localVue, + sync: false, + store: createStore(), + propsData: { + endpoint: API_ENDPOINT, + projectNamespace: 'gitlab-org', + projectPath: 'gitlab-ce', + }, + }); + + setTimeout(done); + }); + + afterEach(() => { + wrapper.destroy(); + mock.restore(); + }); + + describe('methods', () => { + describe('getAssignees', () => { + const assignees = [{ name: 'foo' }, { name: 'bar' }]; + + describe('when there is assignees array', () => { + it('should return assignees array', () => { + const mr = { assignees }; + + expect(wrapper.vm.getAssignees(mr)).toEqual(assignees); + }); + }); + + it('should return an array with single assingee', () => { + const mr = { assignee: assignees[0] }; + + expect(wrapper.vm.getAssignees(mr)).toEqual([assignees[0]]); + }); + + it('should return empty array when assignee is not set', () => { + expect(wrapper.vm.getAssignees({})).toEqual([]); + expect(wrapper.vm.getAssignees({ assignee: null })).toEqual([]); + }); + }); + }); + + describe('template', () => { + it('should render related merge request items', () => { + expect(wrapper.find('.js-items-count').text()).toEqual('2'); + expect(wrapper.findAll(RelatedIssuableItem).length).toEqual(2); + + const props = wrapper + .findAll(RelatedIssuableItem) + .at(1) + .props(); + const data = mockData[1]; + + expect(props.idKey).toEqual(data.id); + expect(props.pathIdSeparator).toEqual('!'); + expect(props.pipelineStatus).toBe(data.head_pipeline.detailed_status); + expect(props.assignees).toEqual([data.assignee]); + expect(props.isMergeRequest).toBe(true); + expect(props.confidential).toEqual(false); + expect(props.title).toEqual(data.title); + expect(props.state).toEqual(data.state); + expect(props.createdAt).toEqual(data.created_at); + }); + }); +}); diff --git a/spec/javascripts/related_merge_requests/store/actions_spec.js b/spec/javascripts/related_merge_requests/store/actions_spec.js new file mode 100644 index 00000000000..65e436fbb17 --- /dev/null +++ b/spec/javascripts/related_merge_requests/store/actions_spec.js @@ -0,0 +1,110 @@ +import MockAdapter from 'axios-mock-adapter'; +import axios from '~/lib/utils/axios_utils'; +import * as types from '~/related_merge_requests/store/mutation_types'; +import actionsModule, * as actions from '~/related_merge_requests/store/actions'; +import testAction from 'spec/helpers/vuex_action_helper'; + +describe('RelatedMergeRequest store actions', () => { + let state; + let flashSpy; + let mock; + + beforeEach(() => { + state = { + apiEndpoint: '/api/related_merge_requests', + }; + flashSpy = spyOnDependency(actionsModule, 'createFlash'); + mock = new MockAdapter(axios); + }); + + afterEach(() => { + mock.restore(); + }); + + describe('setInitialState', () => { + it('commits types.SET_INITIAL_STATE with given props', done => { + const props = { a: 1, b: 2 }; + + testAction( + actions.setInitialState, + props, + {}, + [{ type: types.SET_INITIAL_STATE, payload: props }], + [], + done, + ); + }); + }); + + describe('requestData', () => { + it('commits types.REQUEST_DATA', done => { + testAction(actions.requestData, null, {}, [{ type: types.REQUEST_DATA }], [], done); + }); + }); + + describe('receiveDataSuccess', () => { + it('commits types.RECEIVE_DATA_SUCCESS with data', done => { + const data = { a: 1, b: 2 }; + + testAction( + actions.receiveDataSuccess, + data, + {}, + [{ type: types.RECEIVE_DATA_SUCCESS, payload: data }], + [], + done, + ); + }); + }); + + describe('receiveDataError', () => { + it('commits types.RECEIVE_DATA_ERROR', done => { + testAction( + actions.receiveDataError, + null, + {}, + [{ type: types.RECEIVE_DATA_ERROR }], + [], + done, + ); + }); + }); + + describe('fetchMergeRequests', () => { + describe('for a successful request', () => { + it('should dispatch success action', done => { + const data = { a: 1 }; + mock.onGet(`${state.apiEndpoint}?per_page=100`).replyOnce(200, data, { 'x-total': 2 }); + + testAction( + actions.fetchMergeRequests, + null, + state, + [], + [{ type: 'requestData' }, { type: 'receiveDataSuccess', payload: { data, total: 2 } }], + done, + ); + }); + }); + + describe('for a failing request', () => { + it('should dispatch error action', done => { + mock.onGet(`${state.apiEndpoint}?per_page=100`).replyOnce(400); + + testAction( + actions.fetchMergeRequests, + null, + state, + [], + [{ type: 'requestData' }, { type: 'receiveDataError' }], + () => { + expect(flashSpy).toHaveBeenCalledTimes(1); + expect(flashSpy).toHaveBeenCalledWith(jasmine.stringMatching('Something went wrong')); + + done(); + }, + ); + }); + }); + }); +}); diff --git a/spec/javascripts/related_merge_requests/store/mutations_spec.js b/spec/javascripts/related_merge_requests/store/mutations_spec.js new file mode 100644 index 00000000000..21b6e26376b --- /dev/null +++ b/spec/javascripts/related_merge_requests/store/mutations_spec.js @@ -0,0 +1,49 @@ +import mutations from '~/related_merge_requests/store/mutations'; +import * as types from '~/related_merge_requests/store/mutation_types'; + +describe('RelatedMergeRequests Store Mutations', () => { + describe('SET_INITIAL_STATE', () => { + it('should set initial state according to given data', () => { + const apiEndpoint = '/api'; + const state = {}; + + mutations[types.SET_INITIAL_STATE](state, { apiEndpoint }); + + expect(state.apiEndpoint).toEqual(apiEndpoint); + }); + }); + + describe('REQUEST_DATA', () => { + it('should set loading flag', () => { + const state = {}; + + mutations[types.REQUEST_DATA](state); + + expect(state.isFetchingMergeRequests).toEqual(true); + }); + }); + + describe('RECEIVE_DATA_SUCCESS', () => { + it('should set loading flag and data', () => { + const state = {}; + const mrs = [1, 2, 3]; + + mutations[types.RECEIVE_DATA_SUCCESS](state, { data: mrs, total: mrs.length }); + + expect(state.isFetchingMergeRequests).toEqual(false); + expect(state.mergeRequests).toEqual(mrs); + expect(state.totalCount).toEqual(mrs.length); + }); + }); + + describe('RECEIVE_DATA_ERROR', () => { + it('should set loading and error flags', () => { + const state = {}; + + mutations[types.RECEIVE_DATA_ERROR](state); + + expect(state.isFetchingMergeRequests).toEqual(false); + expect(state.hasErrorFetchingMergeRequests).toEqual(true); + }); + }); +}); |