diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-01-12 12:14:10 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-01-12 12:14:10 +0000 |
commit | da646aac6c559584f63d1fc06132d7351abcfac6 (patch) | |
tree | e6e17878b47c081dcd7e161e9bfc3bacd535c8a6 /spec | |
parent | 612dd7d31ab927dd79968a6be7cb36599291bace (diff) | |
download | gitlab-ce-da646aac6c559584f63d1fc06132d7351abcfac6.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
18 files changed, 373 insertions, 189 deletions
diff --git a/spec/controllers/import/gitlab_controller_spec.rb b/spec/controllers/import/gitlab_controller_spec.rb index 826625ba9c3..f757b7c69cf 100644 --- a/spec/controllers/import/gitlab_controller_spec.rb +++ b/spec/controllers/import/gitlab_controller_spec.rb @@ -33,15 +33,16 @@ RSpec.describe Import::GitlabController do end describe "GET status" do + let(:repo_fake) { Struct.new(:id, :path, :path_with_namespace, :web_url, keyword_init: true) } + let(:repo) { repo_fake.new(id: 1, path: 'vim', path_with_namespace: 'asd/vim', web_url: 'https://gitlab.com/asd/vim') } + before do - @repo = OpenStruct.new(id: 1, path: 'vim', path_with_namespace: 'asd/vim', web_url: 'https://gitlab.com/asd/vim') assign_session_token end it_behaves_like 'import controller status' do - let(:repo) { @repo } - let(:repo_id) { @repo.id } - let(:import_source) { @repo.path_with_namespace } + let(:repo_id) { repo.id } + let(:import_source) { repo.path_with_namespace } let(:provider_name) { 'gitlab' } let(:client_repos_field) { :projects } end diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb index 889401e78f8..d5fe32ac094 100644 --- a/spec/controllers/registrations_controller_spec.rb +++ b/spec/controllers/registrations_controller_spec.rb @@ -20,6 +20,10 @@ RSpec.describe RegistrationsController do end describe '#create' do + before do + allow(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).and_return(false) + end + let_it_be(:base_user_params) do { first_name: 'first', last_name: 'last', username: 'new_username', email: 'new@user.com', password: 'Any_password' } end @@ -410,6 +414,18 @@ RSpec.describe RegistrationsController do end end + context 'when the rate limit has been reached' do + it 'returns status 429 Too Many Requests', :aggregate_failures do + ip = '1.2.3.4' + expect(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).with(:user_sign_up, scope: ip).and_return(true) + + controller.request.env['REMOTE_ADDR'] = ip + post(:create, params: user_params, session: session_params) + + expect(response).to have_gitlab_http_status(:too_many_requests) + end + end + it "logs a 'User Created' message" do expect(Gitlab::AppLogger).to receive(:info).with(/\AUser Created: username=new_username email=new@user.com.+\z/).and_call_original diff --git a/spec/features/help_dropdown_spec.rb b/spec/features/help_dropdown_spec.rb new file mode 100644 index 00000000000..db98f58240d --- /dev/null +++ b/spec/features/help_dropdown_spec.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe "Help Dropdown", :js do + let_it_be(:user) { create(:user) } + let_it_be(:admin) { create(:admin) } + + before do + stub_application_setting(version_check_enabled: true) + end + + context 'when logged in as non-admin' do + before do + sign_in(user) + visit root_path + end + + it 'does not render version data' do + page.within '.header-help' do + find('.header-help-dropdown-toggle').click + + expect(page).not_to have_text('Your GitLab Version') + expect(page).not_to have_text("#{Gitlab.version_info.major}.#{Gitlab.version_info.minor}") + expect(page).not_to have_selector('.version-check-badge') + expect(page).not_to have_text('Up to date') + end + end + end + + context 'when logged in as admin' do + before do + sign_in(admin) + gitlab_enable_admin_mode_sign_in(admin) + end + + describe 'does render version data' do + where(:response, :ui_text) do + [ + [{ "severity" => "success" }, 'Up to date'], + [{ "severity" => "warning" }, 'Update available'], + [{ "severity" => "danger" }, 'Update ASAP'] + ] + end + + with_them do + before do + allow_next_instance_of(VersionCheck) do |instance| + allow(instance).to receive(:response).and_return(response) + end + visit root_path + end + + it 'renders correct version badge variant' do + page.within '.header-help' do + find('.header-help-dropdown-toggle').click + + expect(page).to have_text('Your GitLab Version') + expect(page).to have_text("#{Gitlab.version_info.major}.#{Gitlab.version_info.minor}") + expect(page).to have_selector('.version-check-badge') + expect(page).to have_text(ui_text) + end + end + end + end + end +end diff --git a/spec/frontend/integrations/edit/components/dynamic_field_spec.js b/spec/frontend/integrations/edit/components/dynamic_field_spec.js index bf044e388ea..b0fb94d2b29 100644 --- a/spec/frontend/integrations/edit/components/dynamic_field_spec.js +++ b/spec/frontend/integrations/edit/components/dynamic_field_spec.js @@ -61,7 +61,7 @@ describe('DynamicField', () => { }); it(`renders GlFormCheckbox with correct text content when checkboxLabel is ${checkboxLabel}`, () => { - expect(findGlFormCheckbox().text()).toBe(checkboxLabel ?? defaultProps.title); + expect(findGlFormCheckbox().text()).toContain(checkboxLabel ?? defaultProps.title); }); it('does not render other types of input', () => { @@ -182,6 +182,17 @@ describe('DynamicField', () => { expect(findGlFormGroup().find('small').text()).toBe(defaultProps.help); }); + describe('when type is checkbox', () => { + it('renders description with help text', () => { + createComponent({ + type: 'checkbox', + }); + + expect(findGlFormGroup().find('small').exists()).toBe(false); + expect(findGlFormCheckbox().text()).toContain(defaultProps.help); + }); + }); + it('renders description with help text as HTML', () => { const helpHTML = 'The <strong>URL</strong> of the project'; diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js index f06300efa29..5278e730ec9 100644 --- a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js +++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js @@ -1,7 +1,6 @@ -import { GlDropdownItem, GlIcon } from '@gitlab/ui'; +import { GlDropdownItem, GlIcon, GlDropdown } from '@gitlab/ui'; import { shallowMount, createLocalVue } from '@vue/test-utils'; import VueApollo from 'vue-apollo'; -import { GlDropdown } from 'jest/packages_and_registries/container_registry/explorer/stubs'; import { useFakeDate } from 'helpers/fake_date'; import createMockApollo from 'helpers/mock_apollo_helper'; import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; @@ -51,6 +50,7 @@ describe('Details Header', () => { const findCleanup = () => findByTestId('cleanup'); const findDeleteButton = () => wrapper.findComponent(GlDropdownItem); const findInfoIcon = () => wrapper.findComponent(GlIcon); + const findMenu = () => wrapper.findComponent(GlDropdown); const waitForMetadataItems = async () => { // Metadata items are printed by a loop in the title-area and it takes two ticks for them to be available @@ -139,51 +139,53 @@ describe('Details Header', () => { }); }); - describe('delete button', () => { - it('exists', () => { - mountComponent(); + describe('menu', () => { + it.each` + canDelete | disabled | isVisible + ${true} | ${false} | ${true} + ${true} | ${true} | ${false} + ${false} | ${false} | ${false} + ${false} | ${true} | ${false} + `( + 'when canDelete is $canDelete and disabled is $disabled is $isVisible that the menu is visible', + ({ canDelete, disabled, isVisible }) => { + mountComponent({ propsData: { image: { ...defaultImage, canDelete }, disabled } }); - expect(findDeleteButton().exists()).toBe(true); - }); + expect(findMenu().exists()).toBe(isVisible); + }, + ); - it('has the correct text', () => { - mountComponent(); + describe('delete button', () => { + it('exists', () => { + mountComponent(); - expect(findDeleteButton().text()).toBe('Delete image repository'); - }); + expect(findDeleteButton().exists()).toBe(true); + }); - it('has the correct props', () => { - mountComponent(); + it('has the correct text', () => { + mountComponent(); - expect(findDeleteButton().attributes()).toMatchObject( - expect.objectContaining({ - variant: 'danger', - }), - ); - }); + expect(findDeleteButton().text()).toBe('Delete image repository'); + }); - it('emits the correct event', () => { - mountComponent(); + it('has the correct props', () => { + mountComponent(); - findDeleteButton().vm.$emit('click'); + expect(findDeleteButton().attributes()).toMatchObject( + expect.objectContaining({ + variant: 'danger', + }), + ); + }); - expect(wrapper.emitted('delete')).toEqual([[]]); - }); + it('emits the correct event', () => { + mountComponent(); - it.each` - canDelete | disabled | isDisabled - ${true} | ${false} | ${undefined} - ${true} | ${true} | ${'true'} - ${false} | ${false} | ${'true'} - ${false} | ${true} | ${'true'} - `( - 'when canDelete is $canDelete and disabled is $disabled is $isDisabled that the button is disabled', - ({ canDelete, disabled, isDisabled }) => { - mountComponent({ propsData: { image: { ...defaultImage, canDelete }, disabled } }); + findDeleteButton().vm.$emit('click'); - expect(findDeleteButton().attributes('disabled')).toBe(isDisabled); - }, - ); + expect(wrapper.emitted('delete')).toEqual([[]]); + }); + }); }); describe('metadata items', () => { diff --git a/spec/frontend/repository/components/blob_controls_spec.js b/spec/frontend/repository/components/blob_controls_spec.js index cd337f8ced5..03e389ea5cb 100644 --- a/spec/frontend/repository/components/blob_controls_spec.js +++ b/spec/frontend/repository/components/blob_controls_spec.js @@ -7,8 +7,11 @@ import BlobControls from '~/repository/components/blob_controls.vue'; import blobControlsQuery from '~/repository/queries/blob_controls.query.graphql'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import createRouter from '~/repository/router'; +import { updateElementsVisibility } from '~/repository/utils/dom'; import { blobControlsDataMock, refMock } from '../mock_data'; +jest.mock('~/repository/utils/dom'); + let router; let wrapper; let mockResolver; @@ -64,14 +67,22 @@ describe('Blob controls component', () => { expect(findPermalinkButton().attributes('href')).toBe('permalink/file.js'); }); - it('does not render any buttons if no filePath is provided', async () => { - router.replace({ name: 'blobPath', params: { path: null } }); - - await nextTick(); - - expect(findFindButton().exists()).toBe(false); - expect(findBlameButton().exists()).toBe(false); - expect(findHistoryButton().exists()).toBe(false); - expect(findPermalinkButton().exists()).toBe(false); - }); + it.each` + name | path + ${'blobPathDecoded'} | ${null} + ${'treePathDecoded'} | ${'myFile.js'} + `( + 'does not render any buttons if router name is $name and router path is $path', + async ({ name, path }) => { + router.replace({ name, params: { path } }); + + await nextTick(); + + expect(findFindButton().exists()).toBe(false); + expect(findBlameButton().exists()).toBe(false); + expect(findHistoryButton().exists()).toBe(false); + expect(findPermalinkButton().exists()).toBe(false); + expect(updateElementsVisibility).toHaveBeenCalledWith('.tree-controls', true); + }, + ); }); diff --git a/spec/lib/gitlab/database/no_cross_db_foreign_keys_spec.rb b/spec/lib/gitlab/database/no_cross_db_foreign_keys_spec.rb new file mode 100644 index 00000000000..35674dea0d5 --- /dev/null +++ b/spec/lib/gitlab/database/no_cross_db_foreign_keys_spec.rb @@ -0,0 +1,82 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'cross-database foreign keys' do + # TODO: We are trying to empty out this list in + # https://gitlab.com/groups/gitlab-org/-/epics/7249 . Once we are done we can + # keep this test and assert that there are no cross-db foreign keys. We + # should not be adding anything to this list but should instead only add new + # loose foreign keys + # https://docs.gitlab.com/ee/development/database/loose_foreign_keys.html . + let(:allowed_cross_database_foreign_keys) do + %w( + ci_build_report_results.project_id + ci_builds.project_id + ci_builds_metadata.project_id + ci_daily_build_group_report_results.group_id + ci_daily_build_group_report_results.project_id + ci_freeze_periods.project_id + ci_job_artifacts.project_id + ci_job_token_project_scope_links.added_by_id + ci_job_token_project_scope_links.source_project_id + ci_job_token_project_scope_links.target_project_id + ci_pending_builds.namespace_id + ci_pending_builds.project_id + ci_pipeline_artifacts.project_id + ci_pipeline_schedules.owner_id + ci_pipeline_schedules.project_id + ci_pipelines.merge_request_id + ci_pipelines.project_id + ci_project_monthly_usages.project_id + ci_refs.project_id + ci_resource_groups.project_id + ci_runner_namespaces.namespace_id + ci_runner_projects.project_id + ci_running_builds.project_id + ci_sources_pipelines.project_id + ci_sources_pipelines.source_project_id + ci_sources_projects.source_project_id + ci_stages.project_id + ci_subscriptions_projects.downstream_project_id + ci_subscriptions_projects.upstream_project_id + ci_triggers.owner_id + ci_triggers.project_id + ci_unit_tests.project_id + ci_variables.project_id + dast_profiles_pipelines.ci_pipeline_id + dast_scanner_profiles_builds.ci_build_id + dast_site_profiles_builds.ci_build_id + dast_site_profiles_pipelines.ci_pipeline_id + external_pull_requests.project_id + merge_requests.head_pipeline_id + merge_trains.pipeline_id + requirements_management_test_reports.build_id + security_scans.build_id + vulnerability_feedback.pipeline_id + vulnerability_occurrence_pipelines.pipeline_id + vulnerability_statistics.latest_pipeline_id + ).freeze + end + + def foreign_keys_for(table_name) + ApplicationRecord.connection.foreign_keys(table_name) + end + + def is_cross_db?(fk_record) + Gitlab::Database::GitlabSchema.table_schemas([fk_record.from_table, fk_record.to_table]).many? + end + + it 'onlies have allowed list of cross-database foreign keys', :aggregate_failures do + all_tables = ApplicationRecord.connection.data_sources + + all_tables.each do |table| + foreign_keys_for(table).each do |fk| + if is_cross_db?(fk) + column = "#{fk.from_table}.#{fk.column}" + expect(allowed_cross_database_foreign_keys).to include(column), "Found extra cross-database foreign key #{column} referencing #{fk.to_table} with constraint name #{fk.name}. When a foreign key references another database you must use a Loose Foreign Key instead https://docs.gitlab.com/ee/development/database/loose_foreign_keys.html ." + end + end + end + end +end diff --git a/spec/lib/gitlab/database/partitioning/partition_manager_spec.rb b/spec/lib/gitlab/database/partitioning/partition_manager_spec.rb index 5e107109fc9..64dcdb9628a 100644 --- a/spec/lib/gitlab/database/partitioning/partition_manager_spec.rb +++ b/spec/lib/gitlab/database/partitioning/partition_manager_spec.rb @@ -18,7 +18,7 @@ RSpec.describe Gitlab::Database::Partitioning::PartitionManager do let(:model) { double(partitioning_strategy: partitioning_strategy, table_name: table, connection: connection) } let(:partitioning_strategy) { double(missing_partitions: partitions, extra_partitions: [], after_adding_partitions: nil) } let(:connection) { ActiveRecord::Base.connection } - let(:table) { "some_table" } + let(:table) { "issues" } before do allow(connection).to receive(:table_exists?).and_call_original @@ -36,6 +36,7 @@ RSpec.describe Gitlab::Database::Partitioning::PartitionManager do end it 'creates the partition' do + expect(connection).to receive(:execute).with("LOCK TABLE \"#{table}\" IN ACCESS EXCLUSIVE MODE") expect(connection).to receive(:execute).with(partitions.first.to_sql) expect(connection).to receive(:execute).with(partitions.second.to_sql) diff --git a/spec/lib/gitlab/database/partitioning/sliding_list_strategy_spec.rb b/spec/lib/gitlab/database/partitioning/sliding_list_strategy_spec.rb index 636a09e5710..1cec0463055 100644 --- a/spec/lib/gitlab/database/partitioning/sliding_list_strategy_spec.rb +++ b/spec/lib/gitlab/database/partitioning/sliding_list_strategy_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe Gitlab::Database::Partitioning::SlidingListStrategy do let(:connection) { ActiveRecord::Base.connection } let(:table_name) { :_test_partitioned_test } - let(:model) { double('model', table_name: table_name, ignored_columns: %w[partition]) } + let(:model) { double('model', table_name: table_name, ignored_columns: %w[partition], connection: connection) } let(:next_partition_if) { double('next_partition_if') } let(:detach_partition_if) { double('detach_partition_if') } @@ -94,7 +94,8 @@ RSpec.describe Gitlab::Database::Partitioning::SlidingListStrategy do let(:detach_partition_if) { ->(p) { p != 5 } } it 'is the leading set of partitions before that value' do - expect(strategy.extra_partitions.map(&:value)).to contain_exactly(1, 2, 3, 4) + # should not contain partition 2 since it's the default value for the partition column + expect(strategy.extra_partitions.map(&:value)).to contain_exactly(1, 3, 4) end end @@ -102,7 +103,7 @@ RSpec.describe Gitlab::Database::Partitioning::SlidingListStrategy do let(:detach_partition_if) { proc { true } } it 'is all but the most recent partition', :aggregate_failures do - expect(strategy.extra_partitions.map(&:value)).to contain_exactly(1, 2, 3, 4, 5, 6, 7, 8, 9) + expect(strategy.extra_partitions.map(&:value)).to contain_exactly(1, 3, 4, 5, 6, 7, 8, 9) expect(strategy.current_partitions.map(&:value).max).to eq(10) end diff --git a/spec/lib/gitlab/metrics/exporter/base_exporter_spec.rb b/spec/lib/gitlab/metrics/exporter/base_exporter_spec.rb index 204a5dab9c0..c7afc02f0af 100644 --- a/spec/lib/gitlab/metrics/exporter/base_exporter_spec.rb +++ b/spec/lib/gitlab/metrics/exporter/base_exporter_spec.rb @@ -4,13 +4,8 @@ require 'spec_helper' RSpec.describe Gitlab::Metrics::Exporter::BaseExporter do let(:settings) { double('settings') } - let(:exporter) { described_class.new(settings) } - let(:log_filename) { File.join(Rails.root, 'log', 'sidekiq_exporter.log') } - - before do - allow_any_instance_of(described_class).to receive(:log_filename).and_return(log_filename) - allow_any_instance_of(described_class).to receive(:settings).and_return(settings) - end + let(:log_enabled) { false } + let(:exporter) { described_class.new(settings, log_enabled: log_enabled, log_file: 'test_exporter.log') } describe 'when exporter is enabled' do before do @@ -61,6 +56,38 @@ RSpec.describe Gitlab::Metrics::Exporter::BaseExporter do exporter.start.join end + + context 'logging enabled' do + let(:log_enabled) { true } + let(:logger) { instance_double(WEBrick::Log) } + + before do + allow(logger).to receive(:time_format=) + allow(logger).to receive(:info) + end + + it 'configures a WEBrick logger with the given file' do + expect(WEBrick::Log).to receive(:new).with(end_with('test_exporter.log')).and_return(logger) + + exporter + end + + it 'logs any errors during startup' do + expect(::WEBrick::Log).to receive(:new).and_return(logger) + expect(::WEBrick::HTTPServer).to receive(:new).and_raise 'fail' + expect(logger).to receive(:error) + + exporter.start + end + end + + context 'logging disabled' do + it 'configures a WEBrick logger with the null device' do + expect(WEBrick::Log).to receive(:new).with(File::NULL).and_call_original + + exporter + end + end end describe 'when thread is not alive' do diff --git a/spec/lib/gitlab/metrics/exporter/sidekiq_exporter_spec.rb b/spec/lib/gitlab/metrics/exporter/sidekiq_exporter_spec.rb deleted file mode 100644 index 75bc3ba9626..00000000000 --- a/spec/lib/gitlab/metrics/exporter/sidekiq_exporter_spec.rb +++ /dev/null @@ -1,53 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Gitlab::Metrics::Exporter::SidekiqExporter do - let(:exporter) { described_class.new(Settings.monitoring.sidekiq_exporter) } - - after do - exporter.stop - end - - context 'with valid config' do - before do - stub_config( - monitoring: { - sidekiq_exporter: { - enabled: true, - log_enabled: false, - port: 0, - address: '127.0.0.1' - } - } - ) - end - - it 'does start thread' do - expect(exporter.start).not_to be_nil - end - - it 'does not enable logging by default' do - expect(exporter.log_filename).to eq(File::NULL) - end - end - - context 'with logging enabled' do - before do - stub_config( - monitoring: { - sidekiq_exporter: { - enabled: true, - log_enabled: true, - port: 0, - address: '127.0.0.1' - } - } - ) - end - - it 'returns a valid log filename' do - expect(exporter.log_filename).to end_with('sidekiq_exporter.log') - end - end -end diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index c4f4e2cb2dc..a5af0cd32fd 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -2468,6 +2468,16 @@ RSpec.describe Ci::Build do it { is_expected.not_to be_playable } end + + context 'when build is waiting for deployment approval' do + subject { build_stubbed(:ci_build, :manual, environment: 'production') } + + before do + create(:deployment, :blocked, deployable: subject) + end + + it { is_expected.not_to be_playable } + end end describe 'project settings' do @@ -3792,6 +3802,18 @@ RSpec.describe Ci::Build do end end + describe 'when the build is waiting for deployment approval' do + let(:build) { create(:ci_build, :manual, environment: 'production') } + + before do + create(:deployment, :blocked, deployable: build) + end + + it 'does not allow the build to be enqueued' do + expect { build.enqueue! }.to raise_error(StateMachines::InvalidTransition) + end + end + describe 'state transition: any => [:pending]' do let(:build) { create(:ci_build, :created) } diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index 100b7aabd02..04d12913828 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -4695,14 +4695,5 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do it { expect(pipeline.tags_count).to eq(4) } it { expect(pipeline.distinct_tags_count).to eq(3) } end - - context 'with the FF disabled' do - before do - stub_feature_flags(ci_pipeline_logger_tags_count: false) - end - - it { expect(pipeline.tags_count).to be_nil } - it { expect(pipeline.distinct_tags_count).to be_nil } - end end end diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb index 1d250d4f798..cbb27575ea9 100644 --- a/spec/policies/group_policy_spec.rb +++ b/spec/policies/group_policy_spec.rb @@ -10,21 +10,32 @@ RSpec.describe GroupPolicy do let(:current_user) { nil } it do - expect_allowed(:read_group) - expect_allowed(:read_counts) - expect_allowed(*read_group_permissions) + expect_allowed(*public_permissions) expect_disallowed(:upload_file) expect_disallowed(*reporter_permissions) expect_disallowed(*developer_permissions) expect_disallowed(*maintainer_permissions) expect_disallowed(*owner_permissions) expect_disallowed(:read_namespace) - expect_disallowed(:read_crm_organization) - expect_disallowed(:read_crm_contact) end end - context 'with no user and public project' do + context 'public group with user who is not a member' do + let(:group) { create(:group, :public, :crm_enabled) } + let(:current_user) { create(:user) } + + it do + expect_allowed(*public_permissions) + expect_disallowed(:upload_file) + expect_disallowed(*reporter_permissions) + expect_disallowed(*developer_permissions) + expect_disallowed(*maintainer_permissions) + expect_disallowed(*owner_permissions) + expect_disallowed(:read_namespace) + end + end + + context 'private group that has been invited to a public project and with no user' do let(:project) { create(:project, :public, group: create(:group, :crm_enabled)) } let(:current_user) { nil } @@ -32,15 +43,14 @@ RSpec.describe GroupPolicy do create(:project_group_link, project: project, group: group) end - it { expect_disallowed(:read_group) } - it { expect_disallowed(:read_crm_organization) } - it { expect_disallowed(:read_crm_contact) } - it { expect_disallowed(:read_counts) } - it { expect_disallowed(:read_group_runners) } - it { expect_disallowed(*read_group_permissions) } + it do + expect_disallowed(*public_permissions) + expect_disallowed(*reporter_permissions) + expect_disallowed(*owner_permissions) + end end - context 'with foreign user and public project' do + context 'private group that has been invited to a public project and with a foreign user' do let(:project) { create(:project, :public, group: create(:group, :crm_enabled)) } let(:current_user) { create(:user) } @@ -48,12 +58,11 @@ RSpec.describe GroupPolicy do create(:project_group_link, project: project, group: group) end - it { expect_disallowed(:read_group) } - it { expect_disallowed(:read_crm_organization) } - it { expect_disallowed(:read_crm_contact) } - it { expect_disallowed(:read_counts) } - it { expect_disallowed(:read_group_runners) } - it { expect_disallowed(*read_group_permissions) } + it do + expect_disallowed(*public_permissions) + expect_disallowed(*reporter_permissions) + expect_disallowed(*owner_permissions) + end end context 'has projects' do @@ -64,13 +73,13 @@ RSpec.describe GroupPolicy do project.add_developer(current_user) end - it { expect_allowed(*read_group_permissions) } + it { expect_allowed(*(public_permissions - [:read_counts])) } context 'in subgroups' do let(:subgroup) { create(:group, :private, :crm_enabled, parent: group) } let(:project) { create(:project, namespace: subgroup) } - it { expect_allowed(*read_group_permissions) } + it { expect_allowed(*(public_permissions - [:read_counts])) } end end @@ -83,7 +92,7 @@ RSpec.describe GroupPolicy do let(:current_user) { deploy_token } it do - expect_disallowed(*read_group_permissions) + expect_disallowed(*public_permissions) expect_disallowed(*guest_permissions) expect_disallowed(*reporter_permissions) expect_disallowed(*developer_permissions) @@ -96,7 +105,7 @@ RSpec.describe GroupPolicy do let(:current_user) { guest } it do - expect_allowed(*read_group_permissions) + expect_allowed(*public_permissions) expect_allowed(*guest_permissions) expect_disallowed(*reporter_permissions) expect_disallowed(*developer_permissions) @@ -113,7 +122,7 @@ RSpec.describe GroupPolicy do let(:current_user) { reporter } it do - expect_allowed(*read_group_permissions) + expect_allowed(*public_permissions) expect_allowed(*guest_permissions) expect_allowed(*reporter_permissions) expect_disallowed(*developer_permissions) @@ -130,7 +139,7 @@ RSpec.describe GroupPolicy do let(:current_user) { developer } it do - expect_allowed(*read_group_permissions) + expect_allowed(*public_permissions) expect_allowed(*guest_permissions) expect_allowed(*reporter_permissions) expect_allowed(*developer_permissions) @@ -158,7 +167,7 @@ RSpec.describe GroupPolicy do updated_owner_permissions = owner_permissions - create_subgroup_permission - expect_allowed(*read_group_permissions) + expect_allowed(*public_permissions) expect_allowed(*guest_permissions) expect_allowed(*reporter_permissions) expect_allowed(*developer_permissions) @@ -169,7 +178,7 @@ RSpec.describe GroupPolicy do context 'with subgroup_creation_level set to owner' do it 'allows every maintainer permission' do - expect_allowed(*read_group_permissions) + expect_allowed(*public_permissions) expect_allowed(*guest_permissions) expect_allowed(*reporter_permissions) expect_allowed(*developer_permissions) @@ -187,7 +196,7 @@ RSpec.describe GroupPolicy do let(:current_user) { owner } it do - expect_allowed(*read_group_permissions) + expect_allowed(*public_permissions) expect_allowed(*guest_permissions) expect_allowed(*reporter_permissions) expect_allowed(*developer_permissions) @@ -204,7 +213,7 @@ RSpec.describe GroupPolicy do let(:current_user) { admin } specify do - expect_disallowed(*read_group_permissions) + expect_disallowed(*public_permissions) expect_disallowed(*guest_permissions) expect_disallowed(*reporter_permissions) expect_disallowed(*developer_permissions) @@ -214,7 +223,7 @@ RSpec.describe GroupPolicy do context 'with admin mode', :enable_admin_mode do specify do - expect_allowed(*read_group_permissions) + expect_allowed(*public_permissions) expect_allowed(*guest_permissions) expect_allowed(*reporter_permissions) expect_allowed(*developer_permissions) @@ -256,8 +265,7 @@ RSpec.describe GroupPolicy do let(:current_user) { nil } it do - expect_disallowed(:read_counts) - expect_disallowed(*read_group_permissions) + expect_disallowed(*public_permissions) expect_disallowed(*guest_permissions) expect_disallowed(*reporter_permissions) expect_disallowed(*developer_permissions) @@ -270,8 +278,7 @@ RSpec.describe GroupPolicy do let(:current_user) { guest } it do - expect_allowed(:read_counts) - expect_allowed(*read_group_permissions) + expect_allowed(*public_permissions) expect_allowed(*guest_permissions) expect_disallowed(*reporter_permissions) expect_disallowed(*developer_permissions) @@ -284,8 +291,7 @@ RSpec.describe GroupPolicy do let(:current_user) { reporter } it do - expect_allowed(:read_counts) - expect_allowed(*read_group_permissions) + expect_allowed(*public_permissions) expect_allowed(*guest_permissions) expect_allowed(*reporter_permissions) expect_disallowed(*developer_permissions) @@ -298,8 +304,7 @@ RSpec.describe GroupPolicy do let(:current_user) { developer } it do - expect_allowed(:read_counts) - expect_allowed(*read_group_permissions) + expect_allowed(*public_permissions) expect_allowed(*guest_permissions) expect_allowed(*reporter_permissions) expect_allowed(*developer_permissions) @@ -312,8 +317,7 @@ RSpec.describe GroupPolicy do let(:current_user) { maintainer } it do - expect_allowed(:read_counts) - expect_allowed(*read_group_permissions) + expect_allowed(*public_permissions) expect_allowed(*guest_permissions) expect_allowed(*reporter_permissions) expect_allowed(*developer_permissions) @@ -326,8 +330,7 @@ RSpec.describe GroupPolicy do let(:current_user) { owner } it do - expect_allowed(:read_counts) - expect_allowed(*read_group_permissions) + expect_allowed(*public_permissions) expect_allowed(*guest_permissions) expect_allowed(*reporter_permissions) expect_allowed(*developer_permissions) diff --git a/spec/services/ci/pipelines/add_job_service_spec.rb b/spec/services/ci/pipelines/add_job_service_spec.rb index 709a840c644..560724a1c6a 100644 --- a/spec/services/ci/pipelines/add_job_service_spec.rb +++ b/spec/services/ci/pipelines/add_job_service_spec.rb @@ -31,7 +31,7 @@ RSpec.describe Ci::Pipelines::AddJobService do execute end.to change { job.slice(:pipeline, :project, :ref) }.to( pipeline: pipeline, project: pipeline.project, ref: pipeline.ref - ) + ).and change { job.metadata.project }.to(pipeline.project) end it 'returns a service response with the job as payload' do diff --git a/spec/support/database/cross-database-modification-allowlist.yml b/spec/support/database/cross-database-modification-allowlist.yml index 4e901308f2f..51804862a43 100644 --- a/spec/support/database/cross-database-modification-allowlist.yml +++ b/spec/support/database/cross-database-modification-allowlist.yml @@ -1,30 +1,11 @@ -- "./ee/spec/mailers/notify_spec.rb" -- "./ee/spec/models/group_member_spec.rb" - "./ee/spec/replicators/geo/terraform_state_version_replicator_spec.rb" -- "./ee/spec/services/ci/retry_build_service_spec.rb" -- "./spec/controllers/abuse_reports_controller_spec.rb" -- "./spec/controllers/omniauth_callbacks_controller_spec.rb" -- "./spec/controllers/projects/issues_controller_spec.rb" - "./spec/features/issues/issue_detail_spec.rb" - "./spec/features/projects/pipelines/pipeline_spec.rb" - "./spec/features/signed_commits_spec.rb" -- "./spec/helpers/issuables_helper_spec.rb" -- "./spec/lib/gitlab/auth_spec.rb" - "./spec/lib/gitlab/ci/pipeline/chain/create_spec.rb" -- "./spec/lib/gitlab/email/handler/create_issue_handler_spec.rb" -- "./spec/lib/gitlab/email/handler/create_merge_request_handler_spec.rb" -- "./spec/lib/gitlab/email/handler/create_note_handler_spec.rb" -- "./spec/lib/gitlab/email/handler/create_note_on_issuable_handler_spec.rb" - "./spec/models/ci/build_trace_chunk_spec.rb" - "./spec/models/ci/job_artifact_spec.rb" - "./spec/models/clusters/applications/runner_spec.rb" -- "./spec/models/design_management/version_spec.rb" -- "./spec/models/hooks/system_hook_spec.rb" -- "./spec/models/members/project_member_spec.rb" -- "./spec/models/user_spec.rb" -- "./spec/models/user_status_spec.rb" - "./spec/requests/api/commits_spec.rb" - "./spec/services/ci/retry_build_service_spec.rb" - "./spec/services/projects/overwrite_project_service_spec.rb" -- "./spec/workers/merge_requests/create_pipeline_worker_spec.rb" -- "./spec/workers/repository_cleanup_worker_spec.rb" diff --git a/spec/support/shared_contexts/policies/group_policy_shared_context.rb b/spec/support/shared_contexts/policies/group_policy_shared_context.rb index 0827a46313a..0dfd76de79c 100644 --- a/spec/support/shared_contexts/policies/group_policy_shared_context.rb +++ b/spec/support/shared_contexts/policies/group_policy_shared_context.rb @@ -10,6 +10,13 @@ RSpec.shared_context 'GroupPolicy context' do let_it_be(:non_group_member) { create(:user) } let_it_be(:group, refind: true) { create(:group, :private, :owner_subgroup_creation_only, :crm_enabled) } + let(:public_permissions) do + %i[ + read_group read_counts + read_label read_issue_board_list read_milestone read_issue_board + ] + end + let(:guest_permissions) do %i[ read_label read_group upload_file read_namespace read_group_activity @@ -18,8 +25,6 @@ RSpec.shared_context 'GroupPolicy context' do ] end - let(:read_group_permissions) { %i[read_label read_issue_board_list read_milestone read_issue_board] } - let(:reporter_permissions) do %i[ admin_label diff --git a/spec/views/layouts/header/_gitlab_version.html.haml_spec.rb b/spec/views/layouts/header/_gitlab_version.html.haml_spec.rb new file mode 100644 index 00000000000..0e24810f835 --- /dev/null +++ b/spec/views/layouts/header/_gitlab_version.html.haml_spec.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'layouts/header/_gitlab_version' do + describe 'when show_version_check? is true' do + before do + allow(view).to receive(:show_version_check?).and_return(true) + render + end + + it 'renders the version check badge' do + expect(rendered).to have_selector('.js-gitlab-version-check') + end + end +end |