Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-02-23 21:09:16 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-02-23 21:09:16 +0300
commitf6b95a66bc12adeb4fac7277d1eb345d9e7819fd (patch)
treeb2739bb34529d005a356df12da50c0e38caf6a52 /spec
parentb465b2440bbf8ac8c4ef21728ab14fb48589057c (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/projects/blob_controller_spec.rb29
-rw-r--r--spec/features/projects/user_changes_project_visibility_spec.rb19
-rw-r--r--spec/frontend/ci/runner/admin_new_runner_app/admin_new_runner_app_spec.js4
-rw-r--r--spec/helpers/analytics/cycle_analytics_helper_spec.rb61
-rw-r--r--spec/lib/gitlab/analytics/cycle_analytics/request_params_spec.rb27
-rw-r--r--spec/lib/gitlab/database/postgres_partition_spec.rb14
-rw-r--r--spec/lib/gitlab/database/tables_locker_spec.rb205
-rw-r--r--spec/lib/gitlab/patch/node_loader_spec.rb80
-rw-r--r--spec/lib/gitlab/usage_data_counters/editor_unique_counter_spec.rb21
-rw-r--r--spec/lib/sidebars/projects/menus/infrastructure_menu_spec.rb12
-rw-r--r--spec/models/ci/runner_machine_spec.rb112
-rw-r--r--spec/models/ci/runner_spec.rb114
-rw-r--r--spec/requests/api/draft_notes_spec.rb28
-rw-r--r--spec/services/projects/update_service_spec.rb46
-rw-r--r--spec/support/rspec_order_todo.yml2
-rw-r--r--spec/support/shared_examples/analytics/cycle_analytics/request_params_examples.rb127
16 files changed, 593 insertions, 308 deletions
diff --git a/spec/controllers/projects/blob_controller_spec.rb b/spec/controllers/projects/blob_controller_spec.rb
index 5e22be1c488..c091badd09d 100644
--- a/spec/controllers/projects/blob_controller_spec.rb
+++ b/spec/controllers/projects/blob_controller_spec.rb
@@ -345,11 +345,23 @@ RSpec.describe Projects::BlobController do
end
end
- it_behaves_like 'tracking unique hll events' do
+ context 'events tracking' do
+ let(:target_event) { 'g_edit_by_sfe' }
+
subject(:request) { put :update, params: default_params }
- let(:target_event) { 'g_edit_by_sfe' }
- let(:expected_value) { instance_of(Integer) }
+ it_behaves_like 'tracking unique hll events' do
+ let(:expected_value) { instance_of(Integer) }
+ end
+
+ it_behaves_like 'Snowplow event tracking with RedisHLL context' do
+ let(:action) { 'perform_sfe_action' }
+ let(:category) { described_class.to_s }
+ let(:namespace) { project.namespace.reload }
+ let(:property) { target_event }
+ let(:label) { 'usage_activity_by_stage_monthly.create.action_monthly_active_users_sfe_edit' }
+ let(:feature_flag_name) { 'route_hll_to_snowplow_phase4' }
+ end
end
end
@@ -477,6 +489,7 @@ RSpec.describe Projects::BlobController do
describe 'POST create' do
let(:user) { create(:user) }
+ let(:target_event) { 'g_edit_by_sfe' }
let(:default_params) do
{
namespace_id: project.namespace,
@@ -498,10 +511,18 @@ RSpec.describe Projects::BlobController do
subject(:request) { post :create, params: default_params }
it_behaves_like 'tracking unique hll events' do
- let(:target_event) { 'g_edit_by_sfe' }
let(:expected_value) { instance_of(Integer) }
end
+ it_behaves_like 'Snowplow event tracking with RedisHLL context' do
+ let(:action) { 'perform_sfe_action' }
+ let(:category) { described_class.to_s }
+ let(:namespace) { project.namespace }
+ let(:property) { target_event }
+ let(:label) { 'usage_activity_by_stage_monthly.create.action_monthly_active_users_sfe_edit' }
+ let(:feature_flag_name) { 'route_hll_to_snowplow_phase4' }
+ end
+
it 'redirects to blob' do
request
diff --git a/spec/features/projects/user_changes_project_visibility_spec.rb b/spec/features/projects/user_changes_project_visibility_spec.rb
index 5daa5b98b6e..64af25aea28 100644
--- a/spec/features/projects/user_changes_project_visibility_spec.rb
+++ b/spec/features/projects/user_changes_project_visibility_spec.rb
@@ -91,23 +91,4 @@ RSpec.describe 'User changes public project visibility', :js, feature_category:
it_behaves_like 'does not require confirmation'
end
-
- context 'with unlink_fork_network_upon_visibility_decrease = false' do
- let(:project) { create(:project, :empty_repo, :public) }
-
- before do
- stub_feature_flags(unlink_fork_network_upon_visibility_decrease: false)
-
- fork_project(project, project.first_owner)
-
- sign_in(project.first_owner)
-
- visit edit_project_path(project)
-
- # https://gitlab.com/gitlab-org/gitlab/-/issues/381259
- allow(Gitlab::QueryLimiting::Transaction).to receive(:threshold).and_return(110)
- end
-
- it_behaves_like 'does not require confirmation'
- end
end
diff --git a/spec/frontend/ci/runner/admin_new_runner_app/admin_new_runner_app_spec.js b/spec/frontend/ci/runner/admin_new_runner_app/admin_new_runner_app_spec.js
index 1d8ae6ebd3f..37392a9f1f4 100644
--- a/spec/frontend/ci/runner/admin_new_runner_app/admin_new_runner_app_spec.js
+++ b/spec/frontend/ci/runner/admin_new_runner_app/admin_new_runner_app_spec.js
@@ -1,6 +1,8 @@
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import { GlSprintf } from '@gitlab/ui';
+import { s__ } from '~/locale';
+
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { createAlert, VARIANT_SUCCESS } from '~/flash';
@@ -85,7 +87,7 @@ describe('AdminNewRunnerApp', () => {
it('pushes an alert to be shown after redirection', () => {
expect(saveAlertToLocalStorage).toHaveBeenCalledWith({
- message: expect.any(String),
+ message: s__('Runners|Runner created.'),
variant: VARIANT_SUCCESS,
});
});
diff --git a/spec/helpers/analytics/cycle_analytics_helper_spec.rb b/spec/helpers/analytics/cycle_analytics_helper_spec.rb
deleted file mode 100644
index d906646e25c..00000000000
--- a/spec/helpers/analytics/cycle_analytics_helper_spec.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-# frozen_string_literal: true
-require "spec_helper"
-
-RSpec.describe Analytics::CycleAnalyticsHelper do
- describe '#cycle_analytics_initial_data' do
- let(:user) { create(:user, name: 'fake user', username: 'fake_user') }
- let(:image_path_keys) { [:empty_state_svg_path, :no_data_svg_path, :no_access_svg_path] }
- let(:api_path_keys) { [:milestones_path, :labels_path] }
- let(:additional_data_keys) { [:full_path, :group_id, :group_path, :project_id, :request_path] }
- let(:group) { create(:group) }
-
- subject(:cycle_analytics_data) { helper.cycle_analytics_initial_data(project, group) }
-
- before do
- project.add_maintainer(user)
- end
-
- context 'when a group is present' do
- let(:project) { create(:project, group: group) }
-
- it "sets the correct data keys" do
- expect(cycle_analytics_data.keys)
- .to match_array(api_path_keys + image_path_keys + additional_data_keys)
- end
-
- it "sets group paths" do
- expect(cycle_analytics_data)
- .to include({
- full_path: project.full_path,
- group_path: "/#{project.namespace.name}",
- group_id: project.namespace.id,
- request_path: "/#{project.full_path}/-/value_stream_analytics",
- milestones_path: "/groups/#{group.name}/-/milestones.json",
- labels_path: "/groups/#{group.name}/-/labels.json"
- })
- end
- end
-
- context 'when a group is not present' do
- let(:group) { nil }
- let(:project) { create(:project) }
-
- it "sets the correct data keys" do
- expect(cycle_analytics_data.keys)
- .to match_array(image_path_keys + api_path_keys + additional_data_keys)
- end
-
- it "sets project name space paths" do
- expect(cycle_analytics_data)
- .to include({
- full_path: project.full_path,
- group_path: project.namespace.path,
- group_id: project.namespace.id,
- request_path: "/#{project.full_path}/-/value_stream_analytics",
- milestones_path: "/#{project.full_path}/-/milestones.json",
- labels_path: "/#{project.full_path}/-/labels.json"
- })
- end
- end
- end
-end
diff --git a/spec/lib/gitlab/analytics/cycle_analytics/request_params_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/request_params_spec.rb
new file mode 100644
index 00000000000..6f2f1cd9124
--- /dev/null
+++ b/spec/lib/gitlab/analytics/cycle_analytics/request_params_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Analytics::CycleAnalytics::RequestParams, feature_category: :value_stream_management do
+ it_behaves_like 'unlicensed cycle analytics request params' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:root_group) { create(:group) }
+ let_it_be(:project) { create(:project, group: root_group) }
+
+ let(:namespace) { project.project_namespace }
+
+ describe 'project-level data attributes' do
+ subject(:attributes) { described_class.new(params).to_data_attributes }
+
+ it 'includes the namespace attribute' do
+ expect(attributes).to match(hash_including({
+ namespace: {
+ name: project.name,
+ full_path: project.full_path,
+ avatar_url: project.avatar_url
+ }
+ }))
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/database/postgres_partition_spec.rb b/spec/lib/gitlab/database/postgres_partition_spec.rb
index 14a4d405621..48dbdbc7757 100644
--- a/spec/lib/gitlab/database/postgres_partition_spec.rb
+++ b/spec/lib/gitlab/database/postgres_partition_spec.rb
@@ -2,7 +2,8 @@
require 'spec_helper'
-RSpec.describe Gitlab::Database::PostgresPartition, type: :model do
+RSpec.describe Gitlab::Database::PostgresPartition, type: :model, feature_category: :database do
+ let(:current_schema) { ActiveRecord::Base.connection.select_value("SELECT current_schema()") }
let(:schema) { 'gitlab_partitions_dynamic' }
let(:name) { '_test_partition_01' }
let(:identifier) { "#{schema}.#{name}" }
@@ -56,9 +57,20 @@ RSpec.describe Gitlab::Database::PostgresPartition, type: :model do
expect(partitions.pluck(:name)).to eq([name, second_name])
end
+ it 'returns the partitions if the parent table schema is included in the table name' do
+ partitions = described_class.for_parent_table("#{current_schema}._test_partitioned_table")
+
+ expect(partitions.count).to eq(2)
+ expect(partitions.pluck(:name)).to eq([name, second_name])
+ end
+
it 'does not return partitions for tables not in the current schema' do
expect(described_class.for_parent_table('_test_other_table').count).to eq(0)
end
+
+ it 'does not return partitions for tables if the schema is not the current' do
+ expect(described_class.for_parent_table('foo_bar._test_partitioned_table').count).to eq(0)
+ end
end
describe '#parent_identifier' do
diff --git a/spec/lib/gitlab/database/tables_locker_spec.rb b/spec/lib/gitlab/database/tables_locker_spec.rb
index d74f455eaad..1c4d6ddbf3c 100644
--- a/spec/lib/gitlab/database/tables_locker_spec.rb
+++ b/spec/lib/gitlab/database/tables_locker_spec.rb
@@ -2,20 +2,38 @@
require 'spec_helper'
-RSpec.describe Gitlab::Database::TablesLocker, :reestablished_active_record_base, :delete, :silence_stdout,
- :suppress_gitlab_schemas_validate_connection, feature_category: :pods do
- let(:detached_partition_table) { '_test_gitlab_main_part_20220101' }
- let(:lock_writes_manager) do
+RSpec.describe Gitlab::Database::TablesLocker, :suppress_gitlab_schemas_validate_connection, :silence_stdout,
+ feature_category: :pods do
+ let(:default_lock_writes_manager) do
instance_double(Gitlab::Database::LockWritesManager, lock_writes: nil, unlock_writes: nil)
end
before do
- allow(Gitlab::Database::LockWritesManager).to receive(:new).with(any_args).and_return(lock_writes_manager)
+ allow(Gitlab::Database::LockWritesManager).to receive(:new).with(any_args).and_return(default_lock_writes_manager)
+ # Limiting the scope of the tests to a subset of the database tables
+ allow(Gitlab::Database::GitlabSchema).to receive(:tables_to_schema).and_return({
+ 'application_setttings' => :gitlab_main_clusterwide,
+ 'projects' => :gitlab_main,
+ 'security_findings' => :gitlab_main,
+ 'ci_builds' => :gitlab_ci,
+ 'ci_jobs' => :gitlab_ci,
+ 'loose_foreign_keys_deleted_records' => :gitlab_shared,
+ 'ar_internal_metadata' => :gitlab_internal
+ })
end
before(:all) do
+ create_partition_sql = <<~SQL
+ CREATE TABLE IF NOT EXISTS #{Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA}.security_findings_test_partition
+ PARTITION OF security_findings
+ FOR VALUES IN (0)
+ SQL
+
+ ApplicationRecord.connection.execute(create_partition_sql)
+ Ci::ApplicationRecord.connection.execute(create_partition_sql)
+
create_detached_partition_sql = <<~SQL
- CREATE TABLE IF NOT EXISTS gitlab_partitions_dynamic._test_gitlab_main_part_20220101 (
+ CREATE TABLE IF NOT EXISTS gitlab_partitions_dynamic._test_gitlab_main_part_202201 (
id bigserial primary key not null
)
SQL
@@ -31,33 +49,73 @@ RSpec.describe Gitlab::Database::TablesLocker, :reestablished_active_record_base
end
end
- after(:all) do
- drop_detached_partition_sql = <<~SQL
- DROP TABLE IF EXISTS gitlab_partitions_dynamic._test_gitlab_main_part_20220101
- SQL
+ shared_examples "lock tables" do |gitlab_schema, database_name|
+ let(:connection) { Gitlab::Database.database_base_models[database_name].connection }
+ let(:tables_to_lock) do
+ Gitlab::Database::GitlabSchema
+ .tables_to_schema.filter_map { |table_name, schema| table_name if schema == gitlab_schema }
+ end
- ApplicationRecord.connection.execute(drop_detached_partition_sql)
- Ci::ApplicationRecord.connection.execute(drop_detached_partition_sql)
+ it "locks table in schema #{gitlab_schema} and database #{database_name}" do
+ expect(tables_to_lock).not_to be_empty
- Gitlab::Database::SharedModel.using_connection(ApplicationRecord.connection) do
- Postgresql::DetachedPartition.delete_all
+ tables_to_lock.each do |table_name|
+ lock_writes_manager = instance_double(Gitlab::Database::LockWritesManager, lock_writes: nil)
+
+ expect(Gitlab::Database::LockWritesManager).to receive(:new).with(
+ table_name: table_name,
+ connection: connection,
+ database_name: database_name,
+ with_retries: true,
+ logger: anything,
+ dry_run: anything
+ ).once.and_return(lock_writes_manager)
+ expect(lock_writes_manager).to receive(:lock_writes).once
+ end
+
+ subject
end
end
- shared_examples "lock tables" do |table_schema, database_name|
- let(:table_name) do
+ shared_examples "unlock tables" do |gitlab_schema, database_name|
+ let(:connection) { Gitlab::Database.database_base_models[database_name].connection }
+
+ let(:tables_to_unlock) do
Gitlab::Database::GitlabSchema
- .tables_to_schema.filter_map { |table_name, schema| table_name if schema == table_schema }
- .first
+ .tables_to_schema.filter_map { |table_name, schema| table_name if schema == gitlab_schema }
end
- let(:database) { database_name }
+ it "unlocks table in schema #{gitlab_schema} and database #{database_name}" do
+ expect(tables_to_unlock).not_to be_empty
+
+ tables_to_unlock.each do |table_name|
+ lock_writes_manager = instance_double(Gitlab::Database::LockWritesManager, unlock_writes: nil)
+
+ expect(Gitlab::Database::LockWritesManager).to receive(:new).with(
+ table_name: table_name,
+ connection: anything,
+ database_name: database_name,
+ with_retries: true,
+ logger: anything,
+ dry_run: anything
+ ).once.and_return(lock_writes_manager)
+ expect(lock_writes_manager).to receive(:unlock_writes)
+ end
+
+ subject
+ end
+ end
+
+ shared_examples "lock attached partitions" do |partition_identifier, database_name|
+ let(:connection) { Gitlab::Database.database_base_models[database_name].connection }
+
+ it 'locks the partition' do
+ lock_writes_manager = instance_double(Gitlab::Database::LockWritesManager, lock_writes: nil)
- it "locks table in schema #{table_schema} and database #{database_name}" do
expect(Gitlab::Database::LockWritesManager).to receive(:new).with(
- table_name: table_name,
- connection: anything,
- database_name: database,
+ table_name: partition_identifier,
+ connection: connection,
+ database_name: database_name,
with_retries: true,
logger: anything,
dry_run: anything
@@ -68,20 +126,16 @@ RSpec.describe Gitlab::Database::TablesLocker, :reestablished_active_record_base
end
end
- shared_examples "unlock tables" do |table_schema, database_name|
- let(:table_name) do
- Gitlab::Database::GitlabSchema
- .tables_to_schema.filter_map { |table_name, schema| table_name if schema == table_schema }
- .first
- end
+ shared_examples "unlock attached partitions" do |partition_identifier, database_name|
+ let(:connection) { Gitlab::Database.database_base_models[database_name].connection }
- let(:database) { database_name }
+ it 'unlocks the partition' do
+ lock_writes_manager = instance_double(Gitlab::Database::LockWritesManager, unlock_writes: nil)
- it "unlocks table in schema #{table_schema} and database #{database_name}" do
expect(Gitlab::Database::LockWritesManager).to receive(:new).with(
- table_name: table_name,
- connection: anything,
- database_name: database,
+ table_name: partition_identifier,
+ connection: connection,
+ database_name: database_name,
with_retries: true,
logger: anything,
dry_run: anything
@@ -100,25 +154,29 @@ RSpec.describe Gitlab::Database::TablesLocker, :reestablished_active_record_base
describe '#lock_writes' do
subject { described_class.new.lock_writes }
- it 'does not call Gitlab::Database::LockWritesManager.lock_writes' do
- expect(Gitlab::Database::LockWritesManager).to receive(:new).with(any_args).and_return(lock_writes_manager)
- expect(lock_writes_manager).not_to receive(:lock_writes)
+ it 'does not lock any table' do
+ expect(Gitlab::Database::LockWritesManager).to receive(:new)
+ .with(any_args).and_return(default_lock_writes_manager)
+ expect(default_lock_writes_manager).not_to receive(:lock_writes)
subject
end
- include_examples "unlock tables", :gitlab_main, 'main'
- include_examples "unlock tables", :gitlab_ci, 'ci'
- include_examples "unlock tables", :gitlab_shared, 'main'
- include_examples "unlock tables", :gitlab_internal, 'main'
+ it_behaves_like 'unlock tables', :gitlab_main, 'main'
+ it_behaves_like 'unlock tables', :gitlab_ci, 'main'
+ it_behaves_like 'unlock tables', :gitlab_main_clusterwide, 'main'
+ it_behaves_like 'unlock tables', :gitlab_shared, 'main'
+ it_behaves_like 'unlock tables', :gitlab_internal, 'main'
end
describe '#unlock_writes' do
subject { described_class.new.lock_writes }
it 'does call Gitlab::Database::LockWritesManager.unlock_writes' do
- expect(Gitlab::Database::LockWritesManager).to receive(:new).with(any_args).and_return(lock_writes_manager)
- expect(lock_writes_manager).to receive(:unlock_writes)
+ expect(Gitlab::Database::LockWritesManager).to receive(:new)
+ .with(any_args).and_return(default_lock_writes_manager)
+ expect(default_lock_writes_manager).to receive(:unlock_writes)
+ expect(default_lock_writes_manager).not_to receive(:lock_writes)
subject
end
@@ -133,43 +191,53 @@ RSpec.describe Gitlab::Database::TablesLocker, :reestablished_active_record_base
describe '#lock_writes' do
subject { described_class.new.lock_writes }
- include_examples "lock tables", :gitlab_ci, 'main'
- include_examples "lock tables", :gitlab_main, 'ci'
-
- include_examples "unlock tables", :gitlab_main, 'main'
- include_examples "unlock tables", :gitlab_ci, 'ci'
- include_examples "unlock tables", :gitlab_shared, 'main'
- include_examples "unlock tables", :gitlab_shared, 'ci'
- include_examples "unlock tables", :gitlab_internal, 'main'
- include_examples "unlock tables", :gitlab_internal, 'ci'
+ it_behaves_like 'lock tables', :gitlab_ci, 'main'
+ it_behaves_like 'lock tables', :gitlab_main, 'ci'
+ it_behaves_like 'lock tables', :gitlab_main_clusterwide, 'ci'
+
+ it_behaves_like 'unlock tables', :gitlab_main_clusterwide, 'main'
+ it_behaves_like 'unlock tables', :gitlab_main, 'main'
+ it_behaves_like 'unlock tables', :gitlab_ci, 'ci'
+ it_behaves_like 'unlock tables', :gitlab_shared, 'main'
+ it_behaves_like 'unlock tables', :gitlab_shared, 'ci'
+ it_behaves_like 'unlock tables', :gitlab_internal, 'main'
+ it_behaves_like 'unlock tables', :gitlab_internal, 'ci'
+
+ gitlab_main_partition = "#{Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA}.security_findings_test_partition"
+ it_behaves_like 'unlock attached partitions', gitlab_main_partition, 'main'
+ it_behaves_like 'lock attached partitions', gitlab_main_partition, 'ci'
end
describe '#unlock_writes' do
subject { described_class.new.unlock_writes }
- include_examples "unlock tables", :gitlab_ci, 'main'
- include_examples "unlock tables", :gitlab_main, 'ci'
- include_examples "unlock tables", :gitlab_main, 'main'
- include_examples "unlock tables", :gitlab_ci, 'ci'
- include_examples "unlock tables", :gitlab_shared, 'main'
- include_examples "unlock tables", :gitlab_shared, 'ci'
- include_examples "unlock tables", :gitlab_internal, 'main'
- include_examples "unlock tables", :gitlab_internal, 'ci'
+ it_behaves_like "unlock tables", :gitlab_ci, 'main'
+ it_behaves_like "unlock tables", :gitlab_main, 'ci'
+ it_behaves_like "unlock tables", :gitlab_main, 'main'
+ it_behaves_like "unlock tables", :gitlab_ci, 'ci'
+ it_behaves_like "unlock tables", :gitlab_shared, 'main'
+ it_behaves_like "unlock tables", :gitlab_shared, 'ci'
+ it_behaves_like "unlock tables", :gitlab_internal, 'main'
+ it_behaves_like "unlock tables", :gitlab_internal, 'ci'
+
+ gitlab_main_partition = "#{Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA}.security_findings_test_partition"
+ it_behaves_like 'unlock attached partitions', gitlab_main_partition, 'main'
+ it_behaves_like 'unlock attached partitions', gitlab_main_partition, 'ci'
end
context 'when running in dry_run mode' do
subject { described_class.new(dry_run: true).lock_writes }
- it 'passes dry_run flag to LockManger' do
+ it 'passes dry_run flag to LockWritesManager' do
expect(Gitlab::Database::LockWritesManager).to receive(:new).with(
- table_name: 'users',
+ table_name: 'security_findings',
connection: anything,
database_name: 'ci',
with_retries: true,
logger: anything,
dry_run: true
- ).and_return(lock_writes_manager)
- expect(lock_writes_manager).to receive(:lock_writes)
+ ).and_return(default_lock_writes_manager)
+ expect(default_lock_writes_manager).to receive(:lock_writes)
subject
end
@@ -185,8 +253,9 @@ RSpec.describe Gitlab::Database::TablesLocker, :reestablished_active_record_base
end
it 'does not lock any tables if the ci database is shared with main database' do
- expect(Gitlab::Database::LockWritesManager).to receive(:new).with(any_args).and_return(lock_writes_manager)
- expect(lock_writes_manager).not_to receive(:lock_writes)
+ expect(Gitlab::Database::LockWritesManager).to receive(:new)
+ .with(any_args).and_return(default_lock_writes_manager)
+ expect(default_lock_writes_manager).not_to receive(:lock_writes)
subject
end
@@ -220,7 +289,3 @@ RSpec.describe Gitlab::Database::TablesLocker, :reestablished_active_record_base
end
end
end
-
-def number_of_triggers(connection)
- connection.select_value("SELECT count(*) FROM information_schema.triggers")
-end
diff --git a/spec/lib/gitlab/patch/node_loader_spec.rb b/spec/lib/gitlab/patch/node_loader_spec.rb
new file mode 100644
index 00000000000..000083fc6d0
--- /dev/null
+++ b/spec/lib/gitlab/patch/node_loader_spec.rb
@@ -0,0 +1,80 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Patch::NodeLoader, feature_category: :redis do
+ using RSpec::Parameterized::TableSyntax
+
+ describe '#fetch_node_info' do
+ let(:redis) { double(:redis) } # rubocop:disable RSpec/VerifiedDoubles
+
+ # rubocop:disable Naming/InclusiveLanguage
+ where(:case_name, :args, :value) do
+ [
+ [
+ 'when only ip address is present',
+ "07c37df 127.0.0.1:30004@31004 slave e7d1eec 0 1426238317239 4 connected
+67ed2db 127.0.0.1:30002@31002 master - 0 1426238316232 2 connected 5461-10922
+292f8b3 127.0.0.1:30003@31003 master - 0 1426238318243 3 connected 10923-16383
+6ec2392 127.0.0.1:30005@31005 slave 67ed2db 0 1426238316232 5 connected
+824fe11 127.0.0.1:30006@31006 slave 292f8b3 0 1426238317741 6 connected
+e7d1eec 127.0.0.1:30001@31001 myself,master - 0 0 1 connected 0-5460",
+ {
+ '127.0.0.1:30004' => 'slave', '127.0.0.1:30002' => 'master', '127.0.0.1:30003' => 'master',
+ '127.0.0.1:30005' => 'slave', '127.0.0.1:30006' => 'slave', '127.0.0.1:30001' => 'master'
+ }
+ ],
+ [
+ 'when hostname is present',
+ "07c37df 127.0.0.1:30004@31004,host1 slave e7d1eec 0 1426238317239 4 connected
+67ed2db 127.0.0.1:30002@31002,host2 master - 0 1426238316232 2 connected 5461-10922
+292f8b3 127.0.0.1:30003@31003,host3 master - 0 1426238318243 3 connected 10923-16383
+6ec2392 127.0.0.1:30005@31005,host4 slave 67ed2db 0 1426238316232 5 connected
+824fe11 127.0.0.1:30006@31006,host5 slave 292f8b3 0 1426238317741 6 connected
+e7d1eec 127.0.0.1:30001@31001,host6 myself,master - 0 0 1 connected 0-5460",
+ {
+ 'host1:30004' => 'slave', 'host2:30002' => 'master', 'host3:30003' => 'master',
+ 'host4:30005' => 'slave', 'host5:30006' => 'slave', 'host6:30001' => 'master'
+ }
+ ],
+ [
+ 'when auxiliary fields are present',
+ "07c37df 127.0.0.1:30004@31004,,shard-id=69bc slave e7d1eec 0 1426238317239 4 connected
+67ed2db 127.0.0.1:30002@31002,,shard-id=114f master - 0 1426238316232 2 connected 5461-10922
+292f8b3 127.0.0.1:30003@31003,,shard-id=fdb3 master - 0 1426238318243 3 connected 10923-16383
+6ec2392 127.0.0.1:30005@31005,,shard-id=114f slave 67ed2db 0 1426238316232 5 connected
+824fe11 127.0.0.1:30006@31006,,shard-id=fdb3 slave 292f8b3 0 1426238317741 6 connected
+e7d1eec 127.0.0.1:30001@31001,,shard-id=69bc myself,master - 0 0 1 connected 0-5460",
+ {
+ '127.0.0.1:30004' => 'slave', '127.0.0.1:30002' => 'master', '127.0.0.1:30003' => 'master',
+ '127.0.0.1:30005' => 'slave', '127.0.0.1:30006' => 'slave', '127.0.0.1:30001' => 'master'
+ }
+ ],
+ [
+ 'when hostname and auxiliary fields are present',
+ "07c37df 127.0.0.1:30004@31004,host1,shard-id=69bc slave e7d1eec 0 1426238317239 4 connected
+67ed2db 127.0.0.1:30002@31002,host2,shard-id=114f master - 0 1426238316232 2 connected 5461-10922
+292f8b3 127.0.0.1:30003@31003,host3,shard-id=fdb3 master - 0 1426238318243 3 connected 10923-16383
+6ec2392 127.0.0.1:30005@31005,host4,shard-id=114f slave 67ed2db 0 1426238316232 5 connected
+824fe11 127.0.0.1:30006@31006,host5,shard-id=fdb3 slave 292f8b3 0 1426238317741 6 connected
+e7d1eec 127.0.0.1:30001@31001,host6,shard-id=69bc myself,master - 0 0 1 connected 0-5460",
+ {
+ 'host1:30004' => 'slave', 'host2:30002' => 'master', 'host3:30003' => 'master',
+ 'host4:30005' => 'slave', 'host5:30006' => 'slave', 'host6:30001' => 'master'
+ }
+ ]
+ ]
+ end
+ # rubocop:enable Naming/InclusiveLanguage
+
+ with_them do
+ before do
+ allow(redis).to receive(:call).with([:cluster, :nodes]).and_return(args)
+ end
+
+ it do
+ expect(Redis::Cluster::NodeLoader.load_flags([redis])).to eq(value)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/usage_data_counters/editor_unique_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/editor_unique_counter_spec.rb
index f8a4603c1f8..c16d31cd8ef 100644
--- a/spec/lib/gitlab/usage_data_counters/editor_unique_counter_spec.rb
+++ b/spec/lib/gitlab/usage_data_counters/editor_unique_counter_spec.rb
@@ -25,12 +25,29 @@ RSpec.describe Gitlab::UsageDataCounters::EditorUniqueCounter, :clean_gitlab_red
end
end
+ it 'track snowplow event' do
+ track_action(author: user1, project: project)
+
+ expect_snowplow_event(
+ category: described_class.name,
+ action: 'ide_edit',
+ label: 'usage_activity_by_stage_monthly.create.action_monthly_active_users_ide_edit',
+ namespace: project.namespace,
+ property: event_name,
+ project: project,
+ user: user1,
+ context: [Gitlab::Tracking::ServicePingContext.new(data_source: :redis_hll, event: event_name).to_h]
+ )
+ end
+
it 'does not track edit actions if author is not present' do
expect(track_action(author: nil, project: project)).to be_nil
end
end
context 'for web IDE edit actions' do
+ let(:event_name) { described_class::EDIT_BY_WEB_IDE }
+
it_behaves_like 'tracks and counts action' do
def track_action(params)
described_class.track_web_ide_edit_action(**params)
@@ -43,6 +60,8 @@ RSpec.describe Gitlab::UsageDataCounters::EditorUniqueCounter, :clean_gitlab_red
end
context 'for SFE edit actions' do
+ let(:event_name) { described_class::EDIT_BY_SFE }
+
it_behaves_like 'tracks and counts action' do
def track_action(params)
described_class.track_sfe_edit_action(**params)
@@ -55,6 +74,8 @@ RSpec.describe Gitlab::UsageDataCounters::EditorUniqueCounter, :clean_gitlab_red
end
context 'for snippet editor edit actions' do
+ let(:event_name) { described_class::EDIT_BY_SNIPPET_EDITOR }
+
it_behaves_like 'tracks and counts action' do
def track_action(params)
described_class.track_snippet_editor_edit_action(**params)
diff --git a/spec/lib/sidebars/projects/menus/infrastructure_menu_spec.rb b/spec/lib/sidebars/projects/menus/infrastructure_menu_spec.rb
index 116948b7cb0..57d1475e564 100644
--- a/spec/lib/sidebars/projects/menus/infrastructure_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/infrastructure_menu_spec.rb
@@ -141,6 +141,18 @@ RSpec.describe Sidebars::Projects::Menus::InfrastructureMenu do
it_behaves_like 'access rights checks'
end
end
+
+ context 'when instance is not configured for Google OAuth2' do
+ before do
+ stub_feature_flags(incubation_5mp_google_cloud: true)
+ unconfigured_google_oauth2 = Struct.new(:app_id, :app_secret).new('', '')
+ allow(Gitlab::Auth::OAuth::Provider).to receive(:config_for)
+ .with('google_oauth2')
+ .and_return(unconfigured_google_oauth2)
+ end
+
+ it { is_expected.to be_nil }
+ end
end
end
end
diff --git a/spec/models/ci/runner_machine_spec.rb b/spec/models/ci/runner_machine_spec.rb
index d0979d8a485..f687f7f73d6 100644
--- a/spec/models/ci/runner_machine_spec.rb
+++ b/spec/models/ci/runner_machine_spec.rb
@@ -54,9 +54,8 @@ RSpec.describe Ci::RunnerMachine, feature_category: :runner_fleet, type: :model
end
describe '#heartbeat', :freeze_time do
- let(:runner_machine) { create(:ci_runner_machine) }
+ let(:runner_machine) { create(:ci_runner_machine, version: '15.0.0') }
let(:executor) { 'shell' }
- let(:version) { '15.0.1' }
let(:values) do
{
ip_address: '8.8.8.8',
@@ -76,18 +75,26 @@ RSpec.describe Ci::RunnerMachine, feature_category: :runner_fleet, type: :model
runner_machine.contacted_at = Time.current
end
- it 'schedules version update' do
- expect(Ci::Runners::ProcessRunnerVersionUpdateWorker).to receive(:perform_async).with(version).once
+ context 'when version is changed' do
+ let(:version) { '15.0.1' }
- heartbeat
+ before do
+ allow(Ci::Runners::ProcessRunnerVersionUpdateWorker).to receive(:perform_async).with(version)
+ end
- expect(runner_machine.runner_version).to be_nil
- end
+ it 'schedules version information update' do
+ heartbeat
- it 'updates cache' do
- expect_redis_update
+ expect(Ci::Runners::ProcessRunnerVersionUpdateWorker).to have_received(:perform_async).with(version).once
+ end
+
+ it 'updates cache' do
+ expect_redis_update
+
+ heartbeat
- heartbeat
+ expect(runner_machine.runner_version).to be_nil
+ end
end
context 'with only ip_address specified' do
@@ -96,12 +103,7 @@ RSpec.describe Ci::RunnerMachine, feature_category: :runner_fleet, type: :model
end
it 'updates only ip_address' do
- attrs = Gitlab::Json.dump(ip_address: '1.1.1.1', contacted_at: Time.current)
-
- Gitlab::Redis::Cache.with do |redis|
- redis_key = runner_machine.send(:cache_attribute_key)
- expect(redis).to receive(:set).with(redis_key, attrs, any_args)
- end
+ expect_redis_update(values.merge(contacted_at: Time.current))
heartbeat
end
@@ -112,17 +114,29 @@ RSpec.describe Ci::RunnerMachine, feature_category: :runner_fleet, type: :model
before do
runner_machine.contacted_at = 2.hours.ago
- allow(Ci::Runners::ProcessRunnerVersionUpdateWorker).to receive(:perform_async).with(version).once
+ allow(Ci::Runners::ProcessRunnerVersionUpdateWorker).to receive(:perform_async).with(version)
end
- context 'with invalid runner_machine' do
- before do
- runner_machine.runner = nil
- end
+ context 'when version is changed' do
+ let(:version) { '15.0.1' }
- it 'still updates redis cache and database' do
- expect(runner_machine).to be_invalid
+ context 'with invalid runner_machine' do
+ before do
+ runner_machine.runner = nil
+ end
+
+ it 'still updates redis cache and database' do
+ expect(runner_machine).to be_invalid
+
+ expect_redis_update
+ does_db_update
+ expect(Ci::Runners::ProcessRunnerVersionUpdateWorker).to have_received(:perform_async)
+ .with(version).once
+ end
+ end
+
+ it 'updates redis cache and database' do
expect_redis_update
does_db_update
@@ -132,58 +146,52 @@ RSpec.describe Ci::RunnerMachine, feature_category: :runner_fleet, type: :model
end
context 'with unchanged runner_machine version' do
- let(:runner_machine) { create(:ci_runner_machine, version: version) }
+ let(:version) { runner_machine.version }
it 'does not schedule ci_runner_versions update' do
heartbeat
expect(Ci::Runners::ProcessRunnerVersionUpdateWorker).not_to have_received(:perform_async)
end
- end
- it 'updates redis cache and database' do
- expect_redis_update
- does_db_update
+ Ci::Runner::EXECUTOR_NAME_TO_TYPES.each_key do |executor|
+ context "with #{executor} executor" do
+ let(:executor) { executor }
- expect(Ci::Runners::ProcessRunnerVersionUpdateWorker).to have_received(:perform_async)
- .with(version).once
- end
+ it 'updates with expected executor type' do
+ expect_redis_update
- Ci::Runner::EXECUTOR_NAME_TO_TYPES.each_key do |executor|
- context "with #{executor} executor" do
- let(:executor) { executor }
+ heartbeat
- it 'updates with expected executor type' do
- expect_redis_update
-
- heartbeat
+ expect(runner_machine.reload.read_attribute(:executor_type)).to eq(expected_executor_type)
+ end
- expect(runner_machine.reload.read_attribute(:executor_type)).to eq(expected_executor_type)
- end
-
- def expected_executor_type
- executor.gsub(/[+-]/, '_')
+ def expected_executor_type
+ executor.gsub(/[+-]/, '_')
+ end
end
end
- end
- context "with an unknown executor type" do
- let(:executor) { 'some-unknown-type' }
+ context 'with an unknown executor type' do
+ let(:executor) { 'some-unknown-type' }
- it 'updates with unknown executor type' do
- expect_redis_update
+ it 'updates with unknown executor type' do
+ expect_redis_update
- heartbeat
+ heartbeat
- expect(runner_machine.reload.read_attribute(:executor_type)).to eq('unknown')
+ expect(runner_machine.reload.read_attribute(:executor_type)).to eq('unknown')
+ end
end
end
end
- def expect_redis_update
+ def expect_redis_update(values = anything)
+ values_json = values == anything ? anything : Gitlab::Json.dump(values)
+
Gitlab::Redis::Cache.with do |redis|
redis_key = runner_machine.send(:cache_attribute_key)
- expect(redis).to receive(:set).with(redis_key, anything, any_args).and_call_original
+ expect(redis).to receive(:set).with(redis_key, values_json, any_args).and_call_original
end
end
diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb
index 01d5fe7f90b..750b75684ec 100644
--- a/spec/models/ci/runner_spec.rb
+++ b/spec/models/ci/runner_spec.rb
@@ -1076,13 +1076,13 @@ RSpec.describe Ci::Runner, type: :model, feature_category: :runner do
end
end
- describe '#heartbeat' do
- let(:runner) { create(:ci_runner, :project) }
+ describe '#heartbeat', :freeze_time do
+ let(:runner) { create(:ci_runner, :project, version: '15.0.0') }
let(:executor) { 'shell' }
- let(:version) { '15.0.1' }
+ let(:values) { { architecture: '18-bit', config: { gpus: "all" }, executor: executor, version: version } }
subject(:heartbeat) do
- runner.heartbeat(architecture: '18-bit', config: { gpus: "all" }, executor: executor, version: version)
+ runner.heartbeat(values)
end
context 'when database was updated recently' do
@@ -1090,27 +1090,35 @@ RSpec.describe Ci::Runner, type: :model, feature_category: :runner do
runner.contacted_at = Time.current
end
- it 'updates cache' do
- expect_redis_update
- expect(Ci::Runners::ProcessRunnerVersionUpdateWorker).not_to receive(:perform_async)
+ context 'when version is changed' do
+ let(:version) { '15.0.1' }
+
+ before do
+ allow(Ci::Runners::ProcessRunnerVersionUpdateWorker).to receive(:perform_async).with(version)
+ end
+
+ it 'updates cache' do
+ expect_redis_update
- heartbeat
+ heartbeat
- expect(runner.runner_version).to be_nil
+ expect(runner.runner_version).to be_nil
+ end
+
+ it 'schedules version information update' do
+ heartbeat
+
+ expect(Ci::Runners::ProcessRunnerVersionUpdateWorker).to have_received(:perform_async).with(version).once
+ end
end
context 'with only ip_address specified', :freeze_time do
- subject(:heartbeat) do
- runner.heartbeat(ip_address: '1.1.1.1')
+ let(:values) do
+ { ip_address: '1.1.1.1' }
end
it 'updates only ip_address' do
- attrs = Gitlab::Json.dump(ip_address: '1.1.1.1', contacted_at: Time.current)
-
- Gitlab::Redis::Cache.with do |redis|
- redis_key = runner.send(:cache_attribute_key)
- expect(redis).to receive(:set).with(redis_key, attrs, any_args)
- end
+ expect_redis_update(values.merge(contacted_at: Time.current))
heartbeat
end
@@ -1121,65 +1129,81 @@ RSpec.describe Ci::Runner, type: :model, feature_category: :runner do
before do
runner.contacted_at = 2.hours.ago
- allow(Ci::Runners::ProcessRunnerVersionUpdateWorker).to receive(:perform_async)
+ allow(Ci::Runners::ProcessRunnerVersionUpdateWorker).to receive(:perform_async).with(version)
end
- context 'with invalid runner' do
- before do
- runner.runner_projects.delete_all
- end
+ context 'when version is changed' do
+ let(:version) { '15.0.1' }
- it 'still updates redis cache and database' do
- expect(runner).to be_invalid
+ context 'with invalid runner' do
+ before do
+ runner.runner_projects.delete_all
+ end
+
+ it 'still updates redis cache and database' do
+ expect(runner).to be_invalid
+ expect_redis_update
+ does_db_update
+
+ expect(Ci::Runners::ProcessRunnerVersionUpdateWorker).to have_received(:perform_async).with(version).once
+ end
+ end
+
+ it 'updates redis cache and database' do
expect_redis_update
does_db_update
-
- expect(Ci::Runners::ProcessRunnerVersionUpdateWorker).to have_received(:perform_async).once
+ expect(Ci::Runners::ProcessRunnerVersionUpdateWorker).to have_received(:perform_async).with(version).once
end
end
context 'with unchanged runner version' do
- let(:runner) { create(:ci_runner, version: version) }
+ let(:version) { runner.version }
it 'does not schedule ci_runner_versions update' do
heartbeat
expect(Ci::Runners::ProcessRunnerVersionUpdateWorker).not_to have_received(:perform_async)
end
- end
- it 'updates redis cache and database' do
- expect_redis_update
- does_db_update
- expect(Ci::Runners::ProcessRunnerVersionUpdateWorker).to have_received(:perform_async).once
- end
+ Ci::Runner::EXECUTOR_NAME_TO_TYPES.each_key do |executor|
+ context "with #{executor} executor" do
+ let(:executor) { executor }
- %w(custom shell docker docker-windows docker-ssh ssh parallels virtualbox docker+machine docker-ssh+machine kubernetes some-unknown-type).each do |executor|
- context "with #{executor} executor" do
- let(:executor) { executor }
+ it 'updates with expected executor type' do
+ expect_redis_update
- it 'updates with expected executor type' do
- expect_redis_update
+ heartbeat
- heartbeat
+ expect(runner.reload.read_attribute(:executor_type)).to eq(expected_executor_type)
+ end
- expect(runner.reload.read_attribute(:executor_type)).to eq(expected_executor_type)
+ def expected_executor_type
+ executor.gsub(/[+-]/, '_')
+ end
end
+ end
- def expected_executor_type
- return 'unknown' if executor == 'some-unknown-type'
+ context 'with an unknown executor type' do
+ let(:executor) { 'some-unknown-type' }
- executor.gsub(/[+-]/, '_')
+ it 'updates with unknown executor type' do
+ expect_redis_update
+
+ heartbeat
+
+ expect(runner.reload.read_attribute(:executor_type)).to eq('unknown')
end
end
end
end
- def expect_redis_update
+ def expect_redis_update(values = anything)
+ values_json = values == anything ? anything : Gitlab::Json.dump(values)
+
Gitlab::Redis::Cache.with do |redis|
redis_key = runner.send(:cache_attribute_key)
- expect(redis).to receive(:set).with(redis_key, anything, any_args)
+ expect(redis).to receive(:set).with(redis_key, values_json, any_args).and_call_original
end
end
diff --git a/spec/requests/api/draft_notes_spec.rb b/spec/requests/api/draft_notes_spec.rb
index 56b0c834010..7c56d2efc2c 100644
--- a/spec/requests/api/draft_notes_spec.rb
+++ b/spec/requests/api/draft_notes_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe API::DraftNotes, feature_category: :code_review_workflow do
let!(:draft_note_by_current_user) { create(:draft_note, merge_request: merge_request, author: user) }
let!(:draft_note_by_random_user) { create(:draft_note, merge_request: merge_request) }
- let_it_be(:api_stub) { "/projects/#{project.id}/merge_requests/#{merge_request.iid}" }
+ let_it_be(:base_url) { "/projects/#{project.id}/merge_requests/#{merge_request.iid}/draft_notes" }
before do
project.add_developer(user)
@@ -25,13 +25,13 @@ RSpec.describe API::DraftNotes, feature_category: :code_review_workflow do
describe "Get a list of merge request draft notes" do
it "returns 200 OK status" do
- get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/draft_notes", user)
+ get api(base_url, user)
expect(response).to have_gitlab_http_status(:ok)
end
it "returns only draft notes authored by the current user" do
- get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/draft_notes", user)
+ get api(base_url, user)
draft_note_ids = json_response.pluck("id")
@@ -45,7 +45,7 @@ RSpec.describe API::DraftNotes, feature_category: :code_review_workflow do
context "when requesting an existing draft note by the user" do
before do
get api(
- "/projects/#{project.id}/merge_requests/#{merge_request.iid}/draft_notes/#{draft_note_by_current_user.id}",
+ "#{base_url}/#{draft_note_by_current_user.id}",
user
)
end
@@ -61,7 +61,7 @@ RSpec.describe API::DraftNotes, feature_category: :code_review_workflow do
context "when requesting a non-existent draft note" do
it "returns a 404 Not Found response" do
get api(
- "/projects/#{project.id}/merge_requests/#{merge_request.iid}/draft_notes/#{DraftNote.last.id + 1}",
+ "#{base_url}/#{DraftNote.last.id + 1}",
user
)
@@ -72,7 +72,7 @@ RSpec.describe API::DraftNotes, feature_category: :code_review_workflow do
context "when requesting an existing draft note by another user" do
it "returns a 404 Not Found response" do
get api(
- "/projects/#{project.id}/merge_requests/#{merge_request.iid}/draft_notes/#{draft_note_by_random_user.id}",
+ "#{base_url}/#{draft_note_by_random_user.id}",
user
)
@@ -88,7 +88,7 @@ RSpec.describe API::DraftNotes, feature_category: :code_review_workflow do
before do
delete api(
- "/projects/#{project.id}/merge_requests/#{merge_request.iid}/draft_notes/#{draft_note_by_current_user.id}",
+ "#{base_url}/#{draft_note_by_current_user.id}",
user
)
end
@@ -105,7 +105,7 @@ RSpec.describe API::DraftNotes, feature_category: :code_review_workflow do
context "when deleting a non-existent draft note" do
it "returns a 404 Not Found" do
delete api(
- "/projects/#{project.id}/merge_requests/#{merge_request.iid}/draft_notes/#{non_existing_record_id}",
+ "#{base_url}/#{non_existing_record_id}",
user
)
@@ -116,7 +116,7 @@ RSpec.describe API::DraftNotes, feature_category: :code_review_workflow do
context "when deleting a draft note by a different user" do
it "returns a 404 Not Found" do
delete api(
- "/projects/#{project.id}/merge_requests/#{merge_request.iid}/draft_notes/#{draft_note_by_random_user.id}",
+ "#{base_url}/#{draft_note_by_random_user.id}",
user
)
@@ -125,8 +125,8 @@ RSpec.describe API::DraftNotes, feature_category: :code_review_workflow do
end
end
- def create_draft_note(params = {}, url = api_stub)
- post api("#{url}/draft_notes", user), params: params
+ def create_draft_note(params = {}, url = base_url)
+ post api(url, user), params: params
end
describe "Create a new draft note" do
@@ -219,7 +219,7 @@ RSpec.describe API::DraftNotes, feature_category: :code_review_workflow do
describe "Publishing a draft note" do
let(:publish_draft_note) do
put api(
- "#{api_stub}/draft_notes/#{draft_note_by_current_user.id}/publish",
+ "#{base_url}/#{draft_note_by_current_user.id}/publish",
user
)
end
@@ -240,7 +240,7 @@ RSpec.describe API::DraftNotes, feature_category: :code_review_workflow do
context "when publishing a non-existent draft note" do
it "returns a 404 Not Found" do
put api(
- "#{api_stub}/draft_notes/#{non_existing_record_id}/publish",
+ "#{base_url}/#{non_existing_record_id}/publish",
user
)
@@ -251,7 +251,7 @@ RSpec.describe API::DraftNotes, feature_category: :code_review_workflow do
context "when publishing a draft note by a different user" do
it "returns a 404 Not Found" do
put api(
- "#{api_stub}/draft_notes/#{draft_note_by_random_user.id}/publish",
+ "#{base_url}/#{draft_note_by_random_user.id}/publish",
user
)
diff --git a/spec/services/projects/update_service_spec.rb b/spec/services/projects/update_service_spec.rb
index 57249bcd562..0c4f6acc262 100644
--- a/spec/services/projects/update_service_spec.rb
+++ b/spec/services/projects/update_service_spec.rb
@@ -227,48 +227,16 @@ RSpec.describe Projects::UpdateService do
let(:user) { project.first_owner }
let(:forked_project) { fork_project(project) }
- context 'and unlink forks feature flag is off' do
- before do
- stub_feature_flags(unlink_fork_network_upon_visibility_decrease: false)
- end
-
- it 'updates forks visibility level when parent set to more restrictive' do
- opts = { visibility_level: Gitlab::VisibilityLevel::PRIVATE }
-
- expect(project).to be_internal
- expect(forked_project).to be_internal
-
- expect(update_project(project, user, opts)).to eq({ status: :success })
+ it 'does not change visibility of forks' do
+ opts = { visibility_level: Gitlab::VisibilityLevel::PRIVATE }
- expect(project).to be_private
- expect(forked_project.reload).to be_private
- end
-
- it 'does not update forks visibility level when parent set to less restrictive' do
- opts = { visibility_level: Gitlab::VisibilityLevel::PUBLIC }
-
- expect(project).to be_internal
- expect(forked_project).to be_internal
+ expect(project).to be_internal
+ expect(forked_project).to be_internal
- expect(update_project(project, user, opts)).to eq({ status: :success })
+ expect(update_project(project, user, opts)).to eq({ status: :success })
- expect(project).to be_public
- expect(forked_project.reload).to be_internal
- end
- end
-
- context 'and unlink forks feature flag is on' do
- it 'does not change visibility of forks' do
- opts = { visibility_level: Gitlab::VisibilityLevel::PRIVATE }
-
- expect(project).to be_internal
- expect(forked_project).to be_internal
-
- expect(update_project(project, user, opts)).to eq({ status: :success })
-
- expect(project).to be_private
- expect(forked_project.reload).to be_internal
- end
+ expect(project).to be_private
+ expect(forked_project.reload).to be_internal
end
end
diff --git a/spec/support/rspec_order_todo.yml b/spec/support/rspec_order_todo.yml
index d6c310d25f2..8d1e5e907c5 100644
--- a/spec/support/rspec_order_todo.yml
+++ b/spec/support/rspec_order_todo.yml
@@ -957,7 +957,6 @@
- './ee/spec/helpers/ee/geo_helper_spec.rb'
- './ee/spec/helpers/ee/gitlab_routing_helper_spec.rb'
- './ee/spec/helpers/ee/graph_helper_spec.rb'
-- './ee/spec/helpers/ee/groups/analytics/cycle_analytics_helper_spec.rb'
- './ee/spec/helpers/ee/groups/group_members_helper_spec.rb'
- './ee/spec/helpers/ee/groups_helper_spec.rb'
- './ee/spec/helpers/ee/groups/settings_helper_spec.rb'
@@ -5084,7 +5083,6 @@
- './spec/helpers/admin/deploy_key_helper_spec.rb'
- './spec/helpers/admin/identities_helper_spec.rb'
- './spec/helpers/admin/user_actions_helper_spec.rb'
-- './spec/helpers/analytics/cycle_analytics_helper_spec.rb'
- './spec/helpers/appearances_helper_spec.rb'
- './spec/helpers/application_helper_spec.rb'
- './spec/helpers/application_settings_helper_spec.rb'
diff --git a/spec/support/shared_examples/analytics/cycle_analytics/request_params_examples.rb b/spec/support/shared_examples/analytics/cycle_analytics/request_params_examples.rb
new file mode 100644
index 00000000000..9f6031af444
--- /dev/null
+++ b/spec/support/shared_examples/analytics/cycle_analytics/request_params_examples.rb
@@ -0,0 +1,127 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'unlicensed cycle analytics request params' do
+ let(:params) do
+ {
+ created_after: '2019-01-01',
+ created_before: '2019-03-01',
+ project_ids: [2, 3],
+ namespace: namespace,
+ current_user: user
+ }
+ end
+
+ subject { described_class.new(params) }
+
+ before do
+ root_group.add_owner(user)
+ end
+
+ describe 'validations' do
+ it 'is valid' do
+ expect(subject).to be_valid
+ end
+
+ context 'when `created_before` is missing' do
+ before do
+ params[:created_before] = nil
+ end
+
+ it 'is valid', time_travel_to: '2019-03-01' do
+ expect(subject).to be_valid
+ end
+ end
+
+ context 'when `created_before` is earlier than `created_after`' do
+ before do
+ params[:created_before] = '2015-01-01'
+ end
+
+ it 'is invalid' do
+ expect(subject).not_to be_valid
+ expect(subject.errors.messages[:created_before]).not_to be_empty
+ end
+ end
+
+ context 'when the date range exceeds 180 days' do
+ before do
+ params[:created_before] = '2019-07-15'
+ end
+
+ it 'is invalid' do
+ expect(subject).not_to be_valid
+ message = s_('CycleAnalytics|The given date range is larger than 180 days')
+ expect(subject.errors.messages[:created_after]).to include(message)
+ end
+ end
+ end
+
+ it 'casts `created_after` to `Time`' do
+ expect(subject.created_after).to be_a_kind_of(Time)
+ end
+
+ it 'casts `created_before` to `Time`' do
+ expect(subject.created_before).to be_a_kind_of(Time)
+ end
+
+ describe 'optional `value_stream`' do
+ context 'when `value_stream` is not empty' do
+ let(:value_stream) { instance_double('Analytics::CycleAnalytics::ValueStream') }
+
+ before do
+ params[:value_stream] = value_stream
+ end
+
+ it { expect(subject.value_stream).to eq(value_stream) }
+ end
+
+ context 'when `value_stream` is nil' do
+ before do
+ params[:value_stream] = nil
+ end
+
+ it { expect(subject.value_stream).to eq(nil) }
+ end
+ end
+
+ describe 'sorting params' do
+ before do
+ params.merge!(sort: 'duration', direction: 'asc')
+ end
+
+ it 'converts sorting params to symbol when passing it to data collector' do
+ data_collector_params = subject.to_data_collector_params
+
+ expect(data_collector_params[:sort]).to eq(:duration)
+ expect(data_collector_params[:direction]).to eq(:asc)
+ end
+
+ it 'adds sorting params to data attributes' do
+ data_attributes = subject.to_data_attributes
+
+ expect(data_attributes[:sort]).to eq('duration')
+ expect(data_attributes[:direction]).to eq('asc')
+ end
+ end
+
+ describe 'aggregation params' do
+ context 'when not licensed' do
+ it 'returns nil' do
+ data_collector_params = subject.to_data_attributes
+ expect(data_collector_params[:aggregation]).to eq(nil)
+ end
+ end
+ end
+
+ describe 'use_aggregated_data_collector param' do
+ subject(:value) { described_class.new(params).to_data_collector_params[:use_aggregated_data_collector] }
+
+ it { is_expected.to eq(false) }
+ end
+
+ describe 'enable_tasks_by_type_chart data attribute' do
+ subject(:value) { described_class.new(params).to_data_attributes[:enable_tasks_by_type_chart] }
+
+ it { is_expected.to eq(false) }
+ end
+end