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
diff options
context:
space:
mode:
Diffstat (limited to 'spec/models/merge_request_diff_file_spec.rb')
-rw-r--r--spec/models/merge_request_diff_file_spec.rb153
1 files changed, 140 insertions, 13 deletions
diff --git a/spec/models/merge_request_diff_file_spec.rb b/spec/models/merge_request_diff_file_spec.rb
index c9bcb900eca..7dc550a6c93 100644
--- a/spec/models/merge_request_diff_file_spec.rb
+++ b/spec/models/merge_request_diff_file_spec.rb
@@ -13,50 +13,53 @@ RSpec.describe MergeRequestDiffFile do
let(:invalid_items_for_bulk_insertion) { [] } # class does not have any validations defined
end
+ let(:unpacked) { 'unpacked' }
+ let(:packed) { [unpacked].pack('m0') }
+ let(:file) { create(:merge_request).merge_request_diff.merge_request_diff_files.first }
+
describe '#diff' do
+ let(:file) { build(:merge_request_diff_file) }
+
context 'when diff is not stored' do
let(:unpacked) { 'unpacked' }
let(:packed) { [unpacked].pack('m0') }
before do
- subject.diff = packed
+ file.diff = packed
end
context 'when the diff is marked as binary' do
before do
- subject.binary = true
+ file.binary = true
end
it 'unpacks from base 64' do
- expect(subject.diff).to eq(unpacked)
+ expect(file.diff).to eq(unpacked)
end
context 'invalid base64' do
let(:packed) { '---/dev/null' }
it 'returns the raw diff' do
- expect(subject.diff).to eq(packed)
+ expect(file.diff).to eq(packed)
end
end
end
context 'when the diff is not marked as binary' do
it 'returns the raw diff' do
- expect(subject.diff).to eq(packed)
+ expect(file.diff).to eq(packed)
end
end
end
context 'when diff is stored in DB' do
- let(:file) { create(:merge_request).merge_request_diff.merge_request_diff_files.first }
-
it 'returns UTF-8 string' do
expect(file.diff.encoding).to eq Encoding::UTF_8
end
end
context 'when diff is stored in external storage' do
- let(:file) { create(:merge_request).merge_request_diff.merge_request_diff_files.first }
let(:test_dir) { 'tmp/tests/external-diffs' }
around do |example|
@@ -81,17 +84,141 @@ RSpec.describe MergeRequestDiffFile do
describe '#utf8_diff' do
it 'does not raise error when the diff is binary' do
- subject.diff = "\x05\x00\x68\x65\x6c\x6c\x6f"
+ file = build(:merge_request_diff_file)
+ file.diff = "\x05\x00\x68\x65\x6c\x6c\x6f"
- expect { subject.utf8_diff }.not_to raise_error
+ expect { file.utf8_diff }.not_to raise_error
end
it 'calls #diff once' do
- allow(subject).to receive(:diff).and_return('test')
+ allow(file).to receive(:diff).and_return('test')
+
+ expect(file).to receive(:diff).once
+
+ file.utf8_diff
+ end
+
+ context 'externally stored diff caching' do
+ let(:test_dir) { 'tmp/tests/external-diffs' }
+
+ around do |example|
+ FileUtils.mkdir_p(test_dir)
+
+ begin
+ example.run
+ ensure
+ FileUtils.rm_rf(test_dir)
+ end
+ end
+
+ before do
+ stub_external_diffs_setting(enabled: true, storage_path: test_dir)
+ end
+
+ context 'when external diff is not cached' do
+ it 'caches external diffs' do
+ expect(file.merge_request_diff).to receive(:cache_external_diff).and_call_original
+
+ expect(file.utf8_diff).to eq(file.diff)
+ end
+ end
+
+ context 'when external diff is already cached' do
+ it 'reads diff from cached external diff' do
+ file_stub = double
+
+ allow(file.merge_request_diff).to receive(:cached_external_diff).and_yield(file_stub)
+ expect(file_stub).to receive(:seek).with(file.external_diff_offset)
+ expect(file_stub).to receive(:read).with(file.external_diff_size)
+
+ file.utf8_diff
+ end
+ end
+
+ context 'when the diff is marked as binary' do
+ let(:file) { build(:merge_request_diff_file) }
- expect(subject).to receive(:diff).once
+ before do
+ allow(file.merge_request_diff).to receive(:stored_externally?).and_return(true)
+ allow(file.merge_request_diff).to receive(:cached_external_diff).and_return(packed)
+ end
- subject.utf8_diff
+ context 'when the diff is marked as binary' do
+ before do
+ file.binary = true
+ end
+
+ it 'unpacks from base 64' do
+ expect(file.utf8_diff).to eq(unpacked)
+ end
+
+ context 'invalid base64' do
+ let(:packed) { '---/dev/null' }
+
+ it 'returns the raw diff' do
+ expect(file.utf8_diff).to eq(packed)
+ end
+ end
+ end
+
+ context 'when the diff is not marked as binary' do
+ it 'returns the raw diff' do
+ expect(file.utf8_diff).to eq(packed)
+ end
+ end
+ end
+
+ context 'when content responds to #encoding' do
+ it 'encodes content to utf8 encoding' do
+ expect(file.utf8_diff.encoding).to eq(Encoding::UTF_8)
+ end
+ end
+
+ context 'when content is blank' do
+ it 'returns an empty string' do
+ allow(file.merge_request_diff).to receive(:cached_external_diff).and_return(nil)
+
+ expect(file.utf8_diff).to eq('')
+ end
+ end
+
+ context 'when exception is raised' do
+ it 'falls back to #diff' do
+ allow(file).to receive(:binary?).and_raise(StandardError, 'Error!')
+ expect(file).to receive(:diff)
+ expect(Gitlab::AppLogger)
+ .to receive(:warn)
+ .with(
+ a_hash_including(
+ :message => 'Cached external diff export failed',
+ :merge_request_diff_file_id => file.id,
+ :merge_request_diff_id => file.merge_request_diff.id,
+ 'exception.class' => 'StandardError',
+ 'exception.message' => 'Error!'
+ )
+ )
+
+ file.utf8_diff
+ end
+ end
+ end
+
+ context 'when externally_stored_diffs_caching_export feature flag is disabled' do
+ it 'calls #diff' do
+ stub_feature_flags(externally_stored_diffs_caching_export: false)
+
+ expect(file).to receive(:diff)
+
+ file.utf8_diff
+ end
+ end
+
+ context 'when diff is not stored externally' do
+ it 'calls #diff' do
+ expect(file).to receive(:diff)
+
+ file.utf8_diff
+ end
end
end
end