diff --git a/GITLAB_ELASTICSEARCH_INDEXER_VERSION b/GITLAB_ELASTICSEARCH_INDEXER_VERSION index 10c2c0c3d62..46b81d815a2 100644 --- a/GITLAB_ELASTICSEARCH_INDEXER_VERSION +++ b/GITLAB_ELASTICSEARCH_INDEXER_VERSION @@ -1 +1 @@ -2.10.0 +2.11.0 diff --git a/app/assets/javascripts/releases/components/releases_pagination.vue b/app/assets/javascripts/releases/components/releases_pagination.vue index aceea2bde2f..fddf85ead1e 100644 --- a/app/assets/javascripts/releases/components/releases_pagination.vue +++ b/app/assets/javascripts/releases/components/releases_pagination.vue @@ -1,24 +1,37 @@ - diff --git a/app/assets/javascripts/releases/components/releases_pagination_graphql.vue b/app/assets/javascripts/releases/components/releases_pagination_graphql.vue deleted file mode 100644 index 13cbf95b9af..00000000000 --- a/app/assets/javascripts/releases/components/releases_pagination_graphql.vue +++ /dev/null @@ -1,35 +0,0 @@ - - diff --git a/app/assets/javascripts/releases/components/releases_pagination_rest.vue b/app/assets/javascripts/releases/components/releases_pagination_rest.vue deleted file mode 100644 index 5e97a5a0450..00000000000 --- a/app/assets/javascripts/releases/components/releases_pagination_rest.vue +++ /dev/null @@ -1,24 +0,0 @@ - - - diff --git a/app/assets/javascripts/releases/stores/modules/index/actions.js b/app/assets/javascripts/releases/stores/modules/index/actions.js index 35996126658..00be25f089b 100644 --- a/app/assets/javascripts/releases/stores/modules/index/actions.js +++ b/app/assets/javascripts/releases/stores/modules/index/actions.js @@ -45,11 +45,11 @@ export const fetchReleases = ({ dispatch, commit, state }, { before, after }) => }, }) .then((response) => { - const { data, paginationInfo: graphQlPageInfo } = convertAllReleasesGraphQLResponse(response); + const { data, paginationInfo: pageInfo } = convertAllReleasesGraphQLResponse(response); commit(types.RECEIVE_RELEASES_SUCCESS, { data, - graphQlPageInfo, + pageInfo, }); }) .catch(() => dispatch('receiveReleasesError')); diff --git a/app/assets/javascripts/releases/stores/modules/index/mutations.js b/app/assets/javascripts/releases/stores/modules/index/mutations.js index e1aaa2e2a19..55a8a488be8 100644 --- a/app/assets/javascripts/releases/stores/modules/index/mutations.js +++ b/app/assets/javascripts/releases/stores/modules/index/mutations.js @@ -17,12 +17,11 @@ export default { * @param {Object} state * @param {Object} resp */ - [types.RECEIVE_RELEASES_SUCCESS](state, { data, restPageInfo, graphQlPageInfo }) { + [types.RECEIVE_RELEASES_SUCCESS](state, { data, pageInfo }) { state.hasError = false; state.isLoading = false; state.releases = data; - state.restPageInfo = restPageInfo; - state.graphQlPageInfo = graphQlPageInfo; + state.pageInfo = pageInfo; }, /** @@ -36,8 +35,7 @@ export default { state.isLoading = false; state.releases = []; state.hasError = true; - state.restPageInfo = {}; - state.graphQlPageInfo = {}; + state.pageInfo = {}; }, [types.SET_SORTING](state, sorting) { diff --git a/app/assets/javascripts/releases/stores/modules/index/state.js b/app/assets/javascripts/releases/stores/modules/index/state.js index 164a496d450..5e1aaab7b58 100644 --- a/app/assets/javascripts/releases/stores/modules/index/state.js +++ b/app/assets/javascripts/releases/stores/modules/index/state.js @@ -16,8 +16,7 @@ export default ({ isLoading: false, hasError: false, releases: [], - restPageInfo: {}, - graphQlPageInfo: {}, + pageInfo: {}, sorting: { sort: DESCENDING_ORDER, orderBy: RELEASED_AT, diff --git a/doc/install/installation.md b/doc/install/installation.md index e6de9818ca4..85a9bc3f8fa 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -112,9 +112,6 @@ sudo apt-get install -y build-essential zlib1g-dev libyaml-dev libssl-dev libgdb libcurl4-openssl-dev libicu-dev logrotate rsync python-docutils pkg-config cmake runit-systemd ``` -Ubuntu 14.04 (Trusty Tahr) doesn't have the `libre2-dev` package available, but -you can [install re2 manually](https://github.com/google/re2/wiki/Install). - If you want to use Kerberos for user authentication, install `libkrb5-dev` (if you don't know what Kerberos is, you can assume you don't need it): diff --git a/spec/frontend/releases/components/releases_pagination_graphql_spec.js b/spec/frontend/releases/components/releases_pagination_graphql_spec.js deleted file mode 100644 index 5b2dd4bc784..00000000000 --- a/spec/frontend/releases/components/releases_pagination_graphql_spec.js +++ /dev/null @@ -1,175 +0,0 @@ -import { mount, createLocalVue } from '@vue/test-utils'; -import Vuex from 'vuex'; -import { historyPushState } from '~/lib/utils/common_utils'; -import ReleasesPaginationGraphql from '~/releases/components/releases_pagination_graphql.vue'; -import createStore from '~/releases/stores'; -import createIndexModule from '~/releases/stores/modules/index'; - -jest.mock('~/lib/utils/common_utils', () => ({ - ...jest.requireActual('~/lib/utils/common_utils'), - historyPushState: jest.fn(), -})); - -const localVue = createLocalVue(); -localVue.use(Vuex); - -describe('~/releases/components/releases_pagination_graphql.vue', () => { - let wrapper; - let indexModule; - - const cursors = { - startCursor: 'startCursor', - endCursor: 'endCursor', - }; - - const projectPath = 'my/project'; - - const createComponent = (pageInfo) => { - indexModule = createIndexModule({ projectPath }); - - indexModule.state.graphQlPageInfo = pageInfo; - - indexModule.actions.fetchReleases = jest.fn(); - - wrapper = mount(ReleasesPaginationGraphql, { - store: createStore({ - modules: { - index: indexModule, - }, - featureFlags: {}, - }), - localVue, - }); - }; - - afterEach(() => { - wrapper.destroy(); - wrapper = null; - }); - - const findPrevButton = () => wrapper.find('[data-testid="prevButton"]'); - const findNextButton = () => wrapper.find('[data-testid="nextButton"]'); - - const expectDisabledPrev = () => { - expect(findPrevButton().attributes().disabled).toBe('disabled'); - }; - const expectEnabledPrev = () => { - expect(findPrevButton().attributes().disabled).toBe(undefined); - }; - const expectDisabledNext = () => { - expect(findNextButton().attributes().disabled).toBe('disabled'); - }; - const expectEnabledNext = () => { - expect(findNextButton().attributes().disabled).toBe(undefined); - }; - - describe('when there is only one page of results', () => { - beforeEach(() => { - createComponent({ - hasPreviousPage: false, - hasNextPage: false, - }); - }); - - it('does not render anything', () => { - expect(wrapper.html()).toBe(''); - }); - }); - - describe('when there is a next page, but not a previous page', () => { - beforeEach(() => { - createComponent({ - hasPreviousPage: false, - hasNextPage: true, - }); - }); - - it('renders a disabled "Prev" button', () => { - expectDisabledPrev(); - }); - - it('renders an enabled "Next" button', () => { - expectEnabledNext(); - }); - }); - - describe('when there is a previous page, but not a next page', () => { - beforeEach(() => { - createComponent({ - hasPreviousPage: true, - hasNextPage: false, - }); - }); - - it('renders a enabled "Prev" button', () => { - expectEnabledPrev(); - }); - - it('renders an disabled "Next" button', () => { - expectDisabledNext(); - }); - }); - - describe('when there is both a previous page and a next page', () => { - beforeEach(() => { - createComponent({ - hasPreviousPage: true, - hasNextPage: true, - }); - }); - - it('renders a enabled "Prev" button', () => { - expectEnabledPrev(); - }); - - it('renders an enabled "Next" button', () => { - expectEnabledNext(); - }); - }); - - describe('button behavior', () => { - beforeEach(() => { - createComponent({ - hasPreviousPage: true, - hasNextPage: true, - ...cursors, - }); - }); - - describe('next button behavior', () => { - beforeEach(() => { - findNextButton().trigger('click'); - }); - - it('calls fetchReleases with the correct after cursor', () => { - expect(indexModule.actions.fetchReleases.mock.calls).toEqual([ - [expect.anything(), { after: cursors.endCursor }], - ]); - }); - - it('calls historyPushState with the new URL', () => { - expect(historyPushState.mock.calls).toEqual([ - [expect.stringContaining(`?after=${cursors.endCursor}`)], - ]); - }); - }); - - describe('previous button behavior', () => { - beforeEach(() => { - findPrevButton().trigger('click'); - }); - - it('calls fetchReleases with the correct before cursor', () => { - expect(indexModule.actions.fetchReleases.mock.calls).toEqual([ - [expect.anything(), { before: cursors.startCursor }], - ]); - }); - - it('calls historyPushState with the new URL', () => { - expect(historyPushState.mock.calls).toEqual([ - [expect.stringContaining(`?before=${cursors.startCursor}`)], - ]); - }); - }); - }); -}); diff --git a/spec/frontend/releases/components/releases_pagination_rest_spec.js b/spec/frontend/releases/components/releases_pagination_rest_spec.js deleted file mode 100644 index 7d45176967b..00000000000 --- a/spec/frontend/releases/components/releases_pagination_rest_spec.js +++ /dev/null @@ -1,72 +0,0 @@ -import { GlPagination } from '@gitlab/ui'; -import { mount, createLocalVue } from '@vue/test-utils'; -import Vuex from 'vuex'; -import * as commonUtils from '~/lib/utils/common_utils'; -import ReleasesPaginationRest from '~/releases/components/releases_pagination_rest.vue'; -import createStore from '~/releases/stores'; -import createIndexModule from '~/releases/stores/modules/index'; - -commonUtils.historyPushState = jest.fn(); - -const localVue = createLocalVue(); -localVue.use(Vuex); - -describe('~/releases/components/releases_pagination_rest.vue', () => { - let wrapper; - let indexModule; - - const projectId = 19; - - const createComponent = (pageInfo) => { - indexModule = createIndexModule({ projectId }); - - indexModule.state.restPageInfo = pageInfo; - - indexModule.actions.fetchReleases = jest.fn(); - - wrapper = mount(ReleasesPaginationRest, { - store: createStore({ - modules: { - index: indexModule, - }, - featureFlags: {}, - }), - localVue, - }); - }; - - const findGlPagination = () => wrapper.find(GlPagination); - - afterEach(() => { - wrapper.destroy(); - wrapper = null; - }); - - describe('when a page number is clicked', () => { - const newPage = 2; - - beforeEach(() => { - createComponent({ - perPage: 20, - page: 1, - total: 40, - totalPages: 2, - nextPage: 2, - }); - - findGlPagination().vm.$emit('input', newPage); - }); - - it('calls fetchReleases with the correct page', () => { - expect(indexModule.actions.fetchReleases.mock.calls).toEqual([ - [expect.anything(), { page: newPage }], - ]); - }); - - it('calls historyPushState with the new URL', () => { - expect(commonUtils.historyPushState.mock.calls).toEqual([ - [expect.stringContaining(`?page=${newPage}`)], - ]); - }); - }); -}); diff --git a/spec/frontend/releases/components/releases_pagination_spec.js b/spec/frontend/releases/components/releases_pagination_spec.js index 69d83e13497..2d08f72ad8b 100644 --- a/spec/frontend/releases/components/releases_pagination_spec.js +++ b/spec/frontend/releases/components/releases_pagination_spec.js @@ -1,39 +1,177 @@ -import { shallowMount, createLocalVue } from '@vue/test-utils'; +import { GlKeysetPagination } from '@gitlab/ui'; +import { mount, createLocalVue } from '@vue/test-utils'; import Vuex from 'vuex'; +import { historyPushState } from '~/lib/utils/common_utils'; import ReleasesPagination from '~/releases/components/releases_pagination.vue'; -import ReleasesPaginationGraphql from '~/releases/components/releases_pagination_graphql.vue'; -import ReleasesPaginationRest from '~/releases/components/releases_pagination_rest.vue'; +import createStore from '~/releases/stores'; +import createIndexModule from '~/releases/stores/modules/index'; + +jest.mock('~/lib/utils/common_utils', () => ({ + ...jest.requireActual('~/lib/utils/common_utils'), + historyPushState: jest.fn(), +})); const localVue = createLocalVue(); localVue.use(Vuex); describe('~/releases/components/releases_pagination.vue', () => { let wrapper; + let indexModule; - const createComponent = (useGraphQLEndpoint) => { - const store = new Vuex.Store({ - getters: { - useGraphQLEndpoint: () => useGraphQLEndpoint, - }, - }); - - wrapper = shallowMount(ReleasesPagination, { store, localVue }); + const cursors = { + startCursor: 'startCursor', + endCursor: 'endCursor', }; - beforeEach(() => { - createComponent(true); - }); + const projectPath = 'my/project'; + + const createComponent = (pageInfo) => { + indexModule = createIndexModule({ projectPath }); + + indexModule.state.pageInfo = pageInfo; + + indexModule.actions.fetchReleases = jest.fn(); + + wrapper = mount(ReleasesPagination, { + store: createStore({ + modules: { + index: indexModule, + }, + featureFlags: {}, + }), + localVue, + }); + }; afterEach(() => { wrapper.destroy(); wrapper = null; }); - const findRestPagination = () => wrapper.find(ReleasesPaginationRest); - const findGraphQlPagination = () => wrapper.find(ReleasesPaginationGraphql); + const findGlKeysetPagination = () => wrapper.findComponent(GlKeysetPagination); + const findPrevButton = () => findGlKeysetPagination().find('[data-testid="prevButton"]'); + const findNextButton = () => findGlKeysetPagination().find('[data-testid="nextButton"]'); - it('renders the GraphQL pagination component', () => { - expect(findGraphQlPagination().exists()).toBe(true); - expect(findRestPagination().exists()).toBe(false); + const expectDisabledPrev = () => { + expect(findPrevButton().attributes().disabled).toBe('disabled'); + }; + const expectEnabledPrev = () => { + expect(findPrevButton().attributes().disabled).toBe(undefined); + }; + const expectDisabledNext = () => { + expect(findNextButton().attributes().disabled).toBe('disabled'); + }; + const expectEnabledNext = () => { + expect(findNextButton().attributes().disabled).toBe(undefined); + }; + + describe('when there is only one page of results', () => { + beforeEach(() => { + createComponent({ + hasPreviousPage: false, + hasNextPage: false, + }); + }); + + it('does not render a GlKeysetPagination', () => { + expect(findGlKeysetPagination().exists()).toBe(false); + }); + }); + + describe('when there is a next page, but not a previous page', () => { + beforeEach(() => { + createComponent({ + hasPreviousPage: false, + hasNextPage: true, + }); + }); + + it('renders a disabled "Prev" button', () => { + expectDisabledPrev(); + }); + + it('renders an enabled "Next" button', () => { + expectEnabledNext(); + }); + }); + + describe('when there is a previous page, but not a next page', () => { + beforeEach(() => { + createComponent({ + hasPreviousPage: true, + hasNextPage: false, + }); + }); + + it('renders a enabled "Prev" button', () => { + expectEnabledPrev(); + }); + + it('renders an disabled "Next" button', () => { + expectDisabledNext(); + }); + }); + + describe('when there is both a previous page and a next page', () => { + beforeEach(() => { + createComponent({ + hasPreviousPage: true, + hasNextPage: true, + }); + }); + + it('renders a enabled "Prev" button', () => { + expectEnabledPrev(); + }); + + it('renders an enabled "Next" button', () => { + expectEnabledNext(); + }); + }); + + describe('button behavior', () => { + beforeEach(() => { + createComponent({ + hasPreviousPage: true, + hasNextPage: true, + ...cursors, + }); + }); + + describe('next button behavior', () => { + beforeEach(() => { + findNextButton().trigger('click'); + }); + + it('calls fetchReleases with the correct after cursor', () => { + expect(indexModule.actions.fetchReleases.mock.calls).toEqual([ + [expect.anything(), { after: cursors.endCursor }], + ]); + }); + + it('calls historyPushState with the new URL', () => { + expect(historyPushState.mock.calls).toEqual([ + [expect.stringContaining(`?after=${cursors.endCursor}`)], + ]); + }); + }); + + describe('previous button behavior', () => { + beforeEach(() => { + findPrevButton().trigger('click'); + }); + + it('calls fetchReleases with the correct before cursor', () => { + expect(indexModule.actions.fetchReleases.mock.calls).toEqual([ + [expect.anything(), { before: cursors.startCursor }], + ]); + }); + + it('calls historyPushState with the new URL', () => { + expect(historyPushState.mock.calls).toEqual([ + [expect.stringContaining(`?before=${cursors.startCursor}`)], + ]); + }); + }); }); }); diff --git a/spec/frontend/releases/stores/modules/list/actions_spec.js b/spec/frontend/releases/stores/modules/list/actions_spec.js index bae74285594..af520c2eb20 100644 --- a/spec/frontend/releases/stores/modules/list/actions_spec.js +++ b/spec/frontend/releases/stores/modules/list/actions_spec.js @@ -141,7 +141,7 @@ describe('Releases State actions', () => { type: types.RECEIVE_RELEASES_SUCCESS, payload: { data: convertedResponse.data, - graphQlPageInfo: convertedResponse.paginationInfo, + pageInfo: convertedResponse.paginationInfo, }, }, ], diff --git a/spec/frontend/releases/stores/modules/list/mutations_spec.js b/spec/frontend/releases/stores/modules/list/mutations_spec.js index abf78bcdf6b..08d803b3c2c 100644 --- a/spec/frontend/releases/stores/modules/list/mutations_spec.js +++ b/spec/frontend/releases/stores/modules/list/mutations_spec.js @@ -1,10 +1,9 @@ import { getJSONFixture } from 'helpers/fixtures'; -import { parseIntPagination, convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; +import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import * as types from '~/releases/stores/modules/index/mutation_types'; import mutations from '~/releases/stores/modules/index/mutations'; import createState from '~/releases/stores/modules/index/state'; import { convertAllReleasesGraphQLResponse } from '~/releases/util'; -import { pageInfoHeadersWithoutPagination } from '../../../mock_data'; const originalRelease = getJSONFixture('api/releases/release.json'); const originalReleases = [originalRelease]; @@ -15,14 +14,12 @@ const graphqlReleasesResponse = getJSONFixture( describe('Releases Store Mutations', () => { let stateCopy; - let restPageInfo; - let graphQlPageInfo; + let pageInfo; let releases; beforeEach(() => { stateCopy = createState({}); - restPageInfo = parseIntPagination(pageInfoHeadersWithoutPagination); - graphQlPageInfo = convertAllReleasesGraphQLResponse(graphqlReleasesResponse).paginationInfo; + pageInfo = convertAllReleasesGraphQLResponse(graphqlReleasesResponse).paginationInfo; releases = convertObjectPropsToCamelCase(originalReleases, { deep: true }); }); @@ -37,8 +34,7 @@ describe('Releases Store Mutations', () => { describe('RECEIVE_RELEASES_SUCCESS', () => { beforeEach(() => { mutations[types.RECEIVE_RELEASES_SUCCESS](stateCopy, { - restPageInfo, - graphQlPageInfo, + pageInfo, data: releases, }); }); @@ -55,20 +51,15 @@ describe('Releases Store Mutations', () => { expect(stateCopy.releases).toEqual(releases); }); - it('sets restPageInfo', () => { - expect(stateCopy.restPageInfo).toEqual(restPageInfo); - }); - - it('sets graphQlPageInfo', () => { - expect(stateCopy.graphQlPageInfo).toEqual(graphQlPageInfo); + it('sets pageInfo', () => { + expect(stateCopy.pageInfo).toEqual(pageInfo); }); }); describe('RECEIVE_RELEASES_ERROR', () => { it('resets data', () => { mutations[types.RECEIVE_RELEASES_SUCCESS](stateCopy, { - restPageInfo, - graphQlPageInfo, + pageInfo, data: releases, }); @@ -76,8 +67,7 @@ describe('Releases Store Mutations', () => { expect(stateCopy.isLoading).toEqual(false); expect(stateCopy.releases).toEqual([]); - expect(stateCopy.restPageInfo).toEqual({}); - expect(stateCopy.graphQlPageInfo).toEqual({}); + expect(stateCopy.pageInfo).toEqual({}); }); });