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/lib
diff options
context:
space:
mode:
Diffstat (limited to 'spec/lib')
-rw-r--r--spec/lib/after_commit_queue_spec.rb15
-rw-r--r--spec/lib/api/helpers/pagination_spec.rb52
-rw-r--r--spec/lib/gitlab/background_migration/deserialize_merge_request_diffs_and_commits_spec.rb11
-rw-r--r--spec/lib/gitlab/background_migration/migrate_events_to_push_event_payloads_spec.rb21
-rw-r--r--spec/lib/gitlab/background_migration/migrate_stage_status_spec.rb80
-rw-r--r--spec/lib/gitlab/diff/inline_diff_markdown_marker_spec.rb6
-rw-r--r--spec/lib/gitlab/diff/inline_diff_marker_spec.rb14
-rw-r--r--spec/lib/gitlab/git/repository_spec.rb59
-rw-r--r--spec/lib/gitlab/git/storage/forked_storage_check_spec.rb2
-rw-r--r--spec/lib/gitlab/git_access_spec.rb249
-rw-r--r--spec/lib/gitlab/gitaly_client/commit_service_spec.rb14
-rw-r--r--spec/lib/gitlab/gitaly_client/ref_service_spec.rb21
-rw-r--r--spec/lib/gitlab/gitaly_client/repository_service_spec.rb76
-rw-r--r--spec/lib/gitlab/import_export/project.json5
-rw-r--r--spec/lib/gitlab/import_export/project_tree_restorer_spec.rb7
-rw-r--r--spec/lib/gitlab/import_export/project_tree_saver_spec.rb10
-rw-r--r--spec/lib/gitlab/import_export/safe_model_attributes.yml2
-rw-r--r--spec/lib/gitlab/job_waiter_spec.rb41
-rw-r--r--spec/lib/gitlab/sidekiq_throttler_spec.rb50
-rw-r--r--spec/lib/gitlab/string_range_marker_spec.rb39
20 files changed, 527 insertions, 247 deletions
diff --git a/spec/lib/after_commit_queue_spec.rb b/spec/lib/after_commit_queue_spec.rb
new file mode 100644
index 00000000000..6e7c2ec2363
--- /dev/null
+++ b/spec/lib/after_commit_queue_spec.rb
@@ -0,0 +1,15 @@
+require 'spec_helper'
+
+describe AfterCommitQueue do
+ it 'runs after transaction is committed' do
+ called = false
+ test_proc = proc { called = true }
+
+ project = build(:project)
+ project.run_after_commit(&test_proc)
+
+ project.save
+
+ expect(called).to be true
+ end
+end
diff --git a/spec/lib/api/helpers/pagination_spec.rb b/spec/lib/api/helpers/pagination_spec.rb
index fb3ef04b860..59deca7757b 100644
--- a/spec/lib/api/helpers/pagination_spec.rb
+++ b/spec/lib/api/helpers/pagination_spec.rb
@@ -52,7 +52,13 @@ describe API::Helpers::Pagination do
expect_header('X-Page', '1')
expect_header('X-Next-Page', '2')
expect_header('X-Prev-Page', '')
- expect_header('Link', any_args)
+
+ expect_header('Link', anything) do |_key, val|
+ expect(val).to include('rel="first"')
+ expect(val).to include('rel="last"')
+ expect(val).to include('rel="next"')
+ expect(val).not_to include('rel="prev"')
+ end
subject.paginate(resource)
end
@@ -75,15 +81,53 @@ describe API::Helpers::Pagination do
expect_header('X-Page', '2')
expect_header('X-Next-Page', '')
expect_header('X-Prev-Page', '1')
- expect_header('Link', any_args)
+
+ expect_header('Link', anything) do |_key, val|
+ expect(val).to include('rel="first"')
+ expect(val).to include('rel="last"')
+ expect(val).to include('rel="prev"')
+ expect(val).not_to include('rel="next"')
+ end
+
+ subject.paginate(resource)
+ end
+ end
+ end
+
+ context 'when resource empty' do
+ describe 'first page' do
+ before do
+ allow(subject).to receive(:params)
+ .and_return({ page: 1, per_page: 2 })
+ end
+
+ it 'returns appropriate amount of resources' do
+ expect(subject.paginate(resource).count).to eq 0
+ end
+
+ it 'adds appropriate headers' do
+ expect_header('X-Total', '0')
+ expect_header('X-Total-Pages', '1')
+ expect_header('X-Per-Page', '2')
+ expect_header('X-Page', '1')
+ expect_header('X-Next-Page', '')
+ expect_header('X-Prev-Page', '')
+
+ expect_header('Link', anything) do |_key, val|
+ expect(val).to include('rel="first"')
+ expect(val).to include('rel="last"')
+ expect(val).not_to include('rel="prev"')
+ expect(val).not_to include('rel="next"')
+ expect(val).not_to include('page=0')
+ end
subject.paginate(resource)
end
end
end
- def expect_header(name, value)
- expect(subject).to receive(:header).with(name, value)
+ def expect_header(*args, &block)
+ expect(subject).to receive(:header).with(*args, &block)
end
def expect_message(method)
diff --git a/spec/lib/gitlab/background_migration/deserialize_merge_request_diffs_and_commits_spec.rb b/spec/lib/gitlab/background_migration/deserialize_merge_request_diffs_and_commits_spec.rb
index 7cd2ce82eda..c0427639746 100644
--- a/spec/lib/gitlab/background_migration/deserialize_merge_request_diffs_and_commits_spec.rb
+++ b/spec/lib/gitlab/background_migration/deserialize_merge_request_diffs_and_commits_spec.rb
@@ -134,6 +134,17 @@ describe Gitlab::BackgroundMigration::DeserializeMergeRequestDiffsAndCommits do
include_examples 'updated MR diff'
end
+ context 'when the merge request diffs do not have a_mode and b_mode set' do
+ let(:commits) { merge_request_diff.commits.map(&:to_hash) }
+ let(:expected_diffs) { diffs_to_hashes(merge_request_diff.merge_request_diff_files) }
+
+ let(:diffs) do
+ expected_diffs.map { |diff| diff.except(:a_mode, :b_mode) }
+ end
+
+ include_examples 'updated MR diff'
+ end
+
context 'when the merge request diffs have binary content' do
let(:commits) { merge_request_diff.commits.map(&:to_hash) }
let(:expected_diffs) { diffs }
diff --git a/spec/lib/gitlab/background_migration/migrate_events_to_push_event_payloads_spec.rb b/spec/lib/gitlab/background_migration/migrate_events_to_push_event_payloads_spec.rb
index 87f45619e7a..0d5fffa38ff 100644
--- a/spec/lib/gitlab/background_migration/migrate_events_to_push_event_payloads_spec.rb
+++ b/spec/lib/gitlab/background_migration/migrate_events_to_push_event_payloads_spec.rb
@@ -210,7 +210,11 @@ describe Gitlab::BackgroundMigration::MigrateEventsToPushEventPayloads::Event do
end
end
-describe Gitlab::BackgroundMigration::MigrateEventsToPushEventPayloads do
+##
+# The background migration relies on a temporary table, hence we're migrating
+# to a specific version of the database where said table is still present.
+#
+describe Gitlab::BackgroundMigration::MigrateEventsToPushEventPayloads, :migration, schema: 20170608152748 do
let(:migration) { described_class.new }
let(:project) { create(:project_empty_repo) }
let(:author) { create(:user) }
@@ -229,21 +233,6 @@ describe Gitlab::BackgroundMigration::MigrateEventsToPushEventPayloads do
)
end
- # The background migration relies on a temporary table, hence we're migrating
- # to a specific version of the database where said table is still present.
- before :all do
- ActiveRecord::Migration.verbose = false
-
- ActiveRecord::Migrator
- .migrate(ActiveRecord::Migrator.migrations_paths, 20170608152748)
- end
-
- after :all do
- ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.migrations_paths)
-
- ActiveRecord::Migration.verbose = true
- end
-
describe '#perform' do
it 'returns if data should not be migrated' do
allow(migration).to receive(:migrate?).and_return(false)
diff --git a/spec/lib/gitlab/background_migration/migrate_stage_status_spec.rb b/spec/lib/gitlab/background_migration/migrate_stage_status_spec.rb
new file mode 100644
index 00000000000..878158910be
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/migrate_stage_status_spec.rb
@@ -0,0 +1,80 @@
+require 'spec_helper'
+
+describe Gitlab::BackgroundMigration::MigrateStageStatus, :migration, schema: 20170711145320 do
+ let(:projects) { table(:projects) }
+ let(:pipelines) { table(:ci_pipelines) }
+ let(:stages) { table(:ci_stages) }
+ let(:jobs) { table(:ci_builds) }
+
+ STATUSES = { created: 0, pending: 1, running: 2, success: 3,
+ failed: 4, canceled: 5, skipped: 6, manual: 7 }.freeze
+
+ before do
+ projects.create!(id: 1, name: 'gitlab1', path: 'gitlab1')
+ pipelines.create!(id: 1, project_id: 1, ref: 'master', sha: 'adf43c3a')
+ stages.create!(id: 1, pipeline_id: 1, project_id: 1, name: 'test', status: nil)
+ stages.create!(id: 2, pipeline_id: 1, project_id: 1, name: 'deploy', status: nil)
+ end
+
+ context 'when stage status is known' do
+ before do
+ create_job(project: 1, pipeline: 1, stage: 'test', status: 'success')
+ create_job(project: 1, pipeline: 1, stage: 'test', status: 'running')
+ create_job(project: 1, pipeline: 1, stage: 'deploy', status: 'failed')
+ end
+
+ it 'sets a correct stage status' do
+ described_class.new.perform(1, 2)
+
+ expect(stages.first.status).to eq STATUSES[:running]
+ expect(stages.second.status).to eq STATUSES[:failed]
+ end
+ end
+
+ context 'when stage status is not known' do
+ it 'sets a skipped stage status' do
+ described_class.new.perform(1, 2)
+
+ expect(stages.first.status).to eq STATUSES[:skipped]
+ expect(stages.second.status).to eq STATUSES[:skipped]
+ end
+ end
+
+ context 'when stage status includes status of a retried job' do
+ before do
+ create_job(project: 1, pipeline: 1, stage: 'test', status: 'canceled')
+ create_job(project: 1, pipeline: 1, stage: 'deploy', status: 'failed', retried: true)
+ create_job(project: 1, pipeline: 1, stage: 'deploy', status: 'success')
+ end
+
+ it 'sets a correct stage status' do
+ described_class.new.perform(1, 2)
+
+ expect(stages.first.status).to eq STATUSES[:canceled]
+ expect(stages.second.status).to eq STATUSES[:success]
+ end
+ end
+
+ context 'when some job in the stage is blocked / manual' do
+ before do
+ create_job(project: 1, pipeline: 1, stage: 'test', status: 'failed')
+ create_job(project: 1, pipeline: 1, stage: 'test', status: 'manual')
+ create_job(project: 1, pipeline: 1, stage: 'deploy', status: 'success', when: 'manual')
+ end
+
+ it 'sets a correct stage status' do
+ described_class.new.perform(1, 2)
+
+ expect(stages.first.status).to eq STATUSES[:manual]
+ expect(stages.second.status).to eq STATUSES[:success]
+ end
+ end
+
+ def create_job(project:, pipeline:, stage:, status:, **opts)
+ stages = { test: 1, build: 2, deploy: 3 }
+
+ jobs.create!(project_id: project, commit_id: pipeline,
+ stage_idx: stages[stage.to_sym], stage: stage,
+ status: status, **opts)
+ end
+end
diff --git a/spec/lib/gitlab/diff/inline_diff_markdown_marker_spec.rb b/spec/lib/gitlab/diff/inline_diff_markdown_marker_spec.rb
index 046b096e366..7e17437fa2a 100644
--- a/spec/lib/gitlab/diff/inline_diff_markdown_marker_spec.rb
+++ b/spec/lib/gitlab/diff/inline_diff_markdown_marker_spec.rb
@@ -6,9 +6,9 @@ describe Gitlab::Diff::InlineDiffMarkdownMarker do
let(:inline_diffs) { [2..5] }
let(:subject) { described_class.new(raw).mark(inline_diffs, mode: :deletion) }
- it 'marks the range' do
- expect(subject).to eq("ab{-c 'd-}ef'")
- expect(subject).to be_html_safe
+ it 'does not escape html etities and marks the range' do
+ expect(subject).to eq("ab{-c 'd-}ef'")
+ expect(subject).not_to be_html_safe
end
end
end
diff --git a/spec/lib/gitlab/diff/inline_diff_marker_spec.rb b/spec/lib/gitlab/diff/inline_diff_marker_spec.rb
index c3bf34c24ae..7296bbf5df3 100644
--- a/spec/lib/gitlab/diff/inline_diff_marker_spec.rb
+++ b/spec/lib/gitlab/diff/inline_diff_marker_spec.rb
@@ -2,11 +2,13 @@ require 'spec_helper'
describe Gitlab::Diff::InlineDiffMarker do
describe '#mark' do
+ let(:inline_diffs) { [2..5] }
+ let(:raw) { "abc 'def'" }
+
+ subject { described_class.new(raw, rich).mark(inline_diffs) }
+
context "when the rich text is html safe" do
- let(:raw) { "abc 'def'" }
let(:rich) { %{<span class="abc">abc</span><span class="space"> </span><span class="def">&#39;def&#39;</span>}.html_safe }
- let(:inline_diffs) { [2..5] }
- let(:subject) { described_class.new(raw, rich).mark(inline_diffs) }
it 'marks the range' do
expect(subject).to eq(%{<span class="abc">ab<span class="idiff left">c</span></span><span class="space"><span class="idiff"> </span></span><span class="def"><span class="idiff right">&#39;d</span>ef&#39;</span>})
@@ -15,12 +17,10 @@ describe Gitlab::Diff::InlineDiffMarker do
end
context "when the text text is not html safe" do
- let(:raw) { "abc 'def'" }
- let(:inline_diffs) { [2..5] }
- let(:subject) { described_class.new(raw).mark(inline_diffs) }
+ let(:rich) { "abc 'def' differs" }
it 'marks the range' do
- expect(subject).to eq(%{ab<span class="idiff left right">c &#39;d</span>ef&#39;})
+ expect(subject).to eq(%{ab<span class="idiff left right">c &#39;d</span>ef&#39; differs})
expect(subject).to be_html_safe
end
end
diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb
index 4ef5d9070a2..8ec8dfe6acf 100644
--- a/spec/lib/gitlab/git/repository_spec.rb
+++ b/spec/lib/gitlab/git/repository_spec.rb
@@ -235,18 +235,10 @@ describe Gitlab::Git::Repository, seed_helper: true do
it { is_expected.to be < 2 }
end
- describe '#has_commits?' do
- it { expect(repository.has_commits?).to be_truthy }
- end
-
describe '#empty?' do
it { expect(repository.empty?).to be_falsey }
end
- describe '#bare?' do
- it { expect(repository.bare?).to be_truthy }
- end
-
describe '#ref_names' do
let(:ref_names) { repository.ref_names }
subject { ref_names }
@@ -441,15 +433,6 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
end
- describe "#remote_names" do
- let(:remotes) { repository.remote_names }
-
- it "should have one entry: 'origin'" do
- expect(remotes.size).to eq(1)
- expect(remotes.first).to eq("origin")
- end
- end
-
describe "#refs_hash" do
let(:refs) { repository.refs_hash }
@@ -1098,28 +1081,48 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
describe '#tag_exists?' do
- it 'returns true for an existing tag' do
- tag = repository.tag_names.first
+ shared_examples 'checks the existence of tags' do
+ it 'returns true for an existing tag' do
+ tag = repository.tag_names.first
+
+ expect(repository.tag_exists?(tag)).to eq(true)
+ end
- expect(repository.tag_exists?(tag)).to eq(true)
+ it 'returns false for a non-existing tag' do
+ expect(repository.tag_exists?('v9000')).to eq(false)
+ end
end
- it 'returns false for a non-existing tag' do
- expect(repository.tag_exists?('v9000')).to eq(false)
+ context 'when Gitaly ref_exists_tags feature is enabled' do
+ it_behaves_like 'checks the existence of tags'
+ end
+
+ context 'when Gitaly ref_exists_tags feature is disabled', skip_gitaly_mock: true do
+ it_behaves_like 'checks the existence of tags'
end
end
describe '#branch_exists?' do
- it 'returns true for an existing branch' do
- expect(repository.branch_exists?('master')).to eq(true)
+ shared_examples 'checks the existence of branches' do
+ it 'returns true for an existing branch' do
+ expect(repository.branch_exists?('master')).to eq(true)
+ end
+
+ it 'returns false for a non-existing branch' do
+ expect(repository.branch_exists?('kittens')).to eq(false)
+ end
+
+ it 'returns false when using an invalid branch name' do
+ expect(repository.branch_exists?('.bla')).to eq(false)
+ end
end
- it 'returns false for a non-existing branch' do
- expect(repository.branch_exists?('kittens')).to eq(false)
+ context 'when Gitaly ref_exists_branches feature is enabled' do
+ it_behaves_like 'checks the existence of branches'
end
- it 'returns false when using an invalid branch name' do
- expect(repository.branch_exists?('.bla')).to eq(false)
+ context 'when Gitaly ref_exists_branches feature is disabled', skip_gitaly_mock: true do
+ it_behaves_like 'checks the existence of branches'
end
end
diff --git a/spec/lib/gitlab/git/storage/forked_storage_check_spec.rb b/spec/lib/gitlab/git/storage/forked_storage_check_spec.rb
index 12366151f44..c708b15853a 100644
--- a/spec/lib/gitlab/git/storage/forked_storage_check_spec.rb
+++ b/spec/lib/gitlab/git/storage/forked_storage_check_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Gitlab::Git::Storage::ForkedStorageCheck, skip_database_cleaner: true do
+describe Gitlab::Git::Storage::ForkedStorageCheck, broken_storage: true, skip_database_cleaner: true do
let(:existing_path) do
existing_path = TestEnv.repos_path
FileUtils.mkdir_p(existing_path)
diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb
index 2d6ea37d0ac..80dc49e99cb 100644
--- a/spec/lib/gitlab/git_access_spec.rb
+++ b/spec/lib/gitlab/git_access_spec.rb
@@ -1,21 +1,17 @@
require 'spec_helper'
describe Gitlab::GitAccess do
- let(:pull_access_check) { access.check('git-upload-pack', '_any') }
- let(:push_access_check) { access.check('git-receive-pack', '_any') }
- let(:access) { described_class.new(actor, project, protocol, authentication_abilities: authentication_abilities, redirected_path: redirected_path) }
- let(:project) { create(:project, :repository) }
- let(:user) { create(:user) }
+ set(:user) { create(:user) }
+
let(:actor) { user }
+ let(:project) { create(:project, :repository) }
let(:protocol) { 'ssh' }
+ let(:authentication_abilities) { %i[read_project download_code push_code] }
let(:redirected_path) { nil }
- let(:authentication_abilities) do
- [
- :read_project,
- :download_code,
- :push_code
- ]
- end
+
+ let(:access) { described_class.new(actor, project, protocol, authentication_abilities: authentication_abilities, redirected_path: redirected_path) }
+ let(:push_access_check) { access.check('git-receive-pack', '_any') }
+ let(:pull_access_check) { access.check('git-upload-pack', '_any') }
describe '#check with single protocols allowed' do
def disable_protocol(protocol)
@@ -27,12 +23,11 @@ describe Gitlab::GitAccess do
disable_protocol('ssh')
end
- it 'blocks ssh git push' do
- expect { push_access_check }.to raise_unauthorized('Git access over SSH is not allowed')
- end
-
- it 'blocks ssh git pull' do
- expect { pull_access_check }.to raise_unauthorized('Git access over SSH is not allowed')
+ it 'blocks ssh git push and pull' do
+ aggregate_failures do
+ expect { push_access_check }.to raise_unauthorized('Git access over SSH is not allowed')
+ expect { pull_access_check }.to raise_unauthorized('Git access over SSH is not allowed')
+ end
end
end
@@ -43,12 +38,11 @@ describe Gitlab::GitAccess do
disable_protocol('http')
end
- it 'blocks http push' do
- expect { push_access_check }.to raise_unauthorized('Git access over HTTP is not allowed')
- end
-
- it 'blocks http git pull' do
- expect { pull_access_check }.to raise_unauthorized('Git access over HTTP is not allowed')
+ it 'blocks http push and pull' do
+ aggregate_failures do
+ expect { push_access_check }.to raise_unauthorized('Git access over HTTP is not allowed')
+ expect { pull_access_check }.to raise_unauthorized('Git access over HTTP is not allowed')
+ end
end
end
end
@@ -65,22 +59,20 @@ describe Gitlab::GitAccess do
deploy_key.projects << project
end
- it 'allows pull access' do
- expect { pull_access_check }.not_to raise_error
- end
-
- it 'allows push access' do
- expect { push_access_check }.not_to raise_error
+ it 'allows push and pull access' do
+ aggregate_failures do
+ expect { push_access_check }.not_to raise_error
+ expect { pull_access_check }.not_to raise_error
+ end
end
end
context 'when the Deploykey does not have access to the project' do
- it 'blocks pulls with "not found"' do
- expect { pull_access_check }.to raise_not_found('The project you were looking for could not be found.')
- end
-
- it 'blocks pushes with "not found"' do
- expect { push_access_check }.to raise_not_found('The project you were looking for could not be found.')
+ it 'blocks push and pull with "not found"' do
+ aggregate_failures do
+ expect { push_access_check }.to raise_not_found
+ expect { pull_access_check }.to raise_not_found
+ end
end
end
end
@@ -88,25 +80,23 @@ describe Gitlab::GitAccess do
context 'when actor is a User' do
context 'when the User can read the project' do
before do
- project.team << [user, :master]
+ project.add_master(user)
end
- it 'allows pull access' do
- expect { pull_access_check }.not_to raise_error
- end
-
- it 'allows push access' do
- expect { push_access_check }.not_to raise_error
+ it 'allows push and pull access' do
+ aggregate_failures do
+ expect { pull_access_check }.not_to raise_error
+ expect { push_access_check }.not_to raise_error
+ end
end
end
context 'when the User cannot read the project' do
- it 'blocks pulls with "not found"' do
- expect { pull_access_check }.to raise_not_found('The project you were looking for could not be found.')
- end
-
- it 'blocks pushes with "not found"' do
- expect { push_access_check }.to raise_not_found('The project you were looking for could not be found.')
+ it 'blocks push and pull with "not found"' do
+ aggregate_failures do
+ expect { push_access_check }.to raise_not_found
+ expect { pull_access_check }.to raise_not_found
+ end
end
end
end
@@ -121,7 +111,7 @@ describe Gitlab::GitAccess do
end
it 'does not block pushes with "not found"' do
- expect { push_access_check }.to raise_unauthorized('You are not allowed to upload code for this project.')
+ expect { push_access_check }.to raise_unauthorized(described_class::ERROR_MESSAGES[:upload])
end
end
end
@@ -137,17 +127,17 @@ describe Gitlab::GitAccess do
end
it 'does not block pushes with "not found"' do
- expect { push_access_check }.to raise_unauthorized('You are not allowed to upload code for this project.')
+ expect { push_access_check }.to raise_unauthorized(described_class::ERROR_MESSAGES[:upload])
end
end
context 'when guests cannot read the project' do
it 'blocks pulls with "not found"' do
- expect { pull_access_check }.to raise_not_found('The project you were looking for could not be found.')
+ expect { pull_access_check }.to raise_not_found
end
it 'blocks pushes with "not found"' do
- expect { push_access_check }.to raise_not_found('The project you were looking for could not be found.')
+ expect { push_access_check }.to raise_not_found
end
end
end
@@ -156,48 +146,50 @@ describe Gitlab::GitAccess do
context 'when the project is nil' do
let(:project) { nil }
- it 'blocks any command with "not found"' do
- expect { pull_access_check }.to raise_not_found('The project you were looking for could not be found.')
- expect { push_access_check }.to raise_not_found('The project you were looking for could not be found.')
+ it 'blocks push and pull with "not found"' do
+ aggregate_failures do
+ expect { pull_access_check }.to raise_not_found
+ expect { push_access_check }.to raise_not_found
+ end
end
end
end
describe '#check_project_moved!' do
before do
- project.team << [user, :master]
+ project.add_master(user)
end
context 'when a redirect was not followed to find the project' do
- context 'pull code' do
- it { expect { pull_access_check }.not_to raise_error }
- end
-
- context 'push code' do
- it { expect { push_access_check }.not_to raise_error }
+ it 'allows push and pull access' do
+ aggregate_failures do
+ expect { push_access_check }.not_to raise_error
+ expect { pull_access_check }.not_to raise_error
+ end
end
end
context 'when a redirect was followed to find the project' do
let(:redirected_path) { 'some/other-path' }
- context 'pull code' do
- it { expect { pull_access_check }.to raise_not_found(/Project '#{redirected_path}' was moved to '#{project.full_path}'/) }
- it { expect { pull_access_check }.to raise_not_found(/git remote set-url origin #{project.ssh_url_to_repo}/) }
+ it 'blocks push and pull access' do
+ aggregate_failures do
+ expect { push_access_check }.to raise_error(described_class::ProjectMovedError, /Project '#{redirected_path}' was moved to '#{project.full_path}'/)
+ expect { push_access_check }.to raise_error(described_class::ProjectMovedError, /git remote set-url origin #{project.ssh_url_to_repo}/)
- context 'http protocol' do
- let(:protocol) { 'http' }
- it { expect { pull_access_check }.to raise_not_found(/git remote set-url origin #{project.http_url_to_repo}/) }
+ expect { pull_access_check }.to raise_error(described_class::ProjectMovedError, /Project '#{redirected_path}' was moved to '#{project.full_path}'/)
+ expect { pull_access_check }.to raise_error(described_class::ProjectMovedError, /git remote set-url origin #{project.ssh_url_to_repo}/)
end
end
- context 'push code' do
- it { expect { push_access_check }.to raise_not_found(/Project '#{redirected_path}' was moved to '#{project.full_path}'/) }
- it { expect { push_access_check }.to raise_not_found(/git remote set-url origin #{project.ssh_url_to_repo}/) }
+ context 'http protocol' do
+ let(:protocol) { 'http' }
- context 'http protocol' do
- let(:protocol) { 'http' }
- it { expect { push_access_check }.to raise_not_found(/git remote set-url origin #{project.http_url_to_repo}/) }
+ it 'includes the path to the project using HTTP' do
+ aggregate_failures do
+ expect { push_access_check }.to raise_error(described_class::ProjectMovedError, /git remote set-url origin #{project.http_url_to_repo}/)
+ expect { pull_access_check }.to raise_error(described_class::ProjectMovedError, /git remote set-url origin #{project.http_url_to_repo}/)
+ end
end
end
end
@@ -242,40 +234,28 @@ describe Gitlab::GitAccess do
end
describe '#check_download_access!' do
- describe 'master permissions' do
- before do
- project.team << [user, :master]
- end
+ it 'allows masters to pull' do
+ project.add_master(user)
- context 'pull code' do
- it { expect { pull_access_check }.not_to raise_error }
- end
+ expect { pull_access_check }.not_to raise_error
end
- describe 'guest permissions' do
- before do
- project.team << [user, :guest]
- end
+ it 'disallows guests to pull' do
+ project.add_guest(user)
- context 'pull code' do
- it { expect { pull_access_check }.to raise_unauthorized('You are not allowed to download code from this project.') }
- end
+ expect { pull_access_check }.to raise_unauthorized(described_class::ERROR_MESSAGES[:download])
end
- describe 'blocked user' do
- before do
- project.team << [user, :master]
- user.block
- end
+ it 'disallows blocked users to pull' do
+ project.add_master(user)
+ user.block
- context 'pull code' do
- it { expect { pull_access_check }.to raise_unauthorized('Your account has been blocked.') }
- end
+ expect { pull_access_check }.to raise_unauthorized('Your account has been blocked.')
end
describe 'without access to project' do
context 'pull code' do
- it { expect { pull_access_check }.to raise_not_found('The project you were looking for could not be found.') }
+ it { expect { pull_access_check }.to raise_not_found }
end
context 'when project is public' do
@@ -292,7 +272,7 @@ describe Gitlab::GitAccess do
it 'does not give access to download code' do
public_project.project_feature.update_attribute(:repository_access_level, ProjectFeature::DISABLED)
- expect { pull_access_check }.to raise_unauthorized('You are not allowed to download code from this project.')
+ expect { pull_access_check }.to raise_unauthorized(described_class::ERROR_MESSAGES[:download])
end
end
end
@@ -321,13 +301,13 @@ describe Gitlab::GitAccess do
context 'from internal project' do
let(:project) { create(:project, :internal, :repository) }
- it { expect { pull_access_check }.to raise_not_found('The project you were looking for could not be found.') }
+ it { expect { pull_access_check }.to raise_not_found }
end
context 'from private project' do
let(:project) { create(:project, :private, :repository) }
- it { expect { pull_access_check }.to raise_not_found('The project you were looking for could not be found.') }
+ it { expect { pull_access_check }.to raise_not_found }
end
end
end
@@ -369,7 +349,7 @@ describe Gitlab::GitAccess do
context 'when is not member of the project' do
context 'pull code' do
- it { expect { pull_access_check }.to raise_unauthorized('You are not allowed to download code from this project.') }
+ it { expect { pull_access_check }.to raise_unauthorized(described_class::ERROR_MESSAGES[:download]) }
end
end
end
@@ -428,28 +408,30 @@ describe Gitlab::GitAccess do
end
end
- # Run permission checks for a user
def self.run_permission_checks(permissions_matrix)
- permissions_matrix.keys.each do |role|
- describe "#{role} access" do
- before do
- if role == :admin
- user.update_attribute(:admin, true)
- else
- project.team << [user, role]
- end
+ permissions_matrix.each_pair do |role, matrix|
+ # Run through the entire matrix for this role in one test to avoid
+ # repeated setup.
+ #
+ # Expectations are given a custom failure message proc so that it's
+ # easier to identify which check(s) failed.
+ it "has the correct permissions for #{role}s" do
+ if role == :admin
+ user.update_attribute(:admin, true)
+ else
+ project.team << [user, role]
end
- permissions_matrix[role].each do |action, allowed|
- context action.to_s do
- subject { access.send(:check_push_access!, changes[action]) }
+ aggregate_failures do
+ matrix.each do |action, allowed|
+ check = -> { access.send(:check_push_access!, changes[action]) }
- it do
- if allowed
- expect { subject }.not_to raise_error
- else
- expect { subject }.to raise_error(Gitlab::GitAccess::UnauthorizedError)
- end
+ if allowed
+ expect(&check).not_to raise_error,
+ -> { "expected #{action} to be allowed" }
+ else
+ expect(&check).to raise_error(Gitlab::GitAccess::UnauthorizedError),
+ -> { "expected #{action} to be disallowed" }
end
end
end
@@ -588,26 +570,26 @@ describe Gitlab::GitAccess do
project.team << [user, :reporter]
end
- it { expect { push_access_check }.to raise_unauthorized('You are not allowed to upload code for this project.') }
+ it { expect { push_access_check }.to raise_unauthorized(described_class::ERROR_MESSAGES[:upload]) }
end
context 'when unauthorized' do
context 'to public project' do
let(:project) { create(:project, :public, :repository) }
- it { expect { push_access_check }.to raise_unauthorized('You are not allowed to upload code for this project.') }
+ it { expect { push_access_check }.to raise_unauthorized(described_class::ERROR_MESSAGES[:upload]) }
end
context 'to internal project' do
let(:project) { create(:project, :internal, :repository) }
- it { expect { push_access_check }.to raise_unauthorized('You are not allowed to upload code for this project.') }
+ it { expect { push_access_check }.to raise_unauthorized(described_class::ERROR_MESSAGES[:upload]) }
end
context 'to private project' do
let(:project) { create(:project, :private, :repository) }
- it { expect { push_access_check }.to raise_not_found('The project you were looking for could not be found.') }
+ it { expect { push_access_check }.to raise_not_found }
end
end
end
@@ -631,19 +613,19 @@ describe Gitlab::GitAccess do
context 'to public project' do
let(:project) { create(:project, :public, :repository) }
- it { expect { push_access_check }.to raise_unauthorized('This deploy key does not have write access to this project.') }
+ it { expect { push_access_check }.to raise_unauthorized(described_class::ERROR_MESSAGES[:deploy_key_upload]) }
end
context 'to internal project' do
let(:project) { create(:project, :internal, :repository) }
- it { expect { push_access_check }.to raise_not_found('The project you were looking for could not be found.') }
+ it { expect { push_access_check }.to raise_not_found }
end
context 'to private project' do
let(:project) { create(:project, :private, :repository) }
- it { expect { push_access_check }.to raise_not_found('The project you were looking for could not be found.') }
+ it { expect { push_access_check }.to raise_not_found }
end
end
end
@@ -656,26 +638,26 @@ describe Gitlab::GitAccess do
key.projects << project
end
- it { expect { push_access_check }.to raise_unauthorized('This deploy key does not have write access to this project.') }
+ it { expect { push_access_check }.to raise_unauthorized(described_class::ERROR_MESSAGES[:deploy_key_upload]) }
end
context 'when unauthorized' do
context 'to public project' do
let(:project) { create(:project, :public, :repository) }
- it { expect { push_access_check }.to raise_unauthorized('This deploy key does not have write access to this project.') }
+ it { expect { push_access_check }.to raise_unauthorized(described_class::ERROR_MESSAGES[:deploy_key_upload]) }
end
context 'to internal project' do
let(:project) { create(:project, :internal, :repository) }
- it { expect { push_access_check }.to raise_not_found('The project you were looking for could not be found.') }
+ it { expect { push_access_check }.to raise_not_found }
end
context 'to private project' do
let(:project) { create(:project, :private, :repository) }
- it { expect { push_access_check }.to raise_not_found('The project you were looking for could not be found.') }
+ it { expect { push_access_check }.to raise_not_found }
end
end
end
@@ -687,8 +669,9 @@ describe Gitlab::GitAccess do
raise_error(Gitlab::GitAccess::UnauthorizedError, message)
end
- def raise_not_found(message)
- raise_error(Gitlab::GitAccess::NotFoundError, message)
+ def raise_not_found
+ raise_error(Gitlab::GitAccess::NotFoundError,
+ Gitlab::GitAccess::ERROR_MESSAGES[:project_not_found])
end
def build_authentication_abilities
diff --git a/spec/lib/gitlab/gitaly_client/commit_service_spec.rb b/spec/lib/gitlab/gitaly_client/commit_service_spec.rb
index 7fe698fcb18..2eaf4222964 100644
--- a/spec/lib/gitlab/gitaly_client/commit_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/commit_service_spec.rb
@@ -111,6 +111,20 @@ describe Gitlab::GitalyClient::CommitService do
client.tree_entries(repository, revision, path)
end
+
+ context 'with UTF-8 params strings' do
+ let(:revision) { "branch\u011F" }
+ let(:path) { "foo/\u011F.txt" }
+
+ it 'handles string encodings correctly' do
+ expect_any_instance_of(Gitaly::CommitService::Stub)
+ .to receive(:get_tree_entries)
+ .with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash))
+ .and_return([])
+
+ client.tree_entries(repository, revision, path)
+ end
+ end
end
describe '#find_commit' do
diff --git a/spec/lib/gitlab/gitaly_client/ref_service_spec.rb b/spec/lib/gitlab/gitaly_client/ref_service_spec.rb
index 46efc1b18f0..6f59750b4da 100644
--- a/spec/lib/gitlab/gitaly_client/ref_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/ref_service_spec.rb
@@ -1,10 +1,11 @@
require 'spec_helper'
describe Gitlab::GitalyClient::RefService do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:storage_name) { project.repository_storage }
let(:relative_path) { project.disk_path + '.git' }
- let(:client) { described_class.new(project.repository) }
+ let(:repository) { project.repository }
+ let(:client) { described_class.new(repository) }
describe '#branches' do
it 'sends a find_all_branches message' do
@@ -84,11 +85,23 @@ describe Gitlab::GitalyClient::RefService do
end
describe '#find_ref_name', seed_helper: true do
- let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
- let(:client) { described_class.new(repository) }
subject { client.find_ref_name(SeedRepo::Commit::ID, 'refs/heads/master') }
it { is_expected.to be_utf8 }
it { is_expected.to eq('refs/heads/master') }
end
+
+ describe '#ref_exists?', seed_helper: true do
+ it 'finds the master branch ref' do
+ expect(client.ref_exists?('refs/heads/master')).to eq(true)
+ end
+
+ it 'returns false for an illegal tag name ref' do
+ expect(client.ref_exists?('refs/tags/.this-tag-name-is-illegal')).to eq(false)
+ end
+
+ it 'raises an argument error if the ref name parameter does not start with refs/' do
+ expect { client.ref_exists?('reXXXXX') }.to raise_error(ArgumentError)
+ end
+ end
end
diff --git a/spec/lib/gitlab/gitaly_client/repository_service_spec.rb b/spec/lib/gitlab/gitaly_client/repository_service_spec.rb
new file mode 100644
index 00000000000..fd5f984601e
--- /dev/null
+++ b/spec/lib/gitlab/gitaly_client/repository_service_spec.rb
@@ -0,0 +1,76 @@
+require 'spec_helper'
+
+describe Gitlab::GitalyClient::RepositoryService do
+ let(:project) { create(:project) }
+ let(:storage_name) { project.repository_storage }
+ let(:relative_path) { project.disk_path + '.git' }
+ let(:client) { described_class.new(project.repository) }
+
+ describe '#exists?' do
+ it 'sends a repository_exists message' do
+ expect_any_instance_of(Gitaly::RepositoryService::Stub)
+ .to receive(:repository_exists)
+ .with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash))
+ .and_return(double(exists: true))
+
+ client.exists?
+ end
+ end
+
+ describe '#garbage_collect' do
+ it 'sends a garbage_collect message' do
+ expect_any_instance_of(Gitaly::RepositoryService::Stub)
+ .to receive(:garbage_collect)
+ .with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash))
+ .and_return(double(:garbage_collect_response))
+
+ client.garbage_collect(true)
+ end
+ end
+
+ describe '#repack_full' do
+ it 'sends a repack_full message' do
+ expect_any_instance_of(Gitaly::RepositoryService::Stub)
+ .to receive(:repack_full)
+ .with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash))
+ .and_return(double(:repack_full_response))
+
+ client.repack_full(true)
+ end
+ end
+
+ describe '#repack_incremental' do
+ it 'sends a repack_incremental message' do
+ expect_any_instance_of(Gitaly::RepositoryService::Stub)
+ .to receive(:repack_incremental)
+ .with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash))
+ .and_return(double(:repack_incremental_response))
+
+ client.repack_incremental
+ end
+ end
+
+ describe '#repository_size' do
+ it 'sends a repository_size message' do
+ expect_any_instance_of(Gitaly::RepositoryService::Stub)
+ .to receive(:repository_size)
+ .with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash))
+ .and_return(size: 0)
+
+ client.repository_size
+ end
+ end
+
+ describe '#apply_gitattributes' do
+ let(:revision) { 'master' }
+
+ it 'sends an apply_gitattributes message' do
+ expect_any_instance_of(Gitaly::RepositoryService::Stub)
+ .to receive(:apply_gitattributes)
+ .with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash))
+ .and_return(double(:apply_gitattributes_response))
+
+ client.apply_gitattributes(revision)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/import_export/project.json b/spec/lib/gitlab/import_export/project.json
index 4e631e13410..331b7cf2fea 100644
--- a/spec/lib/gitlab/import_export/project.json
+++ b/spec/lib/gitlab/import_export/project.json
@@ -2522,7 +2522,7 @@
"id": 27,
"target_branch": "feature",
"source_branch": "feature_conflict",
- "source_project_id": 5,
+ "source_project_id": 999,
"author_id": 1,
"assignee_id": null,
"title": "MR1",
@@ -2536,6 +2536,9 @@
"position": 0,
"updated_by_id": null,
"merge_error": null,
+ "diff_head_sha": "HEAD",
+ "source_branch_sha": "ABCD",
+ "target_branch_sha": "DCBA",
"merge_params": {
"force_remove_source_branch": null
},
diff --git a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
index 956f1d56eb4..c10427d798f 100644
--- a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
@@ -10,6 +10,13 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do
@shared = Gitlab::ImportExport::Shared.new(relative_path: "", project_path: 'path')
allow(@shared).to receive(:export_path).and_return('spec/lib/gitlab/import_export/')
@project = create(:project, :builds_disabled, :issues_disabled, name: 'project', path: 'project')
+
+ allow(@project.repository).to receive(:fetch_ref).and_return(true)
+ allow(@project.repository.raw).to receive(:rugged_branch_exists?).and_return(false)
+
+ expect_any_instance_of(Gitlab::Git::Repository).to receive(:create_branch).with('feature', 'DCBA')
+ allow_any_instance_of(Gitlab::Git::Repository).to receive(:create_branch)
+
project_tree_restorer = described_class.new(user: @user, shared: @shared, project: @project)
@restored_project_json = project_tree_restorer.restore
end
diff --git a/spec/lib/gitlab/import_export/project_tree_saver_spec.rb b/spec/lib/gitlab/import_export/project_tree_saver_spec.rb
index a278f89c1a1..065b0ec6658 100644
--- a/spec/lib/gitlab/import_export/project_tree_saver_spec.rb
+++ b/spec/lib/gitlab/import_export/project_tree_saver_spec.rb
@@ -11,6 +11,8 @@ describe Gitlab::ImportExport::ProjectTreeSaver do
before do
project.team << [user, :master]
allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path)
+ allow_any_instance_of(MergeRequest).to receive(:source_branch_sha).and_return('ABCD')
+ allow_any_instance_of(MergeRequest).to receive(:target_branch_sha).and_return('DCBA')
end
after do
@@ -43,6 +45,14 @@ describe Gitlab::ImportExport::ProjectTreeSaver do
expect(saved_project_json['merge_requests'].first['milestone']).not_to be_empty
end
+ it 'has merge request\'s source branch SHA' do
+ expect(saved_project_json['merge_requests'].first['source_branch_sha']).to eq('ABCD')
+ end
+
+ it 'has merge request\'s target branch SHA' do
+ expect(saved_project_json['merge_requests'].first['target_branch_sha']).to eq('DCBA')
+ end
+
it 'has events' do
expect(saved_project_json['merge_requests'].first['milestone']['events']).not_to be_empty
end
diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml
index ae3b0173160..a5e03e149a7 100644
--- a/spec/lib/gitlab/import_export/safe_model_attributes.yml
+++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml
@@ -227,6 +227,8 @@ Ci::Pipeline:
Ci::Stage:
- id
- name
+- status
+- lock_version
- project_id
- pipeline_id
- created_at
diff --git a/spec/lib/gitlab/job_waiter_spec.rb b/spec/lib/gitlab/job_waiter_spec.rb
index 6186cec2689..b0b4fdc09bc 100644
--- a/spec/lib/gitlab/job_waiter_spec.rb
+++ b/spec/lib/gitlab/job_waiter_spec.rb
@@ -1,30 +1,39 @@
require 'spec_helper'
describe Gitlab::JobWaiter do
- describe '#wait' do
- let(:waiter) { described_class.new(%w(a)) }
- it 'returns when all jobs have been completed' do
- expect(Gitlab::SidekiqStatus).to receive(:all_completed?).with(%w(a))
- .and_return(true)
+ describe '.notify' do
+ it 'pushes the jid to the named queue' do
+ key = 'gitlab:job_waiter:foo'
+ jid = 1
- expect(waiter).not_to receive(:sleep)
+ redis = double('redis')
+ expect(Gitlab::Redis::SharedState).to receive(:with).and_yield(redis)
+ expect(redis).to receive(:lpush).with(key, jid)
- waiter.wait
+ described_class.notify(key, jid)
end
+ end
+
+ describe '#wait' do
+ let(:waiter) { described_class.new(2) }
- it 'sleeps between checking the job statuses' do
- expect(Gitlab::SidekiqStatus).to receive(:all_completed?)
- .with(%w(a))
- .and_return(false, true)
+ it 'returns when all jobs have been completed' do
+ described_class.notify(waiter.key, 'a')
+ described_class.notify(waiter.key, 'b')
- expect(waiter).to receive(:sleep).with(described_class::INTERVAL)
+ result = nil
+ expect { Timeout.timeout(1) { result = waiter.wait(2) } }.not_to raise_error
- waiter.wait
+ expect(result).to contain_exactly('a', 'b')
end
- it 'returns when timing out' do
- expect(waiter).not_to receive(:sleep)
- waiter.wait(0)
+ it 'times out if not all jobs complete' do
+ described_class.notify(waiter.key, 'a')
+
+ result = nil
+ expect { Timeout.timeout(2) { result = waiter.wait(1) } }.not_to raise_error
+
+ expect(result).to contain_exactly('a')
end
end
end
diff --git a/spec/lib/gitlab/sidekiq_throttler_spec.rb b/spec/lib/gitlab/sidekiq_throttler_spec.rb
index 6374ac80207..2dbb7bb7c34 100644
--- a/spec/lib/gitlab/sidekiq_throttler_spec.rb
+++ b/spec/lib/gitlab/sidekiq_throttler_spec.rb
@@ -1,28 +1,44 @@
require 'spec_helper'
describe Gitlab::SidekiqThrottler do
- before do
- Sidekiq.options[:concurrency] = 35
-
- stub_application_setting(
- sidekiq_throttling_enabled: true,
- sidekiq_throttling_factor: 0.1,
- sidekiq_throttling_queues: %w[build project_cache]
- )
- end
-
describe '#execute!' do
- it 'sets limits on the selected queues' do
- described_class.execute!
+ context 'when job throttling is enabled' do
+ before do
+ Sidekiq.options[:concurrency] = 35
+
+ stub_application_setting(
+ sidekiq_throttling_enabled: true,
+ sidekiq_throttling_factor: 0.1,
+ sidekiq_throttling_queues: %w[build project_cache]
+ )
+ end
+
+ it 'requires sidekiq-limit_fetch' do
+ expect(described_class).to receive(:require).with('sidekiq-limit_fetch').and_call_original
+
+ described_class.execute!
+ end
+
+ it 'sets limits on the selected queues' do
+ described_class.execute!
+
+ expect(Sidekiq::Queue['build'].limit).to eq 4
+ expect(Sidekiq::Queue['project_cache'].limit).to eq 4
+ end
+
+ it 'does not set limits on other queues' do
+ described_class.execute!
- expect(Sidekiq::Queue['build'].limit).to eq 4
- expect(Sidekiq::Queue['project_cache'].limit).to eq 4
+ expect(Sidekiq::Queue['merge'].limit).to be_nil
+ end
end
- it 'does not set limits on other queues' do
- described_class.execute!
+ context 'when job throttling is disabled' do
+ it 'does not require sidekiq-limit_fetch' do
+ expect(described_class).not_to receive(:require).with('sidekiq-limit_fetch')
- expect(Sidekiq::Queue['merge'].limit).to be_nil
+ described_class.execute!
+ end
end
end
end
diff --git a/spec/lib/gitlab/string_range_marker_spec.rb b/spec/lib/gitlab/string_range_marker_spec.rb
index abeaa7f0ddb..6bc02459dbd 100644
--- a/spec/lib/gitlab/string_range_marker_spec.rb
+++ b/spec/lib/gitlab/string_range_marker_spec.rb
@@ -2,34 +2,39 @@ require 'spec_helper'
describe Gitlab::StringRangeMarker do
describe '#mark' do
+ def mark_diff(rich = nil)
+ raw = 'abc <def>'
+ inline_diffs = [2..5]
+
+ described_class.new(raw, rich).mark(inline_diffs) do |text, left:, right:|
+ "LEFT#{text}RIGHT"
+ end
+ end
+
context "when the rich text is html safe" do
- let(:raw) { "abc <def>" }
let(:rich) { %{<span class="abc">abc</span><span class="space"> </span><span class="def">&lt;def&gt;</span>}.html_safe }
- let(:inline_diffs) { [2..5] }
- subject do
- described_class.new(raw, rich).mark(inline_diffs) do |text, left:, right:|
- "LEFT#{text}RIGHT"
- end
- end
it 'marks the inline diffs' do
- expect(subject).to eq(%{<span class="abc">abLEFTcRIGHT</span><span class="space">LEFT RIGHT</span><span class="def">LEFT&lt;dRIGHTef&gt;</span>})
- expect(subject).to be_html_safe
+ expect(mark_diff(rich)).to eq(%{<span class="abc">abLEFTcRIGHT</span><span class="space">LEFT RIGHT</span><span class="def">LEFT&lt;dRIGHTef&gt;</span>})
+ expect(mark_diff(rich)).to be_html_safe
end
end
context "when the rich text is not html safe" do
- let(:raw) { "abc <def>" }
- let(:inline_diffs) { [2..5] }
- subject do
- described_class.new(raw).mark(inline_diffs) do |text, left:, right:|
- "LEFT#{text}RIGHT"
+ context 'when rich text equals raw text' do
+ it 'marks the inline diffs' do
+ expect(mark_diff).to eq(%{abLEFTc <dRIGHTef>})
+ expect(mark_diff).not_to be_html_safe
end
end
- it 'marks the inline diffs' do
- expect(subject).to eq(%{abLEFTc &lt;dRIGHTef&gt;})
- expect(subject).to be_html_safe
+ context 'when rich text doeas not equal raw text' do
+ let(:rich) { "abc <def> differs" }
+
+ it 'marks the inline diffs' do
+ expect(mark_diff(rich)).to eq(%{abLEFTc &lt;dRIGHTef&gt; differs})
+ expect(mark_diff(rich)).to be_html_safe
+ end
end
end
end