diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-28 15:11:48 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-28 15:11:48 +0000 |
commit | baed745d21710f1d78ece03558873acd6fd7d358 (patch) | |
tree | 628622c816195894985d03ab01f55abe7c6ac7ca /spec | |
parent | 22ecb1e3fc02bb923c3e9941b1baa849348a036f (diff) | |
download | gitlab-ce-baed745d21710f1d78ece03558873acd6fd7d358.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
26 files changed, 270 insertions, 69 deletions
diff --git a/spec/controllers/projects/branches_controller_spec.rb b/spec/controllers/projects/branches_controller_spec.rb index 55c148bb66f..600f8047a1d 100644 --- a/spec/controllers/projects/branches_controller_spec.rb +++ b/spec/controllers/projects/branches_controller_spec.rb @@ -277,6 +277,7 @@ RSpec.describe Projects::BranchesController, feature_category: :source_code_mana create_branch name: "<script>alert('merge');</script>", ref: "<script>alert('ref');</script>" expect(response).to have_gitlab_http_status(:unprocessable_entity) + expect(response.body).to include 'Failed to create branch' end end diff --git a/spec/db/schema_spec.rb b/spec/db/schema_spec.rb index 756cb23b7a4..f10adfe5173 100644 --- a/spec/db/schema_spec.rb +++ b/spec/db/schema_spec.rb @@ -36,7 +36,7 @@ RSpec.describe 'Database schema', feature_category: :database do ci_build_pending_states: %w[partition_id build_id], ci_build_report_results: %w[partition_id build_id], ci_build_trace_chunks: %w[partition_id build_id], - ci_build_trace_metadata: %w[partition_id], + ci_build_trace_metadata: %w[partition_id build_id], ci_builds: %w[erased_by_id trigger_request_id partition_id], ci_builds_runner_session: %w[partition_id build_id], p_ci_builds_metadata: %w[partition_id], diff --git a/spec/factories/ci/runner_machine_builds.rb b/spec/factories/ci/runner_machine_builds.rb new file mode 100644 index 00000000000..0181def26ba --- /dev/null +++ b/spec/factories/ci/runner_machine_builds.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :ci_runner_machine_build, class: 'Ci::RunnerMachineBuild' do + build factory: :ci_build, scheduling_type: :dag + runner_machine factory: :ci_runner_machine + end +end diff --git a/spec/features/incidents/incident_timeline_events_spec.rb b/spec/features/incidents/incident_timeline_events_spec.rb index 7404ac64cc9..a4449ee2608 100644 --- a/spec/features/incidents/incident_timeline_events_spec.rb +++ b/spec/features/incidents/incident_timeline_events_spec.rb @@ -96,5 +96,6 @@ RSpec.describe 'Incident timeline events', :js, feature_category: :incident_mana it_behaves_like 'for each incident details route', 'add, edit, and delete timeline events', - tab_text: s_('Incident|Timeline') + tab_text: s_('Incident|Timeline'), + tab: 'timeline' end diff --git a/spec/features/incidents/user_views_alert_details_spec.rb b/spec/features/incidents/user_views_alert_details_spec.rb new file mode 100644 index 00000000000..f3d0273071c --- /dev/null +++ b/spec/features/incidents/user_views_alert_details_spec.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'User uploads alerts to incident', :js, feature_category: :incident_management do + let_it_be(:incident) { create(:incident) } + let_it_be(:project) { incident.project } + let_it_be(:user) { create(:user, developer_projects: [project]) } + + context 'with alert' do + let_it_be(:alert) { create(:alert_management_alert, issue_id: incident.id, project: project) } + + shared_examples 'shows alert tab with details' do + specify do + expect(page).to have_link(s_('Incident|Alert details')) + expect(page).to have_content(alert.title) + end + end + + it_behaves_like 'for each incident details route', + 'shows alert tab with details', + tab_text: s_('Incident|Alert details'), + tab: 'alerts' + end + + context 'with no alerts' do + it 'hides the Alert details tab' do + sign_in(user) + visit project_issue_path(project, incident) + + expect(page).not_to have_link(s_('Incident|Alert details')) + end + end +end diff --git a/spec/frontend/boards/components/board_top_bar_spec.js b/spec/frontend/boards/components/board_top_bar_spec.js index faf1547c47e..002e4034e70 100644 --- a/spec/frontend/boards/components/board_top_bar_spec.js +++ b/spec/frontend/boards/components/board_top_bar_spec.js @@ -11,7 +11,7 @@ import ConfigToggle from '~/boards/components/config_toggle.vue'; import IssueBoardFilteredSearch from '~/boards/components/issue_board_filtered_search.vue'; import NewBoardButton from '~/boards/components/new_board_button.vue'; import ToggleFocus from '~/boards/components/toggle_focus.vue'; -import { BoardType } from '~/boards/constants'; +import { WORKSPACE_GROUP, WORKSPACE_PROJECT } from '~/issues/constants'; import groupBoardQuery from '~/boards/graphql/group_board.query.graphql'; import projectBoardQuery from '~/boards/graphql/project_board.query.graphql'; @@ -116,14 +116,14 @@ describe('BoardTopBar', () => { describe('Apollo boards', () => { it.each` boardType | queryHandler | notCalledHandler - ${BoardType.group} | ${groupBoardQueryHandlerSuccess} | ${projectBoardQueryHandlerSuccess} - ${BoardType.project} | ${projectBoardQueryHandlerSuccess} | ${groupBoardQueryHandlerSuccess} + ${WORKSPACE_GROUP} | ${groupBoardQueryHandlerSuccess} | ${projectBoardQueryHandlerSuccess} + ${WORKSPACE_PROJECT} | ${projectBoardQueryHandlerSuccess} | ${groupBoardQueryHandlerSuccess} `('fetches $boardType boards', async ({ boardType, queryHandler, notCalledHandler }) => { createComponent({ provide: { boardType, - isProjectBoard: boardType === BoardType.project, - isGroupBoard: boardType === BoardType.group, + isProjectBoard: boardType === WORKSPACE_PROJECT, + isGroupBoard: boardType === WORKSPACE_GROUP, isApolloBoard: true, }, }); diff --git a/spec/frontend/boards/components/boards_selector_spec.js b/spec/frontend/boards/components/boards_selector_spec.js index 28f51e0ecbf..afa304a66ff 100644 --- a/spec/frontend/boards/components/boards_selector_spec.js +++ b/spec/frontend/boards/components/boards_selector_spec.js @@ -5,11 +5,11 @@ import Vuex from 'vuex'; import waitForPromises from 'helpers/wait_for_promises'; import { TEST_HOST } from 'spec/test_constants'; import BoardsSelector from '~/boards/components/boards_selector.vue'; -import { BoardType } from '~/boards/constants'; import groupBoardsQuery from '~/boards/graphql/group_boards.query.graphql'; import projectBoardsQuery from '~/boards/graphql/project_boards.query.graphql'; import groupRecentBoardsQuery from '~/boards/graphql/group_recent_boards.query.graphql'; import projectRecentBoardsQuery from '~/boards/graphql/project_recent_boards.query.graphql'; +import { WORKSPACE_GROUP, WORKSPACE_PROJECT } from '~/issues/constants'; import createMockApollo from 'helpers/mock_apollo_helper'; import { mountExtended } from 'helpers/vue_test_utils_helper'; import { @@ -228,13 +228,13 @@ describe('BoardsSelector', () => { describe('fetching all boards', () => { it.each` boardType | queryHandler | notCalledHandler - ${BoardType.group} | ${groupBoardsQueryHandlerSuccess} | ${projectBoardsQueryHandlerSuccess} - ${BoardType.project} | ${projectBoardsQueryHandlerSuccess} | ${groupBoardsQueryHandlerSuccess} + ${WORKSPACE_GROUP} | ${groupBoardsQueryHandlerSuccess} | ${projectBoardsQueryHandlerSuccess} + ${WORKSPACE_PROJECT} | ${projectBoardsQueryHandlerSuccess} | ${groupBoardsQueryHandlerSuccess} `('fetches $boardType boards', async ({ boardType, queryHandler, notCalledHandler }) => { createStore(); createComponent({ - isGroupBoard: boardType === BoardType.group, - isProjectBoard: boardType === BoardType.project, + isGroupBoard: boardType === WORKSPACE_GROUP, + isProjectBoard: boardType === WORKSPACE_PROJECT, }); await nextTick(); diff --git a/spec/frontend/boards/stores/actions_spec.js b/spec/frontend/boards/stores/actions_spec.js index b830ca1126d..13eb3865354 100644 --- a/spec/frontend/boards/stores/actions_spec.js +++ b/spec/frontend/boards/stores/actions_spec.js @@ -2,13 +2,7 @@ import * as Sentry from '@sentry/browser'; import { cloneDeep } from 'lodash'; import Vue from 'vue'; import Vuex from 'vuex'; -import { - inactiveId, - ISSUABLE, - ListType, - BoardType, - DraggableItemTypes, -} from 'ee_else_ce/boards/constants'; +import { inactiveId, ISSUABLE, ListType, DraggableItemTypes } from 'ee_else_ce/boards/constants'; import issueMoveListMutation from 'ee_else_ce/boards/graphql/issue_move_list.mutation.graphql'; import testAction from 'helpers/vuex_action_helper'; import { @@ -26,7 +20,7 @@ import actions from '~/boards/stores/actions'; import * as types from '~/boards/stores/mutation_types'; import mutations from '~/boards/stores/mutations'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; -import { TYPE_ISSUE } from '~/issues/constants'; +import { TYPE_ISSUE, WORKSPACE_GROUP, WORKSPACE_PROJECT } from '~/issues/constants'; import projectBoardMilestones from '~/boards/graphql/project_board_milestones.query.graphql'; import groupBoardMilestones from '~/boards/graphql/group_board_milestones.query.graphql'; @@ -300,8 +294,8 @@ describe('fetchLists', () => { it.each` issuableType | boardType | fullBoardId | isGroup | isProject - ${TYPE_ISSUE} | ${BoardType.group} | ${'gid://gitlab/Board/1'} | ${true} | ${false} - ${TYPE_ISSUE} | ${BoardType.project} | ${'gid://gitlab/Board/1'} | ${false} | ${true} + ${TYPE_ISSUE} | ${WORKSPACE_GROUP} | ${'gid://gitlab/Board/1'} | ${true} | ${false} + ${TYPE_ISSUE} | ${WORKSPACE_PROJECT} | ${'gid://gitlab/Board/1'} | ${false} | ${true} `( 'calls $issuableType query with correct variables', async ({ issuableType, boardType, fullBoardId, isGroup, isProject }) => { diff --git a/spec/frontend/issues/show/components/incidents/incident_tabs_spec.js b/spec/frontend/issues/show/components/incidents/incident_tabs_spec.js index 380b4b92f2e..0f4fb02a40b 100644 --- a/spec/frontend/issues/show/components/incidents/incident_tabs_spec.js +++ b/spec/frontend/issues/show/components/incidents/incident_tabs_spec.js @@ -1,4 +1,5 @@ import merge from 'lodash/merge'; +import { nextTick } from 'vue'; import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { trackIncidentDetailsViewsOptions } from '~/incidents/constants'; import DescriptionComponent from '~/issues/show/components/description.vue'; @@ -11,6 +12,11 @@ import Tracking from '~/tracking'; import AlertDetailsTable from '~/vue_shared/components/alert_details_table.vue'; import { descriptionProps } from '../../mock_data/mock_data'; +const push = jest.fn(); +const $router = { + push, +}; + const mockAlert = { __typename: 'AlertManagementAlert', detailsUrl: INVALID_URL, @@ -28,6 +34,8 @@ const defaultMocks = { }, }, }, + $route: { params: {} }, + $router, }; describe('Incident Tabs component', () => { @@ -165,6 +173,40 @@ describe('Incident Tabs component', () => { expect(findActiveTabs()).toHaveLength(1); expect(findActiveTabs().at(0).text()).toBe(incidentTabsI18n.timelineTitle); + expect(push).toHaveBeenCalledWith('/timeline'); + }); + }); + + describe('loading page with tab', () => { + it('shows the timeline tab when timeline path is passed', async () => { + mountComponent({ + mount: mountExtended, + mocks: { $route: { params: { tabId: 'timeline' } } }, + }); + await nextTick(); + expect(findActiveTabs()).toHaveLength(1); + expect(findActiveTabs().at(0).text()).toBe(incidentTabsI18n.timelineTitle); + }); + + it('shows the alerts tab when timeline path is passed', async () => { + mountComponent({ + mount: mountExtended, + mocks: { $route: { params: { tabId: 'alerts' } } }, + hasLinkedAlerts: true, + }); + await nextTick(); + expect(findActiveTabs()).toHaveLength(1); + expect(findActiveTabs().at(0).text()).toBe(incidentTabsI18n.alertsTitle); + }); + + it('shows the metrics tab when metrics path is passed', async () => { + mountComponent({ + mount: mountExtended, + mocks: { $route: { params: { tabId: 'metrics' } } }, + }); + await nextTick(); + expect(findActiveTabs()).toHaveLength(1); + expect(findActiveTabs().at(0).text()).toBe(incidentTabsI18n.metricsTitle); }); }); }); diff --git a/spec/helpers/issuables_helper_spec.rb b/spec/helpers/issuables_helper_spec.rb index 1ae834c0769..d5fff7f3a31 100644 --- a/spec/helpers/issuables_helper_spec.rb +++ b/spec/helpers/issuables_helper_spec.rb @@ -430,7 +430,8 @@ RSpec.describe IssuablesHelper, feature_category: :team_planning do action: "show", namespace_id: "foo", project_id: "bar", - id: incident.iid + id: incident.iid, + incident_tab: 'timeline' }).permit! end @@ -441,7 +442,9 @@ RSpec.describe IssuablesHelper, feature_category: :team_planning do expected_data = { issueType: 'incident', hasLinkedAlerts: false, - canUpdateTimelineEvent: true + canUpdateTimelineEvent: true, + currentPath: "/foo/bar/-/issues/incident/#{incident.iid}/timeline", + currentTab: 'timeline' } expect(helper.issuable_initial_data(incident)).to match(hash_including(expected_data)) diff --git a/spec/lib/gitlab/database/schema_validation/runner_spec.rb b/spec/lib/gitlab/database/schema_validation/runner_spec.rb index e07deec3062..13980cb148b 100644 --- a/spec/lib/gitlab/database/schema_validation/runner_spec.rb +++ b/spec/lib/gitlab/database/schema_validation/runner_spec.rb @@ -32,7 +32,7 @@ RSpec.describe Gitlab::Database::SchemaValidation::Runner, feature_category: :da let(:extra_indexes) { class_double(class_name) } let(:instace_extra_index) { instance_double(class_name, execute: [inconsistency]) } - let(:inconsistency) { instance_double(inconsistency_class_name, name: 'test') } + let(:inconsistency) { instance_double(inconsistency_class_name, object_name: 'test') } let(:validators) { [extra_indexes] } @@ -43,7 +43,7 @@ RSpec.describe Gitlab::Database::SchemaValidation::Runner, feature_category: :da expect(validator).not_to receive(:new).with(structure_sql, database) end - expect(inconsistencies.map(&:name)).to eql ['test'] + expect(inconsistencies.map(&:object_name)).to eql ['test'] end end end diff --git a/spec/lib/gitlab/database/schema_validation/validators/base_validator_spec.rb b/spec/lib/gitlab/database/schema_validation/validators/base_validator_spec.rb index adac5b4e579..cf5207aee95 100644 --- a/spec/lib/gitlab/database/schema_validation/validators/base_validator_spec.rb +++ b/spec/lib/gitlab/database/schema_validation/validators/base_validator_spec.rb @@ -10,7 +10,7 @@ RSpec.describe Gitlab::Database::SchemaValidation::Validators::BaseValidator, fe expect(all_validators).to eq([ Gitlab::Database::SchemaValidation::Validators::ExtraIndexes, Gitlab::Database::SchemaValidation::Validators::MissingIndexes, - Gitlab::Database::SchemaValidation::Validators::WrongIndexes + Gitlab::Database::SchemaValidation::Validators::DifferentDefinitionIndexes ]) end end diff --git a/spec/lib/gitlab/database/schema_validation/validators/wrong_indexes_spec.rb b/spec/lib/gitlab/database/schema_validation/validators/different_definition_indexes_spec.rb index 026f3fb710c..b9744c86b80 100644 --- a/spec/lib/gitlab/database/schema_validation/validators/wrong_indexes_spec.rb +++ b/spec/lib/gitlab/database/schema_validation/validators/different_definition_indexes_spec.rb @@ -2,6 +2,7 @@ require 'spec_helper' -RSpec.describe Gitlab::Database::SchemaValidation::Validators::WrongIndexes, feature_category: :database do +RSpec.describe Gitlab::Database::SchemaValidation::Validators::DifferentDefinitionIndexes, + feature_category: :database do include_examples 'index validators', described_class, ['wrong_index'] end diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index a22b9d11214..73f29f6debe 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -297,6 +297,7 @@ ci_pipelines: - job_artifacts - vulnerabilities_finding_pipelines - vulnerability_findings +- vulnerability_state_transitions - pipeline_config - security_scans - security_findings @@ -396,6 +397,7 @@ builds: - job_artifacts_cyclonedx - job_artifacts_requirements_v2 - runner_machine +- runner_machine_build - runner_session - trace_metadata - terraform_state_versions diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/index_inconsistencies_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/index_inconsistencies_metric_spec.rb new file mode 100644 index 00000000000..afc9d610207 --- /dev/null +++ b/spec/lib/gitlab/usage/metrics/instrumentations/index_inconsistencies_metric_spec.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Usage::Metrics::Instrumentations::IndexInconsistenciesMetric, feature_category: :database do + it_behaves_like 'a correct instrumented metric value', { time_frame: 'all' } do + let(:expected_value) do + [ + { inconsistency_type: 'wrong_indexes', object_name: 'index_name_1' }, + { inconsistency_type: 'missing_indexes', object_name: 'index_name_2' }, + { inconsistency_type: 'extra_indexes', object_name: 'index_name_3' } + ] + end + + let(:runner) { instance_double(Gitlab::Database::SchemaValidation::Runner, execute: inconsistencies) } + let(:inconsistency_class) { Gitlab::Database::SchemaValidation::Validators::BaseValidator::Inconsistency } + + let(:inconsistencies) do + [ + instance_double(inconsistency_class, object_name: 'index_name_1', type: 'wrong_indexes'), + instance_double(inconsistency_class, object_name: 'index_name_2', type: 'missing_indexes'), + instance_double(inconsistency_class, object_name: 'index_name_3', type: 'extra_indexes') + ] + end + + before do + allow(Gitlab::Database::SchemaValidation::Runner).to receive(:new).and_return(runner) + end + end +end diff --git a/spec/models/ci/build_metadata_spec.rb b/spec/models/ci/build_metadata_spec.rb index fb50ba89cd3..c3b445cbbe5 100644 --- a/spec/models/ci/build_metadata_spec.rb +++ b/spec/models/ci/build_metadata_spec.rb @@ -22,7 +22,6 @@ RSpec.describe Ci::BuildMetadata do it { is_expected.to belong_to(:build) } it { is_expected.to belong_to(:project) } - it { is_expected.to belong_to(:runner_machine) } describe '#update_timeout_state' do subject { metadata } diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index 29cc94ff13f..6836d1b51ef 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -31,7 +31,7 @@ RSpec.describe Ci::Build, feature_category: :continuous_integration, factory_def it { is_expected.to have_many(:pages_deployments).with_foreign_key(:ci_build_id) } it { is_expected.to have_one(:deployment) } - it { is_expected.to have_one(:runner_machine).through(:metadata) } + it { is_expected.to have_one(:runner_machine).through(:runner_machine_build) } it { is_expected.to have_one(:runner_session).with_foreign_key(:build_id) } it { is_expected.to have_one(:trace_metadata).with_foreign_key(:build_id) } it { is_expected.to have_one(:runtime_metadata).with_foreign_key(:build_id) } diff --git a/spec/models/ci/processable_spec.rb b/spec/models/ci/processable_spec.rb index db22d8f3a6c..cf2c176816d 100644 --- a/spec/models/ci/processable_spec.rb +++ b/spec/models/ci/processable_spec.rb @@ -83,7 +83,7 @@ RSpec.describe Ci::Processable, feature_category: :continuous_integration do runner_id tag_taggings taggings tags trigger_request_id user_id auto_canceled_by_id retried failure_reason sourced_pipelines sourced_pipeline artifacts_file_store artifacts_metadata_store - metadata runner_machine_id runner_machine runner_session trace_chunks upstream_pipeline_id + metadata runner_machine_build runner_machine runner_session trace_chunks upstream_pipeline_id artifacts_file artifacts_metadata artifacts_size commands resource resource_group_id processed security_scans author pipeline_id report_results pending_state pages_deployments diff --git a/spec/models/ci/runner_machine_build_spec.rb b/spec/models/ci/runner_machine_build_spec.rb new file mode 100644 index 00000000000..b15d232cbb5 --- /dev/null +++ b/spec/models/ci/runner_machine_build_spec.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Ci::RunnerMachineBuild, model: true, feature_category: :runner_fleet do + it { is_expected.to belong_to(:build) } + it { is_expected.to belong_to(:runner_machine) } + + describe 'partitioning' do + context 'with build' do + let(:build) { FactoryBot.build(:ci_build, partition_id: ci_testing_partition_id) } + let(:runner_machine_build) { FactoryBot.build(:ci_runner_machine_build, build: build) } + + it 'sets partition_id to the current partition value' do + expect { runner_machine_build.valid? }.to change { runner_machine_build.partition_id } + .to(ci_testing_partition_id) + end + + context 'when it is already set' do + let(:runner_machine_build) { FactoryBot.build(:ci_runner_machine_build, partition_id: 125) } + + it 'does not change the partition_id value' do + expect { runner_machine_build.valid? }.not_to change { runner_machine_build.partition_id } + end + end + end + + context 'without build' do + let(:runner_machine_build) { FactoryBot.build(:ci_runner_machine_build, build: nil) } + + it { is_expected.to validate_presence_of(:partition_id) } + + it 'does not change the partition_id value' do + expect { runner_machine_build.valid? }.not_to change { runner_machine_build.partition_id } + end + end + end + + describe 'ci_sliding_list partitioning' do + let(:connection) { described_class.connection } + let(:partition_manager) { Gitlab::Database::Partitioning::PartitionManager.new(described_class) } + + let(:partitioning_strategy) { described_class.partitioning_strategy } + + it { expect(partitioning_strategy.missing_partitions).to be_empty } + it { expect(partitioning_strategy.extra_partitions).to be_empty } + it { expect(partitioning_strategy.current_partitions).to include partitioning_strategy.initial_partition } + it { expect(partitioning_strategy.active_partition).to be_present } + end +end diff --git a/spec/models/ci/runner_machine_spec.rb b/spec/models/ci/runner_machine_spec.rb index 6162077a055..dbefd7aa449 100644 --- a/spec/models/ci/runner_machine_spec.rb +++ b/spec/models/ci/runner_machine_spec.rb @@ -7,8 +7,8 @@ RSpec.describe Ci::RunnerMachine, feature_category: :runner_fleet, type: :model it { is_expected.to belong_to(:runner) } it { is_expected.to belong_to(:runner_version).with_foreign_key(:version) } - it { is_expected.to have_many(:build_metadata) } - it { is_expected.to have_many(:builds).through(:build_metadata) } + it { is_expected.to have_many(:runner_machine_builds) } + it { is_expected.to have_many(:builds).through(:runner_machine_builds) } describe 'validation' do it { is_expected.to validate_presence_of(:runner) } diff --git a/spec/models/concerns/routable_spec.rb b/spec/models/concerns/routable_spec.rb index dc1002f3560..0bbe3dea812 100644 --- a/spec/models/concerns/routable_spec.rb +++ b/spec/models/concerns/routable_spec.rb @@ -74,6 +74,17 @@ RSpec.shared_examples 'routable resource with parent' do describe '#full_name' do it { expect(record.full_name).to eq "#{record.parent.human_name} / #{record.name}" } + context 'without route name' do + before do + stub_feature_flags(cached_route_lookups: true) + record.route.update_attribute(:name, nil) + end + + it 'builds full name' do + expect(record.full_name).to eq("#{record.parent.human_name} / #{record.name}") + end + end + it 'hits the cache when not preloaded' do forcibly_hit_cached_lookup(record, :full_name) diff --git a/spec/requests/projects/issues_controller_spec.rb b/spec/requests/projects/issues_controller_spec.rb index 67a73834f2d..2b9ff442f76 100644 --- a/spec/requests/projects/issues_controller_spec.rb +++ b/spec/requests/projects/issues_controller_spec.rb @@ -25,33 +25,23 @@ RSpec.describe Projects::IssuesController, feature_category: :team_planning do end describe 'GET #show' do - include_context 'group project issue' + before do + login_as(user) + end it_behaves_like "observability csp policy", described_class do + include_context 'group project issue' let(:tested_path) do project_issue_path(project, issue) end end - end - - describe 'GET #index.json' do - let_it_be(:public_project) { create(:project, :public) } - it_behaves_like 'rate limited endpoint', rate_limit_key: :search_rate_limit do - let_it_be(:current_user) { create(:user) } - - before do - sign_in current_user - end - - def request - get project_issues_path(public_project, format: :json), params: { scope: 'all', search: 'test' } - end - end + describe 'incident tabs' do + let_it_be(:incident) { create(:incident, project: project) } - it_behaves_like 'rate limited endpoint', rate_limit_key: :search_rate_limit_unauthenticated do - def request - get project_issues_path(public_project, format: :json), params: { scope: 'all', search: 'test' } + it 'responds with selected tab for incidents' do + get incident_issue_project_issue_path(project, incident, 'timeline') + expect(response.body).to match(/"currentTab":"timeline"/) end end end diff --git a/spec/support/shared_examples/features/incident_details_routing_shared_examples.rb b/spec/support/shared_examples/features/incident_details_routing_shared_examples.rb index dab125caa60..b8e42843e6f 100644 --- a/spec/support/shared_examples/features/incident_details_routing_shared_examples.rb +++ b/spec/support/shared_examples/features/incident_details_routing_shared_examples.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -RSpec.shared_examples 'for each incident details route' do |example, tab_text:| +RSpec.shared_examples 'for each incident details route' do |example, tab_text:, tab:| before do sign_in(user) visit incident_path @@ -25,4 +25,16 @@ RSpec.shared_examples 'for each incident details route' do |example, tab_text:| it_behaves_like example end + + context "for /-/issues/incident/:id/#{tab} route" do + let(:incident_path) { incident_project_issues_path(project, incident, tab) } + + it_behaves_like example + end + + context "for /-/issues/:id/#{tab} route" do + let(:incident_path) { incident_issue_project_issue_path(project, incident, tab) } + + it_behaves_like example + end end diff --git a/spec/support/shared_examples/lib/gitlab/database/index_validators_shared_examples.rb b/spec/support/shared_examples/lib/gitlab/database/index_validators_shared_examples.rb index 0a8fd39bc2c..6b0ea9421de 100644 --- a/spec/support/shared_examples/lib/gitlab/database/index_validators_shared_examples.rb +++ b/spec/support/shared_examples/lib/gitlab/database/index_validators_shared_examples.rb @@ -12,6 +12,8 @@ RSpec.shared_examples "index validators" do |validator, expected_result| ] end + let(:inconsistency_type) { validator.name.demodulize.underscore } + let(:database_name) { 'main' } let(:database_model) { Gitlab::Database.database_base_models[database_name] } @@ -29,7 +31,8 @@ RSpec.shared_examples "index validators" do |validator, expected_result| allow(connection).to receive(:exec_query).and_return(query_result) end - it 'returns extra indexes' do - expect(result.map(&:name)).to match_array(expected_result) + it 'returns index inconsistencies' do + expect(result.map(&:object_name)).to match_array(expected_result) + expect(result.map(&:type)).to all(eql inconsistency_type) end end diff --git a/spec/workers/group_destroy_worker_spec.rb b/spec/workers/group_destroy_worker_spec.rb index 82ae9010a24..fba4573718a 100644 --- a/spec/workers/group_destroy_worker_spec.rb +++ b/spec/workers/group_destroy_worker_spec.rb @@ -2,20 +2,29 @@ require 'spec_helper' -RSpec.describe GroupDestroyWorker do - let(:group) { create(:group) } - let!(:project) { create(:project, namespace: group) } - let(:user) { create(:user) } +RSpec.describe GroupDestroyWorker, feature_category: :subgroups do + let_it_be(:group) { create(:group) } + let_it_be(:project) { create(:project, namespace: group) } + let_it_be(:user) { create(:user) } before do group.add_owner(user) end - subject { described_class.new } + subject(:worker) { described_class.new } + + include_examples 'an idempotent worker' do + let(:job_args) { [group.id, user.id] } + + it 'does not change groups when run twice' do + expect { worker.perform(group.id, user.id) }.to change { Group.count }.by(-1) + expect { worker.perform(group.id, user.id) }.not_to change { Group.count } + end + end describe "#perform" do - it "deletes the project" do - subject.perform(group.id, user.id) + it "deletes the group and associated projects" do + worker.perform(group.id, user.id) expect(Group.all).not_to include(group) expect(Project.all).not_to include(project) diff --git a/spec/workers/project_destroy_worker_spec.rb b/spec/workers/project_destroy_worker_spec.rb index 25508928bbf..d699393d7a0 100644 --- a/spec/workers/project_destroy_worker_spec.rb +++ b/spec/workers/project_destroy_worker_spec.rb @@ -2,15 +2,26 @@ require 'spec_helper' -RSpec.describe ProjectDestroyWorker do - let(:project) { create(:project, :repository, pending_delete: true) } - let!(:repository) { project.repository.raw } +RSpec.describe ProjectDestroyWorker, feature_category: :source_code_management do + let_it_be(:project) { create(:project, :repository, pending_delete: true) } + let_it_be(:repository) { project.repository.raw } - subject { described_class.new } + let(:user) { project.first_owner } + + subject(:worker) { described_class.new } + + include_examples 'an idempotent worker' do + let(:job_args) { [project.id, user.id, {}] } + + it 'does not change projects when run twice' do + expect { worker.perform(project.id, user.id, {}) }.to change { Project.count }.by(-1) + expect { worker.perform(project.id, user.id, {}) }.not_to change { Project.count } + end + end describe '#perform' do it 'deletes the project' do - subject.perform(project.id, project.first_owner.id, {}) + worker.perform(project.id, user.id, {}) expect(Project.all).not_to include(project) expect(repository).not_to exist @@ -18,13 +29,13 @@ RSpec.describe ProjectDestroyWorker do it 'does not raise error when project could not be found' do expect do - subject.perform(-1, project.first_owner.id, {}) + worker.perform(-1, user.id, {}) end.not_to raise_error end it 'does not raise error when user could not be found' do expect do - subject.perform(project.id, -1, {}) + worker.perform(project.id, -1, {}) end.not_to raise_error end end |