diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-14 15:09:34 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-14 15:09:34 +0300 |
commit | 9a5dcad39c5dd81384ae4ec2398435883b944363 (patch) | |
tree | 3c684d30e4500028299d7948171e885b844a1ade /spec | |
parent | 0923a94d58cdd15cdb6379330e5eb41d30ccb8cc (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
59 files changed, 1162 insertions, 900 deletions
diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb index 99caf24cbf1..e3411e4f925 100644 --- a/spec/factories/projects.rb +++ b/spec/factories/projects.rb @@ -392,6 +392,12 @@ FactoryBot.define do end end + factory :ewm_project, parent: :project do + has_external_issue_tracker { true } + + ewm_service + end + factory :project_with_design, parent: :project do after(:create) do |project| issue = create(:issue, project: project) diff --git a/spec/factories/services.rb b/spec/factories/services.rb index 7fbf6f16dc7..9056fd97f13 100644 --- a/spec/factories/services.rb +++ b/spec/factories/services.rb @@ -116,6 +116,12 @@ FactoryBot.define do issue_tracker end + factory :ewm_service do + project + active { true } + issue_tracker + end + trait :issue_tracker do transient do create_data { true } diff --git a/spec/features/groups/board_sidebar_spec.rb b/spec/features/groups/board_sidebar_spec.rb index 690d661ba2f..3bbeed10948 100644 --- a/spec/features/groups/board_sidebar_spec.rb +++ b/spec/features/groups/board_sidebar_spec.rb @@ -19,8 +19,6 @@ RSpec.describe 'Group Issue Boards', :js do let(:card) { find('.board:nth-child(1)').first('.board-card') } before do - # stubbing until sidebar work is done: https://gitlab.com/gitlab-org/gitlab/-/issues/230711 - stub_feature_flags(graphql_board_lists: false) sign_in(user) visit group_board_path(group, board) diff --git a/spec/features/issues/user_edits_issue_spec.rb b/spec/features/issues/user_edits_issue_spec.rb index cc631cc6dd0..7321f2243b9 100644 --- a/spec/features/issues/user_edits_issue_spec.rb +++ b/spec/features/issues/user_edits_issue_spec.rb @@ -152,9 +152,7 @@ RSpec.describe "Issues > User edits issue", :js do visit project_issue_path(project, issue2) page.within '.assignee' do - page.within '.value .author' do - expect(page).to have_content user.name - end + expect(page).to have_content user.name click_link 'Edit' click_link user.name diff --git a/spec/features/merge_request/user_edits_mr_spec.rb b/spec/features/merge_request/user_edits_mr_spec.rb index 2c949ed84f4..397ca70f4a1 100644 --- a/spec/features/merge_request/user_edits_mr_spec.rb +++ b/spec/features/merge_request/user_edits_mr_spec.rb @@ -20,4 +20,32 @@ RSpec.describe 'Merge request > User edits MR' do include_context 'merge request edit context' it_behaves_like 'an editable merge request' end + + context 'when merge_request_reviewers is turned on' do + before do + stub_feature_flags(merge_request_reviewers: true) + end + + context 'non-fork merge request' do + include_context 'merge request edit context' + it_behaves_like 'an editable merge request with reviewers' + end + + context 'for a forked project' do + let(:source_project) { fork_project(target_project, nil, repository: true) } + + include_context 'merge request edit context' + it_behaves_like 'an editable merge request with reviewers' + end + end + + context 'when merge_request_reviewers is turned off' do + before do + stub_feature_flags(merge_request_reviewers: false) + end + + it 'does not render reviewers dropdown' do + expect(page).not_to have_selector('.js-reviewer-search') + end + end end diff --git a/spec/features/projects/services/user_activates_issue_tracker_spec.rb b/spec/features/projects/services/user_activates_issue_tracker_spec.rb index c7389460a07..d7ae79a1543 100644 --- a/spec/features/projects/services/user_activates_issue_tracker_spec.rb +++ b/spec/features/projects/services/user_activates_issue_tracker_spec.rb @@ -16,7 +16,7 @@ RSpec.describe 'User activates issue tracker', :js do fill_in 'service_new_issue_url', with: url unless skip_new_issue_url end - shared_examples 'external issue tracker activation' do |tracker:, skip_new_issue_url: false| + shared_examples 'external issue tracker activation' do |tracker:, skip_new_issue_url: false, skip_test: false| describe 'user sets and activates the Service' do context 'when the connection test succeeds' do before do @@ -25,7 +25,11 @@ RSpec.describe 'User activates issue tracker', :js do visit_project_integration(tracker) fill_form(skip_new_issue_url: skip_new_issue_url) - click_test_integration + if skip_test + click_button('Save changes') + else + click_test_integration + end end it 'activates the service' do @@ -47,7 +51,11 @@ RSpec.describe 'User activates issue tracker', :js do visit_project_integration(tracker) fill_form(skip_new_issue_url: skip_new_issue_url) - click_test_then_save_integration + if skip_test + click_button('Save changes') + else + click_test_then_save_integration + end expect(page).to have_content("#{tracker} activated.") expect(current_path).to eq(edit_project_service_path(project, tracker.parameterize(separator: '_'))) @@ -80,4 +88,5 @@ RSpec.describe 'User activates issue tracker', :js do it_behaves_like 'external issue tracker activation', tracker: 'YouTrack', skip_new_issue_url: true it_behaves_like 'external issue tracker activation', tracker: 'Bugzilla' it_behaves_like 'external issue tracker activation', tracker: 'Custom Issue Tracker' + it_behaves_like 'external issue tracker activation', tracker: 'EWM', skip_test: true end diff --git a/spec/frontend/boards/mock_data.js b/spec/frontend/boards/mock_data.js index a84970eb736..717ab5f3add 100644 --- a/spec/frontend/boards/mock_data.js +++ b/spec/frontend/boards/mock_data.js @@ -98,35 +98,12 @@ export const mockMilestone = { due_date: '2019-12-31', }; -const assignees = [ - { - id: 'gid://gitlab/User/2', - username: 'angelina.herman', - name: 'Bernardina Bosco', - avatar: 'https://www.gravatar.com/avatar/eb7b664b13a30ad9f9ba4b61d7075470?s=80&d=identicon', - webUrl: 'http://127.0.0.1:3000/angelina.herman', - }, -]; - -const labels = [ - { - id: 'gid://gitlab/GroupLabel/5', - title: 'Cosync', - color: '#34ebec', - description: null, - }, -]; - export const rawIssue = { - title: 'Issue 1', - id: 'gid://gitlab/Issue/436', - iid: 27, - dueDate: null, - timeEstimate: 0, - weight: null, + title: 'Testing', + id: 'gid://gitlab/Issue/1', + iid: 1, confidential: false, - referencePath: 'gitlab-org/gitlab-test#27', - path: '/gitlab-org/gitlab-test/-/issues/27', + referencePath: 'gitlab-org/gitlab-test#1', labels: { nodes: [ { @@ -138,24 +115,23 @@ export const rawIssue = { ], }, assignees: { - nodes: assignees, - }, - epic: { - id: 'gid://gitlab/Epic/41', + nodes: [ + { + id: 1, + name: 'name', + username: 'username', + avatar_url: 'http://avatar_url', + }, + ], }, }; export const mockIssue = { - id: 'gid://gitlab/Issue/436', - iid: 27, - title: 'Issue 1', - dueDate: null, - timeEstimate: 0, - weight: null, + title: 'Testing', + id: 1, + iid: 1, confidential: false, - referencePath: 'gitlab-org/gitlab-test#27', - path: '/gitlab-org/gitlab-test/-/issues/27', - assignees, + referencePath: 'gitlab-org/gitlab-test#1', labels: [ { id: 1, @@ -164,64 +140,44 @@ export const mockIssue = { description: 'testing', }, ], - epic: { - id: 'gid://gitlab/Epic/41', - }, + assignees: [ + { + id: 1, + name: 'name', + username: 'username', + avatar_url: 'http://avatar_url', + }, + ], }; export const mockIssueWithModel = new ListIssue(mockIssue); export const mockIssue2 = { - id: 'gid://gitlab/Issue/437', - iid: 28, - title: 'Issue 2', - dueDate: null, - timeEstimate: 0, - weight: null, + title: 'Planning', + id: 2, + iid: 2, confidential: false, referencePath: 'gitlab-org/gitlab-test#2', - path: '/gitlab-org/gitlab-test/-/issues/28', - assignees, - labels, - epic: { - id: 'gid://gitlab/Epic/40', - }, + labels: [ + { + id: 1, + title: 'plan', + color: 'blue', + description: 'planning', + }, + ], + assignees: [ + { + id: 1, + name: 'name', + username: 'username', + avatar_url: 'http://avatar_url', + }, + ], }; export const mockIssue2WithModel = new ListIssue(mockIssue2); -export const mockIssue3 = { - id: 'gid://gitlab/Issue/438', - iid: 29, - title: 'Issue 3', - referencePath: '#29', - dueDate: null, - timeEstimate: 0, - weight: null, - confidential: false, - path: '/gitlab-org/gitlab-test/-/issues/28', - assignees, - labels, - epic: null, -}; - -export const mockIssue4 = { - id: 'gid://gitlab/Issue/439', - iid: 30, - title: 'Issue 4', - referencePath: '#30', - dueDate: null, - timeEstimate: 0, - weight: null, - confidential: false, - path: '/gitlab-org/gitlab-test/-/issues/28', - assignees, - labels, - epic: null, -}; - -export const mockIssues = [mockIssue, mockIssue2]; - export const BoardsMockData = { GET: { '/test/-/boards/1/lists/300/issues?id=300&page=1': { @@ -283,7 +239,6 @@ export const mockLists = [ label: null, assignee: null, milestone: null, - loading: false, }, { id: 'gid://gitlab/List/2', @@ -300,22 +255,9 @@ export const mockLists = [ }, assignee: null, milestone: null, - loading: false, }, ]; export const mockListsWithModel = mockLists.map(listMock => Vue.observable(new List({ ...listMock, doNotFetchIssues: true })), ); - -export const mockIssuesByListId = { - 'gid://gitlab/List/1': [mockIssue.id, mockIssue3.id, mockIssue4.id], - 'gid://gitlab/List/2': mockIssues.map(({ id }) => id), -}; - -export const issues = { - [mockIssue.id]: mockIssue, - [mockIssue2.id]: mockIssue2, - [mockIssue3.id]: mockIssue3, - [mockIssue4.id]: mockIssue4, -}; diff --git a/spec/frontend/boards/stores/actions_spec.js b/spec/frontend/boards/stores/actions_spec.js index 8efad4d3ac7..4eb1a370a9f 100644 --- a/spec/frontend/boards/stores/actions_spec.js +++ b/spec/frontend/boards/stores/actions_spec.js @@ -3,6 +3,7 @@ import { mockListsWithModel, mockLists, mockIssue, + mockIssue2, mockIssueWithModel, mockIssue2WithModel, rawIssue, @@ -133,7 +134,7 @@ describe('createList', () => { { backlog: true }, state, [], - [{ type: 'addList', payload: backlogList }], + [{ type: 'addList', payload: { ...backlogList, id: 1 } }], done, ); }); @@ -231,15 +232,19 @@ describe('deleteList', () => { expectNotImplemented(actions.deleteList); }); +describe('fetchIssuesForList', () => { + expectNotImplemented(actions.fetchIssuesForList); +}); + describe('moveIssue', () => { const listIssues = { - 'gid://gitlab/List/1': [436, 437], + 'gid://gitlab/List/1': [mockIssue.id, mockIssue2.id], 'gid://gitlab/List/2': [], }; const issues = { - '436': mockIssueWithModel, - '437': mockIssue2WithModel, + '1': mockIssueWithModel, + '2': mockIssue2WithModel, }; const state = { @@ -264,7 +269,7 @@ describe('moveIssue', () => { testAction( actions.moveIssue, { - issueId: '436', + issueId: mockIssue.id, issueIid: mockIssue.iid, issuePath: mockIssue.referencePath, fromListId: 'gid://gitlab/List/1', @@ -303,7 +308,7 @@ describe('moveIssue', () => { testAction( actions.moveIssue, { - issueId: '436', + issueId: mockIssue.id, issueIid: mockIssue.iid, issuePath: mockIssue.referencePath, fromListId: 'gid://gitlab/List/1', diff --git a/spec/frontend/boards/stores/getters_spec.js b/spec/frontend/boards/stores/getters_spec.js index 288143a0f21..267451845ba 100644 --- a/spec/frontend/boards/stores/getters_spec.js +++ b/spec/frontend/boards/stores/getters_spec.js @@ -1,6 +1,5 @@ import getters from '~/boards/stores/getters'; import { inactiveId } from '~/boards/constants'; -import { mockIssue, mockIssue2, mockIssues, mockIssuesByListId, issues } from '../mock_data'; describe('Boards - Getters', () => { describe('getLabelToggleState', () => { @@ -116,18 +115,4 @@ describe('Boards - Getters', () => { expect(getters.getActiveIssue(state)).toEqual(expected); }); }); - - describe('getIssues', () => { - const boardsState = { - issuesByListId: mockIssuesByListId, - issues, - }; - it('returns issues for a given listId', () => { - const getIssueById = issueId => [mockIssue, mockIssue2].find(({ id }) => id === issueId); - - expect(getters.getIssues(boardsState, { getIssueById })('gid://gitlab/List/2')).toEqual( - mockIssues, - ); - }); - }); }); diff --git a/spec/frontend/boards/stores/mutations_spec.js b/spec/frontend/boards/stores/mutations_spec.js index a13a99a507e..350eccfa82e 100644 --- a/spec/frontend/boards/stores/mutations_spec.js +++ b/spec/frontend/boards/stores/mutations_spec.js @@ -54,11 +54,11 @@ describe('Board Store Mutations', () => { }); }); - describe('RECEIVE_BOARD_LISTS_SUCCESS', () => { + describe('RECEIVE_LISTS', () => { it('Should set boardLists to state', () => { const lists = [listObj, listObjDuplicate]; - mutations[types.RECEIVE_BOARD_LISTS_SUCCESS](state, lists); + mutations[types.RECEIVE_LISTS](state, lists); expect(state.boardLists).toEqual(lists); }); @@ -145,33 +145,6 @@ describe('Board Store Mutations', () => { expectNotImplemented(mutations.RECEIVE_REMOVE_LIST_ERROR); }); - describe('RECEIVE_ISSUES_FOR_LIST_SUCCESS', () => { - it('updates issuesByListId and issues on state', () => { - const listIssues = { - 'gid://gitlab/List/1': [mockIssue.id], - }; - const issues = { - '1': mockIssue, - }; - - state = { - ...state, - isLoadingIssues: true, - issuesByListId: {}, - issues: {}, - boardLists: mockListsWithModel, - }; - - mutations.RECEIVE_ISSUES_FOR_LIST_SUCCESS(state, { - listIssues: { listData: listIssues, issues }, - listId: 'gid://gitlab/List/1', - }); - - expect(state.issuesByListId).toEqual(listIssues); - expect(state.issues).toEqual(issues); - }); - }); - describe('REQUEST_ISSUES_FOR_ALL_LISTS', () => { it('sets isLoadingIssues to true', () => { expect(state.isLoadingIssues).toBe(false); @@ -182,28 +155,10 @@ describe('Board Store Mutations', () => { }); }); - describe('RECEIVE_ISSUES_FOR_LIST_FAILURE', () => { - it('sets error message', () => { - state = { - ...state, - boardLists: mockListsWithModel, - error: undefined, - }; - - const listId = 'gid://gitlab/List/1'; - - mutations.RECEIVE_ISSUES_FOR_LIST_FAILURE(state, listId); - - expect(state.error).toEqual( - 'An error occurred while fetching the board issues. Please reload the page.', - ); - }); - }); - describe('RECEIVE_ISSUES_FOR_ALL_LISTS_SUCCESS', () => { it('sets isLoadingIssues to false and updates issuesByListId object', () => { const listIssues = { - 'gid://gitlab/List/1': [mockIssue.id], + '': [mockIssue.id], }; const issues = { '1': mockIssue, @@ -332,7 +287,7 @@ describe('Board Store Mutations', () => { describe('MOVE_ISSUE_SUCCESS', () => { it('updates issue in issues state', () => { const issues = { - '436': { id: rawIssue.id }, + '1': { id: rawIssue.id }, }; state = { @@ -344,7 +299,7 @@ describe('Board Store Mutations', () => { issue: rawIssue, }); - expect(state.issues).toEqual({ '436': { ...mockIssueWithModel, id: 436 } }); + expect(state.issues).toEqual({ '1': { ...mockIssueWithModel, id: 1 } }); }); }); diff --git a/spec/frontend/deploy_freeze/components/timezone_dropdown_spec.js b/spec/frontend/deploy_freeze/components/timezone_dropdown_spec.js index 644cd0b5f27..99cb864ce34 100644 --- a/spec/frontend/deploy_freeze/components/timezone_dropdown_spec.js +++ b/spec/frontend/deploy_freeze/components/timezone_dropdown_spec.js @@ -1,6 +1,6 @@ import Vuex from 'vuex'; import { shallowMount, createLocalVue } from '@vue/test-utils'; -import { GlDeprecatedDropdownItem, GlNewDropdown } from '@gitlab/ui'; +import { GlDeprecatedDropdownItem, GlDropdown } from '@gitlab/ui'; import TimezoneDropdown from '~/vue_shared/components/timezone_dropdown.vue'; import createStore from '~/deploy_freeze/store'; @@ -92,7 +92,7 @@ describe('Deploy freeze timezone dropdown', () => { }); it('renders selected time zone as dropdown label', () => { - expect(wrapper.find(GlNewDropdown).vm.text).toBe('Alaska'); + expect(wrapper.find(GlDropdown).vm.text).toBe('Alaska'); }); }); }); diff --git a/spec/frontend/design_management/components/upload/__snapshots__/design_version_dropdown_spec.js.snap b/spec/frontend/design_management/components/upload/__snapshots__/design_version_dropdown_spec.js.snap index d6fd09eb698..335cbe9c55e 100644 --- a/spec/frontend/design_management/components/upload/__snapshots__/design_version_dropdown_spec.js.snap +++ b/spec/frontend/design_management/components/upload/__snapshots__/design_version_dropdown_spec.js.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Design management design version dropdown component renders design version dropdown button 1`] = ` -<gl-new-dropdown-stub +<gl-dropdown-stub category="tertiary" headertext="" issueiid="" @@ -35,11 +35,11 @@ exports[`Design management design version dropdown component renders design vers 1 </gl-new-dropdown-item-stub> -</gl-new-dropdown-stub> +</gl-dropdown-stub> `; exports[`Design management design version dropdown component renders design version list 1`] = ` -<gl-new-dropdown-stub +<gl-dropdown-stub category="tertiary" headertext="" issueiid="" @@ -73,5 +73,5 @@ exports[`Design management design version dropdown component renders design vers 1 </gl-new-dropdown-item-stub> -</gl-new-dropdown-stub> +</gl-dropdown-stub> `; diff --git a/spec/frontend/design_management/components/upload/design_version_dropdown_spec.js b/spec/frontend/design_management/components/upload/design_version_dropdown_spec.js index f4206cdaeb3..cc4274b0d02 100644 --- a/spec/frontend/design_management/components/upload/design_version_dropdown_spec.js +++ b/spec/frontend/design_management/components/upload/design_version_dropdown_spec.js @@ -1,5 +1,5 @@ import { shallowMount } from '@vue/test-utils'; -import { GlNewDropdown, GlNewDropdownItem, GlSprintf } from '@gitlab/ui'; +import { GlDropdown, GlNewDropdownItem, GlSprintf } from '@gitlab/ui'; import DesignVersionDropdown from '~/design_management/components/upload/design_version_dropdown.vue'; import mockAllVersions from './mock_data/all_versions'; @@ -75,7 +75,7 @@ describe('Design management design version dropdown component', () => { createComponent(); return wrapper.vm.$nextTick().then(() => { - expect(wrapper.find(GlNewDropdown).attributes('text')).toBe('Showing latest version'); + expect(wrapper.find(GlDropdown).attributes('text')).toBe('Showing latest version'); }); }); @@ -83,7 +83,7 @@ describe('Design management design version dropdown component', () => { createComponent({ maxVersions: 1 }); return wrapper.vm.$nextTick().then(() => { - expect(wrapper.find(GlNewDropdown).attributes('text')).toBe('Showing latest version'); + expect(wrapper.find(GlDropdown).attributes('text')).toBe('Showing latest version'); }); }); @@ -91,7 +91,7 @@ describe('Design management design version dropdown component', () => { createComponent({ $route: designRouteFactory(PREVIOUS_VERSION_ID) }); return wrapper.vm.$nextTick().then(() => { - expect(wrapper.find(GlNewDropdown).attributes('text')).toBe(`Showing version #1`); + expect(wrapper.find(GlDropdown).attributes('text')).toBe(`Showing version #1`); }); }); @@ -99,7 +99,7 @@ describe('Design management design version dropdown component', () => { createComponent({ $route: designRouteFactory(LATEST_VERSION_ID) }); return wrapper.vm.$nextTick().then(() => { - expect(wrapper.find(GlNewDropdown).attributes('text')).toBe('Showing latest version'); + expect(wrapper.find(GlDropdown).attributes('text')).toBe('Showing latest version'); }); }); diff --git a/spec/frontend/ide/commit_icon_spec.js b/spec/frontend/ide/commit_icon_spec.js index e4a7394b089..0dfcae00298 100644 --- a/spec/frontend/ide/commit_icon_spec.js +++ b/spec/frontend/ide/commit_icon_spec.js @@ -7,7 +7,6 @@ const createFile = (name = 'name', id = name, type = '', parent = null) => id, type, icon: 'icon', - url: 'url', name, path: parent ? `${parent.path}/${name}` : name, parentPath: parent ? parent.path : '', diff --git a/spec/frontend/ide/components/repo_tab_spec.js b/spec/frontend/ide/components/repo_tab_spec.js index 5a591d3dcd0..d5080acfe9f 100644 --- a/spec/frontend/ide/components/repo_tab_spec.js +++ b/spec/frontend/ide/components/repo_tab_spec.js @@ -34,7 +34,7 @@ describe('RepoTab', () => { }); vm.$store.state.openFiles.push(vm.tab); const close = vm.$el.querySelector('.multi-file-tab-close'); - const name = vm.$el.querySelector(`[title="${vm.tab.url}"]`); + const name = vm.$el.querySelector(`[title]`); expect(close.innerHTML).toContain('#close'); expect(name.textContent.trim()).toEqual(vm.tab.name); diff --git a/spec/frontend/ide/components/repo_tabs_spec.js b/spec/frontend/ide/components/repo_tabs_spec.js index df5b01770f5..b251f207853 100644 --- a/spec/frontend/ide/components/repo_tabs_spec.js +++ b/spec/frontend/ide/components/repo_tabs_spec.js @@ -1,27 +1,40 @@ -import Vue from 'vue'; -import repoTabs from '~/ide/components/repo_tabs.vue'; -import createComponent from '../../helpers/vue_mount_component_helper'; +import Vuex from 'vuex'; +import { mount, createLocalVue } from '@vue/test-utils'; +import { createStore } from '~/ide/stores'; +import RepoTabs from '~/ide/components/repo_tabs.vue'; import { file } from '../helpers'; +const localVue = createLocalVue(); +localVue.use(Vuex); + describe('RepoTabs', () => { - const openedFiles = [file('open1'), file('open2')]; - const RepoTabs = Vue.extend(repoTabs); - let vm; + let wrapper; + let store; + + beforeEach(() => { + store = createStore(); + store.state.openFiles = [file('open1'), file('open2')]; + + wrapper = mount(RepoTabs, { + propsData: { + files: store.state.openFiles, + viewer: 'editor', + activeFile: file('activeFile'), + }, + store, + localVue, + }); + }); afterEach(() => { - vm.$destroy(); + wrapper.destroy(); }); it('renders a list of tabs', done => { - vm = createComponent(RepoTabs, { - files: openedFiles, - viewer: 'editor', - activeFile: file('activeFile'), - }); - openedFiles[0].active = true; + store.state.openFiles[0].active = true; - vm.$nextTick(() => { - const tabs = [...vm.$el.querySelectorAll('.multi-file-tab')]; + wrapper.vm.$nextTick(() => { + const tabs = [...wrapper.vm.$el.querySelectorAll('.multi-file-tab')]; expect(tabs.length).toEqual(2); expect(tabs[0].parentNode.classList.contains('active')).toEqual(true); diff --git a/spec/frontend/ide/helpers.js b/spec/frontend/ide/helpers.js index 8caa9c2b437..0e85b523cbd 100644 --- a/spec/frontend/ide/helpers.js +++ b/spec/frontend/ide/helpers.js @@ -6,7 +6,6 @@ export const file = (name = 'name', id = name, type = '', parent = null) => id, type, icon: 'icon', - url: 'url', name, path: parent ? `${parent.path}/${name}` : name, parentPath: parent ? parent.path : '', diff --git a/spec/frontend/ide/lib/files_spec.js b/spec/frontend/ide/lib/files_spec.js index 6974cdc4074..b223cf64278 100644 --- a/spec/frontend/ide/lib/files_spec.js +++ b/spec/frontend/ide/lib/files_spec.js @@ -2,25 +2,16 @@ import { viewerInformationForPath } from '~/vue_shared/components/content_viewer import { decorateFiles, splitParent } from '~/ide/lib/files'; import { decorateData } from '~/ide/stores/utils'; -const TEST_BRANCH_ID = 'lorem-ipsum'; -const TEST_PROJECT_ID = 10; - const createEntries = paths => { const createEntry = (acc, { path, type, children }) => { - // Sometimes we need to end the url with a '/' - const createUrl = base => (type === 'tree' ? `${base}/` : base); - const { name, parent } = splitParent(path); const previewMode = viewerInformationForPath(name); acc[path] = { ...decorateData({ - projectId: TEST_PROJECT_ID, - branchId: TEST_BRANCH_ID, id: path, name, path, - url: createUrl(`/${TEST_PROJECT_ID}/${type}/${TEST_BRANCH_ID}/-/${path}`), type, previewMode, binary: (previewMode && previewMode.binary) || false, @@ -56,11 +47,7 @@ describe('IDE lib decorate files', () => { { path: 'README.md', type: 'blob', children: [] }, ]); - const { entries, treeList } = decorateFiles({ - data, - branchId: TEST_BRANCH_ID, - projectId: TEST_PROJECT_ID, - }); + const { entries, treeList } = decorateFiles({ data }); // Here we test the keys and then each key/value individually because `expect(entries).toEqual(expectedEntries)` // was taking a very long time for some reason. Probably due to large objects and nested `expect.objectContaining`. diff --git a/spec/frontend/ide/services/index_spec.js b/spec/frontend/ide/services/index_spec.js index bc3f86702cf..d2c32a81811 100644 --- a/spec/frontend/ide/services/index_spec.js +++ b/spec/frontend/ide/services/index_spec.js @@ -146,7 +146,7 @@ describe('IDE services', () => { it('gives back file.baseRaw for files with that property present', () => { file.baseRaw = TEST_FILE_CONTENTS; - return services.getBaseRawFileData(file, TEST_COMMIT_SHA).then(content => { + return services.getBaseRawFileData(file, TEST_PROJECT_ID, TEST_COMMIT_SHA).then(content => { expect(content).toEqual(TEST_FILE_CONTENTS); }); }); @@ -155,7 +155,7 @@ describe('IDE services', () => { file.tempFile = true; file.baseRaw = TEST_FILE_CONTENTS; - return services.getBaseRawFileData(file, TEST_COMMIT_SHA).then(content => { + return services.getBaseRawFileData(file, TEST_PROJECT_ID, TEST_COMMIT_SHA).then(content => { expect(content).toEqual(TEST_FILE_CONTENTS); }); }); @@ -192,7 +192,7 @@ describe('IDE services', () => { }); it('fetches file content', () => - services.getBaseRawFileData(file, TEST_COMMIT_SHA).then(content => { + services.getBaseRawFileData(file, TEST_PROJECT_ID, TEST_COMMIT_SHA).then(content => { expect(content).toEqual(TEST_FILE_CONTENTS); })); }, diff --git a/spec/frontend/ide/stores/actions/file_spec.js b/spec/frontend/ide/stores/actions/file_spec.js index 88e7a9fff36..5166e07abcb 100644 --- a/spec/frontend/ide/stores/actions/file_spec.js +++ b/spec/frontend/ide/stores/actions/file_spec.js @@ -27,6 +27,10 @@ describe('IDE store file actions', () => { }; store = createStore(); + + store.state.currentProjectId = 'test/test'; + store.state.currentBranchId = 'master'; + router = createRouter(store); jest.spyOn(store, 'commit'); @@ -72,10 +76,7 @@ describe('IDE store file actions', () => { }); it('closes file & opens next available file', () => { - const f = { - ...file('newOpenFile'), - url: '/newOpenFile', - }; + const f = file('newOpenFile'); store.state.openFiles.push(f); store.state.entries[f.path] = f; @@ -84,7 +85,7 @@ describe('IDE store file actions', () => { .dispatch('closeFile', localFile) .then(Vue.nextTick) .then(() => { - expect(router.push).toHaveBeenCalledWith(`/project${f.url}`); + expect(router.push).toHaveBeenCalledWith('/project/test/test/tree/master/-/newOpenFile/'); }); }); @@ -296,7 +297,6 @@ describe('IDE store file actions', () => { describe('Re-named success', () => { beforeEach(() => { localFile = file(`newCreate-${Math.random()}`); - localFile.url = `project/getFileDataURL`; localFile.prevPath = 'old-dull-file'; localFile.path = 'new-shiny-file'; store.state.entries[localFile.path] = localFile; @@ -393,7 +393,11 @@ describe('IDE store file actions', () => { tmpFile.mrChange = { new_file: false }; return store.dispatch('getRawFileData', { path: tmpFile.path }).then(() => { - expect(service.getBaseRawFileData).toHaveBeenCalledWith(tmpFile, 'SHA'); + expect(service.getBaseRawFileData).toHaveBeenCalledWith( + tmpFile, + 'gitlab-org/gitlab-ce', + 'SHA', + ); expect(tmpFile.baseRaw).toBe('baseraw'); }); }); @@ -660,7 +664,7 @@ describe('IDE store file actions', () => { }); it('pushes route for active file', () => { - expect(router.push).toHaveBeenCalledWith(`/project${tmpFile.url}`); + expect(router.push).toHaveBeenCalledWith('/project/test/test/tree/master/-/tempFile/'); }); }); }); @@ -735,10 +739,8 @@ describe('IDE store file actions', () => { }); it('pushes router URL when added', () => { - store.state.currentBranchId = 'master'; - return store.dispatch('openPendingTab', { file: f, keyPrefix: 'pending' }).then(() => { - expect(router.push).toHaveBeenCalledWith('/project/123/tree/master/'); + expect(router.push).toHaveBeenCalledWith('/project/test/test/tree/master/'); }); }); }); diff --git a/spec/frontend/ide/stores/actions/merge_request_spec.js b/spec/frontend/ide/stores/actions/merge_request_spec.js index 62971b9cad6..b1cceda9d85 100644 --- a/spec/frontend/ide/stores/actions/merge_request_spec.js +++ b/spec/frontend/ide/stores/actions/merge_request_spec.js @@ -453,11 +453,9 @@ describe('IDE store merge request actions', () => { it('updates activity bar view and gets file data, if changes are found', done => { store.state.entries.foo = { - url: 'test', type: 'blob', }; store.state.entries.bar = { - url: 'test', type: 'blob', }; diff --git a/spec/frontend/ide/stores/actions_spec.js b/spec/frontend/ide/stores/actions_spec.js index f77dbd80025..ebf39df2f6f 100644 --- a/spec/frontend/ide/stores/actions_spec.js +++ b/spec/frontend/ide/stores/actions_spec.js @@ -123,7 +123,6 @@ describe('Multi-file store actions', () => { it('creates temp tree', done => { store .dispatch('createTempEntry', { - branchId: store.state.currentBranchId, name: 'test', type: 'tree', }) @@ -150,7 +149,6 @@ describe('Multi-file store actions', () => { store .dispatch('createTempEntry', { - branchId: store.state.currentBranchId, name: 'testing/test', type: 'tree', }) @@ -176,7 +174,6 @@ describe('Multi-file store actions', () => { store .dispatch('createTempEntry', { - branchId: store.state.currentBranchId, name: 'testing', type: 'tree', }) @@ -197,7 +194,6 @@ describe('Multi-file store actions', () => { store .dispatch('createTempEntry', { name, - branchId: 'mybranch', type: 'blob', }) .then(() => { @@ -217,7 +213,6 @@ describe('Multi-file store actions', () => { store .dispatch('createTempEntry', { name, - branchId: 'mybranch', type: 'blob', }) .then(() => { @@ -237,7 +232,6 @@ describe('Multi-file store actions', () => { store .dispatch('createTempEntry', { name, - branchId: 'mybranch', type: 'blob', }) .then(() => { @@ -249,7 +243,7 @@ describe('Multi-file store actions', () => { }); it('sets tmp file as active', () => { - createTempEntry(store, { name: 'test', branchId: 'mybranch', type: 'blob' }); + createTempEntry(store, { name: 'test', type: 'blob' }); expect(store.dispatch).toHaveBeenCalledWith('setFileActive', 'test'); }); @@ -262,7 +256,6 @@ describe('Multi-file store actions', () => { store .dispatch('createTempEntry', { name: 'test', - branchId: 'mybranch', type: 'blob', }) .then(() => { @@ -780,9 +773,11 @@ describe('Multi-file store actions', () => { }); it('routes to the renamed file if the original file has been opened', done => { + store.state.currentProjectId = 'test/test'; + store.state.currentBranchId = 'master'; + Object.assign(store.state.entries.orig, { opened: true, - url: '/foo-bar.md', }); store @@ -792,7 +787,7 @@ describe('Multi-file store actions', () => { }) .then(() => { expect(router.push.mock.calls).toHaveLength(1); - expect(router.push).toHaveBeenCalledWith(`/project/foo-bar.md`); + expect(router.push).toHaveBeenCalledWith(`/project/test/test/tree/master/-/renamed/`); }) .then(done) .catch(done.fail); diff --git a/spec/frontend/ide/stores/getters_spec.js b/spec/frontend/ide/stores/getters_spec.js index dcf05329ce0..17fc08144f6 100644 --- a/spec/frontend/ide/stores/getters_spec.js +++ b/spec/frontend/ide/stores/getters_spec.js @@ -482,4 +482,15 @@ describe('IDE store getters', () => { expect(localStore.getters.getAvailableFileName('foo-bar1.jpg')).toBe('foo-bar1.jpg'); }); }); + + describe('getUrlForPath', () => { + it('returns a route url for the given path', () => { + localState.currentProjectId = 'test/test'; + localState.currentBranchId = 'master'; + + expect(localStore.getters.getUrlForPath('path/to/foo/bar-1.jpg')).toBe( + `/project/test/test/tree/master/-/path/to/foo/bar-1.jpg/`, + ); + }); + }); }); diff --git a/spec/frontend/ide/stores/integration_spec.js b/spec/frontend/ide/stores/integration_spec.js index f95f036f572..b6a7c7fd02d 100644 --- a/spec/frontend/ide/stores/integration_spec.js +++ b/spec/frontend/ide/stores/integration_spec.js @@ -36,8 +36,6 @@ describe('IDE store integration', () => { beforeEach(() => { const { entries, treeList } = decorateFiles({ data: [`${TEST_PATH_DIR}/`, TEST_PATH, 'README.md'], - projectId: TEST_PROJECT_ID, - branchId: TEST_BRANCH, }); Object.assign(entries[TEST_PATH], { diff --git a/spec/frontend/ide/stores/mutations_spec.js b/spec/frontend/ide/stores/mutations_spec.js index 1b29648fb8b..09e9481e5d4 100644 --- a/spec/frontend/ide/stores/mutations_spec.js +++ b/spec/frontend/ide/stores/mutations_spec.js @@ -113,8 +113,6 @@ describe('Multi-file store mutations', () => { }, treeList: [tmpFile], }, - projectId: 'gitlab-ce', - branchId: 'master', }); expect(localState.trees['gitlab-ce/master'].tree.length).toEqual(1); @@ -272,7 +270,6 @@ describe('Multi-file store mutations', () => { prevId: undefined, prevPath: undefined, prevName: undefined, - prevUrl: undefined, prevKey: undefined, }), ); @@ -337,7 +334,6 @@ describe('Multi-file store mutations', () => { }; Object.assign(localState.entries['root-folder/oldPath'], { parentPath: 'root-folder', - url: 'root-folder/oldPath-blob-root-folder/oldPath', }); mutations.RENAME_ENTRY(localState, { @@ -366,9 +362,6 @@ describe('Multi-file store mutations', () => { }); it('renames entry, preserving old parameters', () => { - Object.assign(localState.entries.oldPath, { - url: `project/-/oldPath`, - }); const oldPathData = localState.entries.oldPath; mutations.RENAME_ENTRY(localState, { @@ -382,12 +375,10 @@ describe('Multi-file store mutations', () => { id: 'newPath', path: 'newPath', name: 'newPath', - url: `project/-/newPath`, key: expect.stringMatching('newPath'), prevId: 'oldPath', prevName: 'oldPath', prevPath: 'oldPath', - prevUrl: `project/-/oldPath`, prevKey: oldPathData.key, prevParentPath: oldPathData.parentPath, }); @@ -409,7 +400,6 @@ describe('Multi-file store mutations', () => { prevId: expect.anything(), prevName: expect.anything(), prevPath: expect.anything(), - prevUrl: expect.anything(), prevKey: expect.anything(), prevParentPath: expect.anything(), }), @@ -419,7 +409,7 @@ describe('Multi-file store mutations', () => { it('properly handles files with spaces in name', () => { const path = 'my fancy path'; const newPath = 'new path'; - const oldEntry = { ...file(path, path, 'blob'), url: `project/-/${path}` }; + const oldEntry = file(path, path, 'blob'); localState.entries[path] = oldEntry; @@ -435,12 +425,10 @@ describe('Multi-file store mutations', () => { id: newPath, path: newPath, name: newPath, - url: `project/-/new path`, key: expect.stringMatching(newPath), prevId: path, prevName: path, prevPath: path, - prevUrl: `project/-/my fancy path`, prevKey: oldEntry.key, prevParentPath: oldEntry.parentPath, }); @@ -549,7 +537,7 @@ describe('Multi-file store mutations', () => { it('correctly saves original values if an entry is renamed multiple times', () => { const original = { ...localState.entries.oldPath }; - const paramsToCheck = ['prevId', 'prevPath', 'prevName', 'prevUrl']; + const paramsToCheck = ['prevId', 'prevPath', 'prevName']; const expectedObj = paramsToCheck.reduce( (o, param) => ({ ...o, [param]: original[param.replace('prev', '').toLowerCase()] }), {}, @@ -577,7 +565,6 @@ describe('Multi-file store mutations', () => { prevId: 'lorem/orig', prevPath: 'lorem/orig', prevName: 'orig', - prevUrl: 'project/-/loren/orig', prevKey: 'lorem/orig', prevParentPath: 'lorem', }; @@ -602,7 +589,6 @@ describe('Multi-file store mutations', () => { prevId: undefined, prevPath: undefined, prevName: undefined, - prevUrl: undefined, prevKey: undefined, prevParentPath: undefined, }), diff --git a/spec/frontend/incidents_settings/components/__snapshots__/alerts_form_spec.js.snap b/spec/frontend/incidents_settings/components/__snapshots__/alerts_form_spec.js.snap index fd6af59eb48..a3a7d96bf14 100644 --- a/spec/frontend/incidents_settings/components/__snapshots__/alerts_form_spec.js.snap +++ b/spec/frontend/incidents_settings/components/__snapshots__/alerts_form_spec.js.snap @@ -45,7 +45,7 @@ exports[`Alert integration settings form default state should match the default </gl-link-stub> </label> - <gl-new-dropdown-stub + <gl-dropdown-stub block="true" category="tertiary" data-qa-selector="incident_templates_dropdown" @@ -68,7 +68,7 @@ exports[`Alert integration settings form default state should match the default No template selected </gl-new-dropdown-item-stub> - </gl-new-dropdown-stub> + </gl-dropdown-stub> </gl-form-group-stub> <gl-form-group-stub diff --git a/spec/frontend/integrations/edit/components/override_dropdown_spec.js b/spec/frontend/integrations/edit/components/override_dropdown_spec.js index 00ec8fc36cd..44e14cb3760 100644 --- a/spec/frontend/integrations/edit/components/override_dropdown_spec.js +++ b/spec/frontend/integrations/edit/components/override_dropdown_spec.js @@ -1,5 +1,5 @@ import { shallowMount } from '@vue/test-utils'; -import { GlNewDropdown, GlLink } from '@gitlab/ui'; +import { GlDropdown, GlLink } from '@gitlab/ui'; import { createStore } from '~/integrations/edit/store'; import { integrationLevels, overrideDropdownDescriptions } from '~/integrations/edit/constants'; @@ -34,14 +34,14 @@ describe('OverrideDropdown', () => { }); const findGlLink = () => wrapper.find(GlLink); - const findGlNewDropdown = () => wrapper.find(GlNewDropdown); + const findGlDropdown = () => wrapper.find(GlDropdown); describe('template', () => { describe('override prop is true', () => { it('renders GlToggle as disabled', () => { createComponent(); - expect(findGlNewDropdown().props('text')).toBe('Use custom settings'); + expect(findGlDropdown().props('text')).toBe('Use custom settings'); }); }); @@ -49,7 +49,7 @@ describe('OverrideDropdown', () => { it('renders GlToggle as disabled', () => { createComponent({ override: false }); - expect(findGlNewDropdown().props('text')).toBe('Use default settings'); + expect(findGlDropdown().props('text')).toBe('Use default settings'); }); }); diff --git a/spec/frontend/jira_import/components/jira_import_form_spec.js b/spec/frontend/jira_import/components/jira_import_form_spec.js index 39cb63af2f0..d184c054b8a 100644 --- a/spec/frontend/jira_import/components/jira_import_form_spec.js +++ b/spec/frontend/jira_import/components/jira_import_form_spec.js @@ -1,4 +1,4 @@ -import { GlAlert, GlButton, GlNewDropdown, GlFormSelect, GlLabel, GlTable } from '@gitlab/ui'; +import { GlAlert, GlButton, GlDropdown, GlFormSelect, GlLabel, GlTable } from '@gitlab/ui'; import { getByRole } from '@testing-library/dom'; import { mount, shallowMount } from '@vue/test-utils'; import AxiosMockAdapter from 'axios-mock-adapter'; @@ -35,7 +35,7 @@ describe('JiraImportForm', () => { const getTable = () => wrapper.find(GlTable); - const getUserDropdown = () => getTable().find(GlNewDropdown); + const getUserDropdown = () => getTable().find(GlDropdown); const getHeader = name => getByRole(wrapper.element, 'columnheader', { name }); diff --git a/spec/frontend/milestones/project_milestone_combobox_spec.js b/spec/frontend/milestones/project_milestone_combobox_spec.js index 4859561c4e3..60d68aa5816 100644 --- a/spec/frontend/milestones/project_milestone_combobox_spec.js +++ b/spec/frontend/milestones/project_milestone_combobox_spec.js @@ -1,7 +1,7 @@ import axios from 'axios'; import MockAdapter from 'axios-mock-adapter'; import { shallowMount } from '@vue/test-utils'; -import { GlNewDropdown, GlLoadingIcon, GlSearchBoxByType } from '@gitlab/ui'; +import { GlDropdown, GlLoadingIcon, GlSearchBoxByType } from '@gitlab/ui'; import { ENTER_KEY } from '~/lib/utils/keys'; import MilestoneCombobox from '~/milestones/project_milestone_combobox.vue'; import { milestones as projectMilestones } from './mock_data'; @@ -53,7 +53,7 @@ describe('Milestone selector', () => { }); it('renders the dropdown', () => { - expect(wrapper.find(GlNewDropdown)).toExist(); + expect(wrapper.find(GlDropdown)).toExist(); }); it('renders additional links', () => { diff --git a/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap b/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap index 80eacbe0a6a..a85c5a2bffc 100644 --- a/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap +++ b/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap @@ -32,7 +32,7 @@ exports[`Dashboard template matches the default snapshot 1`] = ` <div class="mb-2 pr-2 d-flex d-sm-block" > - <gl-new-dropdown-stub + <gl-dropdown-stub category="tertiary" class="flex-grow-1" data-qa-selector="environments_dropdown" @@ -69,7 +69,7 @@ exports[`Dashboard template matches the default snapshot 1`] = ` </div> </div> - </gl-new-dropdown-stub> + </gl-dropdown-stub> </div> <div diff --git a/spec/frontend/monitoring/components/refresh_button_spec.js b/spec/frontend/monitoring/components/refresh_button_spec.js index a9b8295f38e..56cc7a344fb 100644 --- a/spec/frontend/monitoring/components/refresh_button_spec.js +++ b/spec/frontend/monitoring/components/refresh_button_spec.js @@ -1,6 +1,6 @@ import { shallowMount } from '@vue/test-utils'; import Visibility from 'visibilityjs'; -import { GlNewDropdown, GlNewDropdownItem, GlButton } from '@gitlab/ui'; +import { GlDropdown, GlNewDropdownItem, GlButton } from '@gitlab/ui'; import { createStore } from '~/monitoring/stores'; import RefreshButton from '~/monitoring/components/refresh_button.vue'; @@ -15,7 +15,7 @@ describe('RefreshButton', () => { }; const findRefreshBtn = () => wrapper.find(GlButton); - const findDropdown = () => wrapper.find(GlNewDropdown); + const findDropdown = () => wrapper.find(GlDropdown); const findOptions = () => findDropdown().findAll(GlNewDropdownItem); const findOptionAt = index => findOptions().at(index); diff --git a/spec/frontend/pipeline_new/components/pipeline_new_form_spec.js b/spec/frontend/pipeline_new/components/pipeline_new_form_spec.js index 406a2f8872c..4867e3de09e 100644 --- a/spec/frontend/pipeline_new/components/pipeline_new_form_spec.js +++ b/spec/frontend/pipeline_new/components/pipeline_new_form_spec.js @@ -1,5 +1,5 @@ import { mount, shallowMount } from '@vue/test-utils'; -import { GlNewDropdown, GlNewDropdownItem, GlForm } from '@gitlab/ui'; +import { GlDropdown, GlNewDropdownItem, GlForm } from '@gitlab/ui'; import MockAdapter from 'axios-mock-adapter'; import waitForPromises from 'helpers/wait_for_promises'; import axios from '~/lib/utils/axios_utils'; @@ -23,7 +23,7 @@ describe('Pipeline New Form', () => { }; const findForm = () => wrapper.find(GlForm); - const findDropdown = () => wrapper.find(GlNewDropdown); + const findDropdown = () => wrapper.find(GlDropdown); const findDropdownItems = () => wrapper.findAll(GlNewDropdownItem); const findVariableRows = () => wrapper.findAll('[data-testid="ci-variable-row"]'); const findRemoveIcons = () => wrapper.findAll('[data-testid="remove-ci-variable-row"]'); diff --git a/spec/frontend/pipelines/graph/linked_pipeline_spec.js b/spec/frontend/pipelines/graph/linked_pipeline_spec.js index d2afc1a1d55..8e65f0d4f71 100644 --- a/spec/frontend/pipelines/graph/linked_pipeline_spec.js +++ b/spec/frontend/pipelines/graph/linked_pipeline_spec.js @@ -17,7 +17,7 @@ describe('Linked pipeline', () => { const findPipelineLabel = () => wrapper.find('[data-testid="downstream-pipeline-label"]'); const findLinkedPipeline = () => wrapper.find({ ref: 'linkedPipeline' }); const findLoadingIcon = () => wrapper.find(GlLoadingIcon); - const findPipelineLink = () => wrapper.find('[data-testid="childPipelineLink"]'); + const findPipelineLink = () => wrapper.find('[data-testid="pipelineLink"]'); const findExpandButton = () => wrapper.find('[data-testid="expandPipelineButton"]'); const createWrapper = (propsData, data = []) => { @@ -126,14 +126,14 @@ describe('Linked pipeline', () => { expect(findPipelineLabel().exists()).toBe(true); }); - it('downsteram pipeline should link to the child pipeline if child', () => { + it('downstream pipeline should contain the correct link', () => { createWrapper(downstreamProps); expect(findPipelineLink().attributes('href')).toBe(mockData.triggered_by.path); }); - it('upstream pipeline should not contain a link', () => { + it('upstream pipeline should contain the correct link', () => { createWrapper(upstreamProps); - expect(findPipelineLink().exists()).toBe(false); + expect(findPipelineLink().attributes('href')).toBe(mockData.triggered_by.path); }); it.each` diff --git a/spec/frontend/pipelines/test_reports/test_suite_table_spec.js b/spec/frontend/pipelines/test_reports/test_suite_table_spec.js index 3a4aa94571e..2feb6aa5799 100644 --- a/spec/frontend/pipelines/test_reports/test_suite_table_spec.js +++ b/spec/frontend/pipelines/test_reports/test_suite_table_spec.js @@ -23,8 +23,6 @@ describe('Test reports suite table', () => { const noCasesMessage = () => wrapper.find('.js-no-test-cases'); const allCaseRows = () => wrapper.findAll('.js-case-row'); const findCaseRowAtIndex = index => wrapper.findAll('.js-case-row').at(index); - const allCaseNames = () => - wrapper.findAll('[data-testid="caseName"]').wrappers.map(el => el.attributes('text')); const findIconForRow = (row, status) => row.find(`.ci-status-icon-${status}`); const createComponent = (suite = testSuite) => { @@ -63,16 +61,6 @@ describe('Test reports suite table', () => { expect(allCaseRows().length).toBe(testCases.length); }); - it('renders the failed tests first, skipped tests next, then successful tests', () => { - const expectedCaseOrder = [ - ...testCases.filter(x => x.status === TestStatus.FAILED), - ...testCases.filter(x => x.status === TestStatus.SKIPPED), - ...testCases.filter(x => x.status === TestStatus.SUCCESS), - ].map(x => x.name); - - expect(allCaseNames()).toEqual(expectedCaseOrder); - }); - it('renders the correct icon for each status', () => { const failedTest = testCases.findIndex(x => x.status === TestStatus.FAILED); const skippedTest = testCases.findIndex(x => x.status === TestStatus.SKIPPED); diff --git a/spec/frontend/projects/commits/components/author_select_spec.js b/spec/frontend/projects/commits/components/author_select_spec.js index a99c644a675..d38fdeb48a6 100644 --- a/spec/frontend/projects/commits/components/author_select_spec.js +++ b/spec/frontend/projects/commits/components/author_select_spec.js @@ -1,11 +1,6 @@ import { shallowMount, createLocalVue } from '@vue/test-utils'; import Vuex from 'vuex'; -import { - GlNewDropdown, - GlNewDropdownHeader, - GlSearchBoxByType, - GlNewDropdownItem, -} from '@gitlab/ui'; +import { GlDropdown, GlNewDropdownHeader, GlSearchBoxByType, GlNewDropdownItem } from '@gitlab/ui'; import * as urlUtility from '~/lib/utils/url_utility'; import AuthorSelect from '~/projects/commits/components/author_select.vue'; import { createStore } from '~/projects/commits/store'; @@ -63,7 +58,7 @@ describe('Author Select', () => { }); const findDropdownContainer = () => wrapper.find({ ref: 'dropdownContainer' }); - const findDropdown = () => wrapper.find(GlNewDropdown); + const findDropdown = () => wrapper.find(GlDropdown); const findDropdownHeader = () => wrapper.find(GlNewDropdownHeader); const findSearchBox = () => wrapper.find(GlSearchBoxByType); const findDropdownItems = () => wrapper.findAll(GlNewDropdownItem); diff --git a/spec/frontend/ref/components/ref_selector_spec.js b/spec/frontend/ref/components/ref_selector_spec.js index 6490bdcf038..77671287a4c 100644 --- a/spec/frontend/ref/components/ref_selector_spec.js +++ b/spec/frontend/ref/components/ref_selector_spec.js @@ -177,7 +177,7 @@ describe('Ref selector component', () => { return waitForRequests(); }); - it('adds the provided ID to the GlNewDropdown instance', () => { + it('adds the provided ID to the GlDropdown instance', () => { expect(wrapper.attributes().id).toBe(id); }); }); diff --git a/spec/frontend/sidebar/issuable_assignees_spec.js b/spec/frontend/sidebar/issuable_assignees_spec.js new file mode 100644 index 00000000000..aa930bd4198 --- /dev/null +++ b/spec/frontend/sidebar/issuable_assignees_spec.js @@ -0,0 +1,59 @@ +import { shallowMount } from '@vue/test-utils'; +import IssuableAssignees from '~/sidebar/components/assignees/issuable_assignees.vue'; +import UncollapsedAssigneeList from '~/sidebar/components/assignees/uncollapsed_assignee_list.vue'; + +describe('IssuableAssignees', () => { + let wrapper; + + const createComponent = (props = { users: [] }) => { + wrapper = shallowMount(IssuableAssignees, { + provide: { + rootPath: '', + }, + propsData: { ...props }, + }); + }; + const findLabel = () => wrapper.find('[data-testid="assigneeLabel"'); + const findUncollapsedAssigneeList = () => wrapper.find(UncollapsedAssigneeList); + const findEmptyAssignee = () => wrapper.find('[data-testid="none"]'); + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + }); + + describe('when no assignees are present', () => { + beforeEach(() => { + createComponent(); + }); + + it('renders "None"', () => { + expect(findEmptyAssignee().text()).toBe('None'); + }); + + it('renders "0 assignees"', () => { + expect(findLabel().text()).toBe('0 Assignees'); + }); + }); + + describe('when assignees are present', () => { + it('renders UncollapsedAssigneesList', () => { + createComponent({ users: [{ id: 1 }] }); + + expect(findUncollapsedAssigneeList().exists()).toBe(true); + }); + + it.each` + assignees | expected + ${[{ id: 1 }]} | ${'Assignee'} + ${[{ id: 1 }, { id: 2 }]} | ${'2 Assignees'} + `( + 'when assignees have a length of $assignees.length, it renders $expected', + ({ assignees, expected }) => { + createComponent({ users: assignees }); + + expect(findLabel().text()).toBe(expected); + }, + ); + }); +}); diff --git a/spec/frontend/vue_shared/components/__snapshots__/clone_dropdown_spec.js.snap b/spec/frontend/vue_shared/components/__snapshots__/clone_dropdown_spec.js.snap index e84eb7789d3..402a6daf922 100644 --- a/spec/frontend/vue_shared/components/__snapshots__/clone_dropdown_spec.js.snap +++ b/spec/frontend/vue_shared/components/__snapshots__/clone_dropdown_spec.js.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Clone Dropdown Button rendering matches the snapshot 1`] = ` -<gl-new-dropdown-stub +<gl-dropdown-stub category="primary" headertext="" right="" @@ -94,5 +94,5 @@ exports[`Clone Dropdown Button rendering matches the snapshot 1`] = ` </div> </div> </div> -</gl-new-dropdown-stub> +</gl-dropdown-stub> `; diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js index 2681488f76a..7b3c893ac05 100644 --- a/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js +++ b/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js @@ -3,7 +3,7 @@ import { GlFilteredSearch, GlButtonGroup, GlButton, - GlNewDropdown as GlDropdown, + GlDropdown, GlNewDropdownItem as GlDropdownItem, } from '@gitlab/ui'; diff --git a/spec/frontend/vue_shared/components/resizable_chart/__snapshots__/skeleton_loader_spec.js.snap b/spec/frontend/vue_shared/components/resizable_chart/__snapshots__/skeleton_loader_spec.js.snap index 70a60a2f746..3990248d021 100644 --- a/spec/frontend/vue_shared/components/resizable_chart/__snapshots__/skeleton_loader_spec.js.snap +++ b/spec/frontend/vue_shared/components/resizable_chart/__snapshots__/skeleton_loader_spec.js.snap @@ -1,425 +1,433 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Resizable Skeleton Loader default setup renders the bars, labels, and grid with correct position, size, and rx percentages 1`] = ` -<svg - class="gl-skeleton-loader" - preserveAspectRatio="xMidYMid meet" - version="1.1" - viewBox="0 0 400 130" +<div + class="gl-px-8" > - <rect - clip-path="url(#null-idClip)" - height="130" - style="fill: url(#null-idGradient);" - width="400" - x="0" - y="0" - /> - <defs> - <clippath - id="null-idClip" - > - <rect - data-testid="skeleton-chart-grid" - height="1px" - width="100%" - x="0" - y="30%" - /> - <rect - data-testid="skeleton-chart-grid" - height="1px" - width="100%" - x="0" - y="60%" - /> - <rect - data-testid="skeleton-chart-grid" - height="1px" - width="100%" - x="0" - y="90%" - /> - - <rect - data-testid="skeleton-chart-bar" - height="5%" - rx="0.4%" - width="6%" - x="5.875%" - y="85%" - /> - <rect - data-testid="skeleton-chart-bar" - height="7%" - rx="0.4%" - width="6%" - x="17.625%" - y="83%" - /> - <rect - data-testid="skeleton-chart-bar" - height="9%" - rx="0.4%" - width="6%" - x="29.375%" - y="81%" - /> - <rect - data-testid="skeleton-chart-bar" - height="14%" - rx="0.4%" - width="6%" - x="41.125%" - y="76%" - /> - <rect - data-testid="skeleton-chart-bar" - height="21%" - rx="0.4%" - width="6%" - x="52.875%" - y="69%" - /> - <rect - data-testid="skeleton-chart-bar" - height="35%" - rx="0.4%" - width="6%" - x="64.625%" - y="55%" - /> - <rect - data-testid="skeleton-chart-bar" - height="50%" - rx="0.4%" - width="6%" - x="76.375%" - y="40%" - /> - <rect - data-testid="skeleton-chart-bar" - height="80%" - rx="0.4%" - width="6%" - x="88.125%" - y="10%" - /> - - <rect - data-testid="skeleton-chart-label" - height="5%" - rx="0.4%" - width="4%" - x="6.875%" - y="95%" - /> - <rect - data-testid="skeleton-chart-label" - height="5%" - rx="0.4%" - width="4%" - x="18.625%" - y="95%" - /> - <rect - data-testid="skeleton-chart-label" - height="5%" - rx="0.4%" - width="4%" - x="30.375%" - y="95%" - /> - <rect - data-testid="skeleton-chart-label" - height="5%" - rx="0.4%" - width="4%" - x="42.125%" - y="95%" - /> - <rect - data-testid="skeleton-chart-label" - height="5%" - rx="0.4%" - width="4%" - x="53.875%" - y="95%" - /> - <rect - data-testid="skeleton-chart-label" - height="5%" - rx="0.4%" - width="4%" - x="65.625%" - y="95%" - /> - <rect - data-testid="skeleton-chart-label" - height="5%" - rx="0.4%" - width="4%" - x="77.375%" - y="95%" - /> - <rect - data-testid="skeleton-chart-label" - height="5%" - rx="0.4%" - width="4%" - x="89.125%" - y="95%" - /> - </clippath> - <lineargradient - id="null-idGradient" - > - <stop - class="primary-stop" - offset="0%" + <svg + class="gl-skeleton-loader" + preserveAspectRatio="xMidYMid meet" + version="1.1" + viewBox="0 0 400 130" + > + <rect + clip-path="url(#null-idClip)" + height="130" + style="fill: url(#null-idGradient);" + width="400" + x="0" + y="0" + /> + <defs> + <clippath + id="null-idClip" > - <animate - attributeName="offset" - dur="1s" - repeatCount="indefinite" - values="-2; 1" - /> - </stop> - <stop - class="secondary-stop" - offset="50%" - > - <animate - attributeName="offset" - dur="1s" - repeatCount="indefinite" - values="-1.5; 1.5" - /> - </stop> - <stop - class="primary-stop" - offset="100%" + <rect + data-testid="skeleton-chart-grid" + height="1px" + width="100%" + x="0" + y="30%" + /> + <rect + data-testid="skeleton-chart-grid" + height="1px" + width="100%" + x="0" + y="60%" + /> + <rect + data-testid="skeleton-chart-grid" + height="1px" + width="100%" + x="0" + y="90%" + /> + + <rect + data-testid="skeleton-chart-bar" + height="5%" + rx="0.4%" + width="4%" + x="6%" + y="85%" + /> + <rect + data-testid="skeleton-chart-bar" + height="7%" + rx="0.4%" + width="4%" + x="18%" + y="83%" + /> + <rect + data-testid="skeleton-chart-bar" + height="9%" + rx="0.4%" + width="4%" + x="30%" + y="81%" + /> + <rect + data-testid="skeleton-chart-bar" + height="14%" + rx="0.4%" + width="4%" + x="42%" + y="76%" + /> + <rect + data-testid="skeleton-chart-bar" + height="21%" + rx="0.4%" + width="4%" + x="54%" + y="69%" + /> + <rect + data-testid="skeleton-chart-bar" + height="35%" + rx="0.4%" + width="4%" + x="66%" + y="55%" + /> + <rect + data-testid="skeleton-chart-bar" + height="50%" + rx="0.4%" + width="4%" + x="78%" + y="40%" + /> + <rect + data-testid="skeleton-chart-bar" + height="80%" + rx="0.4%" + width="4%" + x="90%" + y="10%" + /> + + <rect + data-testid="skeleton-chart-label" + height="3%" + rx="0.4%" + width="3%" + x="6.5%" + y="97%" + /> + <rect + data-testid="skeleton-chart-label" + height="3%" + rx="0.4%" + width="3%" + x="18.5%" + y="97%" + /> + <rect + data-testid="skeleton-chart-label" + height="3%" + rx="0.4%" + width="3%" + x="30.5%" + y="97%" + /> + <rect + data-testid="skeleton-chart-label" + height="3%" + rx="0.4%" + width="3%" + x="42.5%" + y="97%" + /> + <rect + data-testid="skeleton-chart-label" + height="3%" + rx="0.4%" + width="3%" + x="54.5%" + y="97%" + /> + <rect + data-testid="skeleton-chart-label" + height="3%" + rx="0.4%" + width="3%" + x="66.5%" + y="97%" + /> + <rect + data-testid="skeleton-chart-label" + height="3%" + rx="0.4%" + width="3%" + x="78.5%" + y="97%" + /> + <rect + data-testid="skeleton-chart-label" + height="3%" + rx="0.4%" + width="3%" + x="90.5%" + y="97%" + /> + </clippath> + <lineargradient + id="null-idGradient" > - <animate - attributeName="offset" - dur="1s" - repeatCount="indefinite" - values="-1; 2" - /> - </stop> - </lineargradient> - </defs> -</svg> + <stop + class="primary-stop" + offset="0%" + > + <animate + attributeName="offset" + dur="1s" + repeatCount="indefinite" + values="-2; 1" + /> + </stop> + <stop + class="secondary-stop" + offset="50%" + > + <animate + attributeName="offset" + dur="1s" + repeatCount="indefinite" + values="-1.5; 1.5" + /> + </stop> + <stop + class="primary-stop" + offset="100%" + > + <animate + attributeName="offset" + dur="1s" + repeatCount="indefinite" + values="-1; 2" + /> + </stop> + </lineargradient> + </defs> + </svg> +</div> `; exports[`Resizable Skeleton Loader with custom settings renders the correct position, and size percentages for bars and labels with different settings 1`] = ` -<svg - class="gl-skeleton-loader" - preserveAspectRatio="xMidYMid meet" - version="1.1" - viewBox="0 0 400 130" +<div + class="gl-px-8" > - <rect - clip-path="url(#-idClip)" - height="130" - style="fill: url(#-idGradient);" - width="400" - x="0" - y="0" - /> - <defs> - <clippath - id="-idClip" - > - <rect - data-testid="skeleton-chart-grid" - height="1px" - width="100%" - x="0" - y="30%" - /> - <rect - data-testid="skeleton-chart-grid" - height="1px" - width="100%" - x="0" - y="60%" - /> - <rect - data-testid="skeleton-chart-grid" - height="1px" - width="100%" - x="0" - y="90%" - /> - - <rect - data-testid="skeleton-chart-bar" - height="5%" - rx="0.6%" - width="3%" - x="6.0625%" - y="85%" - /> - <rect - data-testid="skeleton-chart-bar" - height="7%" - rx="0.6%" - width="3%" - x="18.1875%" - y="83%" - /> - <rect - data-testid="skeleton-chart-bar" - height="9%" - rx="0.6%" - width="3%" - x="30.3125%" - y="81%" - /> - <rect - data-testid="skeleton-chart-bar" - height="14%" - rx="0.6%" - width="3%" - x="42.4375%" - y="76%" - /> - <rect - data-testid="skeleton-chart-bar" - height="21%" - rx="0.6%" - width="3%" - x="54.5625%" - y="69%" - /> - <rect - data-testid="skeleton-chart-bar" - height="35%" - rx="0.6%" - width="3%" - x="66.6875%" - y="55%" - /> - <rect - data-testid="skeleton-chart-bar" - height="50%" - rx="0.6%" - width="3%" - x="78.8125%" - y="40%" - /> - <rect - data-testid="skeleton-chart-bar" - height="80%" - rx="0.6%" - width="3%" - x="90.9375%" - y="10%" - /> - - <rect - data-testid="skeleton-chart-label" - height="2%" - rx="0.6%" - width="7%" - x="4.0625%" - y="98%" - /> - <rect - data-testid="skeleton-chart-label" - height="2%" - rx="0.6%" - width="7%" - x="16.1875%" - y="98%" - /> - <rect - data-testid="skeleton-chart-label" - height="2%" - rx="0.6%" - width="7%" - x="28.3125%" - y="98%" - /> - <rect - data-testid="skeleton-chart-label" - height="2%" - rx="0.6%" - width="7%" - x="40.4375%" - y="98%" - /> - <rect - data-testid="skeleton-chart-label" - height="2%" - rx="0.6%" - width="7%" - x="52.5625%" - y="98%" - /> - <rect - data-testid="skeleton-chart-label" - height="2%" - rx="0.6%" - width="7%" - x="64.6875%" - y="98%" - /> - <rect - data-testid="skeleton-chart-label" - height="2%" - rx="0.6%" - width="7%" - x="76.8125%" - y="98%" - /> - <rect - data-testid="skeleton-chart-label" - height="2%" - rx="0.6%" - width="7%" - x="88.9375%" - y="98%" - /> - </clippath> - <lineargradient - id="-idGradient" - > - <stop - class="primary-stop" - offset="0%" + <svg + class="gl-skeleton-loader" + preserveAspectRatio="xMidYMid meet" + version="1.1" + viewBox="0 0 400 130" + > + <rect + clip-path="url(#-idClip)" + height="130" + style="fill: url(#-idGradient);" + width="400" + x="0" + y="0" + /> + <defs> + <clippath + id="-idClip" > - <animate - attributeName="offset" - dur="1s" - repeatCount="indefinite" - values="-2; 1" - /> - </stop> - <stop - class="secondary-stop" - offset="50%" - > - <animate - attributeName="offset" - dur="1s" - repeatCount="indefinite" - values="-1.5; 1.5" - /> - </stop> - <stop - class="primary-stop" - offset="100%" + <rect + data-testid="skeleton-chart-grid" + height="1px" + width="100%" + x="0" + y="30%" + /> + <rect + data-testid="skeleton-chart-grid" + height="1px" + width="100%" + x="0" + y="60%" + /> + <rect + data-testid="skeleton-chart-grid" + height="1px" + width="100%" + x="0" + y="90%" + /> + + <rect + data-testid="skeleton-chart-bar" + height="5%" + rx="0.6%" + width="3%" + x="6.0625%" + y="85%" + /> + <rect + data-testid="skeleton-chart-bar" + height="7%" + rx="0.6%" + width="3%" + x="18.1875%" + y="83%" + /> + <rect + data-testid="skeleton-chart-bar" + height="9%" + rx="0.6%" + width="3%" + x="30.3125%" + y="81%" + /> + <rect + data-testid="skeleton-chart-bar" + height="14%" + rx="0.6%" + width="3%" + x="42.4375%" + y="76%" + /> + <rect + data-testid="skeleton-chart-bar" + height="21%" + rx="0.6%" + width="3%" + x="54.5625%" + y="69%" + /> + <rect + data-testid="skeleton-chart-bar" + height="35%" + rx="0.6%" + width="3%" + x="66.6875%" + y="55%" + /> + <rect + data-testid="skeleton-chart-bar" + height="50%" + rx="0.6%" + width="3%" + x="78.8125%" + y="40%" + /> + <rect + data-testid="skeleton-chart-bar" + height="80%" + rx="0.6%" + width="3%" + x="90.9375%" + y="10%" + /> + + <rect + data-testid="skeleton-chart-label" + height="2%" + rx="0.6%" + width="7%" + x="4.0625%" + y="98%" + /> + <rect + data-testid="skeleton-chart-label" + height="2%" + rx="0.6%" + width="7%" + x="16.1875%" + y="98%" + /> + <rect + data-testid="skeleton-chart-label" + height="2%" + rx="0.6%" + width="7%" + x="28.3125%" + y="98%" + /> + <rect + data-testid="skeleton-chart-label" + height="2%" + rx="0.6%" + width="7%" + x="40.4375%" + y="98%" + /> + <rect + data-testid="skeleton-chart-label" + height="2%" + rx="0.6%" + width="7%" + x="52.5625%" + y="98%" + /> + <rect + data-testid="skeleton-chart-label" + height="2%" + rx="0.6%" + width="7%" + x="64.6875%" + y="98%" + /> + <rect + data-testid="skeleton-chart-label" + height="2%" + rx="0.6%" + width="7%" + x="76.8125%" + y="98%" + /> + <rect + data-testid="skeleton-chart-label" + height="2%" + rx="0.6%" + width="7%" + x="88.9375%" + y="98%" + /> + </clippath> + <lineargradient + id="-idGradient" > - <animate - attributeName="offset" - dur="1s" - repeatCount="indefinite" - values="-1; 2" - /> - </stop> - </lineargradient> - </defs> -</svg> + <stop + class="primary-stop" + offset="0%" + > + <animate + attributeName="offset" + dur="1s" + repeatCount="indefinite" + values="-2; 1" + /> + </stop> + <stop + class="secondary-stop" + offset="50%" + > + <animate + attributeName="offset" + dur="1s" + repeatCount="indefinite" + values="-1.5; 1.5" + /> + </stop> + <stop + class="primary-stop" + offset="100%" + > + <animate + attributeName="offset" + dur="1s" + repeatCount="indefinite" + values="-1; 2" + /> + </stop> + </lineargradient> + </defs> + </svg> +</div> `; diff --git a/spec/helpers/notifications_helper_spec.rb b/spec/helpers/notifications_helper_spec.rb index 8d2806cbef6..176585e2ded 100644 --- a/spec/helpers/notifications_helper_spec.rb +++ b/spec/helpers/notifications_helper_spec.rb @@ -4,12 +4,12 @@ require 'spec_helper' RSpec.describe NotificationsHelper do describe 'notification_icon' do - it { expect(notification_icon(:disabled)).to match('class="fa fa-microphone-slash fa-fw"') } - it { expect(notification_icon(:owner_disabled)).to match('class="fa fa-microphone-slash fa-fw"') } - it { expect(notification_icon(:participating)).to match('class="fa fa-volume-up fa-fw"') } - it { expect(notification_icon(:mention)).to match('class="fa fa-at fa-fw"') } - it { expect(notification_icon(:global)).to match('class="fa fa-globe fa-fw"') } - it { expect(notification_icon(:watch)).to match('class="fa fa-eye fa-fw"') } + it { expect(notification_icon(:disabled)).to match('data-testid="notifications-off-icon"') } + it { expect(notification_icon(:owner_disabled)).to match('data-testid="notifications-off-icon"') } + it { expect(notification_icon(:participating)).to match('data-testid="notifications-icon"') } + it { expect(notification_icon(:mention)).to match('data-testid="at-icon"') } + it { expect(notification_icon(:global)).to match('data-testid="earth-icon') } + it { expect(notification_icon(:watch)).to match('data-testid="eye-icon"') } end describe 'notification_title' do diff --git a/spec/lib/backup/artifacts_spec.rb b/spec/lib/backup/artifacts_spec.rb new file mode 100644 index 00000000000..2a3f1949ba5 --- /dev/null +++ b/spec/lib/backup/artifacts_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Backup::Artifacts do + let(:progress) { StringIO.new } + + subject(:backup) { described_class.new(progress) } + + describe '#initialize' do + it 'uses the correct upload dir' do + Dir.mktmpdir do |tmpdir| + allow(JobArtifactUploader).to receive(:root) { "#{tmpdir}" } + + expect(backup.app_files_dir).to eq("#{tmpdir}") + end + end + end + + describe '#dump' do + before do + allow(File).to receive(:realpath).with('/var/gitlab-artifacts').and_return('/var/gitlab-artifacts') + allow(File).to receive(:realpath).with('/var/gitlab-artifacts/..').and_return('/var') + allow(JobArtifactUploader).to receive(:root) { '/var/gitlab-artifacts' } + end + + it 'uses the correct artifact dir' do + expect(backup.app_files_dir).to eq('/var/gitlab-artifacts') + end + + it 'excludes tmp from backup tar' do + expect(backup).to receive(:tar).and_return('blabla-tar') + expect(backup).to receive(:run_pipeline!).with([%w(blabla-tar --exclude=lost+found --exclude=./tmp -C /var/gitlab-artifacts -cf - .), 'gzip -c -1'], any_args) + backup.dump + end + end +end diff --git a/spec/lib/backup/files_spec.rb b/spec/lib/backup/files_spec.rb index a7374b82ce0..c2dbaac7f15 100644 --- a/spec/lib/backup/files_spec.rb +++ b/spec/lib/backup/files_spec.rb @@ -14,6 +14,8 @@ RSpec.describe Backup::Files do allow(File).to receive(:exist?).and_return(true) allow(File).to receive(:realpath).with("/var/gitlab-registry").and_return("/var/gitlab-registry") allow(File).to receive(:realpath).with("/var/gitlab-registry/..").and_return("/var") + allow(File).to receive(:realpath).with("/var/gitlab-pages").and_return("/var/gitlab-pages") + allow(File).to receive(:realpath).with("/var/gitlab-pages/..").and_return("/var") allow_any_instance_of(String).to receive(:color) do |string, _color| string @@ -82,4 +84,48 @@ RSpec.describe Backup::Files do end end end + + describe '#dump' do + subject { described_class.new('pages', '/var/gitlab-pages', excludes: ['@pages.tmp']) } + + before do + allow(subject).to receive(:run_pipeline!).and_return(true) + end + + it 'raises no errors' do + expect { subject.dump }.not_to raise_error + end + + it 'excludes tmp dirs from archive' do + expect(subject).to receive(:tar).and_return('blabla-tar') + + expect(subject).to receive(:run_pipeline!).with([%w(blabla-tar --exclude=lost+found --exclude=./@pages.tmp -C /var/gitlab-pages -cf - .), 'gzip -c -1'], any_args) + subject.dump + end + + describe 'with STRATEGY=copy' do + before do + stub_env('STRATEGY', 'copy') + end + + it 'excludes tmp dirs from rsync' do + allow(Gitlab.config.backup).to receive(:path) { '/var/gitlab-backup' } + allow(File).to receive(:realpath).with("/var/gitlab-backup").and_return("/var/gitlab-backup") + + expect(Gitlab::Popen).to receive(:popen).with(%w(rsync -a --exclude=lost+found --exclude=/@pages.tmp /var/gitlab-pages /var/gitlab-backup)).and_return(['', 0]) + + subject.dump + end + end + + describe '#exclude_dirs' do + it 'prepends a leading dot slash to tar excludes' do + expect(subject.exclude_dirs(:tar)).to eq(['--exclude=lost+found', '--exclude=./@pages.tmp']) + end + + it 'prepends a leading slash to rsync excludes' do + expect(subject.exclude_dirs(:rsync)).to eq(['--exclude=lost+found', '--exclude=/@pages.tmp']) + end + end + end end diff --git a/spec/lib/backup/pages_spec.rb b/spec/lib/backup/pages_spec.rb new file mode 100644 index 00000000000..59df4d1adf7 --- /dev/null +++ b/spec/lib/backup/pages_spec.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Backup::Pages do + let(:progress) { StringIO.new } + + subject { described_class.new(progress) } + + before do + allow(File).to receive(:realpath).with("/var/gitlab-pages").and_return("/var/gitlab-pages") + allow(File).to receive(:realpath).with("/var/gitlab-pages/..").and_return("/var") + end + + describe '#dump' do + it 'uses the correct pages dir' do + allow(Gitlab.config.pages).to receive(:path) { '/var/gitlab-pages' } + + expect(subject.app_files_dir).to eq('/var/gitlab-pages') + end + + it 'excludes tmp from backup tar' do + allow(Gitlab.config.pages).to receive(:path) { '/var/gitlab-pages' } + + expect(subject).to receive(:tar).and_return('blabla-tar') + expect(subject).to receive(:run_pipeline!).with([%w(blabla-tar --exclude=lost+found --exclude=./@pages.tmp -C /var/gitlab-pages -cf - .), 'gzip -c -1'], any_args) + subject.dump + end + end +end diff --git a/spec/lib/backup/uploads_spec.rb b/spec/lib/backup/uploads_spec.rb index 7c2d715b580..678b670db34 100644 --- a/spec/lib/backup/uploads_spec.rb +++ b/spec/lib/backup/uploads_spec.rb @@ -18,4 +18,22 @@ RSpec.describe Backup::Uploads do end end end + + describe '#dump' do + before do + allow(File).to receive(:realpath).with('/var/uploads').and_return('/var/uploads') + allow(File).to receive(:realpath).with('/var/uploads/..').and_return('/var') + allow(Gitlab.config.uploads).to receive(:storage_path) { '/var' } + end + + it 'uses the correct upload dir' do + expect(backup.app_files_dir).to eq('/var/uploads') + end + + it 'excludes tmp from backup tar' do + expect(backup).to receive(:tar).and_return('blabla-tar') + expect(backup).to receive(:run_pipeline!).with([%w(blabla-tar --exclude=lost+found --exclude=./tmp -C /var/uploads -cf - .), 'gzip -c -1'], any_args) + backup.dump + end + end end diff --git a/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb b/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb index 7d8fb183dbb..e7b6c910b8a 100644 --- a/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb @@ -208,4 +208,47 @@ RSpec.describe Banzai::Filter::ExternalIssueReferenceFilter do end end end + + context "ewm project" do + let_it_be(:project) { create(:ewm_project) } + + before do + project.update!(issues_enabled: false) + end + + context "rtcwi keyword" do + let(:issue) { ExternalIssue.new("rtcwi 123", project) } + let(:reference) { issue.to_reference } + + it_behaves_like "external issue tracker" + end + + context "workitem keyword" do + let(:issue) { ExternalIssue.new("workitem 123", project) } + let(:reference) { issue.to_reference } + + it_behaves_like "external issue tracker" + end + + context "defect keyword" do + let(:issue) { ExternalIssue.new("defect 123", project) } + let(:reference) { issue.to_reference } + + it_behaves_like "external issue tracker" + end + + context "task keyword" do + let(:issue) { ExternalIssue.new("task 123", project) } + let(:reference) { issue.to_reference } + + it_behaves_like "external issue tracker" + end + + context "bug keyword" do + let(:issue) { ExternalIssue.new("bug 123", project) } + let(:reference) { issue.to_reference } + + it_behaves_like "external issue tracker" + end + end end diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index bfdc6c959d3..5f691799e9c 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -365,6 +365,7 @@ project: - youtrack_service - custom_issue_tracker_service - bugzilla_service +- ewm_service - external_wiki_service - mock_ci_service - mock_deployment_service diff --git a/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb index c93fc2c17f1..f881da71251 100644 --- a/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb +++ b/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb @@ -20,7 +20,7 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s describe '.categories' do it 'gets all unique category names' do - expect(described_class.categories).to contain_exactly('analytics', 'compliance', 'ide_edit', 'search', 'source_code', 'incident_management') + expect(described_class.categories).to contain_exactly('analytics', 'compliance', 'ide_edit', 'search', 'source_code', 'incident_management', 'issues_edit') end end diff --git a/spec/lib/gitlab/usage_data_counters/issue_activity_unique_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/issue_activity_unique_counter_spec.rb new file mode 100644 index 00000000000..479fe36bcdd --- /dev/null +++ b/spec/lib/gitlab/usage_data_counters/issue_activity_unique_counter_spec.rb @@ -0,0 +1,111 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_gitlab_redis_shared_state do + let(:user1) { build(:user, id: 1) } + let(:user2) { build(:user, id: 2) } + let(:user3) { build(:user, id: 3) } + let(:time) { Time.zone.now } + + shared_examples 'tracks and counts action' do + before do + stub_application_setting(usage_ping_enabled: true) + end + + def count_unique(date_from:, date_to:) + Gitlab::UsageDataCounters::HLLRedisCounter.unique_events(event_names: action, start_date: date_from, end_date: date_to) + end + + specify do + aggregate_failures do + expect(track_action(author: user1)).to be_truthy + expect(track_action(author: user1)).to be_truthy + expect(track_action(author: user2)).to be_truthy + expect(track_action(author: user3, time: time - 3.days)).to be_truthy + + expect(count_unique(date_from: time, date_to: time)).to eq(2) + expect(count_unique(date_from: time - 5.days, date_to: 1.day.since(time))).to eq(3) + end + end + + it 'does not track edit actions if author is not present' do + expect(track_action(author: nil)).to be_nil + end + + context 'when feature flag track_issue_activity_actions is disabled' do + it 'does not track edit actions' do + stub_feature_flags(track_issue_activity_actions: false) + + expect(track_action(author: user1)).to be_nil + end + end + end + + context 'for Issue title edit actions' do + it_behaves_like 'tracks and counts action' do + let(:action) { described_class::ISSUE_TITLE_CHANGED } + + def track_action(params) + described_class.track_issue_title_changed_action(params) + end + end + end + + context 'for Issue description edit actions' do + it_behaves_like 'tracks and counts action' do + let(:action) { described_class::ISSUE_DESCRIPTION_CHANGED } + + def track_action(params) + described_class.track_issue_description_changed_action(params) + end + end + end + + context 'for Issue assignee edit actions' do + it_behaves_like 'tracks and counts action' do + let(:action) { described_class::ISSUE_ASSIGNEE_CHANGED } + + def track_action(params) + described_class.track_issue_assignee_changed_action(params) + end + end + end + + context 'for Issue make confidential actions' do + it_behaves_like 'tracks and counts action' do + let(:action) { described_class::ISSUE_MADE_CONFIDENTIAL } + + def track_action(params) + described_class.track_issue_made_confidential_action(params) + end + end + end + + context 'for Issue make visible actions' do + it_behaves_like 'tracks and counts action' do + let(:action) { described_class::ISSUE_MADE_VISIBLE } + + def track_action(params) + described_class.track_issue_made_visible_action(params) + end + end + end + + it 'can return the count of actions per user deduplicated', :aggregate_failures do + described_class.track_issue_title_changed_action(author: user1) + described_class.track_issue_description_changed_action(author: user1) + described_class.track_issue_assignee_changed_action(author: user1) + described_class.track_issue_title_changed_action(author: user2, time: time - 2.days) + described_class.track_issue_title_changed_action(author: user3, time: time - 3.days) + described_class.track_issue_description_changed_action(author: user3, time: time - 3.days) + described_class.track_issue_assignee_changed_action(author: user3, time: time - 3.days) + + events = Gitlab::UsageDataCounters::HLLRedisCounter.events_for_category(described_class::ISSUE_CATEGORY) + today_count = Gitlab::UsageDataCounters::HLLRedisCounter.unique_events(event_names: events, start_date: time, end_date: time) + week_count = Gitlab::UsageDataCounters::HLLRedisCounter.unique_events(event_names: events, start_date: time - 5.days, end_date: 1.day.since(time)) + + expect(today_count).to eq(1) + expect(week_count).to eq(3) + end +end diff --git a/spec/models/alert_management/alert_spec.rb b/spec/models/alert_management/alert_spec.rb index f937a879400..87aeb3d78c0 100644 --- a/spec/models/alert_management/alert_spec.rb +++ b/spec/models/alert_management/alert_spec.rb @@ -332,33 +332,6 @@ RSpec.describe AlertManagement::Alert do end end - describe '#details' do - let(:payload) do - { - 'title' => 'Details title', - 'custom' => { - 'alert' => { - 'fields' => %w[one two] - } - }, - 'yet' => { - 'another' => 'field' - } - } - end - - let(:alert) { build(:alert_management_alert, project: project, title: 'Details title', payload: payload) } - - subject { alert.details } - - it 'renders the payload as inline hash' do - is_expected.to eq( - 'custom.alert.fields' => %w[one two], - 'yet.another' => 'field' - ) - end - end - describe '#to_reference' do it { expect(triggered_alert.to_reference).to eq('') } end diff --git a/spec/models/project_services/ewm_service_spec.rb b/spec/models/project_services/ewm_service_spec.rb new file mode 100644 index 00000000000..311c456569e --- /dev/null +++ b/spec/models/project_services/ewm_service_spec.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe EwmService do + describe 'Associations' do + it { is_expected.to belong_to :project } + it { is_expected.to have_one :service_hook } + end + + describe 'Validations' do + context 'when service is active' do + before do + subject.active = true + end + + it { is_expected.to validate_presence_of(:project_url) } + it { is_expected.to validate_presence_of(:issues_url) } + it { is_expected.to validate_presence_of(:new_issue_url) } + it_behaves_like 'issue tracker service URL attribute', :project_url + it_behaves_like 'issue tracker service URL attribute', :issues_url + it_behaves_like 'issue tracker service URL attribute', :new_issue_url + end + + context 'when service is inactive' do + before do + subject.active = false + end + + it { is_expected.not_to validate_presence_of(:project_url) } + it { is_expected.not_to validate_presence_of(:issues_url) } + it { is_expected.not_to validate_presence_of(:new_issue_url) } + end + end + + describe "ReferencePatternValidation" do + it "extracts bug" do + expect(described_class.reference_pattern.match("This is bug 123")[:issue]).to eq("bug 123") + end + + it "extracts task" do + expect(described_class.reference_pattern.match("This is task 123.")[:issue]).to eq("task 123") + end + + it "extracts work item" do + expect(described_class.reference_pattern.match("This is work item 123 now")[:issue]).to eq("work item 123") + end + + it "extracts workitem" do + expect(described_class.reference_pattern.match("workitem 123 at the beginning")[:issue]).to eq("workitem 123") + end + + it "extracts defect" do + expect(described_class.reference_pattern.match("This is defect 123 defect")[:issue]).to eq("defect 123") + end + + it "extracts rtcwi" do + expect(described_class.reference_pattern.match("This is rtcwi 123")[:issue]).to eq("rtcwi 123") + end + end +end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 546b869ffd9..77b8b22e3f3 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -61,6 +61,7 @@ RSpec.describe Project do it { is_expected.to have_one(:youtrack_service) } it { is_expected.to have_one(:custom_issue_tracker_service) } it { is_expected.to have_one(:bugzilla_service) } + it { is_expected.to have_one(:ewm_service) } it { is_expected.to have_one(:external_wiki_service) } it { is_expected.to have_one(:confluence_service) } it { is_expected.to have_one(:project_feature) } diff --git a/spec/presenters/alert_management/alert_presenter_spec.rb b/spec/presenters/alert_management/alert_presenter_spec.rb index 365dc84ff53..3b7920dfd5e 100644 --- a/spec/presenters/alert_management/alert_presenter_spec.rb +++ b/spec/presenters/alert_management/alert_presenter_spec.rb @@ -9,7 +9,14 @@ RSpec.describe AlertManagement::AlertPresenter do { 'title' => 'Alert title', 'start_time' => '2020-04-27T10:10:22.265949279Z', - 'custom' => { 'param' => 73 } + 'custom' => { + 'alert' => { + 'fields' => %w[one two] + } + }, + 'yet' => { + 'another' => 73 + } } end @@ -37,7 +44,10 @@ RSpec.describe AlertManagement::AlertPresenter do #### Alert Details - **custom.param:** 73 + **title:** Alert title#{markdown_line_break} + **start_time:** 2020-04-27T10:10:22.265949279Z#{markdown_line_break} + **custom.alert.fields:** ["one", "two"]#{markdown_line_break} + **yet.another:** 73 MARKDOWN ) end @@ -54,4 +64,17 @@ RSpec.describe AlertManagement::AlertPresenter do expect(presenter.details_url).to match(%r{#{project.web_url}/-/alert_management/#{alert.iid}/details}) end end + + describe '#details' do + subject { presenter.details } + + it 'renders the payload as inline hash' do + is_expected.to eq( + 'title' => 'Alert title', + 'start_time' => '2020-04-27T10:10:22.265949279Z', + 'custom.alert.fields' => %w[one two], + 'yet.another' => 73 + ) + end + end end diff --git a/spec/presenters/alert_management/prometheus_alert_presenter_spec.rb b/spec/presenters/alert_management/prometheus_alert_presenter_spec.rb index 8ff51b9a8e1..74c77b70e5a 100644 --- a/spec/presenters/alert_management/prometheus_alert_presenter_spec.rb +++ b/spec/presenters/alert_management/prometheus_alert_presenter_spec.rb @@ -38,7 +38,11 @@ RSpec.describe AlertManagement::PrometheusAlertPresenter do #### Alert Details - **custom annotation:** custom annotation value + **annotations.custom annotation:** custom annotation value#{markdown_line_break} + **annotations.gitlab_incident_markdown:** **`markdown example`**#{markdown_line_break} + **annotations.title:** Alert title#{markdown_line_break} + **startsAt:** 2020-04-27T10:10:22.265949279Z#{markdown_line_break} + **generatorURL:** http://8d467bd4607a:9090/graph?g0.expr=vector%281%29&g0.tab=1 --- diff --git a/spec/presenters/projects/prometheus/alert_presenter_spec.rb b/spec/presenters/projects/prometheus/alert_presenter_spec.rb index 1c37e551385..4f1b1931fb9 100644 --- a/spec/presenters/projects/prometheus/alert_presenter_spec.rb +++ b/spec/presenters/projects/prometheus/alert_presenter_spec.rb @@ -65,32 +65,25 @@ RSpec.describe Projects::Prometheus::AlertPresenter do <<~MARKDOWN.chomp **Start time:** #{presenter.start_time} - MARKDOWN - ) - end - end - - context 'with annotations' do - before do - payload['annotations'] = { 'title' => 'Alert Title', 'foo' => 'value1', 'bar' => 'value2' } - end - - it do - is_expected.to eq( - <<~MARKDOWN.chomp - **Start time:** #{presenter.start_time} - #### Alert Details - **foo:** value1#{markdown_line_break} - **bar:** value2 + **startsAt:** #{presenter.starts_at_raw} MARKDOWN ) end end - context 'with full query' do + context 'with optional attributes' do before do + payload['annotations'] = { + 'title' => 'Alert Title', + 'foo' => 'value1', + 'bar' => 'value2', + 'description' => 'Alert Description', + 'monitoring_tool' => 'monitoring_tool_name', + 'service' => 'service_name', + 'hosts' => ['http://localhost:3000', 'http://localhost:3001'] + } payload['generatorURL'] = 'http://host?g0.expr=query' end @@ -98,72 +91,52 @@ RSpec.describe Projects::Prometheus::AlertPresenter do is_expected.to eq( <<~MARKDOWN.chomp **Start time:** #{presenter.start_time}#{markdown_line_break} - **full_query:** `query` + **full_query:** `query`#{markdown_line_break} + **Service:** service_name#{markdown_line_break} + **Monitoring tool:** monitoring_tool_name#{markdown_line_break} + **Hosts:** http://localhost:3000 http://localhost:3001 + #### Alert Details + + **annotations.hosts:** ["http://localhost:3000", "http://localhost:3001"]#{markdown_line_break} + **annotations.service:** service_name#{markdown_line_break} + **annotations.monitoring_tool:** monitoring_tool_name#{markdown_line_break} + **annotations.description:** Alert Description#{markdown_line_break} + **annotations.bar:** value2#{markdown_line_break} + **annotations.foo:** value1#{markdown_line_break} + **annotations.title:** Alert Title#{markdown_line_break} + **generatorURL:** http://host?g0.expr=query#{markdown_line_break} + **startsAt:** #{presenter.starts_at_raw} MARKDOWN ) end end - context 'with the Generic Alert parameters' do - let(:generic_alert_params) do - { - 'title' => 'The Generic Alert Title', - 'description' => 'The Generic Alert Description', - 'monitoring_tool' => 'monitoring_tool_name', - 'service' => 'service_name', - 'hosts' => ['http://localhost:3000', 'http://localhost:3001'] - } - end - + context 'when hosts is a string' do before do - payload['annotations'] = generic_alert_params + payload['annotations'] = { 'hosts' => 'http://localhost:3000' } end it do is_expected.to eq( <<~MARKDOWN.chomp - **Start time:** #{presenter.start_time}#{markdown_line_break} - **Service:** service_name#{markdown_line_break} - **Monitoring tool:** monitoring_tool_name#{markdown_line_break} - **Hosts:** http://localhost:3000 http://localhost:3001 + **Start time:** #{presenter.start_time}#{markdown_line_break} + **Hosts:** http://localhost:3000 - #### Alert Details + #### Alert Details - **description:** The Generic Alert Description + **annotations.hosts:** http://localhost:3000#{markdown_line_break} + **startsAt:** #{presenter.starts_at_raw} MARKDOWN ) end - - context 'when hosts is a string' do - before do - payload['annotations'] = { 'hosts' => 'http://localhost:3000' } - end - - it do - is_expected.to eq( - <<~MARKDOWN.chomp - **Start time:** #{presenter.start_time}#{markdown_line_break} - **Hosts:** http://localhost:3000 - - MARKDOWN - ) - end - end end context 'with embedded metrics' do let(:starts_at) { '2018-03-12T09:06:00Z' } shared_examples_for 'markdown with metrics embed' do - let(:expected_markdown) do - <<~MARKDOWN.chomp - **Start time:** #{presenter.start_time}#{markdown_line_break} - **full_query:** `avg(metric) > 1.0` - - [](#{presenter.metrics_dashboard_url}) - MARKDOWN - end + let(:embed_regex) { /\n\[\]\(#{Regexp.quote(presenter.metrics_dashboard_url)}\)\z/ } context 'without a starting time available' do around do |example| @@ -174,11 +147,11 @@ RSpec.describe Projects::Prometheus::AlertPresenter do payload.delete('startsAt') end - it { is_expected.to eq(expected_markdown) } + it { is_expected.to match(embed_regex) } end context 'with a starting time available' do - it { is_expected.to eq(expected_markdown) } + it { is_expected.to match(embed_regex) } end end @@ -208,12 +181,8 @@ RSpec.describe Projects::Prometheus::AlertPresenter do end context 'when not enough information is present for an embed' do - let(:expected_markdown) do - <<~MARKDOWN.chomp - **Start time:** #{presenter.start_time}#{markdown_line_break} - **full_query:** `avg(metric) > 1.0` - - MARKDOWN + shared_examples_for 'does not include an embed' do + it { is_expected.not_to match(/\[\]\(.+\)/) } end context 'without title' do @@ -221,7 +190,7 @@ RSpec.describe Projects::Prometheus::AlertPresenter do payload['annotations'].delete('title') end - it { is_expected.to eq(expected_markdown) } + it_behaves_like 'does not include an embed' end context 'without environment' do @@ -229,22 +198,15 @@ RSpec.describe Projects::Prometheus::AlertPresenter do payload['labels'].delete('gitlab_environment_name') end - it { is_expected.to eq(expected_markdown) } + it_behaves_like 'does not include an embed' end context 'without full_query' do - let(:expected_markdown) do - <<~MARKDOWN.chomp - **Start time:** #{presenter.start_time} - - MARKDOWN - end - before do payload.delete('generatorURL') end - it { is_expected.to eq(expected_markdown) } + it_behaves_like 'does not include an embed' end end end diff --git a/spec/requests/api/variables_spec.rb b/spec/requests/api/variables_spec.rb index 7bb73e9664b..1ae9b0d548d 100644 --- a/spec/requests/api/variables_spec.rb +++ b/spec/requests/api/variables_spec.rb @@ -60,25 +60,10 @@ RSpec.describe API::Variables do let!(:var2) { create(:ci_variable, project: project, key: 'key1', environment_scope: 'production') } context 'when filter[environment_scope] is not passed' do - context 'FF ci_variables_api_filter_environment_scope is enabled' do - it 'returns 409' do - get api("/projects/#{project.id}/variables/key1", user) + it 'returns 409' do + get api("/projects/#{project.id}/variables/key1", user) - expect(response).to have_gitlab_http_status(:conflict) - end - end - - context 'FF ci_variables_api_filter_environment_scope is disabled' do - before do - stub_feature_flags(ci_variables_api_filter_environment_scope: false) - end - - it 'returns random one' do - get api("/projects/#{project.id}/variables/key1", user) - - expect(response).to have_gitlab_http_status(:ok) - expect(json_response['key']).to eq('key1') - end + expect(response).to have_gitlab_http_status(:conflict) end end @@ -232,25 +217,10 @@ RSpec.describe API::Variables do let!(:var2) { create(:ci_variable, project: project, key: 'key1', environment_scope: 'production') } context 'when filter[environment_scope] is not passed' do - context 'FF ci_variables_api_filter_environment_scope is enabled' do - it 'returns 409' do - get api("/projects/#{project.id}/variables/key1", user) + it 'returns 409' do + get api("/projects/#{project.id}/variables/key1", user) - expect(response).to have_gitlab_http_status(:conflict) - end - end - - context 'FF ci_variables_api_filter_environment_scope is disabled' do - before do - stub_feature_flags(ci_variables_api_filter_environment_scope: false) - end - - it 'updates random one' do - put api("/projects/#{project.id}/variables/key1", user), params: { value: 'new_val' } - - expect(response).to have_gitlab_http_status(:ok) - expect(json_response['value']).to eq('new_val') - end + expect(response).to have_gitlab_http_status(:conflict) end end @@ -312,26 +282,10 @@ RSpec.describe API::Variables do let!(:var2) { create(:ci_variable, project: project, key: 'key1', environment_scope: 'production') } context 'when filter[environment_scope] is not passed' do - context 'FF ci_variables_api_filter_environment_scope is enabled' do - it 'returns 409' do - get api("/projects/#{project.id}/variables/key1", user) - - expect(response).to have_gitlab_http_status(:conflict) - end - end - - context 'FF ci_variables_api_filter_environment_scope is disabled' do - before do - stub_feature_flags(ci_variables_api_filter_environment_scope: false) - end + it 'returns 409' do + get api("/projects/#{project.id}/variables/key1", user) - it 'deletes random one' do - expect do - delete api("/projects/#{project.id}/variables/key1", user), params: { 'filter[environment_scope]': 'production' } - - expect(response).to have_gitlab_http_status(:no_content) - end.to change {project.variables.count}.by(-1) - end + expect(response).to have_gitlab_http_status(:conflict) end end diff --git a/spec/rubocop/cop/migration/create_table_with_foreign_keys_spec.rb b/spec/rubocop/cop/migration/create_table_with_foreign_keys_spec.rb index 8dbd90afa5e..fa4acc62226 100644 --- a/spec/rubocop/cop/migration/create_table_with_foreign_keys_spec.rb +++ b/spec/rubocop/cop/migration/create_table_with_foreign_keys_spec.rb @@ -42,14 +42,28 @@ RSpec.describe RuboCop::Cop::Migration::CreateTableWithForeignKeys, type: :ruboc context 'with foreign key' do context 'with just one foreign key' do context 'when the foreign_key targets a high traffic table' do - it 'does not register any offenses' do - expect_no_offenses(<<~RUBY) - def up - create_table(:foo) do |t| - t.references :project, "foreign_key" => { on_delete: 'cascade', to_table: 'projects' } + context 'when the foreign_key has to_table option set' do + it 'does not register any offenses' do + expect_no_offenses(<<~RUBY) + def up + create_table(:foo) do |t| + t.references :project, "foreign_key" => { on_delete: 'cascade', to_table: 'projects' } + end end - end - RUBY + RUBY + end + end + + context 'when the foreign_key does not have to_table option set' do + it 'does not register any offenses' do + expect_no_offenses(<<~RUBY) + def up + create_table(:foo) do |t| + t.references :project, foreign_key: { on_delete: 'cascade' } + end + end + RUBY + end end end diff --git a/spec/support/shared_examples/features/editable_merge_request_shared_examples.rb b/spec/support/shared_examples/features/editable_merge_request_shared_examples.rb index 487c38da7da..c9910487798 100644 --- a/spec/support/shared_examples/features/editable_merge_request_shared_examples.rb +++ b/spec/support/shared_examples/features/editable_merge_request_shared_examples.rb @@ -124,3 +124,16 @@ end def get_textarea_height page.evaluate_script('document.getElementById("merge_request_description").offsetHeight') end + +RSpec.shared_examples 'an editable merge request with reviewers' do + it 'updates merge request', :js do + find('.js-reviewer-search').click + page.within '.dropdown-menu-user' do + click_link user.name + end + expect(find('input[name="merge_request[reviewer_ids][]"]', visible: false).value).to match(user.id.to_s) + page.within '.js-reviewer-search' do + expect(page).to have_content user.name + end + end +end diff --git a/spec/views/projects/merge_requests/edit.html.haml_spec.rb b/spec/views/projects/merge_requests/edit.html.haml_spec.rb index 55a74dc8229..215d404e395 100644 --- a/spec/views/projects/merge_requests/edit.html.haml_spec.rb +++ b/spec/views/projects/merge_requests/edit.html.haml_spec.rb @@ -20,6 +20,7 @@ RSpec.describe 'projects/merge_requests/edit.html.haml' do target_project: project, author: user, assignees: [user], + reviewers: [user], milestone: milestone) end |