diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-08-12 21:10:45 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-08-12 21:10:45 +0300 |
commit | bf1990164b801489b4475504701eefb66146e724 (patch) | |
tree | b21f9118116f413cdbde621048bd9b93c1388424 /spec | |
parent | dc250651ab26bf7bce9205d5fa4a45dd58e2df81 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
21 files changed, 428 insertions, 194 deletions
diff --git a/spec/db/schema_spec.rb b/spec/db/schema_spec.rb index 18f2f7b54c4..7e4b8c53885 100644 --- a/spec/db/schema_spec.rb +++ b/spec/db/schema_spec.rb @@ -86,7 +86,8 @@ RSpec.describe 'Database schema' do users: %w[color_scheme_id created_by_id theme_id email_opted_in_source_id], users_star_projects: %w[user_id], vulnerability_identifiers: %w[external_id], - vulnerability_scanners: %w[external_id] + vulnerability_scanners: %w[external_id], + security_scans: %w[pipeline_id] # foreign key is not added as ci_pipeline table will be moved into different db soon }.with_indifferent_access.freeze context 'for table' do diff --git a/spec/features/clusters/cluster_health_dashboard_spec.rb b/spec/features/clusters/cluster_health_dashboard_spec.rb index 32caad775e4..e4a36f654e5 100644 --- a/spec/features/clusters/cluster_health_dashboard_spec.rb +++ b/spec/features/clusters/cluster_health_dashboard_spec.rb @@ -80,7 +80,7 @@ RSpec.describe 'Cluster Health board', :js, :kubeclient, :use_clean_rails_memory expect(page).to have_content('Avg') end - it 'focuses the single panel on toggle' do + it 'focuses the single panel on toggle', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338341' do click_button('More actions') click_button('Expand panel') diff --git a/spec/finders/issues_finder_spec.rb b/spec/finders/issues_finder_spec.rb index 1c8c2af8e03..0cb73f3da6d 100644 --- a/spec/finders/issues_finder_spec.rb +++ b/spec/finders/issues_finder_spec.rb @@ -789,7 +789,7 @@ RSpec.describe IssuesFinder do context 'user filters confidential issues' do let(:params) { { confidential: true } } - it 'returns only confdential issues' do + it 'returns only confidential issues' do expect(issues).to contain_exactly(confidential_issue) end end @@ -797,7 +797,7 @@ RSpec.describe IssuesFinder do context 'user filters only public issues' do let(:params) { { confidential: false } } - it 'returns only confdential issues' do + it 'returns only public issues' do expect(issues).to contain_exactly(issue1, issue2, issue3, issue4, issue5) end end @@ -1004,9 +1004,38 @@ RSpec.describe IssuesFinder do let(:guest) { create(:user) } let_it_be(:authorized_user) { create(:user) } + let_it_be(:banned_user) { create(:user, :banned) } let_it_be(:project) { create(:project, namespace: authorized_user.namespace) } let_it_be(:public_issue) { create(:issue, project: project) } let_it_be(:confidential_issue) { create(:issue, project: project, confidential: true) } + let_it_be(:hidden_issue) { create(:issue, project: project, author: banned_user) } + + shared_examples 'returns public, does not return hidden or confidential' do + it 'returns only public issues' do + expect(subject).to include(public_issue) + expect(subject).not_to include(confidential_issue, hidden_issue) + end + end + + shared_examples 'returns public and confidential, does not return hidden' do + it 'returns only public and confidential issues' do + expect(subject).to include(public_issue, confidential_issue) + expect(subject).not_to include(hidden_issue) + end + end + + shared_examples 'returns public and hidden, does not return confidential' do + it 'returns only public and hidden issues' do + expect(subject).to include(public_issue, hidden_issue) + expect(subject).not_to include(confidential_issue) + end + end + + shared_examples 'returns public, confidential, and hidden' do + it 'returns all issues' do + expect(subject).to include(public_issue, confidential_issue, hidden_issue) + end + end context 'when no project filter is given' do let(:params) { {} } @@ -1014,18 +1043,28 @@ RSpec.describe IssuesFinder do context 'for an anonymous user' do subject { described_class.new(nil, params).with_confidentiality_access_check } - it 'returns only public issues' do - expect(subject).to include(public_issue) - expect(subject).not_to include(confidential_issue) + it_behaves_like 'returns public, does not return hidden or confidential' + + context 'when feature flag is disabled' do + before do + stub_feature_flags(ban_user_feature_flag: false) + end + + it_behaves_like 'returns public and hidden, does not return confidential' end end context 'for a user without project membership' do subject { described_class.new(user, params).with_confidentiality_access_check } - it 'returns only public issues' do - expect(subject).to include(public_issue) - expect(subject).not_to include(confidential_issue) + it_behaves_like 'returns public, does not return hidden or confidential' + + context 'when feature flag is disabled' do + before do + stub_feature_flags(ban_user_feature_flag: false) + end + + it_behaves_like 'returns public and hidden, does not return confidential' end end @@ -1036,17 +1075,28 @@ RSpec.describe IssuesFinder do project.add_guest(guest) end - it 'returns only public issues' do - expect(subject).to include(public_issue) - expect(subject).not_to include(confidential_issue) + it_behaves_like 'returns public, does not return hidden or confidential' + + context 'when feature flag is disabled' do + before do + stub_feature_flags(ban_user_feature_flag: false) + end + + it_behaves_like 'returns public and hidden, does not return confidential' end end context 'for a project member with access to view confidential issues' do subject { described_class.new(authorized_user, params).with_confidentiality_access_check } - it 'returns all issues' do - expect(subject).to include(public_issue, confidential_issue) + it_behaves_like 'returns public and confidential, does not return hidden' + + context 'when feature flag is disabled' do + before do + stub_feature_flags(ban_user_feature_flag: false) + end + + it_behaves_like 'returns public, confidential, and hidden' end end @@ -1056,15 +1106,26 @@ RSpec.describe IssuesFinder do subject { described_class.new(admin_user, params).with_confidentiality_access_check } context 'when admin mode is enabled', :enable_admin_mode do - it 'returns all issues' do - expect(subject).to include(public_issue, confidential_issue) + it_behaves_like 'returns public, confidential, and hidden' + + context 'when feature flag is disabled' do + before do + stub_feature_flags(ban_user_feature_flag: false) + end + + it_behaves_like 'returns public, confidential, and hidden' end end context 'when admin mode is disabled' do - it 'returns only public issues' do - expect(subject).to include(public_issue) - expect(subject).not_to include(confidential_issue) + it_behaves_like 'returns public, does not return hidden or confidential' + + context 'when feature flag is disabled' do + before do + stub_feature_flags(ban_user_feature_flag: false) + end + + it_behaves_like 'returns public and hidden, does not return confidential' end end end @@ -1076,14 +1137,18 @@ RSpec.describe IssuesFinder do context 'for an anonymous user' do subject { described_class.new(nil, params).with_confidentiality_access_check } - it 'returns only public issues' do - expect(subject).to include(public_issue) - expect(subject).not_to include(confidential_issue) + it_behaves_like 'returns public, does not return hidden or confidential' + + context 'when feature flag is disabled' do + before do + stub_feature_flags(ban_user_feature_flag: false) + end + + it_behaves_like 'returns public and hidden, does not return confidential' end it 'does not filter by confidentiality' do expect(Issue).not_to receive(:where).with(a_string_matching('confidential'), anything) - subject end end @@ -1091,9 +1156,14 @@ RSpec.describe IssuesFinder do context 'for a user without project membership' do subject { described_class.new(user, params).with_confidentiality_access_check } - it 'returns only public issues' do - expect(subject).to include(public_issue) - expect(subject).not_to include(confidential_issue) + it_behaves_like 'returns public, does not return hidden or confidential' + + context 'when feature flag is disabled' do + before do + stub_feature_flags(ban_user_feature_flag: false) + end + + it_behaves_like 'returns public and hidden, does not return confidential' end it 'filters by confidentiality' do @@ -1108,9 +1178,14 @@ RSpec.describe IssuesFinder do project.add_guest(guest) end - it 'returns only public issues' do - expect(subject).to include(public_issue) - expect(subject).not_to include(confidential_issue) + it_behaves_like 'returns public, does not return hidden or confidential' + + context 'when feature flag is disabled' do + before do + stub_feature_flags(ban_user_feature_flag: false) + end + + it_behaves_like 'returns public and hidden, does not return confidential' end it 'filters by confidentiality' do @@ -1121,8 +1196,14 @@ RSpec.describe IssuesFinder do context 'for a project member with access to view confidential issues' do subject { described_class.new(authorized_user, params).with_confidentiality_access_check } - it 'returns all issues' do - expect(subject).to include(public_issue, confidential_issue) + it_behaves_like 'returns public and confidential, does not return hidden' + + context 'when feature flag is disabled' do + before do + stub_feature_flags(ban_user_feature_flag: false) + end + + it_behaves_like 'returns public, confidential, and hidden' end it 'does not filter by confidentiality' do @@ -1138,8 +1219,14 @@ RSpec.describe IssuesFinder do subject { described_class.new(admin_user, params).with_confidentiality_access_check } context 'when admin mode is enabled', :enable_admin_mode do - it 'returns all issues' do - expect(subject).to include(public_issue, confidential_issue) + it_behaves_like 'returns public, confidential, and hidden' + + context 'when feature flag is disabled' do + before do + stub_feature_flags(ban_user_feature_flag: false) + end + + it_behaves_like 'returns public, confidential, and hidden' end it 'does not filter by confidentiality' do @@ -1150,9 +1237,14 @@ RSpec.describe IssuesFinder do end context 'when admin mode is disabled' do - it 'returns only public issues' do - expect(subject).to include(public_issue) - expect(subject).not_to include(confidential_issue) + it_behaves_like 'returns public, does not return hidden or confidential' + + context 'when feature flag is disabled' do + before do + stub_feature_flags(ban_user_feature_flag: false) + end + + it_behaves_like 'returns public and hidden, does not return confidential' end it 'filters by confidentiality' do diff --git a/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric.yml b/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric.yml index af5704f7d01..8495d983d10 100644 --- a/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric.yml +++ b/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric.yml @@ -12,7 +12,7 @@ milestone: "13.9" introduced_by_url: time_frame: 7d data_source: -data_category: Operational +data_category: operational performance_indicator_type: distribution: - ce diff --git a/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_ee.yml b/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_ee.yml index 6f4e2b3f9ee..82e9af5b04f 100644 --- a/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_ee.yml +++ b/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_ee.yml @@ -12,7 +12,7 @@ milestone: "13.9" introduced_by_url: time_frame: 7d data_source: -data_category: Optional +data_category: optional performance_indicator_type: distribution: - ee diff --git a/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_name_suggestions.yml b/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_name_suggestions.yml index a0e5ea799a5..aad7dc76290 100644 --- a/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_name_suggestions.yml +++ b/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_name_suggestions.yml @@ -13,7 +13,7 @@ milestone: "13.9" introduced_by_url: time_frame: 7d data_source: -data_category: Optional +data_category: optional performance_indicator_type: distribution: - ce diff --git a/spec/frontend/environments/environments_app_spec.js b/spec/frontend/environments/environments_app_spec.js index 1abdeff614c..dc176001943 100644 --- a/spec/frontend/environments/environments_app_spec.js +++ b/spec/frontend/environments/environments_app_spec.js @@ -1,4 +1,4 @@ -import { GlTabs } from '@gitlab/ui'; +import { GlTabs, GlAlert } from '@gitlab/ui'; import { mount, shallowMount } from '@vue/test-utils'; import MockAdapter from 'axios-mock-adapter'; import { extendedWrapper } from 'helpers/vue_test_utils_helper'; @@ -7,7 +7,9 @@ import DeployBoard from '~/environments/components/deploy_board.vue'; import EmptyState from '~/environments/components/empty_state.vue'; import EnableReviewAppModal from '~/environments/components/enable_review_app_modal.vue'; import EnvironmentsApp from '~/environments/components/environments_app.vue'; +import { ENVIRONMENTS_SURVEY_DISMISSED_COOKIE_NAME } from '~/environments/constants'; import axios from '~/lib/utils/axios_utils'; +import { setCookie, getCookie, removeCookie } from '~/lib/utils/common_utils'; import * as urlUtils from '~/lib/utils/url_utility'; import { environment, folder } from './mock_data'; @@ -48,6 +50,7 @@ describe('Environment', () => { const findNewEnvironmentButton = () => wrapper.findByTestId('new-environment'); const findEnvironmentsTabAvailable = () => wrapper.find('.js-environments-tab-available > a'); const findEnvironmentsTabStopped = () => wrapper.find('.js-environments-tab-stopped > a'); + const findSurveyAlert = () => wrapper.find(GlAlert); beforeEach(() => { mock = new MockAdapter(axios); @@ -280,4 +283,49 @@ describe('Environment', () => { expect(wrapper.findComponent(GlTabs).attributes('value')).toBe('1'); }); }); + + describe('survey alert', () => { + beforeEach(async () => { + mockRequest(200, { environments: [] }); + await createWrapper(true); + }); + + afterEach(() => { + removeCookie(ENVIRONMENTS_SURVEY_DISMISSED_COOKIE_NAME); + }); + + describe('when the user has not dismissed the alert', () => { + it('shows the alert', () => { + expect(findSurveyAlert().exists()).toBe(true); + }); + + describe('when the user dismisses the alert', () => { + beforeEach(() => { + findSurveyAlert().vm.$emit('dismiss'); + }); + + it('hides the alert', () => { + expect(findSurveyAlert().exists()).toBe(false); + }); + + it('persists the dismisal using a cookie', () => { + const cookieValue = getCookie(ENVIRONMENTS_SURVEY_DISMISSED_COOKIE_NAME); + + expect(cookieValue).toBe('true'); + }); + }); + }); + + describe('when the user has previously dismissed the alert', () => { + beforeEach(async () => { + setCookie(ENVIRONMENTS_SURVEY_DISMISSED_COOKIE_NAME, 'true'); + + await createWrapper(true); + }); + + it('does not show the alert', () => { + expect(findSurveyAlert().exists()).toBe(false); + }); + }); + }); }); diff --git a/spec/frontend/terraform/components/states_table_actions_spec.js b/spec/frontend/terraform/components/states_table_actions_spec.js index 34e7d597cd8..9d28e8ce294 100644 --- a/spec/frontend/terraform/components/states_table_actions_spec.js +++ b/spec/frontend/terraform/components/states_table_actions_spec.js @@ -275,7 +275,7 @@ describe('StatesTableActions', () => { it('displays a remove modal', () => { expect(findRemoveModal().text()).toContain( - `You are about to remove the State file ${defaultProps.state.name}`, + `You are about to remove the state file ${defaultProps.state.name}`, ); }); diff --git a/spec/graphql/mutations/design_management/delete_spec.rb b/spec/graphql/mutations/design_management/delete_spec.rb index 3efa865c64b..93fff5e5103 100644 --- a/spec/graphql/mutations/design_management/delete_spec.rb +++ b/spec/graphql/mutations/design_management/delete_spec.rb @@ -86,9 +86,9 @@ RSpec.describe Mutations::DesignManagement::Delete do end end - it 'runs no more than 28 queries' do + it 'runs no more than 29 queries' do filenames.each(&:present?) # ignore setup - # Queries: as of 2019-08-28 + # Queries: as of 2021-07-22 # ------------- # 01. routing query # 02. find project by id @@ -100,25 +100,26 @@ RSpec.describe Mutations::DesignManagement::Delete do # 09. find namespace by id # 10. find group namespace by id # 11. project.authorizations for user (same query as 5) - # 12. project.project_features (same query as 3) - # 13. project.authorizations for user (same query as 5) - # 14. current designs by filename and issue - # 15, 16 project.authorizations for user (same query as 5) - # 17. find route by id and source_type + # 12. find user by id + # 13. project.project_features (same query as 3) + # 14. project.authorizations for user (same query as 5) + # 15. current designs by filename and issue + # 16, 17 project.authorizations for user (same query as 5) + # 18. find route by id and source_type # ------------- our queries are below: - # 18. start transaction 1 - # 19. start transaction 2 - # 20. find version by sha and issue - # 21. exists version with sha and issue? - # 22. leave transaction 2 - # 23. create version with sha and issue - # 24. create design-version links - # 25. validate version.actions.present? - # 26. validate version.issue.present? - # 27. validate version.sha is unique - # 28. leave transaction 1 + # 19. start transaction 1 + # 20. start transaction 2 + # 21. find version by sha and issue + # 22. exists version with sha and issue? + # 23. leave transaction 2 + # 24. create version with sha and issue + # 25. create design-version links + # 26. validate version.actions.present? + # 27. validate version.issue.present? + # 28. validate version.sha is unique + # 29. leave transaction 1 # - expect { run_mutation }.not_to exceed_query_limit(28) + expect { run_mutation }.not_to exceed_query_limit(29) end end diff --git a/spec/graphql/resolvers/issues_resolver_spec.rb b/spec/graphql/resolvers/issues_resolver_spec.rb index d0675633a9b..6e187e57729 100644 --- a/spec/graphql/resolvers/issues_resolver_spec.rb +++ b/spec/graphql/resolvers/issues_resolver_spec.rb @@ -393,13 +393,13 @@ RSpec.describe Resolvers::IssuesResolver do end it 'finds a specific issue with iid', :request_store do - result = batch_sync(max_queries: 4) { resolve_issues(iid: issue1.iid).to_a } + result = batch_sync(max_queries: 5) { resolve_issues(iid: issue1.iid).to_a } expect(result).to contain_exactly(issue1) end it 'batches queries that only include IIDs', :request_store do - result = batch_sync(max_queries: 4) do + result = batch_sync(max_queries: 5) do [issue1, issue2] .map { |issue| resolve_issues(iid: issue.iid.to_s) } .flat_map(&:to_a) @@ -409,7 +409,7 @@ RSpec.describe Resolvers::IssuesResolver do end it 'finds a specific issue with iids', :request_store do - result = batch_sync(max_queries: 4) do + result = batch_sync(max_queries: 5) do resolve_issues(iids: [issue1.iid]).to_a end diff --git a/spec/lib/gitlab/background_migration/copy_ci_builds_columns_to_security_scans_spec.rb b/spec/lib/gitlab/background_migration/copy_ci_builds_columns_to_security_scans_spec.rb new file mode 100644 index 00000000000..db822f36c21 --- /dev/null +++ b/spec/lib/gitlab/background_migration/copy_ci_builds_columns_to_security_scans_spec.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::BackgroundMigration::CopyCiBuildsColumnsToSecurityScans, schema: 20210728174349 do + let(:migration) { described_class.new } + + let_it_be(:namespaces) { table(:namespaces) } + let_it_be(:projects) { table(:projects) } + let_it_be(:ci_pipelines) { table(:ci_pipelines) } + let_it_be(:ci_builds) { table(:ci_builds) } + let_it_be(:security_scans) { table(:security_scans) } + + let!(:namespace) { namespaces.create!(name: 'namespace', path: 'namespace') } + let!(:project1) { projects.create!(namespace_id: namespace.id) } + let!(:project2) { projects.create!(namespace_id: namespace.id) } + let!(:pipeline1) { ci_pipelines.create!(status: "success")} + let!(:pipeline2) { ci_pipelines.create!(status: "success")} + + let!(:build1) { ci_builds.create!(commit_id: pipeline1.id, type: 'Ci::Build', project_id: project1.id) } + let!(:build2) { ci_builds.create!(commit_id: pipeline2.id, type: 'Ci::Build', project_id: project2.id) } + let!(:build3) { ci_builds.create!(commit_id: pipeline1.id, type: 'Ci::Build', project_id: project1.id) } + + let!(:scan1) { security_scans.create!(build_id: build1.id, scan_type: 1) } + let!(:scan2) { security_scans.create!(build_id: build2.id, scan_type: 1) } + let!(:scan3) { security_scans.create!(build_id: build3.id, scan_type: 1) } + + subject { migration.perform(scan1.id, scan2.id) } + + before do + stub_const("#{described_class}::UPDATE_BATCH_SIZE", 2) + end + + it 'copies `project_id`, `commit_id` from `ci_builds` to `security_scans`', :aggregate_failures do + expect(migration).to receive(:mark_job_as_succeeded).with(scan1.id, scan2.id) + + subject + + scan1.reload + expect(scan1.project_id).to eq(project1.id) + expect(scan1.pipeline_id).to eq(pipeline1.id) + + scan2.reload + expect(scan2.project_id).to eq(project2.id) + expect(scan2.pipeline_id).to eq(pipeline2.id) + + scan3.reload + expect(scan3.project_id).to be_nil + expect(scan3.pipeline_id).to be_nil + end +end diff --git a/spec/lib/gitlab/usage/docs/helper_spec.rb b/spec/lib/gitlab/usage/docs/helper_spec.rb index e2bb1d8d818..6cff1ab4126 100644 --- a/spec/lib/gitlab/usage/docs/helper_spec.rb +++ b/spec/lib/gitlab/usage/docs/helper_spec.rb @@ -13,7 +13,7 @@ RSpec.describe Gitlab::Usage::Docs::Helper do let(:metric_definition) do { - data_category: 'Standard', + data_category: 'standard', name: 'test_metric', description: description, product_group: 'group::product intelligence', @@ -66,7 +66,7 @@ RSpec.describe Gitlab::Usage::Docs::Helper do end describe '#render_data_category' do - let(:expected) { 'Data Category: `Standard`' } + let(:expected) { 'Data Category: `standard`' } it { expect(helper.render_data_category(metric_definition)).to eq(expected) } end diff --git a/spec/lib/gitlab/usage/metric_definition_spec.rb b/spec/lib/gitlab/usage/metric_definition_spec.rb index a7cff80e43a..1ae8a0881ef 100644 --- a/spec/lib/gitlab/usage/metric_definition_spec.rb +++ b/spec/lib/gitlab/usage/metric_definition_spec.rb @@ -18,7 +18,7 @@ RSpec.describe Gitlab::Usage::MetricDefinition do distribution: %w(ee ce), tier: %w(free starter premium ultimate bronze silver gold), name: 'uuid', - data_category: 'Standard' + data_category: 'standard' } end @@ -199,7 +199,7 @@ RSpec.describe Gitlab::Usage::MetricDefinition do data_source: 'database', distribution: %w(ee ce), tier: %w(free starter premium ultimate bronze silver gold), - data_category: 'Optional' + data_category: 'optional' } end diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/collected_data_categories_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/collected_data_categories_metric_spec.rb index 8f52d550e5c..1b2170baf17 100644 --- a/spec/lib/gitlab/usage/metrics/instrumentations/collected_data_categories_metric_spec.rb +++ b/spec/lib/gitlab/usage/metrics/instrumentations/collected_data_categories_metric_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe Gitlab::Usage::Metrics::Instrumentations::CollectedDataCategoriesMetric do it_behaves_like 'a correct instrumented metric value', {} do - let(:expected_value) { %w[Standard Subscription Operational Optional] } + let(:expected_value) { %w[standard subscription operational optional] } before do allow_next_instance_of(ServicePing::PermitDataCategoriesService) do |instance| diff --git a/spec/lib/gitlab/usage_data_metrics_spec.rb b/spec/lib/gitlab/usage_data_metrics_spec.rb index cb3ca32b31e..7608fa7e7a0 100644 --- a/spec/lib/gitlab/usage_data_metrics_spec.rb +++ b/spec/lib/gitlab/usage_data_metrics_spec.rb @@ -26,130 +26,54 @@ RSpec.describe Gitlab::UsageDataMetrics do expect(subject[:counts]).to include(:boards) end - it 'includes i_quickactions_approve monthly and weekly key' do - expect(subject[:redis_hll_counters][:quickactions]).to include(:i_quickactions_approve_monthly) - expect(subject[:redis_hll_counters][:quickactions]).to include(:i_quickactions_approve_weekly) - end - - it 'includes ide_edit monthly and weekly keys' do - expect(subject[:redis_hll_counters][:ide_edit].keys).to contain_exactly(*[ - :g_edit_by_web_ide_monthly, :g_edit_by_web_ide_weekly, - :g_edit_by_sfe_monthly, :g_edit_by_sfe_weekly, - :g_edit_by_sse_monthly, :g_edit_by_sse_weekly, - :g_edit_by_snippet_ide_monthly, :g_edit_by_snippet_ide_weekly, - :ide_edit_total_unique_counts_monthly, :ide_edit_total_unique_counts_weekly - ]) - end - - it 'includes incident_management_alerts monthly and weekly keys' do - expect(subject[:redis_hll_counters][:incident_management_alerts].keys).to contain_exactly(*[ - :incident_management_alert_create_incident_monthly, :incident_management_alert_create_incident_weekly - ]) - end - - it 'includes incident_management monthly and weekly keys' do - expect(subject[:redis_hll_counters][:incident_management]).to include( - :incident_management_incident_created_monthly, :incident_management_incident_created_weekly, - :incident_management_incident_reopened_monthly, :incident_management_incident_reopened_weekly, - :incident_management_incident_closed_monthly, :incident_management_incident_closed_weekly, - :incident_management_incident_assigned_monthly, :incident_management_incident_assigned_weekly, - :incident_management_incident_todo_monthly, :incident_management_incident_todo_weekly, - :incident_management_incident_comment_monthly, :incident_management_incident_comment_weekly, - :incident_management_incident_zoom_meeting_monthly, :incident_management_incident_zoom_meeting_weekly, - :incident_management_incident_relate_monthly, :incident_management_incident_relate_weekly, - :incident_management_incident_unrelate_monthly, :incident_management_incident_unrelate_weekly, - :incident_management_incident_change_confidential_monthly, :incident_management_incident_change_confidential_weekly, - :incident_management_alert_status_changed_monthly, :incident_management_alert_status_changed_weekly, - :incident_management_alert_assigned_monthly, :incident_management_alert_assigned_weekly, - :incident_management_alert_todo_monthly, :incident_management_alert_todo_weekly, - :incident_management_total_unique_counts_monthly, :incident_management_total_unique_counts_weekly - ) - end - - it 'includes testing monthly and weekly keys' do - expect(subject[:redis_hll_counters][:testing]).to include( - :i_testing_test_case_parsed_monthly, :i_testing_test_case_parsed_weekly, - :users_expanding_testing_code_quality_report_monthly, :users_expanding_testing_code_quality_report_weekly, - :users_expanding_testing_accessibility_report_monthly, :users_expanding_testing_accessibility_report_weekly, - :i_testing_summary_widget_total_monthly, :i_testing_summary_widget_total_weekly, - :testing_total_unique_counts_monthly - ) - end - - it 'includes source_code monthly and weekly keys' do - expect(subject[:redis_hll_counters][:source_code].keys).to contain_exactly(*[ - :wiki_action_monthly, :wiki_action_weekly, - :design_action_monthly, :design_action_weekly, - :project_action_monthly, :project_action_weekly, - :git_write_action_monthly, :git_write_action_weekly, - :merge_request_action_monthly, :merge_request_action_weekly, - :i_source_code_code_intelligence_monthly, :i_source_code_code_intelligence_weekly - ]) - end - - it 'includes code_review monthly and weekly keys' do - category = 'code_review' - events = Gitlab::UsageDataCounters::HLLRedisCounter.known_events.select { |event| event['category'] == category}.map { |event| event['name'] } - known_events_keys = [] - events.each do |event_name| - known_events_keys << "#{event_name}_monthly".to_sym - known_events_keys << "#{event_name}_weekly".to_sym + describe 'Redis_HLL_counters' do + # categories to be merged on future MR + let(:ignored_metric_files_key_patterns) do + %w( + analytics + ci_templates + ecosystem + deploy_token_packages + user_packages + epic_events + snippets + epics_usage + network_policies + ).freeze end - known_events_keys << "#{category}_total_unique_counts_monthly".to_sym - known_events_keys << "#{category}_total_unique_counts_weekly".to_sym - - expect(subject[:redis_hll_counters][:code_review].keys).to contain_exactly(*known_events_keys) - end - it 'includes terraform monthly key' do - expect(subject[:redis_hll_counters][:terraform].keys).to include(:p_terraform_state_api_unique_users_monthly) - end + let(:metric_files_key_paths) do + Gitlab::Usage::MetricDefinition + .definitions + .select { |k, v| v.attributes[:data_source] == 'redis_hll' && v.key_path.starts_with?('redis_hll_counters') } + .reject { |k, v| v.key_path =~ Regexp.union(ignored_metric_files_key_patterns) } + .keys + .sort + end - it 'includes terraform monthly and weekly keys' do - expect(subject[:redis_hll_counters][:pipeline_authoring].keys).to contain_exactly(*[ - :o_pipeline_authoring_unique_users_committing_ciconfigfile_monthly, :o_pipeline_authoring_unique_users_committing_ciconfigfile_weekly, - :o_pipeline_authoring_unique_users_pushing_mr_ciconfigfile_monthly, :o_pipeline_authoring_unique_users_pushing_mr_ciconfigfile_weekly, - :pipeline_authoring_total_unique_counts_monthly, :pipeline_authoring_total_unique_counts_weekly - ]) - end + # Recursively traverse nested Hash of a generated Usage Ping to return an Array of key paths + # in the dotted format used in metric definition YAML files, e.g.: 'count.category.metric_name' + def parse_service_ping_keys(object, key_path = []) + if object.is_a?(Hash) + object.each_with_object([]) do |(key, value), result| + result.append parse_service_ping_keys(value, key_path + [key]) + end + else + key_path.join('.') + end + end - it 'includes users_expanding_secure_security_report monthly and weekly keys' do - expect(subject[:redis_hll_counters][:secure].keys).to contain_exactly(*[ - :users_expanding_secure_security_report_monthly, :users_expanding_secure_security_report_weekly - ]) - end + let(:usage_ping_key_paths) do + parse_service_ping_keys(subject) + .flatten + .select { |k| k.starts_with?('redis_hll_counters') } + .reject {|k| k =~ Regexp.union(ignored_metric_files_key_patterns) } + .sort + end - it 'includes issues_edit monthly and weekly keys' do - expect(subject[:redis_hll_counters][:issues_edit].keys).to include( - :g_project_management_issue_title_changed_monthly, :g_project_management_issue_title_changed_weekly, - :g_project_management_issue_description_changed_monthly, :g_project_management_issue_description_changed_weekly, - :g_project_management_issue_assignee_changed_monthly, :g_project_management_issue_assignee_changed_weekly, - :g_project_management_issue_made_confidential_monthly, :g_project_management_issue_made_confidential_weekly, - :g_project_management_issue_made_visible_monthly, :g_project_management_issue_made_visible_weekly, - :g_project_management_issue_created_monthly, :g_project_management_issue_created_weekly, - :g_project_management_issue_closed_monthly, :g_project_management_issue_closed_weekly, - :g_project_management_issue_reopened_monthly, :g_project_management_issue_reopened_weekly, - :g_project_management_issue_label_changed_monthly, :g_project_management_issue_label_changed_weekly, - :g_project_management_issue_milestone_changed_monthly, :g_project_management_issue_milestone_changed_weekly, - :g_project_management_issue_cross_referenced_monthly, :g_project_management_issue_cross_referenced_weekly, - :g_project_management_issue_moved_monthly, :g_project_management_issue_moved_weekly, - :g_project_management_issue_related_monthly, :g_project_management_issue_related_weekly, - :g_project_management_issue_unrelated_monthly, :g_project_management_issue_unrelated_weekly, - :g_project_management_issue_marked_as_duplicate_monthly, :g_project_management_issue_marked_as_duplicate_weekly, - :g_project_management_issue_locked_monthly, :g_project_management_issue_locked_weekly, - :g_project_management_issue_unlocked_monthly, :g_project_management_issue_unlocked_weekly, - :g_project_management_issue_designs_added_monthly, :g_project_management_issue_designs_added_weekly, - :g_project_management_issue_designs_modified_monthly, :g_project_management_issue_designs_modified_weekly, - :g_project_management_issue_designs_removed_monthly, :g_project_management_issue_designs_removed_weekly, - :g_project_management_issue_due_date_changed_monthly, :g_project_management_issue_due_date_changed_weekly, - :g_project_management_issue_time_estimate_changed_monthly, :g_project_management_issue_time_estimate_changed_weekly, - :g_project_management_issue_time_spent_changed_monthly, :g_project_management_issue_time_spent_changed_weekly, - :g_project_management_issue_comment_added_monthly, :g_project_management_issue_comment_added_weekly, - :g_project_management_issue_comment_edited_monthly, :g_project_management_issue_comment_edited_weekly, - :g_project_management_issue_comment_removed_monthly, :g_project_management_issue_comment_removed_weekly, - :g_project_management_issue_cloned_monthly, :g_project_management_issue_cloned_weekly, - :issues_edit_total_unique_counts_monthly, :issues_edit_total_unique_counts_weekly - ) + it 'is included in the Usage Ping hash structure' do + expect(metric_files_key_paths).to match_array(usage_ping_key_paths) + end end it 'includes counts keys' do diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb index 86121b984ac..b216d3698b5 100644 --- a/spec/lib/gitlab/usage_data_spec.rb +++ b/spec/lib/gitlab/usage_data_spec.rb @@ -1080,7 +1080,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do end it 'reports collected data categories' do - expected_value = %w[Standard Subscription Operational Optional] + expected_value = %w[standard subscription operational optional] allow_next_instance_of(ServicePing::PermitDataCategoriesService) do |instance| expect(instance).to receive(:execute).and_return(expected_value) diff --git a/spec/migrations/schedule_copy_ci_builds_columns_to_security_scans_spec.rb b/spec/migrations/schedule_copy_ci_builds_columns_to_security_scans_spec.rb new file mode 100644 index 00000000000..5ebd8753892 --- /dev/null +++ b/spec/migrations/schedule_copy_ci_builds_columns_to_security_scans_spec.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe ScheduleCopyCiBuildsColumnsToSecurityScans do + let_it_be(:namespaces) { table(:namespaces) } + let_it_be(:projects) { table(:projects) } + let_it_be(:ci_pipelines) { table(:ci_pipelines) } + let_it_be(:ci_builds) { table(:ci_builds) } + let_it_be(:security_scans) { table(:security_scans) } + + let!(:namespace) { namespaces.create!(name: 'namespace', path: 'namespace') } + let!(:project) { projects.create!(namespace_id: namespace.id) } + let!(:pipeline) { ci_pipelines.create!(status: "success")} + + let!(:build1) { ci_builds.create!(commit_id: pipeline.id, type: 'Ci::Build', project_id: project.id) } + let!(:build2) { ci_builds.create!(commit_id: pipeline.id, type: 'Ci::Build', project_id: project.id) } + let!(:build3) { ci_builds.create!(commit_id: pipeline.id, type: 'Ci::Build', project_id: project.id) } + + let!(:scan1) { security_scans.create!(build_id: build1.id, scan_type: 1) } + let!(:scan2) { security_scans.create!(build_id: build2.id, scan_type: 1) } + let!(:scan3) { security_scans.create!(build_id: build3.id, scan_type: 1) } + + before do + stub_const("#{described_class}::BATCH_SIZE", 2) + allow_next_instance_of(Gitlab::BackgroundMigration::CopyCiBuildsColumnsToSecurityScans) do |instance| + allow(instance).to receive(:mark_job_as_succeeded) + end + end + + around do |example| + freeze_time { Sidekiq::Testing.fake! { example.run } } + end + + it 'schedules background migrations', :aggregate_failures do + migrate! + + expect(BackgroundMigrationWorker.jobs.size).to eq(2) + expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, scan1.id, scan2.id) + expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, scan3.id, scan3.id) + end +end diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb index 26d2a05c54f..8e28b7dd250 100644 --- a/spec/models/issue_spec.rb +++ b/spec/models/issue_spec.rb @@ -796,17 +796,47 @@ RSpec.describe Issue do end end + shared_examples 'hidden issue readable by user' do + before do + issue.author.ban! + end + + specify do + is_expected.to eq(true) + end + + after do + issue.author.activate! + end + end + + shared_examples 'hidden issue not readable by user' do + before do + issue.author.ban! + end + + specify do + is_expected.to eq(false) + end + + after do + issue.author.activate! + end + end + context 'with an admin user' do let(:user) { build(:admin) } context 'when admin mode is enabled', :enable_admin_mode do it_behaves_like 'issue readable by user' it_behaves_like 'confidential issue readable by user' + it_behaves_like 'hidden issue readable by user' end context 'when admin mode is disabled' do it_behaves_like 'issue not readable by user' it_behaves_like 'confidential issue not readable by user' + it_behaves_like 'hidden issue not readable by user' end end @@ -817,6 +847,7 @@ RSpec.describe Issue do it_behaves_like 'issue readable by user' it_behaves_like 'confidential issue readable by user' + it_behaves_like 'hidden issue not readable by user' end context 'with a reporter user' do @@ -826,6 +857,7 @@ RSpec.describe Issue do it_behaves_like 'issue readable by user' it_behaves_like 'confidential issue readable by user' + it_behaves_like 'hidden issue not readable by user' end context 'with a guest user' do @@ -835,6 +867,7 @@ RSpec.describe Issue do it_behaves_like 'issue readable by user' it_behaves_like 'confidential issue not readable by user' + it_behaves_like 'hidden issue not readable by user' context 'when user is an assignee' do before do @@ -843,6 +876,7 @@ RSpec.describe Issue do it_behaves_like 'issue readable by user' it_behaves_like 'confidential issue readable by user' + it_behaves_like 'hidden issue not readable by user' end context 'when user is the author' do @@ -852,6 +886,7 @@ RSpec.describe Issue do it_behaves_like 'issue readable by user' it_behaves_like 'confidential issue readable by user' + it_behaves_like 'hidden issue not readable by user' end end @@ -861,6 +896,7 @@ RSpec.describe Issue do it_behaves_like 'issue readable by user' it_behaves_like 'confidential issue not readable by user' + it_behaves_like 'hidden issue not readable by user' end context 'using an internal project' do @@ -873,6 +909,7 @@ RSpec.describe Issue do it_behaves_like 'issue readable by user' it_behaves_like 'confidential issue not readable by user' + it_behaves_like 'hidden issue not readable by user' end context 'using an external user' do @@ -882,6 +919,7 @@ RSpec.describe Issue do it_behaves_like 'issue not readable by user' it_behaves_like 'confidential issue not readable by user' + it_behaves_like 'hidden issue not readable by user' end end @@ -892,6 +930,7 @@ RSpec.describe Issue do it_behaves_like 'issue not readable by user' it_behaves_like 'confidential issue not readable by user' + it_behaves_like 'hidden issue not readable by user' end end @@ -1160,6 +1199,26 @@ RSpec.describe Issue do end end + describe '.without_hidden' do + let_it_be(:banned_user) { create(:user, :banned) } + let_it_be(:public_issue) { create(:issue, project: reusable_project) } + let_it_be(:hidden_issue) { create(:issue, project: reusable_project, author: banned_user) } + + it 'only returns without_hidden issues' do + expect(described_class.without_hidden).to eq([public_issue]) + end + + context 'when feature flag is disabled' do + before do + stub_feature_flags(ban_user_feature_flag: false) + end + + it 'returns public and hidden issues' do + expect(described_class.without_hidden).to eq([public_issue, hidden_issue]) + end + end + end + describe '.by_project_id_and_iid' do let_it_be(:issue_a) { create(:issue, project: reusable_project) } let_it_be(:issue_b) { create(:issue, iid: issue_a.iid) } diff --git a/spec/policies/issue_policy_spec.rb b/spec/policies/issue_policy_spec.rb index 8ff936d5a35..d62271eedf6 100644 --- a/spec/policies/issue_policy_spec.rb +++ b/spec/policies/issue_policy_spec.rb @@ -360,6 +360,21 @@ RSpec.describe IssuePolicy do expect(permissions(assignee, confidential_issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata) end end + + context 'with a hidden issue' do + let(:user) { create(:user) } + let(:banned_user) { create(:user, :banned) } + let(:admin) { create(:user, :admin)} + let(:hidden_issue) { create(:issue, project: project, author: banned_user) } + + it 'does not allow non-admin user to read the issue' do + expect(permissions(user, hidden_issue)).not_to be_allowed(:read_issue) + end + + it 'allows admin to read the issue', :enable_admin_mode do + expect(permissions(admin, hidden_issue)).to be_allowed(:read_issue) + end + end end context 'with external authorization enabled' do diff --git a/spec/services/service_ping/permit_data_categories_service_spec.rb b/spec/services/service_ping/permit_data_categories_service_spec.rb index 5b25f216c4d..550c0ea5e13 100644 --- a/spec/services/service_ping/permit_data_categories_service_spec.rb +++ b/spec/services/service_ping/permit_data_categories_service_spec.rb @@ -13,7 +13,7 @@ RSpec.describe ServicePing::PermitDataCategoriesService do end it 'returns all categories' do - expect(permitted_categories).to match_array(%w[Standard Subscription Operational Optional]) + expect(permitted_categories).to match_array(%w[standard subscription operational optional]) end end diff --git a/spec/support/shared_contexts/services/service_ping/stubbed_service_ping_metrics_definitions_shared_context.rb b/spec/support/shared_contexts/services/service_ping/stubbed_service_ping_metrics_definitions_shared_context.rb index ea72398010c..6b49a415889 100644 --- a/spec/support/shared_contexts/services/service_ping/stubbed_service_ping_metrics_definitions_shared_context.rb +++ b/spec/support/shared_contexts/services/service_ping/stubbed_service_ping_metrics_definitions_shared_context.rb @@ -6,20 +6,20 @@ RSpec.shared_context 'stubbed service ping metrics definitions' do let(:metrics_definitions) { standard_metrics + subscription_metrics + operational_metrics + optional_metrics } let(:standard_metrics) do [ - metric_attributes('uuid', "Standard") + metric_attributes('uuid', "standard") ] end let(:operational_metrics) do [ - metric_attributes('counts.merge_requests', "Operational"), - metric_attributes('counts.todos', "Operational") + metric_attributes('counts.merge_requests', "operational"), + metric_attributes('counts.todos', "operational") ] end let(:optional_metrics) do [ - metric_attributes('counts.boards', "Optional"), + metric_attributes('counts.boards', "optional"), metric_attributes('gitaly.filesystems', '').except('data_category') ] end |