diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-04-20 13:00:54 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-04-20 13:00:54 +0300 |
commit | 3cccd102ba543e02725d247893729e5c73b38295 (patch) | |
tree | f36a04ec38517f5deaaacb5acc7d949688d1e187 /spec/frontend/pages/import/history/components/import_history_app_spec.js | |
parent | 205943281328046ef7b4528031b90fbda70c75ac (diff) |
Add latest changes from gitlab-org/gitlab@14-10-stable-eev14.10.0-rc42
Diffstat (limited to 'spec/frontend/pages/import/history/components/import_history_app_spec.js')
-rw-r--r-- | spec/frontend/pages/import/history/components/import_history_app_spec.js | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/spec/frontend/pages/import/history/components/import_history_app_spec.js b/spec/frontend/pages/import/history/components/import_history_app_spec.js new file mode 100644 index 00000000000..0d821b114cf --- /dev/null +++ b/spec/frontend/pages/import/history/components/import_history_app_spec.js @@ -0,0 +1,205 @@ +import { GlEmptyState, GlLoadingIcon, GlTable } from '@gitlab/ui'; +import { mount, shallowMount } from '@vue/test-utils'; +import MockAdapter from 'axios-mock-adapter'; +import axios from '~/lib/utils/axios_utils'; +import ImportErrorDetails from '~/pages/import/history/components/import_error_details.vue'; +import ImportHistoryApp from '~/pages/import/history/components/import_history_app.vue'; +import PaginationBar from '~/vue_shared/components/pagination_bar/pagination_bar.vue'; +import { extendedWrapper } from 'helpers/vue_test_utils_helper'; +import { stubComponent } from 'helpers/stub_component'; + +describe('ImportHistoryApp', () => { + const API_URL = '/api/v4/projects.json'; + + const DEFAULT_HEADERS = { + 'x-page': 1, + 'x-per-page': 20, + 'x-next-page': 2, + 'x-total': 22, + 'x-total-pages': 2, + 'x-prev-page': null, + }; + const DUMMY_RESPONSE = [ + { + id: 1, + path_with_namespace: 'root/imported', + created_at: '2022-03-10T15:10:03.172Z', + import_url: null, + import_type: 'gitlab_project', + import_status: 'finished', + }, + { + id: 2, + name_with_namespace: 'Administrator / Dummy', + path_with_namespace: 'root/dummy', + created_at: '2022-03-09T11:23:04.974Z', + import_url: 'https://dummy.github/url', + import_type: 'github', + import_status: 'failed', + }, + { + id: 3, + name_with_namespace: 'Administrator / Dummy', + path_with_namespace: 'root/dummy2', + created_at: '2022-03-09T11:23:04.974Z', + import_url: 'git://non-http.url', + import_type: 'gi', + import_status: 'finished', + }, + ]; + let wrapper; + let mock; + + function createComponent({ shallow = true } = {}) { + const mountFn = shallow ? shallowMount : mount; + wrapper = mountFn(ImportHistoryApp, { + provide: { assets: { gitlabLogo: 'http://dummy.host' } }, + stubs: shallow ? { GlTable: { ...stubComponent(GlTable), props: ['items'] } } : {}, + }); + } + + const originalApiVersion = gon.api_version; + beforeAll(() => { + gon.api_version = 'v4'; + }); + + afterAll(() => { + gon.api_version = originalApiVersion; + }); + + beforeEach(() => { + mock = new MockAdapter(axios); + }); + + afterEach(() => { + mock.restore(); + wrapper.destroy(); + }); + + describe('general behavior', () => { + it('renders loading state when loading', () => { + createComponent(); + expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); + }); + + it('renders empty state when no data is available', async () => { + mock.onGet(API_URL).reply(200, [], DEFAULT_HEADERS); + createComponent(); + await axios.waitForAll(); + + expect(wrapper.find(GlLoadingIcon).exists()).toBe(false); + expect(wrapper.find(GlEmptyState).exists()).toBe(true); + }); + + it('renders table with data when history is available', async () => { + mock.onGet(API_URL).reply(200, DUMMY_RESPONSE, DEFAULT_HEADERS); + createComponent(); + await axios.waitForAll(); + + const table = wrapper.find(GlTable); + expect(table.exists()).toBe(true); + expect(table.props().items).toStrictEqual(DUMMY_RESPONSE); + }); + + it('changes page when requested by pagination bar', async () => { + const NEW_PAGE = 4; + + mock.onGet(API_URL).reply(200, DUMMY_RESPONSE, DEFAULT_HEADERS); + createComponent(); + await axios.waitForAll(); + mock.resetHistory(); + + const FAKE_NEXT_PAGE_REPLY = [ + { + id: 4, + path_with_namespace: 'root/some_other_project', + created_at: '2022-03-10T15:10:03.172Z', + import_url: null, + import_type: 'gitlab_project', + import_status: 'finished', + }, + ]; + + mock.onGet(API_URL).reply(200, FAKE_NEXT_PAGE_REPLY, DEFAULT_HEADERS); + + wrapper.findComponent(PaginationBar).vm.$emit('set-page', NEW_PAGE); + await axios.waitForAll(); + + expect(mock.history.get.length).toBe(1); + expect(mock.history.get[0].params).toStrictEqual(expect.objectContaining({ page: NEW_PAGE })); + expect(wrapper.find(GlTable).props().items).toStrictEqual(FAKE_NEXT_PAGE_REPLY); + }); + }); + + it('changes page size when requested by pagination bar', async () => { + const NEW_PAGE_SIZE = 4; + + mock.onGet(API_URL).reply(200, DUMMY_RESPONSE, DEFAULT_HEADERS); + createComponent(); + await axios.waitForAll(); + mock.resetHistory(); + + wrapper.findComponent(PaginationBar).vm.$emit('set-page-size', NEW_PAGE_SIZE); + await axios.waitForAll(); + + expect(mock.history.get.length).toBe(1); + expect(mock.history.get[0].params).toStrictEqual( + expect.objectContaining({ per_page: NEW_PAGE_SIZE }), + ); + }); + + it('resets page to 1 when page size is changed', async () => { + const NEW_PAGE_SIZE = 4; + + mock.onGet(API_URL).reply(200, DUMMY_RESPONSE, DEFAULT_HEADERS); + createComponent(); + await axios.waitForAll(); + wrapper.findComponent(PaginationBar).vm.$emit('set-page', 2); + await axios.waitForAll(); + mock.resetHistory(); + + wrapper.findComponent(PaginationBar).vm.$emit('set-page-size', NEW_PAGE_SIZE); + await axios.waitForAll(); + + expect(mock.history.get.length).toBe(1); + expect(mock.history.get[0].params).toStrictEqual( + expect.objectContaining({ per_page: NEW_PAGE_SIZE, page: 1 }), + ); + }); + + describe('details button', () => { + beforeEach(() => { + mock.onGet(API_URL).reply(200, DUMMY_RESPONSE, DEFAULT_HEADERS); + createComponent({ shallow: false }); + return axios.waitForAll(); + }); + + it('renders details button if relevant item has failed', async () => { + expect( + extendedWrapper(wrapper.find('tbody').findAll('tr').at(1)).findByText('Details').exists(), + ).toBe(true); + }); + + it('does not render details button if relevant item does not failed', () => { + expect( + extendedWrapper(wrapper.find('tbody').findAll('tr').at(0)).findByText('Details').exists(), + ).toBe(false); + }); + + it('expands details when details button is clicked', async () => { + const ORIGINAL_ROW_INDEX = 1; + await extendedWrapper(wrapper.find('tbody').findAll('tr').at(ORIGINAL_ROW_INDEX)) + .findByText('Details') + .trigger('click'); + + const detailsRowContent = wrapper + .find('tbody') + .findAll('tr') + .at(ORIGINAL_ROW_INDEX + 1) + .findComponent(ImportErrorDetails); + + expect(detailsRowContent.exists()).toBe(true); + expect(detailsRowContent.props().id).toBe(DUMMY_RESPONSE[1].id); + }); + }); +}); |