diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-11-04 15:10:55 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-11-04 15:10:55 +0300 |
commit | f2fd07aa1c0bfb732b80c3d028cd23c91547991c (patch) | |
tree | 7b2c53ef4b4caddb65b2443ecd34dfa2289719ab /spec | |
parent | 9f0d27648937cb04d685ca9207f5c45f3ac98010 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
30 files changed, 421 insertions, 149 deletions
diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb index b132c0b5a69..527cba9e618 100644 --- a/spec/controllers/projects/pipelines_controller_spec.rb +++ b/spec/controllers/projects/pipelines_controller_spec.rb @@ -20,23 +20,11 @@ RSpec.describe Projects::PipelinesController do end shared_examples 'the show page' do |param| - it 'redirects to pipeline path with param' do + it 'renders the show template' do get param, params: { namespace_id: project.namespace, project_id: project, id: pipeline } - expect(response).to redirect_to(pipeline_path(pipeline, tab: param)) - end - - context 'when the FF pipeline_tabs_vue is disabled' do - before do - stub_feature_flags(pipeline_tabs_vue: false) - end - - it 'renders the show template' do - get param, params: { namespace_id: project.namespace, project_id: project, id: pipeline } - - expect(response).to have_gitlab_http_status(:ok) - expect(response).to render_template :show - end + expect(response).to have_gitlab_http_status(:ok) + expect(response).to render_template :show end end @@ -710,37 +698,25 @@ RSpec.describe Projects::PipelinesController do describe 'GET failures' do let(:pipeline) { create(:ci_pipeline, project: project) } - context 'with ff `pipeline_tabs_vue` disabled' do + context 'with failed jobs' do before do - stub_feature_flags(pipeline_tabs_vue: false) - end - - context 'with failed jobs' do - before do - create(:ci_build, :failed, pipeline: pipeline, name: 'hello') - end - - it 'shows the page' do - get :failures, params: { namespace_id: project.namespace, project_id: project, id: pipeline } - - expect(response).to have_gitlab_http_status(:ok) - expect(response).to render_template :show - end + create(:ci_build, :failed, pipeline: pipeline, name: 'hello') end - context 'without failed jobs' do - it 'redirects to the main pipeline page' do - get :failures, params: { namespace_id: project.namespace, project_id: project, id: pipeline } + it 'shows the page' do + get :failures, params: { namespace_id: project.namespace, project_id: project, id: pipeline } - expect(response).to redirect_to(pipeline_path(pipeline)) - end + expect(response).to have_gitlab_http_status(:ok) + expect(response).to render_template :show end end - it 'redirects to the pipeline page with `failures` query param' do - get :failures, params: { namespace_id: project.namespace, project_id: project, id: pipeline } + context 'without failed jobs' do + it 'redirects to the main pipeline page' do + get :failures, params: { namespace_id: project.namespace, project_id: project, id: pipeline } - expect(response).to redirect_to(pipeline_path(pipeline, tab: 'failures')) + expect(response).to redirect_to(pipeline_path(pipeline)) + end end end diff --git a/spec/db/schema_spec.rb b/spec/db/schema_spec.rb index 1c24d091649..c383c4b6f24 100644 --- a/spec/db/schema_spec.rb +++ b/spec/db/schema_spec.rb @@ -80,7 +80,7 @@ RSpec.describe 'Database schema' do project_error_tracking_settings: %w[sentry_project_id], project_group_links: %w[group_id], project_statistics: %w[namespace_id], - projects: %w[ci_id mirror_user_id], + projects: %w[creator_id ci_id mirror_user_id], redirect_routes: %w[source_id], repository_languages: %w[programming_language_id], routes: %w[source_id], diff --git a/spec/features/boards/board_filters_spec.rb b/spec/features/boards/board_filters_spec.rb index 1184aea1114..eab92de7e8a 100644 --- a/spec/features/boards/board_filters_spec.rb +++ b/spec/features/boards/board_filters_spec.rb @@ -22,6 +22,7 @@ RSpec.describe 'Issue board filters', :js do let(:filter_submit) { find('.gl-search-box-by-click-search-button') } before do + stub_feature_flags(apollo_boards: false) project.add_maintainer(user) sign_in(user) diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb index a09c9d258dc..fee9b5b378e 100644 --- a/spec/features/boards/boards_spec.rb +++ b/spec/features/boards/boards_spec.rb @@ -19,6 +19,7 @@ RSpec.describe 'Project issue boards', :js do context 'signed in user' do before do + stub_feature_flags(apollo_boards: false) project.add_maintainer(user) project.add_maintainer(user2) @@ -29,7 +30,7 @@ RSpec.describe 'Project issue boards', :js do context 'no lists' do before do - visit_project_board_path_without_query_limit(project, board) + visit_project_board(project, board) end it 'creates default lists' do @@ -73,7 +74,7 @@ RSpec.describe 'Project issue boards', :js do let_it_be(:issue10) { create(:labeled_issue, project: project, title: 'issue +', description: 'A+ great issue', labels: [a_plus]) } before do - visit_project_board_path_without_query_limit(project, board) + visit_project_board(project, board) end it 'shows description tooltip on list title', :quarantine do @@ -124,7 +125,7 @@ RSpec.describe 'Project issue boards', :js do it 'infinite scrolls list' do create_list(:labeled_issue, 30, project: project, labels: [planning]) - visit_project_board_path_without_query_limit(project, board) + visit_project_board(project, board) page.within(find('.board:nth-child(2)')) do expect(page.find('.board-header')).to have_content('38') @@ -203,7 +204,7 @@ RSpec.describe 'Project issue boards', :js do expect(find('.board:nth-child(3) [data-testid="board-list-header"]')).to have_content(planning.title) # Make sure list positions are preserved after a reload - visit_project_board_path_without_query_limit(project, board) + visit_project_board(project, board) expect(find('.board:nth-child(2) [data-testid="board-list-header"]')).to have_content(development.title) expect(find('.board:nth-child(3) [data-testid="board-list-header"]')).to have_content(planning.title) @@ -215,15 +216,19 @@ RSpec.describe 'Project issue boards', :js do let_it_be(:list2) { create(:list, board: board, label: development, position: 1) } it 'changes position of list' do - visit_project_board_path_without_query_limit(project, board) + inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do + visit_project_board(project, board) + end drag(list_from_index: 0, list_to_index: 1, selector: '.board-header') expect(find('.board:nth-child(1) [data-testid="board-list-header"]')).to have_content(development.title) expect(find('.board:nth-child(2) [data-testid="board-list-header"]')).to have_content(planning.title) - # Make sure list positions are preserved after a reload - visit_project_board_path_without_query_limit(project, board) + inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do + # Make sure list positions are preserved after a reload + visit_project_board(project, board) + end expect(find('.board:nth-child(1) [data-testid="board-list-header"]')).to have_content(development.title) expect(find('.board:nth-child(2) [data-testid="board-list-header"]')).to have_content(planning.title) @@ -234,7 +239,9 @@ RSpec.describe 'Project issue boards', :js do selector = '.board:not(.is-ghost) .board-header' expect(page).to have_selector(selector, text: development.title, count: 1) - drag(list_from_index: 2, list_to_index: 1, selector: '.board-header', perform_drop: false) + inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do + drag(list_from_index: 2, list_to_index: 1, selector: '.board-header', perform_drop: false) + end expect(page).to have_selector(selector, text: development.title, count: 1) end @@ -492,7 +499,7 @@ RSpec.describe 'Project issue boards', :js do context 'keyboard shortcuts' do before do - visit_project_board_path_without_query_limit(project, board) + visit_project_board(project, board) wait_for_requests end @@ -505,6 +512,7 @@ RSpec.describe 'Project issue boards', :js do context 'signed out user' do before do + stub_feature_flags(apollo_boards: false) visit project_board_path(project, board) wait_for_requests end @@ -526,6 +534,7 @@ RSpec.describe 'Project issue boards', :js do let_it_be(:user_guest) { create(:user) } before do + stub_feature_flags(apollo_boards: false) project.add_guest(user_guest) sign_in(user_guest) visit project_board_path(project, board) @@ -587,11 +596,9 @@ RSpec.describe 'Project issue boards', :js do end end - def visit_project_board_path_without_query_limit(project, board) - inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do - visit project_board_path(project, board) + def visit_project_board(project, board) + visit project_board_path(project, board) - wait_for_requests - end + wait_for_requests end end diff --git a/spec/features/boards/issue_ordering_spec.rb b/spec/features/boards/issue_ordering_spec.rb index 57f2bf26752..a3dda3b9d2f 100644 --- a/spec/features/boards/issue_ordering_spec.rb +++ b/spec/features/boards/issue_ordering_spec.rb @@ -15,6 +15,7 @@ RSpec.describe 'Issue Boards', :js do let!(:issue3) { create(:labeled_issue, project: project, title: 'testing 3', labels: [label], relative_position: 1) } before do + stub_feature_flags(apollo_boards: false) project.add_maintainer(user) sign_in(user) diff --git a/spec/features/boards/sidebar_labels_spec.rb b/spec/features/boards/sidebar_labels_spec.rb index 511233b50c0..12d91e9c5a8 100644 --- a/spec/features/boards/sidebar_labels_spec.rb +++ b/spec/features/boards/sidebar_labels_spec.rb @@ -20,6 +20,7 @@ RSpec.describe 'Project issue boards sidebar labels', :js do let(:card) { find('.board:nth-child(2)').first('.board-card') } before do + stub_feature_flags(apollo_boards: false) project.add_maintainer(user) sign_in(user) diff --git a/spec/features/boards/sidebar_spec.rb b/spec/features/boards/sidebar_spec.rb index 0e914ae19d1..2b2a412194a 100644 --- a/spec/features/boards/sidebar_spec.rb +++ b/spec/features/boards/sidebar_spec.rb @@ -15,6 +15,7 @@ RSpec.describe 'Project issue boards sidebar', :js do let_it_be(:issue, reload: true) { create(:issue, project: project, relative_position: 1) } before do + stub_feature_flags(apollo_boards: false) project.add_maintainer(user) sign_in(user) diff --git a/spec/features/boards/user_adds_lists_to_board_spec.rb b/spec/features/boards/user_adds_lists_to_board_spec.rb index a1728d066cd..480a88a6b84 100644 --- a/spec/features/boards/user_adds_lists_to_board_spec.rb +++ b/spec/features/boards/user_adds_lists_to_board_spec.rb @@ -31,6 +31,7 @@ RSpec.describe 'User adds lists', :js do with_them do before do + stub_feature_flags(apollo_boards: false) sign_in(user) set_cookie('sidebar_collapsed', 'true') diff --git a/spec/features/boards/user_visits_board_spec.rb b/spec/features/boards/user_visits_board_spec.rb index 5587d9560a2..c386477fa9d 100644 --- a/spec/features/boards/user_visits_board_spec.rb +++ b/spec/features/boards/user_visits_board_spec.rb @@ -44,6 +44,7 @@ RSpec.describe 'User visits issue boards', :js do with_them do before do + stub_feature_flags(apollo_boards: false) visit board_path wait_for_requests @@ -59,6 +60,7 @@ RSpec.describe 'User visits issue boards', :js do end context "project boards" do + stub_feature_flags(apollo_boards: false) let_it_be(:board) { create_default(:board, project: project) } let_it_be(:backlog_list) { create_default(:backlog_list, board: board) } @@ -68,6 +70,7 @@ RSpec.describe 'User visits issue boards', :js do end context "group boards" do + stub_feature_flags(apollo_boards: false) let_it_be(:board) { create_default(:board, group: group) } let_it_be(:backlog_list) { create_default(:backlog_list, board: board) } diff --git a/spec/features/groups/board_sidebar_spec.rb b/spec/features/groups/board_sidebar_spec.rb index aa42b29b3ac..10ef28f3fbc 100644 --- a/spec/features/groups/board_sidebar_spec.rb +++ b/spec/features/groups/board_sidebar_spec.rb @@ -19,6 +19,7 @@ RSpec.describe 'Group Issue Boards', :js do let(:card) { find('.board:nth-child(1)').first('.board-card') } before do + stub_feature_flags(apollo_boards: false) sign_in(user) visit group_board_path(group, board) diff --git a/spec/features/incidents/user_views_incident_spec.rb b/spec/features/incidents/user_views_incident_spec.rb index a669966502e..054a084ea9c 100644 --- a/spec/features/incidents/user_views_incident_spec.rb +++ b/spec/features/incidents/user_views_incident_spec.rb @@ -4,12 +4,16 @@ require "spec_helper" RSpec.describe "User views incident" do let_it_be(:project) { create(:project_empty_repo, :public) } - let_it_be(:user) { create(:user) } - let_it_be(:incident) { create(:incident, project: project, description: "# Description header\n\n**Lorem** _ipsum_ dolor sit [amet](https://example.com)", author: user) } - let_it_be(:note) { create(:note, noteable: incident, project: project, author: user) } + let_it_be(:guest) { create(:user) } + let_it_be(:developer) { create(:user) } + let_it_be(:user) { developer } + let(:author) { developer } + let(:description) { "# Description header\n\n**Lorem** _ipsum_ dolor sit [amet](https://example.com)" } + let(:incident) { create(:incident, project: project, description: description, author: author) } before_all do - project.add_developer(user) + project.add_developer(developer) + project.add_guest(guest) end before do @@ -18,57 +22,61 @@ RSpec.describe "User views incident" do visit(project_issues_incident_path(project, incident)) end - it { expect(page).to have_header_with_correct_id_and_link(1, "Description header", "description-header") } + specify do + expect(page).to have_header_with_correct_id_and_link(1, 'Description header', 'description-header') + end it_behaves_like 'page meta description', ' Description header Lorem ipsum dolor sit amet' describe 'user actions' do it 'shows the merge request and incident actions', :js, :aggregate_failures do + expected_href = new_project_issue_path(project, + issuable_template: 'incident', + issue: { issue_type: 'incident' }, + add_related_issue: incident.iid) + click_button 'Incident actions' - expect(page).to have_link('New related incident', href: new_project_issue_path(project, { issuable_template: 'incident', issue: { issue_type: 'incident' }, add_related_issue: incident.iid })) + expect(page).to have_link('New related incident', href: expected_href) expect(page).to have_button('Create merge request') expect(page).to have_button('Close incident') end - context 'when user is a guest' do - before do - project.add_guest(user) + context 'when user is guest' do + let(:user) { guest } - login_as(user) + context 'and author' do + let(:author) { guest } - visit(project_issues_incident_path(project, incident)) + it 'does not show the incident actions', :js do + expect(page).not_to have_button('Incident actions') + end end - it 'does not show the incident actions', :js, :aggregate_failures do - expect(page).not_to have_button('Incident actions') + context 'and not author' do + it 'shows incident actions', :js do + click_button 'Incident actions' + + expect(page).to have_link 'Report abuse' + end end end end context 'when the project is archived' do - before do + before_all do project.update!(archived: true) - visit(project_issues_incident_path(project, incident)) end - it 'hides the merge request and incident actions', :aggregate_failures do - expect(page).not_to have_link('New incident') - expect(page).not_to have_button('Create merge request') - expect(page).not_to have_link('Close incident') + it 'does not show the incident actions', :js do + expect(page).not_to have_button('Incident actions') end end describe 'user status' do - subject { visit(project_issues_incident_path(project, incident)) } - context 'when showing status of the author of the incident' do - it_behaves_like 'showing user status' do - let(:user_with_status) { user } - end - end + subject { visit(project_issues_incident_path(project, incident)) } - context 'when showing status of a user who commented on an incident', :js do it_behaves_like 'showing user status' do let(:user_with_status) { user } end diff --git a/spec/features/issues/user_bulk_edits_issues_labels_spec.rb b/spec/features/issues/user_bulk_edits_issues_labels_spec.rb index 4837d13574c..2a201e0bc23 100644 --- a/spec/features/issues/user_bulk_edits_issues_labels_spec.rb +++ b/spec/features/issues/user_bulk_edits_issues_labels_spec.rb @@ -417,7 +417,7 @@ RSpec.describe 'Issues > Labels bulk assignment' do click_button 'Select milestone' wait_for_requests items.map do |item| - click_link item + click_button item end end diff --git a/spec/features/issues/user_bulk_edits_issues_spec.rb b/spec/features/issues/user_bulk_edits_issues_spec.rb index 1ef2918adec..d7fad355cb4 100644 --- a/spec/features/issues/user_bulk_edits_issues_spec.rb +++ b/spec/features/issues/user_bulk_edits_issues_spec.rb @@ -80,7 +80,7 @@ RSpec.describe 'Multiple issue updating from issues#index', :js do click_button 'Edit issues' check 'Select all' click_button 'Select milestone' - click_link milestone.title + click_button milestone.title click_update_issues_button expect(page.find('.issue')).to have_content milestone.title @@ -97,7 +97,7 @@ RSpec.describe 'Multiple issue updating from issues#index', :js do click_button 'Edit issues' check 'Select all' click_button 'Select milestone' - click_link 'No milestone' + click_button 'No milestone' click_update_issues_button expect(find('.issue:first-of-type')).not_to have_text milestone.title diff --git a/spec/features/merge_requests/user_mass_updates_spec.rb b/spec/features/merge_requests/user_mass_updates_spec.rb index cf9760bcd7f..5c3cb098e28 100644 --- a/spec/features/merge_requests/user_mass_updates_spec.rb +++ b/spec/features/merge_requests/user_mass_updates_spec.rb @@ -130,7 +130,7 @@ RSpec.describe 'Merge requests > User mass updates', :js do click_button 'Edit merge requests' check 'Select all' click_button 'Select milestone' - click_link text + click_button text click_update_merge_requests_button end diff --git a/spec/frontend/boards/components/board_app_spec.js b/spec/frontend/boards/components/board_app_spec.js index dee097bfb08..c209f2f82e6 100644 --- a/spec/frontend/boards/components/board_app_spec.js +++ b/spec/frontend/boards/components/board_app_spec.js @@ -28,6 +28,7 @@ describe('BoardApp', () => { store, provide: { ...provide, + fullBoardId: 'gid://gitlab/Board/1', }, }); }; diff --git a/spec/frontend/boards/components/board_content_spec.js b/spec/frontend/boards/components/board_content_spec.js index bb1650cd2cc..bf491029c41 100644 --- a/spec/frontend/boards/components/board_content_spec.js +++ b/spec/frontend/boards/components/board_content_spec.js @@ -1,15 +1,20 @@ import { GlAlert } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; import Vue, { nextTick } from 'vue'; +import VueApollo from 'vue-apollo'; import Draggable from 'vuedraggable'; import Vuex from 'vuex'; +import waitForPromises from 'helpers/wait_for_promises'; +import createMockApollo from 'helpers/mock_apollo_helper'; import EpicsSwimlanes from 'ee_component/boards/components/epics_swimlanes.vue'; import getters from 'ee_else_ce/boards/stores/getters'; +import boardListsQuery from 'ee_else_ce/boards/graphql/board_lists.query.graphql'; import BoardColumn from '~/boards/components/board_column.vue'; import BoardContent from '~/boards/components/board_content.vue'; import BoardContentSidebar from '~/boards/components/board_content_sidebar.vue'; -import { mockLists } from '../mock_data'; +import { mockLists, boardListsQueryResponse } from '../mock_data'; +Vue.use(VueApollo); Vue.use(Vuex); const actions = { @@ -18,6 +23,7 @@ const actions = { describe('BoardContent', () => { let wrapper; + let fakeApollo; window.gon = {}; const defaultState = { @@ -35,19 +41,33 @@ describe('BoardContent', () => { }); }; - const createComponent = ({ state, props = {}, canAdminList = true } = {}) => { + const createComponent = ({ + state, + props = {}, + canAdminList = true, + isApolloBoard = false, + issuableType = 'issue', + boardListQueryHandler = jest.fn().mockResolvedValue(boardListsQueryResponse), + } = {}) => { + fakeApollo = createMockApollo([[boardListsQuery, boardListQueryHandler]]); + const store = createStore({ ...defaultState, ...state, }); wrapper = shallowMount(BoardContent, { + apolloProvider: fakeApollo, propsData: { - lists: mockLists, disabled: false, + boardId: 'gid://gitlab/Board/1', ...props, }, provide: { canAdminList, + boardType: 'group', + fullPath: 'gitlab-org/gitlab', + issuableType, + isApolloBoard, }, store, }); @@ -78,6 +98,7 @@ describe('BoardContent', () => { afterEach(() => { wrapper.destroy(); + fakeApollo = null; }); describe('default', () => { @@ -112,7 +133,7 @@ describe('BoardContent', () => { describe('when issuableType is not issue', () => { beforeEach(() => { - createComponent({ state: { issuableType: 'foo' } }); + createComponent({ issuableType: 'foo' }); }); it('does not render BoardContentSidebar', () => { @@ -139,4 +160,19 @@ describe('BoardContent', () => { expect(wrapper.findComponent(Draggable).exists()).toBe(false); }); }); + + describe('when Apollo boards FF is on', () => { + beforeEach(async () => { + createComponent({ isApolloBoard: true }); + await waitForPromises(); + }); + + it('renders a BoardColumn component per list', () => { + expect(wrapper.findAllComponents(BoardColumn)).toHaveLength(mockLists.length); + }); + + it('renders BoardContentSidebar', () => { + expect(wrapper.findComponent(BoardContentSidebar).exists()).toBe(true); + }); + }); }); diff --git a/spec/frontend/boards/mock_data.js b/spec/frontend/boards/mock_data.js index dc1f3246be0..17dcf5868a2 100644 --- a/spec/frontend/boards/mock_data.js +++ b/spec/frontend/boards/mock_data.js @@ -433,8 +433,11 @@ export const mockList = { label: null, assignee: null, milestone: null, + iteration: null, loading: false, issuesCount: 1, + maxIssueCount: 0, + __typename: 'BoardList', }; export const mockLabelList = { @@ -449,11 +452,15 @@ export const mockLabelList = { color: '#F0AD4E', textColor: '#FFFFFF', description: null, + descriptionHtml: null, }, assignee: null, milestone: null, + iteration: null, loading: false, issuesCount: 0, + maxIssueCount: 0, + __typename: 'BoardList', }; export const mockMilestoneList = { @@ -844,6 +851,22 @@ export const mockGroupLabelsResponse = { }, }; +export const boardListsQueryResponse = { + data: { + group: { + id: 'gid://gitlab/Group/1', + board: { + id: 'gid://gitlab/Board/1', + hideBacklogList: false, + lists: { + nodes: mockLists, + }, + }, + __typename: 'Group', + }, + }, +}; + export const boardListQueryResponse = (issuesCount = 20) => ({ data: { boardList: { diff --git a/spec/frontend/pipelines/components/pipeline_tabs_spec.js b/spec/frontend/pipelines/components/pipeline_tabs_spec.js index 3680d9d62c7..c2cb95d4320 100644 --- a/spec/frontend/pipelines/components/pipeline_tabs_spec.js +++ b/spec/frontend/pipelines/components/pipeline_tabs_spec.js @@ -2,10 +2,6 @@ import { shallowMount } from '@vue/test-utils'; import { GlTab } from '@gitlab/ui'; import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import PipelineTabs from '~/pipelines/components/pipeline_tabs.vue'; -import PipelineGraphWrapper from '~/pipelines/components/graph/graph_component_wrapper.vue'; -import Dag from '~/pipelines/components/dag/dag.vue'; -import JobsApp from '~/pipelines/components/jobs/jobs_app.vue'; -import TestReports from '~/pipelines/components/test_reports/test_reports.vue'; describe('The Pipeline Tabs', () => { let wrapper; @@ -16,12 +12,6 @@ describe('The Pipeline Tabs', () => { const findPipelineTab = () => wrapper.findByTestId('pipeline-tab'); const findTestsTab = () => wrapper.findByTestId('tests-tab'); - const findDagApp = () => wrapper.findComponent(Dag); - const findFailedJobsApp = () => wrapper.findComponent(JobsApp); - const findJobsApp = () => wrapper.findComponent(JobsApp); - const findPipelineApp = () => wrapper.findComponent(PipelineGraphWrapper); - const findTestsApp = () => wrapper.findComponent(TestReports); - const findFailedJobsBadge = () => wrapper.findByTestId('failed-builds-counter'); const findJobsBadge = () => wrapper.findByTestId('builds-counter'); const findTestsBadge = () => wrapper.findByTestId('tests-counter'); @@ -43,6 +33,7 @@ describe('The Pipeline Tabs', () => { }, stubs: { GlTab, + RouterView: true, }, }), ); @@ -54,17 +45,16 @@ describe('The Pipeline Tabs', () => { describe('Tabs', () => { it.each` - tabName | tabComponent | appComponent - ${'Pipeline'} | ${findPipelineTab} | ${findPipelineApp} - ${'Dag'} | ${findDagTab} | ${findDagApp} - ${'Jobs'} | ${findJobsTab} | ${findJobsApp} - ${'Failed Jobs'} | ${findFailedJobsTab} | ${findFailedJobsApp} - ${'Tests'} | ${findTestsTab} | ${findTestsApp} - `('shows $tabName tab with its associated component', ({ appComponent, tabComponent }) => { + tabName | tabComponent + ${'Pipeline'} | ${findPipelineTab} + ${'Dag'} | ${findDagTab} + ${'Jobs'} | ${findJobsTab} + ${'Failed Jobs'} | ${findFailedJobsTab} + ${'Tests'} | ${findTestsTab} + `('shows $tabName tab', ({ tabComponent }) => { createComponent(); expect(tabComponent().exists()).toBe(true); - expect(appComponent().exists()).toBe(true); }); describe('with no failed jobs', () => { diff --git a/spec/frontend/pipelines/pipeline_graph/utils_spec.js b/spec/frontend/pipelines/pipeline_graph/utils_spec.js index d6b13da3c3a..41b020189d0 100644 --- a/spec/frontend/pipelines/pipeline_graph/utils_spec.js +++ b/spec/frontend/pipelines/pipeline_graph/utils_spec.js @@ -1,5 +1,5 @@ import { createJobsHash, generateJobNeedsDict, getPipelineDefaultTab } from '~/pipelines/utils'; -import { TAB_QUERY_PARAM, validPipelineTabNames } from '~/pipelines/constants'; +import { validPipelineTabNames } from '~/pipelines/constants'; describe('utils functions', () => { const jobName1 = 'build_1'; @@ -173,18 +173,25 @@ describe('utils functions', () => { describe('getPipelineDefaultTab', () => { const baseUrl = 'http://gitlab.com/user/multi-projects-small/-/pipelines/332/'; - it('returns null if there was no `tab` params', () => { + it('returns null if there is only the base url', () => { expect(getPipelineDefaultTab(baseUrl)).toBe(null); }); - it('returns null if there was no valid tab param', () => { - expect(getPipelineDefaultTab(`${baseUrl}?${TAB_QUERY_PARAM}=invalid`)).toBe(null); + it('returns null if there was no valid last url part', () => { + expect(getPipelineDefaultTab(`${baseUrl}something`)).toBe(null); }); it('returns the correct tab name if present', () => { validPipelineTabNames.forEach((tabName) => { - expect(getPipelineDefaultTab(`${baseUrl}?${TAB_QUERY_PARAM}=${tabName}`)).toBe(tabName); + expect(getPipelineDefaultTab(`${baseUrl}${tabName}`)).toBe(tabName); }); }); + + it('returns the right value even with query params', () => { + const [tabName] = validPipelineTabNames; + expect(getPipelineDefaultTab(`${baseUrl}${tabName}?query="something"&query2="else"`)).toBe( + tabName, + ); + }); }); }); diff --git a/spec/frontend/pipelines/pipeline_tabs_spec.js b/spec/frontend/pipelines/pipeline_tabs_spec.js index b184ce31d20..099748a5cca 100644 --- a/spec/frontend/pipelines/pipeline_tabs_spec.js +++ b/spec/frontend/pipelines/pipeline_tabs_spec.js @@ -1,9 +1,7 @@ -import { createAppOptions, createPipelineTabs } from '~/pipelines/pipeline_tabs'; -import { updateHistory } from '~/lib/utils/url_utility'; +import { createAppOptions } from '~/pipelines/pipeline_tabs'; jest.mock('~/lib/utils/url_utility', () => ({ removeParams: () => 'gitlab.com', - updateHistory: jest.fn(), joinPaths: () => {}, setUrlFragment: () => {}, })); @@ -64,32 +62,4 @@ describe('~/pipelines/pipeline_tabs.js', () => { expect(createAppOptions('foo', null)).toBe(null); }); }); - - describe('createPipelineTabs', () => { - const title = 'Pipeline Tabs'; - - beforeAll(() => { - document.title = title; - }); - - afterAll(() => { - document.title = ''; - }); - - it('calls `updateHistory` with correct params', () => { - createPipelineTabs({}); - - expect(updateHistory).toHaveBeenCalledWith({ - title, - url: 'gitlab.com', - replace: true, - }); - }); - - it("returns early if options aren't provided", () => { - createPipelineTabs(); - - expect(updateHistory).not.toHaveBeenCalled(); - }); - }); }); diff --git a/spec/frontend/sidebar/components/milestone/bulk_update_milestone_dropdown_spec.js b/spec/frontend/sidebar/components/milestone/bulk_update_milestone_dropdown_spec.js new file mode 100644 index 00000000000..03b2a3ca728 --- /dev/null +++ b/spec/frontend/sidebar/components/milestone/bulk_update_milestone_dropdown_spec.js @@ -0,0 +1,74 @@ +import { shallowMount } from '@vue/test-utils'; +import { nextTick } from 'vue'; +import { getIdFromGraphQLId } from '~/graphql_shared/utils'; +import { IssuableType, WorkspaceType } from '~/issues/constants'; +import { __ } from '~/locale'; +import BulkUpdateMilestoneDropdown from '~/sidebar/components/milestone/bulk_update_milestone_dropdown.vue'; +import SidebarDropdown from '~/sidebar/components/sidebar_dropdown.vue'; + +describe('BulkUpdateMilestoneDropdown component', () => { + let wrapper; + + const propsData = { + attrWorkspacePath: 'full/path', + issuableType: IssuableType.Issue, + workspaceType: WorkspaceType.project, + }; + + const findHiddenInput = () => wrapper.find('input'); + const findSidebarDropdown = () => wrapper.findComponent(SidebarDropdown); + + const createComponent = () => { + wrapper = shallowMount(BulkUpdateMilestoneDropdown, { propsData }); + }; + + beforeEach(() => { + createComponent(); + }); + + it('renders SidebarDropdown', () => { + expect(findSidebarDropdown().props()).toMatchObject({ + attrWorkspacePath: propsData.attrWorkspacePath, + issuableAttribute: BulkUpdateMilestoneDropdown.issuableAttribute, + issuableType: propsData.issuableType, + workspaceType: propsData.workspaceType, + }); + }); + + it('renders hidden input', () => { + expect(findHiddenInput().attributes()).toEqual({ + type: 'hidden', + name: 'update[milestone_id]', + value: undefined, + }); + }); + + describe('when SidebarDropdown emits `change` event', () => { + describe('when valid milestone is emitted', () => { + it('updates the hidden input value', async () => { + const milestone = { + id: 'gid://gitlab/Milestone/52', + title: __('Milestone 52'), + }; + + findSidebarDropdown().vm.$emit('change', milestone); + await nextTick(); + + expect(findHiddenInput().attributes('value')).toBe( + getIdFromGraphQLId(milestone.id).toString(), + ); + }); + }); + + describe('when null milestone is emitted', () => { + it('updates the hidden input value to `0`', async () => { + const milestone = { id: null }; + + findSidebarDropdown().vm.$emit('change', milestone); + await nextTick(); + + expect(findHiddenInput().attributes('value')).toBe('0'); + }); + }); + }); +}); diff --git a/spec/helpers/projects/pipeline_helper_spec.rb b/spec/helpers/projects/pipeline_helper_spec.rb index a70544ace1a..0d3466d6ed2 100644 --- a/spec/helpers/projects/pipeline_helper_spec.rb +++ b/spec/helpers/projects/pipeline_helper_spec.rb @@ -31,6 +31,7 @@ RSpec.describe Projects::PipelineHelper do suite_endpoint: project_pipeline_test_path(project, pipeline, suite_name: 'suite', format: :json), blob_path: project_blob_path(project, pipeline.sha), has_test_report: pipeline.complete_and_has_reports?(Ci::JobArtifact.of_report_type(:test)), + empty_dag_svg_path: match_asset_path('illustrations/empty-state/empty-dag-md.svg'), empty_state_image_path: match_asset_path('illustrations/empty-state/empty-test-cases-lg.svg'), artifacts_expired_image_path: match_asset_path('illustrations/pipeline.svg'), tests_count: pipeline.test_report_summary.total[:count] diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb index 5bc56f11425..a12cab11293 100644 --- a/spec/lib/gitlab/database/migration_helpers_spec.rb +++ b/spec/lib/gitlab/database/migration_helpers_spec.rb @@ -389,6 +389,40 @@ RSpec.describe Gitlab::Database::MigrationHelpers do model.add_concurrent_index(:users, :foo) end + + context 'when targeting a partition table' do + let(:schema) { 'public' } + let(:name) { '_test_partition_01' } + let(:identifier) { "#{schema}.#{name}" } + + before do + model.execute(<<~SQL) + CREATE TABLE public._test_partitioned_table ( + id serial NOT NULL, + partition_id serial NOT NULL, + PRIMARY KEY (id, partition_id) + ) PARTITION BY LIST(partition_id); + + CREATE TABLE #{identifier} PARTITION OF public._test_partitioned_table + FOR VALUES IN (1); + SQL + end + + context 'when allow_partition is true' do + it 'creates the index concurrently' do + expect(model).to receive(:add_index).with(:_test_partition_01, :foo, algorithm: :concurrently) + + model.add_concurrent_index(:_test_partition_01, :foo, allow_partition: true) + end + end + + context 'when allow_partition is not provided' do + it 'raises ArgumentError' do + expect { model.add_concurrent_index(:_test_partition_01, :foo) } + .to raise_error(ArgumentError, /use add_concurrent_partitioned_index/) + end + end + end end context 'inside a transaction' do @@ -2889,4 +2923,36 @@ RSpec.describe Gitlab::Database::MigrationHelpers do model.add_sequence(:test_table, :test_column, :test_table_id_seq, 1) end end + + describe "#partition?" do + subject { model.partition?(table_name) } + + let(:table_name) { 'ci_builds_metadata' } + + context "when a partition table exist" do + context 'when the view postgres_partitions exists' do + it 'calls the view', :aggregate_failures do + expect(Gitlab::Database::PostgresPartition).to receive(:partition_exists?).with(table_name).and_call_original + expect(subject).to be_truthy + end + end + + context 'when the view postgres_partitions does not exist' do + before do + allow(model).to receive(:view_exists?).and_return(false) + end + + it 'does not call the view', :aggregate_failures do + expect(Gitlab::Database::PostgresPartition).to receive(:legacy_partition_exists?).with(table_name).and_call_original + expect(subject).to be_truthy + end + end + end + + context "when a partition table does not exist" do + let(:table_name) { 'partition_does_not_exist' } + + it { is_expected.to be_falsey } + end + end end diff --git a/spec/lib/gitlab/database/partitioning_migration_helpers/index_helpers_spec.rb b/spec/lib/gitlab/database/partitioning_migration_helpers/index_helpers_spec.rb index 5d02266e8a2..a81c8a5a49c 100644 --- a/spec/lib/gitlab/database/partitioning_migration_helpers/index_helpers_spec.rb +++ b/spec/lib/gitlab/database/partitioning_migration_helpers/index_helpers_spec.rb @@ -65,8 +65,11 @@ RSpec.describe Gitlab::Database::PartitioningMigrationHelpers::IndexHelpers do end def expect_add_concurrent_index_and_call_original(table, column, index) - expect(migration).to receive(:add_concurrent_index).ordered.with(table, column, { name: index }) - .and_wrap_original { |_, table, column, options| connection.add_index(table, column, **options) } + expect(migration).to receive(:add_concurrent_index).ordered.with(table, column, { name: index, allow_partition: true }) + .and_wrap_original do |_, table, column, options| + options.delete(:allow_partition) + connection.add_index(table, column, **options) + end end end @@ -91,7 +94,7 @@ RSpec.describe Gitlab::Database::PartitioningMigrationHelpers::IndexHelpers do it 'forwards them to the index helper methods', :aggregate_failures do expect(migration).to receive(:add_concurrent_index) - .with(partition1_identifier, column_name, { name: partition1_index, where: 'x > 0', unique: true }) + .with(partition1_identifier, column_name, { name: partition1_index, where: 'x > 0', unique: true, allow_partition: true }) expect(migration).to receive(:add_index) .with(table_name, column_name, { name: index_name, where: 'x > 0', unique: true }) diff --git a/spec/lib/gitlab/database/postgres_partition_spec.rb b/spec/lib/gitlab/database/postgres_partition_spec.rb index 5a44090d5ae..14a4d405621 100644 --- a/spec/lib/gitlab/database/postgres_partition_spec.rb +++ b/spec/lib/gitlab/database/postgres_partition_spec.rb @@ -72,4 +72,36 @@ RSpec.describe Gitlab::Database::PostgresPartition, type: :model do expect(find(identifier).condition).to eq("FOR VALUES FROM ('2020-01-01 00:00:00+00') TO ('2020-02-01 00:00:00+00')") end end + + describe '.partition_exists?' do + subject { described_class.partition_exists?(table_name) } + + context 'when the partition exists' do + let(:table_name) { "ci_builds_metadata" } + + it { is_expected.to be_truthy } + end + + context 'when the partition does not exist' do + let(:table_name) { 'partition_does_not_exist' } + + it { is_expected.to be_falsey } + end + end + + describe '.legacy_partition_exists?' do + subject { described_class.legacy_partition_exists?(table_name) } + + context 'when the partition exists' do + let(:table_name) { "ci_builds_metadata" } + + it { is_expected.to be_truthy } + end + + context 'when the partition does not exist' do + let(:table_name) { 'partition_does_not_exist' } + + it { is_expected.to be_falsey } + end + end end diff --git a/spec/lib/gitlab/gon_helper_spec.rb b/spec/lib/gitlab/gon_helper_spec.rb index dd4dcca809b..94192a9257c 100644 --- a/spec/lib/gitlab/gon_helper_spec.rb +++ b/spec/lib/gitlab/gon_helper_spec.rb @@ -39,6 +39,72 @@ RSpec.describe Gitlab::GonHelper do helper.add_gon_variables end end + + describe 'sentry configuration' do + let(:legacy_clientside_dsn) { 'https://xxx@sentry-legacy.example.com/1' } + let(:clientside_dsn) { 'https://xxx@sentry.example.com/1' } + let(:environment) { 'production' } + + context 'with enable_old_sentry_clientside_integration enabled' do + before do + stub_feature_flags( + enable_old_sentry_clientside_integration: true, + enable_new_sentry_clientside_integration: false + ) + + stub_config(sentry: { enabled: true, clientside_dsn: legacy_clientside_dsn, environment: environment }) + end + + it 'sets sentry dsn and environment from config' do + expect(gon).to receive(:sentry_dsn=).with(legacy_clientside_dsn) + expect(gon).to receive(:sentry_environment=).with(environment) + + helper.add_gon_variables + end + end + + context 'with enable_new_sentry_clientside_integration enabled' do + before do + stub_feature_flags( + enable_old_sentry_clientside_integration: false, + enable_new_sentry_clientside_integration: true + ) + + stub_application_setting(sentry_enabled: true) + stub_application_setting(sentry_clientside_dsn: clientside_dsn) + stub_application_setting(sentry_environment: environment) + end + + it 'sets sentry dsn and environment from application settings' do + expect(gon).to receive(:sentry_dsn=).with(clientside_dsn) + expect(gon).to receive(:sentry_environment=).with(environment) + + helper.add_gon_variables + end + end + + context 'with enable_old_sentry_clientside_integration and enable_new_sentry_clientside_integration enabled' do + before do + stub_feature_flags( + enable_old_sentry_clientside_integration: true, + enable_new_sentry_clientside_integration: true + ) + + stub_config(sentry: { enabled: true, clientside_dsn: legacy_clientside_dsn, environment: environment }) + + stub_application_setting(sentry_enabled: true) + stub_application_setting(sentry_clientside_dsn: clientside_dsn) + stub_application_setting(sentry_environment: environment) + end + + it 'sets sentry dsn and environment from application settings' do + expect(gon).to receive(:sentry_dsn=).with(clientside_dsn) + expect(gon).to receive(:sentry_environment=).with(environment) + + helper.add_gon_variables + end + end + end end describe '#push_frontend_feature_flag' do diff --git a/spec/models/alert_management/http_integration_spec.rb b/spec/models/alert_management/http_integration_spec.rb index f88a66a7c27..b453b3a82e0 100644 --- a/spec/models/alert_management/http_integration_spec.rb +++ b/spec/models/alert_management/http_integration_spec.rb @@ -13,6 +13,11 @@ RSpec.describe AlertManagement::HttpIntegration do it { is_expected.to belong_to(:project) } end + describe 'default values' do + it { expect(described_class.new.endpoint_identifier).to be_present } + it { expect(described_class.new(endpoint_identifier: 'test').endpoint_identifier).to eq('test') } + end + describe 'validations' do it { is_expected.to validate_presence_of(:project) } it { is_expected.to validate_presence_of(:name) } @@ -124,10 +129,6 @@ RSpec.describe AlertManagement::HttpIntegration do end context 'when unsaved' do - context 'when unassigned' do - it_behaves_like 'valid token' - end - context 'when assigned' do include_context 'assign token', 'random_token' diff --git a/spec/support/rspec_order_todo.yml b/spec/support/rspec_order_todo.yml index b8fe8412d55..77d36cbee62 100644 --- a/spec/support/rspec_order_todo.yml +++ b/spec/support/rspec_order_todo.yml @@ -4089,7 +4089,6 @@ - './spec/features/incidents/user_creates_new_incident_spec.rb' - './spec/features/incidents/user_filters_incidents_by_status_spec.rb' - './spec/features/incidents/user_searches_incidents_spec.rb' -- './spec/features/incidents/user_views_incident_spec.rb' - './spec/features/invites_spec.rb' - './spec/features/issuables/issuable_list_spec.rb' - './spec/features/issuables/markdown_references/internal_references_spec.rb' diff --git a/spec/support/shared_examples/boards/multiple_issue_boards_shared_examples.rb b/spec/support/shared_examples/boards/multiple_issue_boards_shared_examples.rb index fa048b76e18..7df4b7635d3 100644 --- a/spec/support/shared_examples/boards/multiple_issue_boards_shared_examples.rb +++ b/spec/support/shared_examples/boards/multiple_issue_boards_shared_examples.rb @@ -3,6 +3,7 @@ RSpec.shared_examples 'multiple issue boards' do context 'authorized user' do before do + stub_feature_flags(apollo_boards: false) parent.add_maintainer(user) login_as(user) @@ -121,6 +122,7 @@ RSpec.shared_examples 'multiple issue boards' do context 'unauthorized user' do before do + stub_feature_flags(apollo_boards: false) visit boards_path wait_for_requests end diff --git a/spec/support/shared_examples/requests/api/multiple_and_scoped_issue_boards_shared_examples.rb b/spec/support/shared_examples/requests/api/multiple_and_scoped_issue_boards_shared_examples.rb index fa111ca5811..d749479544d 100644 --- a/spec/support/shared_examples/requests/api/multiple_and_scoped_issue_boards_shared_examples.rb +++ b/spec/support/shared_examples/requests/api/multiple_and_scoped_issue_boards_shared_examples.rb @@ -5,6 +5,7 @@ RSpec.shared_examples 'multiple and scoped issue boards' do |route_definition| context 'multiple issue boards' do before do + stub_feature_flags(apollo_boards: false) board_parent.add_reporter(user) stub_licensed_features(multiple_group_issue_boards: true) end |