diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-12-06 18:08:22 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-12-06 18:08:22 +0000 |
commit | 5a73318262aab6ab952f2b7205b3674ea1f20053 (patch) | |
tree | e53191adbc529ce23ca08a73e1235c7b6fb6ced5 /spec | |
parent | 552877c4d1c535f529be13862692a8fe826a72a2 (diff) | |
download | gitlab-ce-5a73318262aab6ab952f2b7205b3674ea1f20053.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
18 files changed, 540 insertions, 32 deletions
diff --git a/spec/features/incidents/incident_details_spec.rb b/spec/features/incidents/incident_details_spec.rb index 7c24943eb6f..e1167285464 100644 --- a/spec/features/incidents/incident_details_spec.rb +++ b/spec/features/incidents/incident_details_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Incident details', :js do +RSpec.describe 'Incident details', :js, feature_category: :incident_management do let_it_be(:project) { create(:project) } let_it_be(:developer) { create(:user) } let_it_be(:incident) { create(:incident, project: project, author: developer, description: 'description') } diff --git a/spec/features/milestones/user_creates_milestone_spec.rb b/spec/features/milestones/user_creates_milestone_spec.rb index 1ab231632fb..b750f035e36 100644 --- a/spec/features/milestones/user_creates_milestone_spec.rb +++ b/spec/features/milestones/user_creates_milestone_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe "User creates milestone", :js do +RSpec.describe "User creates milestone", :js, feature_category: :team_planning do let_it_be(:developer) { create(:user) } let_it_be(:inherited_guest) { create(:user) } let_it_be(:inherited_developer) { create(:user) } diff --git a/spec/frontend/editor/components/source_editor_toolbar_button_spec.js b/spec/frontend/editor/components/source_editor_toolbar_button_spec.js index ded31bb62dc..f62061f6eaf 100644 --- a/spec/frontend/editor/components/source_editor_toolbar_button_spec.js +++ b/spec/frontend/editor/components/source_editor_toolbar_button_spec.js @@ -54,6 +54,25 @@ describe('Source Editor Toolbar button', () => { }); }); + describe('data attributes', () => { + it.each` + description | data | expectedDataset + ${'does not set any attribute'} | ${undefined} | ${{}} + ${'does not set any attribute'} | ${[]} | ${{}} + ${'does not set any attribute'} | ${['foo']} | ${{}} + ${'does not set any attribute'} | ${'bar'} | ${{}} + ${'does set single attribute correctly'} | ${{ qaSelector: 'foo' }} | ${{ qaSelector: 'foo' }} + ${'does set multiple attributes correctly'} | ${{ qaSelector: 'foo', youCanSeeMe: true }} | ${{ qaSelector: 'foo', youCanSeeMe: 'true' }} + `('$description when data="$data"', ({ data, expectedDataset }) => { + createComponent({ + button: { + data, + }, + }); + expect(findButton().element.dataset).toEqual(expect.objectContaining(expectedDataset)); + }); + }); + describe('click handler', () => { let clickEvent; diff --git a/spec/lib/gitlab/github_gists_import/importer/gist_importer_spec.rb b/spec/lib/gitlab/github_gists_import/importer/gist_importer_spec.rb new file mode 100644 index 00000000000..69a4d646562 --- /dev/null +++ b/spec/lib/gitlab/github_gists_import/importer/gist_importer_spec.rb @@ -0,0 +1,128 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::GithubGistsImport::Importer::GistImporter, feature_category: :importer do + subject { described_class.new(gist_object, user.id).execute } + + let_it_be(:user) { create(:user) } + let(:created_at) { Time.utc(2022, 1, 9, 12, 15) } + let(:updated_at) { Time.utc(2022, 5, 9, 12, 17) } + let(:gist_file) { { file_name: '_Summary.md', file_content: 'File content' } } + let(:url) { 'https://host.com/gistid.git' } + let(:gist_object) do + instance_double('Gitlab::GithubGistsImport::Representation::Gist', + truncated_title: 'My Gist', + visibility_level: 0, + files: { '_Summary.md': gist_file }, + first_file: gist_file, + git_pull_url: url, + created_at: created_at, + updated_at: updated_at + ) + end + + let(:expected_snippet_attrs) do + { + title: 'My Gist', + visibility_level: 0, + content: 'File content', + file_name: '_Summary.md', + author_id: user.id, + created_at: gist_object.created_at, + updated_at: gist_object.updated_at + }.stringify_keys + end + + describe '#execute' do + context 'when success' do + it 'creates expected snippet and snippet repository' do + expect_next_instance_of(Repository) do |repository| + expect(repository).to receive(:fetch_as_mirror) + end + + expect { subject }.to change { user.snippets.count }.by(1) + expect(user.snippets[0].attributes).to include expected_snippet_attrs + end + end + + context 'when file size limit exeeded' do + before do + files = [].tap { |array| 11.times { |n| array << ["file#{n}.txt", {}] } }.to_h + + allow(gist_object).to receive(:files).and_return(files) + allow_next_instance_of(Repository) do |repository| + allow(repository).to receive(:fetch_as_mirror) + allow(repository).to receive(:empty?).and_return(false) + allow(repository).to receive(:ls_files).and_return(files.keys) + end + end + + it 'returns error' do + result = subject + + expect(user.snippets.count).to eq(0) + expect(result.error?).to eq(true) + expect(result.errors).to match_array(['Snippet max file count exceeded']) + end + end + + context 'when invalid attributes' do + let(:gist_file) { { file_name: '_Summary.md', file_content: nil } } + + it 'raises an error' do + expect { subject }.to raise_error(ActiveRecord::RecordInvalid, "Validation failed: Content can't be blank") + end + end + + context 'when repository cloning fails' do + it 'returns error' do + expect_next_instance_of(Repository) do |repository| + expect(repository).to receive(:fetch_as_mirror).and_raise(Gitlab::Shell::Error) + expect(repository).to receive(:remove) + end + + expect { subject }.to raise_error(Gitlab::Shell::Error) + expect(user.snippets.count).to eq(0) + end + end + + context 'when url is invalid' do + let(:url) { 'invalid' } + + context 'when local network is allowed' do + before do + allow(::Gitlab::CurrentSettings) + .to receive(:allow_local_requests_from_web_hooks_and_services?).and_return(true) + end + + it 'raises error' do + expect(Gitlab::UrlBlocker) + .to receive(:validate!) + .with(url, ports: [80, 443], schemes: %w[http https git], + allow_localhost: true, allow_local_network: true) + .and_raise(Gitlab::UrlBlocker::BlockedUrlError) + + expect { subject }.to raise_error(Gitlab::UrlBlocker::BlockedUrlError) + end + end + + context 'when local network is not allowed' do + before do + allow(::Gitlab::CurrentSettings) + .to receive(:allow_local_requests_from_web_hooks_and_services?).and_return(false) + end + + it 'raises error' do + expect(Gitlab::UrlBlocker) + .to receive(:validate!) + .with(url, ports: [80, 443], schemes: %w[http https git], + allow_localhost: false, allow_local_network: false) + .and_raise(Gitlab::UrlBlocker::BlockedUrlError) + + expect { subject }.to raise_error(Gitlab::UrlBlocker::BlockedUrlError) + end + end + end + end +end diff --git a/spec/lib/gitlab/github_gists_import/representation/gist_spec.rb b/spec/lib/gitlab/github_gists_import/representation/gist_spec.rb new file mode 100644 index 00000000000..f36fbc637d0 --- /dev/null +++ b/spec/lib/gitlab/github_gists_import/representation/gist_spec.rb @@ -0,0 +1,111 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::GithubGistsImport::Representation::Gist do + shared_examples 'a Gist' do + it 'returns an instance of Gist' do + expect(gist).to be_an_instance_of(described_class) + end + + context 'with Gist' do + it 'includes gist attributes' do + expect(gist).to have_attributes( + id: '1', + description: 'Gist title', + is_public: true, + files: { '_Summary.md': { filename: '_Summary.md', raw_url: 'https://some_url' } }, + git_pull_url: 'https://gist.github.com/gistid.git' + ) + end + end + end + + describe '.from_api_response' do + let(:response) do + { + id: '1', + description: 'Gist title', + public: true, + created_at: '2022-04-26 18:30:53 UTC', + updated_at: '2022-04-26 18:30:53 UTC', + files: { '_Summary.md': { filename: '_Summary.md', raw_url: 'https://some_url' } }, + git_pull_url: 'https://gist.github.com/gistid.git' + } + end + + it_behaves_like 'a Gist' do + let(:gist) { described_class.from_api_response(response) } + end + end + + describe '.from_json_hash' do + it_behaves_like 'a Gist' do + let(:hash) do + { + 'id' => '1', + 'description' => 'Gist title', + 'is_public' => true, + 'files' => { '_Summary.md': { filename: '_Summary.md', raw_url: 'https://some_url' } }, + 'git_pull_url' => 'https://gist.github.com/gistid.git' + } + end + + let(:gist) { described_class.from_json_hash(hash) } + end + end + + describe '#truncated_title' do + it 'truncates the title to 255 characters' do + object = described_class.new(description: 'm' * 300) + + expect(object.truncated_title.length).to eq(255) + end + + it 'does not truncate the title if it is shorter than 255 characters' do + object = described_class.new(description: 'foo') + + expect(object.truncated_title).to eq('foo') + end + end + + describe '#github_identifiers' do + it 'returns a hash with needed identifiers' do + github_identifiers = { id: 1 } + gist = described_class.new(github_identifiers.merge(something_else: '_something_else_')) + + expect(gist.github_identifiers).to eq(github_identifiers) + end + end + + describe '#visibility_level' do + it 'returns 20 when public' do + visibility = { is_public: true } + gist = described_class.new(visibility.merge(something_else: '_something_else_')) + + expect(gist.visibility_level).to eq(20) + end + + it 'returns 0 when private' do + visibility = { is_public: false } + gist = described_class.new(visibility.merge(something_else: '_something_else_')) + + expect(gist.visibility_level).to eq(0) + end + end + + describe '#first_file' do + let(:http_response) { instance_double('HTTParty::Response', body: 'File content') } + + before do + allow(Gitlab::HTTP).to receive(:try_get).and_return(http_response) + end + + it 'returns a hash with needed identifiers' do + files = { files: { '_Summary.md': { filename: '_Summary.md', raw_url: 'https://some_url' } } } + gist = described_class.new(files.merge(something_else: '_something_else_')) + + expect(gist.first_file).to eq(file_name: '_Summary.md', file_content: 'File content') + end + end +end diff --git a/spec/lib/gitlab/memory/watchdog/configurator_spec.rb b/spec/lib/gitlab/memory/watchdog/configurator_spec.rb index 892bad603a8..72661829bab 100644 --- a/spec/lib/gitlab/memory/watchdog/configurator_spec.rb +++ b/spec/lib/gitlab/memory/watchdog/configurator_spec.rb @@ -243,7 +243,7 @@ RSpec.describe Gitlab::Memory::Watchdog::Configurator do it_behaves_like 'as configurator', Gitlab::Memory::Watchdog::TermProcessHandler, - Gitlab::Memory::Watchdog::EventReporter, + Gitlab::Memory::Watchdog::SidekiqEventReporter, 'SIDEKIQ_MEMORY_KILLER_CHECK_INTERVAL', described_class::DEFAULT_SIDEKIQ_SLEEP_INTERVAL_S diff --git a/spec/lib/gitlab/memory/watchdog/sidekiq_event_reporter_spec.rb b/spec/lib/gitlab/memory/watchdog/sidekiq_event_reporter_spec.rb new file mode 100644 index 00000000000..b6be4c59a0e --- /dev/null +++ b/spec/lib/gitlab/memory/watchdog/sidekiq_event_reporter_spec.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Memory::Watchdog::SidekiqEventReporter, feature_category: :application_performance do + let(:counter) { instance_double(::Prometheus::Client::Counter) } + + before do + allow(Gitlab::Metrics).to receive(:counter).and_return(counter) + allow(counter).to receive(:increment) + end + + describe 'delegations' do + it { is_expected.to delegate_method(:started).to(:event_reporter) } + it { is_expected.to delegate_method(:stopped).to(:event_reporter) } + it { is_expected.to delegate_method(:threshold_violated).to(:event_reporter) } + it { is_expected.to delegate_method(:logger).to(:event_reporter) } + end + + describe '#strikes_exceeded' do + let(:sidekiq_event_reporter) { described_class.new(logger: logger) } + let(:sidekiq_watchdog_running_jobs_counter) { instance_double(::Prometheus::Client::Counter) } + let(:logger) { instance_double(::Logger) } + let(:queue) { 'default' } + let(:jid) { SecureRandom.hex } + let(:running_jobs) { { jid => { worker_class: DummyWorker } } } + let(:worker) do + Class.new do + def self.name + 'DummyWorker' + end + end + end + + before do + stub_const("DummyWorker", worker) + allow(::Gitlab::Metrics).to receive(:counter) + .with(:sidekiq_watchdog_running_jobs_total, anything) + .and_return(sidekiq_watchdog_running_jobs_counter) + allow(sidekiq_watchdog_running_jobs_counter).to receive(:increment) + allow(logger).to receive(:warn) + + allow(Gitlab::SidekiqDaemon::Monitor.instance).to receive(:with_running_jobs).and_yield(running_jobs) + end + + it 'delegates #strikes_exceeded with correct arguments' do + is_expected.to delegate_method(:strikes_exceeded).to(:event_reporter) + .with_arguments( + :monitor_name, + { + message: 'dummy_text', + running_jobs: running_jobs + } + ) + end + + it 'increment running jobs counter' do + expect(sidekiq_watchdog_running_jobs_counter).to receive(:increment) + .with({ worker_class: "DummyWorker" }) + + sidekiq_event_reporter.strikes_exceeded(:monitor_name, { message: 'dummy_text' }) + end + end +end diff --git a/spec/lib/gitlab/merge_requests/message_generator_spec.rb b/spec/lib/gitlab/merge_requests/message_generator_spec.rb index fbdd6a1e56d..59aaffc4377 100644 --- a/spec/lib/gitlab/merge_requests/message_generator_spec.rb +++ b/spec/lib/gitlab/merge_requests/message_generator_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Gitlab::MergeRequests::MessageGenerator do +RSpec.describe Gitlab::MergeRequests::MessageGenerator, feature_category: :code_review do let(:merge_commit_template) { nil } let(:squash_commit_template) { nil } let(:project) do diff --git a/spec/lib/gitlab/sidekiq_daemon/monitor_spec.rb b/spec/lib/gitlab/sidekiq_daemon/monitor_spec.rb index f93c0e28fc0..9f49605be8a 100644 --- a/spec/lib/gitlab/sidekiq_daemon/monitor_spec.rb +++ b/spec/lib/gitlab/sidekiq_daemon/monitor_spec.rb @@ -37,6 +37,17 @@ RSpec.describe Gitlab::SidekiqDaemon::Monitor do end end + describe '#with_running_jobs' do + it 'yields with correct jobs' do + jid = SecureRandom.hex + running_jobs = { jid => hash_including(worker_class: 'worker_class') } + + monitor.within_job('worker_class', jid, 'queue') do + expect { |b| monitor.with_running_jobs(&b) }.to yield_with_args(running_jobs) + end + end + end + describe '#run_thread when notification channel not enabled' do subject { monitor.send(:run_thread) } diff --git a/spec/lib/version_check_spec.rb b/spec/lib/version_check_spec.rb index 1803dd66ba7..f14b38c55dd 100644 --- a/spec/lib/version_check_spec.rb +++ b/spec/lib/version_check_spec.rb @@ -2,7 +2,9 @@ require 'spec_helper' -RSpec.describe VersionCheck do +RSpec.describe VersionCheck, :use_clean_rails_memory_store_caching do + include ReactiveCachingHelpers + describe '.url' do it 'returns the correct URL' do expect(described_class.url).to match(%r{\A#{Regexp.escape(described_class.host)}/check\.json\?gitlab_info=\w+}) @@ -30,7 +32,7 @@ RSpec.describe VersionCheck do end it 'returns the response object' do - expect(described_class.new.calculate_reactive_cache).to eq("{ \"status\": \"success\" }") + expect(described_class.new.calculate_reactive_cache).to eq({ "status" => "success" }) end end @@ -39,38 +41,31 @@ RSpec.describe VersionCheck do stub_request(:get, described_class.url).to_return(status: 500, body: nil, headers: {}) end - it 'returns nil' do - expect(described_class.new.calculate_reactive_cache).to be(nil) + it 'returns an error hash' do + expect(described_class.new.calculate_reactive_cache).to eq({ error: 'version check failed', status: 500 }) end end end describe '#response' do context 'cache returns value' do - let(:response) { { "severity" => "success" }.to_json } - - before do - allow_next_instance_of(described_class) do |instance| - allow(instance).to receive(:with_reactive_cache).and_return(response) - end - end - it 'returns the response object' do - expect(described_class.new.response).to be(response) + version_check = described_class.new + data = { status: 'success' } + stub_reactive_cache(version_check, data) + + expect(version_check.response).to eq(data) end end - context 'cache returns nil' do - let(:response) { nil } - - before do - allow_next_instance_of(described_class) do |instance| - allow(instance).to receive(:with_reactive_cache).and_return(response) - end - end + context 'cache returns error' do + it 'returns nil and invalidates the reactive cache' do + version_check = described_class.new + stub_reactive_cache(version_check, error: 'version check failed') - it 'returns nil' do - expect(described_class.new.response).to be(nil) + expect(version_check).to receive(:refresh_reactive_cache!).and_call_original + expect(version_check.response).to be_nil + expect(read_reactive_cache(version_check)).to be_nil end end end diff --git a/spec/models/ci/build_need_spec.rb b/spec/models/ci/build_need_spec.rb index c2cf9027055..aa1c57d1788 100644 --- a/spec/models/ci/build_need_spec.rb +++ b/spec/models/ci/build_need_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Ci::BuildNeed, model: true do +RSpec.describe Ci::BuildNeed, model: true, feature_category: :continuous_integration do let(:build_need) { build(:ci_build_need) } it { is_expected.to belong_to(:build).class_name('Ci::Processable') } @@ -35,4 +35,62 @@ RSpec.describe Ci::BuildNeed, model: true do end end end + + describe 'partitioning' do + context 'with build' do + let(:build) { FactoryBot.build(:ci_build, partition_id: ci_testing_partition_id) } + let(:build_need) { FactoryBot.build(:ci_build_need, build: build) } + + it 'sets partition_id to the current partition value' do + expect { build_need.valid? }.to change { build_need.partition_id }.to(ci_testing_partition_id) + end + + context 'when it is already set' do + let(:build_need) { FactoryBot.build(:ci_build_need, partition_id: 125) } + + it 'does not change the partition_id value' do + expect { build_need.valid? }.not_to change { build_need.partition_id } + end + end + end + + context 'without build' do + let(:build_need) { FactoryBot.build(:ci_build_need, build: nil) } + + it { is_expected.to validate_presence_of(:partition_id) } + + it 'does not change the partition_id value' do + expect { build_need.valid? }.not_to change { build_need.partition_id } + end + end + + context 'when using bulk_insert' do + include Ci::PartitioningHelpers + + let(:new_pipeline) { create(:ci_pipeline) } + let(:ci_build) { build(:ci_build, pipeline: new_pipeline) } + + before do + stub_current_partition_id + end + + it 'creates build needs successfully', :aggregate_failures do + ci_build.needs_attributes = [ + { name: "build", artifacts: true }, + { name: "build2", artifacts: true }, + { name: "build3", artifacts: true } + ] + + expect(described_class).to receive(:bulk_insert!).and_call_original + + BulkInsertableAssociations.with_bulk_insert do + ci_build.save! + end + + expect(described_class.count).to eq(3) + expect(described_class.first.partition_id).to eq(ci_testing_partition_id) + expect(described_class.second.partition_id).to eq(ci_testing_partition_id) + end + end + end end diff --git a/spec/models/ci/processable_spec.rb b/spec/models/ci/processable_spec.rb index e62e5f84a6d..2ff29bf207e 100644 --- a/spec/models/ci/processable_spec.rb +++ b/spec/models/ci/processable_spec.rb @@ -423,8 +423,8 @@ RSpec.describe Ci::Processable do it 'returns all needs attributes' do is_expected.to contain_exactly( - { 'artifacts' => true, 'name' => 'test1', 'optional' => false }, - { 'artifacts' => true, 'name' => 'test2', 'optional' => false } + { 'artifacts' => true, 'name' => 'test1', 'optional' => false, 'partition_id' => build.partition_id }, + { 'artifacts' => true, 'name' => 'test2', 'optional' => false, 'partition_id' => build.partition_id } ) end end diff --git a/spec/requests/api/helpers_spec.rb b/spec/requests/api/helpers_spec.rb index e29e5c31a34..38275ce0057 100644 --- a/spec/requests/api/helpers_spec.rb +++ b/spec/requests/api/helpers_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' require 'raven/transports/dummy' require_relative '../../../config/initializers/sentry' -RSpec.describe API::Helpers do +RSpec.describe API::Helpers, :enable_admin_mode, feature_category: :authentication_and_authorization do include API::APIGuard::HelperMethods include described_class include TermsHelper diff --git a/spec/requests/api/project_attributes.yml b/spec/requests/api/project_attributes.yml index da478a3547e..c0e64b51853 100644 --- a/spec/requests/api/project_attributes.yml +++ b/spec/requests/api/project_attributes.yml @@ -164,6 +164,7 @@ project_setting: - suggested_reviewers_enabled - jitsu_key - mirror_branch_regex + - allow_pipeline_trigger_approve_deployment build_service_desk_setting: # service_desk_setting unexposed_attributes: diff --git a/spec/services/ci/create_pipeline_service/partitioning_spec.rb b/spec/services/ci/create_pipeline_service/partitioning_spec.rb index f34d103d965..a87135cefdd 100644 --- a/spec/services/ci/create_pipeline_service/partitioning_spec.rb +++ b/spec/services/ci/create_pipeline_service/partitioning_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe Ci::CreatePipelineService, :yaml_processor_feature_flag_corectness, :aggregate_failures, -:ci_partitionable do +:ci_partitionable, feature_category: :continuous_integration do let_it_be(:project) { create(:project, :repository) } let_it_be(:user) { project.first_owner } @@ -15,8 +15,13 @@ RSpec.describe Ci::CreatePipelineService, :yaml_processor_feature_flag_corectnes - test - deploy + needs:build: + stage: build + script: echo "needs..." + build: stage: build + needs: ["needs:build"] script: make build test: @@ -95,6 +100,12 @@ RSpec.describe Ci::CreatePipelineService, :yaml_processor_feature_flag_corectnes expect(pipeline.variables.size).to eq(2) expect(variables_partition_ids).to eq([current_partition_id]) end + + it 'assigns partition_id to needs' do + needs = find_need('build') + + expect(needs.partition_id).to eq(current_partition_id) + end end context 'with parent child pipelines' do @@ -144,4 +155,12 @@ RSpec.describe Ci::CreatePipelineService, :yaml_processor_feature_flag_corectnes .find { |job| job.name == name } .metadata end + + def find_need(name) + pipeline + .processables + .find { |job| job.name == name } + .needs + .first + end end diff --git a/spec/support/models/ci/partitioning_testing/cascade_check.rb b/spec/support/models/ci/partitioning_testing/cascade_check.rb index f553a47ef4f..bcfc9675476 100644 --- a/spec/support/models/ci/partitioning_testing/cascade_check.rb +++ b/spec/support/models/ci/partitioning_testing/cascade_check.rb @@ -15,6 +15,13 @@ module PartitioningTesting raise "partition_id was expected to equal #{partition_scope_value} but it was #{partition_id}." end + + class_methods do + # Allowing partition callback to be used with BulkInsertSafe + def _bulk_insert_callback_allowed?(name, args) + super || args.first == :after && args.second == :check_partition_cascade_value + end + end end end diff --git a/spec/workers/every_sidekiq_worker_spec.rb b/spec/workers/every_sidekiq_worker_spec.rb index 1cee67f68ab..70772fd8b52 100644 --- a/spec/workers/every_sidekiq_worker_spec.rb +++ b/spec/workers/every_sidekiq_worker_spec.rb @@ -286,6 +286,7 @@ RSpec.describe 'Every Sidekiq worker' do 'Gitlab::GithubImport::Stage::ImportPullRequestsReviewsWorker' => 5, 'Gitlab::GithubImport::Stage::ImportPullRequestsWorker' => 5, 'Gitlab::GithubImport::Stage::ImportRepositoryWorker' => 5, + 'Gitlab::GithubGistsImport::ImportGistWorker' => 5, 'Gitlab::JiraImport::AdvanceStageWorker' => 5, 'Gitlab::JiraImport::ImportIssueWorker' => 5, 'Gitlab::JiraImport::Stage::FinishImportWorker' => 5, diff --git a/spec/workers/gitlab/github_gists_import/import_gist_worker_spec.rb b/spec/workers/gitlab/github_gists_import/import_gist_worker_spec.rb new file mode 100644 index 00000000000..dfc5084bb10 --- /dev/null +++ b/spec/workers/gitlab/github_gists_import/import_gist_worker_spec.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::GithubGistsImport::ImportGistWorker, feature_category: :importer do + subject { described_class.new } + + let_it_be(:user) { create(:user) } + let(:token) { 'token' } + let(:gist_hash) do + { + id: '055b70', + git_pull_url: 'https://gist.github.com/foo/bar.git', + files: { + 'random.txt': { + filename: 'random.txt', + type: 'text/plain', + language: 'Text', + raw_url: 'https://gist.githubusercontent.com/user_name/055b70/raw/66a7be0d/random.txt', + size: 166903 + } + }, + is_public: false, + created_at: '2022-09-06T11:38:18Z', + updated_at: '2022-09-06T11:38:18Z', + description: 'random text' + } + end + + let(:importer) { instance_double('Gitlab::GithubGistsImport::Importer::GistImporter') } + let(:importer_result) { instance_double('ServiceResponse', success?: true) } + let(:gist_object) do + instance_double('Gitlab::GithubGistsImport::Representation::Gist', + gist_hash.merge(github_identifiers: { id: '055b70' }, truncated_title: 'random text', visibility_level: 0)) + end + + let(:log_attributes) do + { + 'user_id' => user.id, + 'github_identifiers' => { 'id': gist_object.id }, + 'class' => 'Gitlab::GithubGistsImport::ImportGistWorker', + 'correlation_id' => 'new-correlation-id', + 'jid' => nil, + 'job_status' => 'running', + 'queue' => 'github_gists_importer:github_gists_import_import_gist' + } + end + + describe '#perform' do + before do + allow(Gitlab::GithubGistsImport::Representation::Gist) + .to receive(:from_json_hash) + .with(gist_hash) + .and_return(gist_object) + + allow(Gitlab::GithubGistsImport::Importer::GistImporter) + .to receive(:new) + .with(gist_object, user.id) + .and_return(importer) + + allow(Gitlab::ApplicationContext).to receive(:current).and_return('correlation_id' => 'new-correlation-id') + allow(described_class).to receive(:queue).and_return('github_gists_importer:github_gists_import_import_gist') + end + + context 'when success' do + it 'imports gist' do + expect(Gitlab::GithubImport::Logger) + .to receive(:info) + .with(log_attributes.merge('message' => 'start importer')) + expect(importer).to receive(:execute).and_return(importer_result) + expect(Gitlab::JobWaiter).to receive(:notify).with('some_key', subject.jid) + expect(Gitlab::GithubImport::Logger) + .to receive(:info) + .with(log_attributes.merge('message' => 'importer finished')) + + subject.perform(user.id, gist_hash, 'some_key') + end + end + + context 'when importer raised an error' do + it 'raises an error' do + exception = StandardError.new('_some_error_') + + expect(importer).to receive(:execute).and_raise(exception) + expect(Gitlab::GithubImport::Logger) + .to receive(:error) + .with(log_attributes.merge('message' => 'importer failed', 'error.message' => '_some_error_')) + expect(Gitlab::ErrorTracking).to receive(:track_exception) + + expect { subject.perform(user.id, gist_hash, 'some_key') }.to raise_error(StandardError) + end + end + end +end |