summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-10-04 00:06:03 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2019-10-04 00:06:03 +0000
commit8c726c7487db581867ade785f798d84315cb787e (patch)
treeaaf96b1cf74942fbb26b2aa379f9d51c8f874617
parent1da3754b25657f49afdcb0b942506d365b1ee89d (diff)
downloadgitlab-ce-8c726c7487db581867ade785f798d84315cb787e.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.dockerignore1
-rw-r--r--app/models/deployment.rb2
-rw-r--r--app/models/release.rb2
-rw-r--r--qa/Dockerfile10
-rw-r--r--spec/frontend/ide/components/merge_requests/list_spec.js214
-rw-r--r--spec/javascripts/ide/components/merge_requests/list_spec.js159
6 files changed, 225 insertions, 163 deletions
diff --git a/.dockerignore b/.dockerignore
index d5568619169..2d1af2c25fc 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -3,6 +3,7 @@
# Ignore all folders except qa/, config/initializers and the root of lib/ since
# the files we need to build the QA image are in these folders.
# Following are the files we need:
+# - ./config/light_settings.rb
# - ./config/initializers/0_inject_enterprise_edition_module.rb
# - ./ee/app/models/license.rb
# - ./lib/gitlab.rb
diff --git a/app/models/deployment.rb b/app/models/deployment.rb
index db7f9e06362..30694313f7a 100644
--- a/app/models/deployment.rb
+++ b/app/models/deployment.rb
@@ -180,3 +180,5 @@ class Deployment < ApplicationRecord
self.created_at if success? && !read_attribute(:finished_at)
end
end
+
+Deployment.prepend_if_ee('EE::Deployment')
diff --git a/app/models/release.rb b/app/models/release.rb
index 9117a475ee9..8759e38060c 100644
--- a/app/models/release.rb
+++ b/app/models/release.rb
@@ -67,3 +67,5 @@ class Release < ApplicationRecord
end
end
end
+
+Release.prepend_if_ee('EE::Release')
diff --git a/qa/Dockerfile b/qa/Dockerfile
index 84dbfae1008..97c2cd482f5 100644
--- a/qa/Dockerfile
+++ b/qa/Dockerfile
@@ -49,13 +49,15 @@ RUN export CLOUD_SDK_REPO="cloud-sdk-$(lsb_release -c -s)" && \
WORKDIR /home/gitlab/qa
COPY ./qa/Gemfile* /home/gitlab/qa/
+COPY ./config/light_settings.rb /home/gitlab/config/light_settings.rb
COPY ./config/initializers/0_inject_enterprise_edition_module.rb /home/gitlab/config/initializers/
-# Copy VERSION to ensure the COPY succeeds to copy at least one file since ee/app/models/license.rb isn't present in CE
+# Copy VERSION to ensure the COPY succeeds to copy at least one file since ee/app/models/license.rb isn't present in FOSS
+# The [b] part makes ./ee/app/models/license.r[b] a pattern that is allowed to return no files (which is the case in FOSS)
COPY VERSION ./ee/app/models/license.r[b] /home/gitlab/ee/app/models/
+COPY ./config/light_settings.rb /home/gitlab/config/
COPY ./lib/gitlab.rb /home/gitlab/lib/
-COPY ./INSTALLATION_TYPE /home/gitlab/
-COPY ./VERSION /home/gitlab/
-RUN cd /home/gitlab/qa/ && bundle install
+COPY ./INSTALLATION_TYPE ./VERSION /home/gitlab/
+RUN cd /home/gitlab/qa/ && bundle install --jobs=$(nproc) --retry=3 --quiet
COPY ./qa /home/gitlab/qa
ENTRYPOINT ["bin/test"]
diff --git a/spec/frontend/ide/components/merge_requests/list_spec.js b/spec/frontend/ide/components/merge_requests/list_spec.js
new file mode 100644
index 00000000000..86a311acad4
--- /dev/null
+++ b/spec/frontend/ide/components/merge_requests/list_spec.js
@@ -0,0 +1,214 @@
+import { shallowMount, createLocalVue } from '@vue/test-utils';
+import Vuex from 'vuex';
+import List from '~/ide/components/merge_requests/list.vue';
+import Item from '~/ide/components/merge_requests/item.vue';
+import TokenedInput from '~/ide/components/shared/tokened_input.vue';
+import { GlLoadingIcon } from '@gitlab/ui';
+import { mergeRequests as mergeRequestsMock } from '../../mock_data';
+
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+describe('IDE merge requests list', () => {
+ let wrapper;
+ let fetchMergeRequestsMock;
+
+ const findSearchTypeButtons = () => wrapper.findAll('button');
+ const findTokenedInput = () => wrapper.find(TokenedInput);
+
+ const createComponent = (state = {}) => {
+ const { mergeRequests = {}, ...restOfState } = state;
+ const fakeStore = new Vuex.Store({
+ state: {
+ currentMergeRequestId: '1',
+ currentProjectId: 'project/master',
+ ...restOfState,
+ },
+ modules: {
+ mergeRequests: {
+ namespaced: true,
+ state: {
+ isLoading: false,
+ mergeRequests: [],
+ ...mergeRequests,
+ },
+ actions: {
+ fetchMergeRequests: fetchMergeRequestsMock,
+ },
+ },
+ },
+ });
+
+ wrapper = shallowMount(List, {
+ store: fakeStore,
+ localVue,
+ sync: false,
+ });
+ };
+
+ beforeEach(() => {
+ fetchMergeRequestsMock = jest.fn();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ it('calls fetch on mounted', () => {
+ createComponent();
+ expect(fetchMergeRequestsMock).toHaveBeenCalledWith(
+ expect.any(Object),
+ {
+ search: '',
+ type: '',
+ },
+ undefined,
+ );
+ });
+
+ it('renders loading icon when merge request is loading', () => {
+ createComponent({ mergeRequests: { isLoading: true } });
+ expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
+ });
+
+ it('renders no search results text when search is not empty', () => {
+ createComponent();
+ findTokenedInput().vm.$emit('input', 'something');
+ return wrapper.vm.$nextTick().then(() => {
+ expect(wrapper.text()).toContain('No merge requests found');
+ });
+ });
+
+ it('clicking on search type, sets currentSearchType and loads merge requests', () => {
+ createComponent();
+ findTokenedInput().vm.$emit('focus');
+
+ return wrapper.vm
+ .$nextTick()
+ .then(() => {
+ findSearchTypeButtons()
+ .at(0)
+ .trigger('click');
+ return wrapper.vm.$nextTick();
+ })
+ .then(() => {
+ const searchType = wrapper.vm.$options.searchTypes[0];
+
+ expect(findTokenedInput().props('tokens')).toEqual([searchType]);
+ expect(fetchMergeRequestsMock).toHaveBeenCalledWith(
+ expect.any(Object),
+ {
+ type: searchType.type,
+ search: '',
+ },
+ undefined,
+ );
+ });
+ });
+
+ describe('with merge requests', () => {
+ let defaultStateWithMergeRequests;
+
+ beforeAll(() => {
+ defaultStateWithMergeRequests = {
+ mergeRequests: {
+ isLoading: false,
+ mergeRequests: [
+ { ...mergeRequestsMock[0], projectPathWithNamespace: 'gitlab-org/gitlab-foss' },
+ ],
+ },
+ };
+ });
+
+ it('renders list', () => {
+ createComponent(defaultStateWithMergeRequests);
+
+ expect(wrapper.findAll(Item).length).toBe(1);
+ expect(wrapper.find(Item).props('item')).toBe(
+ defaultStateWithMergeRequests.mergeRequests.mergeRequests[0],
+ );
+ });
+
+ describe('when searching merge requests', () => {
+ it('calls `loadMergeRequests` on input in search field', () => {
+ createComponent(defaultStateWithMergeRequests);
+ const input = findTokenedInput();
+ input.vm.$emit('input', 'something');
+ fetchMergeRequestsMock.mockClear();
+
+ jest.runAllTimers();
+ return wrapper.vm.$nextTick().then(() => {
+ expect(fetchMergeRequestsMock).toHaveBeenCalledWith(
+ expect.any(Object),
+ {
+ search: 'something',
+ type: '',
+ },
+ undefined,
+ );
+ });
+ });
+ });
+ });
+
+ describe('on search focus', () => {
+ let input;
+
+ beforeEach(() => {
+ createComponent();
+ input = findTokenedInput();
+ });
+
+ describe('without search value', () => {
+ beforeEach(() => {
+ input.vm.$emit('focus');
+ return wrapper.vm.$nextTick();
+ });
+
+ it('shows search types', () => {
+ const buttons = findSearchTypeButtons();
+ expect(buttons.wrappers.map(x => x.text().trim())).toEqual(
+ wrapper.vm.$options.searchTypes.map(x => x.label),
+ );
+ });
+
+ it('hides search types when search changes', () => {
+ input.vm.$emit('input', 'something');
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findSearchTypeButtons().exists()).toBe(false);
+ });
+ });
+
+ describe('with search type', () => {
+ beforeEach(() => {
+ findSearchTypeButtons()
+ .at(0)
+ .trigger('click');
+
+ return wrapper.vm
+ .$nextTick()
+ .then(() => input.vm.$emit('focus'))
+ .then(() => wrapper.vm.$nextTick());
+ });
+
+ it('does not show search types', () => {
+ expect(findSearchTypeButtons().exists()).toBe(false);
+ });
+ });
+ });
+
+ describe('with search value', () => {
+ beforeEach(() => {
+ input.vm.$emit('input', 'something');
+ input.vm.$emit('focus');
+ return wrapper.vm.$nextTick();
+ });
+
+ it('does not show search types', () => {
+ expect(findSearchTypeButtons().exists()).toBe(false);
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/ide/components/merge_requests/list_spec.js b/spec/javascripts/ide/components/merge_requests/list_spec.js
deleted file mode 100644
index 55e4f46d9ca..00000000000
--- a/spec/javascripts/ide/components/merge_requests/list_spec.js
+++ /dev/null
@@ -1,159 +0,0 @@
-import Vue from 'vue';
-import store from '~/ide/stores';
-import List from '~/ide/components/merge_requests/list.vue';
-import { createComponentWithStore } from '../../../helpers/vue_mount_component_helper';
-import { mergeRequests } from '../../mock_data';
-import { resetStore } from '../../helpers';
-
-describe('IDE merge requests list', () => {
- const Component = Vue.extend(List);
- let vm;
-
- beforeEach(() => {
- vm = createComponentWithStore(Component, store, {});
-
- spyOn(vm, 'fetchMergeRequests');
-
- vm.$mount();
- });
-
- afterEach(() => {
- vm.$destroy();
-
- resetStore(vm.$store);
- });
-
- it('calls fetch on mounted', () => {
- expect(vm.fetchMergeRequests).toHaveBeenCalledWith({
- search: '',
- type: '',
- });
- });
-
- it('renders loading icon', done => {
- vm.$store.state.mergeRequests.isLoading = true;
-
- vm.$nextTick(() => {
- expect(vm.$el.querySelector('.loading-container')).not.toBe(null);
-
- done();
- });
- });
-
- it('renders no search results text when search is not empty', done => {
- vm.search = 'testing';
-
- vm.$nextTick(() => {
- expect(vm.$el.textContent).toContain('No merge requests found');
-
- done();
- });
- });
-
- it('clicking on search type, sets currentSearchType and loads merge requests', done => {
- vm.onSearchFocus();
-
- vm.$nextTick()
- .then(() => {
- vm.$el.querySelector('li button').click();
-
- return vm.$nextTick();
- })
- .then(() => {
- expect(vm.currentSearchType).toEqual(vm.$options.searchTypes[0]);
- expect(vm.fetchMergeRequests).toHaveBeenCalledWith({
- type: vm.currentSearchType.type,
- search: '',
- });
- })
- .then(done)
- .catch(done.fail);
- });
-
- describe('with merge requests', () => {
- beforeEach(done => {
- vm.$store.state.mergeRequests.mergeRequests.push({
- ...mergeRequests[0],
- projectPathWithNamespace: 'gitlab-org/gitlab-ce',
- });
-
- vm.$nextTick(done);
- });
-
- it('renders list', () => {
- expect(vm.$el.querySelectorAll('li').length).toBe(1);
- expect(vm.$el.querySelector('li').textContent).toContain(mergeRequests[0].title);
- });
- });
-
- describe('searchMergeRequests', () => {
- beforeEach(() => {
- spyOn(vm, 'loadMergeRequests');
-
- jasmine.clock().install();
- });
-
- afterEach(() => {
- jasmine.clock().uninstall();
- });
-
- it('calls loadMergeRequests on input in search field', () => {
- const event = new Event('input');
-
- vm.$el.querySelector('input').dispatchEvent(event);
-
- jasmine.clock().tick(300);
-
- expect(vm.loadMergeRequests).toHaveBeenCalled();
- });
- });
-
- describe('onSearchFocus', () => {
- it('shows search types', done => {
- vm.$el.querySelector('input').dispatchEvent(new Event('focus'));
-
- expect(vm.hasSearchFocus).toBe(true);
- expect(vm.showSearchTypes).toBe(true);
-
- vm.$nextTick()
- .then(() => {
- const expectedSearchTypes = vm.$options.searchTypes.map(x => x.label);
- const renderedSearchTypes = Array.from(vm.$el.querySelectorAll('li')).map(x =>
- x.textContent.trim(),
- );
-
- expect(renderedSearchTypes).toEqual(expectedSearchTypes);
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('does not show search types, if already has search value', () => {
- vm.search = 'lorem ipsum';
- vm.$el.querySelector('input').dispatchEvent(new Event('focus'));
-
- expect(vm.hasSearchFocus).toBe(true);
- expect(vm.showSearchTypes).toBe(false);
- });
-
- it('does not show search types, if already has a search type', () => {
- vm.currentSearchType = {};
- vm.$el.querySelector('input').dispatchEvent(new Event('focus'));
-
- expect(vm.hasSearchFocus).toBe(true);
- expect(vm.showSearchTypes).toBe(false);
- });
-
- it('resets hasSearchFocus when search changes', done => {
- vm.hasSearchFocus = true;
- vm.search = 'something else';
-
- vm.$nextTick()
- .then(() => {
- expect(vm.hasSearchFocus).toBe(false);
- })
- .then(done)
- .catch(done.fail);
- });
- });
-});