diff options
Diffstat (limited to 'spec/lib/gitlab/git')
-rw-r--r-- | spec/lib/gitlab/git/blame_spec.rb | 98 | ||||
-rw-r--r-- | spec/lib/gitlab/git/diff_spec.rb | 58 | ||||
-rw-r--r-- | spec/lib/gitlab/git/repository_spec.rb | 2 |
3 files changed, 109 insertions, 49 deletions
diff --git a/spec/lib/gitlab/git/blame_spec.rb b/spec/lib/gitlab/git/blame_spec.rb index 495cb16ebab..7dd7460b142 100644 --- a/spec/lib/gitlab/git/blame_spec.rb +++ b/spec/lib/gitlab/git/blame_spec.rb @@ -4,71 +4,81 @@ require "spec_helper" RSpec.describe Gitlab::Git::Blame, :seed_helper do let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '', 'group/project') } - let(:blame) do - Gitlab::Git::Blame.new(repository, SeedRepo::Commit::ID, "CONTRIBUTING.md") + + let(:sha) { SeedRepo::Commit::ID } + let(:path) { 'CONTRIBUTING.md' } + let(:range) { nil } + + subject(:blame) { Gitlab::Git::Blame.new(repository, sha, path, range: range) } + + let(:result) do + [].tap do |data| + blame.each do |commit, line, previous_path| + data << { commit: commit, line: line, previous_path: previous_path } + end + end end describe 'blaming a file' do - context "each count" do - it do - data = [] - blame.each do |commit, line| - data << { - commit: commit, - line: line - } - end + it 'has the right number of lines' do + expect(result.size).to eq(95) + expect(result.first[:commit]).to be_kind_of(Gitlab::Git::Commit) + expect(result.first[:line]).to eq("# Contribute to GitLab") + expect(result.first[:line]).to be_utf8 + end - expect(data.size).to eq(95) - expect(data.first[:commit]).to be_kind_of(Gitlab::Git::Commit) - expect(data.first[:line]).to eq("# Contribute to GitLab") - expect(data.first[:line]).to be_utf8 + context 'blaming a range' do + let(:range) { 2..4 } + + it 'only returns the range' do + expect(result.size).to eq(range.size) + expect(result.map {|r| r[:line] }).to eq(['', 'This guide details how contribute to GitLab.', '']) end end context "ISO-8859 encoding" do - let(:blame) do - Gitlab::Git::Blame.new(repository, SeedRepo::EncodingCommit::ID, "encoding/iso8859.txt") - end + let(:sha) { SeedRepo::EncodingCommit::ID } + let(:path) { 'encoding/iso8859.txt' } it 'converts to UTF-8' do - data = [] - blame.each do |commit, line| - data << { - commit: commit, - line: line - } - end - - expect(data.size).to eq(1) - expect(data.first[:commit]).to be_kind_of(Gitlab::Git::Commit) - expect(data.first[:line]).to eq("Ä ü") - expect(data.first[:line]).to be_utf8 + expect(result.size).to eq(1) + expect(result.first[:commit]).to be_kind_of(Gitlab::Git::Commit) + expect(result.first[:line]).to eq("Ä ü") + expect(result.first[:line]).to be_utf8 end end context "unknown encoding" do - let(:blame) do - Gitlab::Git::Blame.new(repository, SeedRepo::EncodingCommit::ID, "encoding/iso8859.txt") - end + let(:sha) { SeedRepo::EncodingCommit::ID } + let(:path) { 'encoding/iso8859.txt' } it 'converts to UTF-8' do expect_next_instance_of(CharlockHolmes::EncodingDetector) do |detector| expect(detector).to receive(:detect).and_return(nil) end - data = [] - blame.each do |commit, line| - data << { - commit: commit, - line: line - } - end + expect(result.size).to eq(1) + expect(result.first[:commit]).to be_kind_of(Gitlab::Git::Commit) + expect(result.first[:line]).to eq(" ") + expect(result.first[:line]).to be_utf8 + end + end + + context "renamed file" do + let(:project) { create(:project, :repository) } + let(:repository) { project.repository.raw_repository } + let(:commit) { project.commit('blame-on-renamed') } + let(:sha) { commit.id } + let(:path) { 'files/plain_text/renamed' } + + it 'includes the previous path' do + expect(result.size).to eq(5) - expect(data.size).to eq(1) - expect(data.first[:commit]).to be_kind_of(Gitlab::Git::Commit) - expect(data.first[:line]).to eq(" ") - expect(data.first[:line]).to be_utf8 + expect(result[0]).to include(line: 'Initial commit', previous_path: nil) + expect(result[1]).to include(line: 'Initial commit', previous_path: nil) + expect(result[2]).to include(line: 'Renamed as "filename"', previous_path: 'files/plain_text/initial-commit') + expect(result[3]).to include(line: 'Renamed as renamed', previous_path: 'files/plain_text/"filename"') + expect(result[4]).to include(line: 'Last edit, no rename', previous_path: path) end end end diff --git a/spec/lib/gitlab/git/diff_spec.rb b/spec/lib/gitlab/git/diff_spec.rb index 17bb83d0f2f..46f544797bb 100644 --- a/spec/lib/gitlab/git/diff_spec.rb +++ b/spec/lib/gitlab/git/diff_spec.rb @@ -161,6 +161,52 @@ EOT expect(diff).not_to have_binary_notice end end + + context 'when diff contains invalid characters' do + let(:bad_string) { [0xae].pack("C*") } + let(:bad_string_two) { [0x89].pack("C*") } + + let(:diff) { described_class.new(@raw_diff_hash.merge({ diff: bad_string })) } + let(:diff_two) { described_class.new(@raw_diff_hash.merge({ diff: bad_string_two })) } + + context 'when replace_invalid_utf8_chars is true' do + it 'will convert invalid characters and not cause an encoding error' do + expect(diff.diff).to include(Gitlab::EncodingHelper::UNICODE_REPLACEMENT_CHARACTER) + expect(diff_two.diff).to include(Gitlab::EncodingHelper::UNICODE_REPLACEMENT_CHARACTER) + + expect { Oj.dump(diff) }.not_to raise_error(EncodingError) + expect { Oj.dump(diff_two) }.not_to raise_error(EncodingError) + end + + context 'when the diff is binary' do + let(:project) { create(:project, :repository) } + + it 'will not try to replace characters' do + expect(Gitlab::EncodingHelper).not_to receive(:encode_utf8_with_replacement_character?) + expect(binary_diff(project).diff).not_to be_empty + end + end + + context 'when convert_diff_to_utf8_with_replacement_symbol feature flag is disabled' do + before do + stub_feature_flags(convert_diff_to_utf8_with_replacement_symbol: false) + end + + it 'will not try to convert invalid characters' do + expect(Gitlab::EncodingHelper).not_to receive(:encode_utf8_with_replacement_character?) + end + end + end + + context 'when replace_invalid_utf8_chars is false' do + let(:not_replaced_diff) { described_class.new(@raw_diff_hash.merge({ diff: bad_string, replace_invalid_utf8_chars: false }) ) } + let(:not_replaced_diff_two) { described_class.new(@raw_diff_hash.merge({ diff: bad_string_two, replace_invalid_utf8_chars: false }) ) } + + it 'will not try to convert invalid characters' do + expect(Gitlab::EncodingHelper).not_to receive(:encode_utf8_with_replacement_character?) + end + end + end end describe 'straight diffs' do @@ -255,12 +301,11 @@ EOT let(:project) { create(:project, :repository) } it 'fake binary message when it detects binary' do - # Rugged will not detect this as binary, but we can fake it diff_message = "Binary files files/images/icn-time-tracking.pdf and files/images/icn-time-tracking.pdf differ\n" - binary_diff = described_class.between(project.repository, 'add-pdf-text-binary', 'add-pdf-text-binary^').first - expect(binary_diff.diff).not_to be_empty - expect(binary_diff.json_safe_diff).to eq(diff_message) + diff = binary_diff(project) + expect(diff.diff).not_to be_empty + expect(diff.json_safe_diff).to eq(diff_message) end it 'leave non-binary diffs as-is' do @@ -374,4 +419,9 @@ EOT expect(diff.line_count).to eq(0) end end + + def binary_diff(project) + # rugged will not detect this as binary, but we can fake it + described_class.between(project.repository, 'add-pdf-text-binary', 'add-pdf-text-binary^').first + end end diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb index ae6ca728573..47688c4b3e6 100644 --- a/spec/lib/gitlab/git/repository_spec.rb +++ b/spec/lib/gitlab/git/repository_spec.rb @@ -2448,7 +2448,7 @@ RSpec.describe Gitlab::Git::Repository, :seed_helper do it 'delegates to Gitaly' do expect_next_instance_of(Gitlab::GitalyClient::RepositoryService) do |svc| - expect(svc).to receive(:import_repository).with(url).and_return(nil) + expect(svc).to receive(:import_repository).with(url, http_authorization_header: '', mirror: false).and_return(nil) end repository.import_repository(url) |