gitlab-org--gitlab-foss/spec/models/blob_spec.rb
Yorick Peterse 0bc443e3b4
Handle encoding in non-binary Blob instances
gitlab_git 10.6.4 relies on Rugged marking blobs as binary or not,
instead of relying on Linguist. Linguist in turn would mark text blobs
as binary whenever they would contain byte sequences that could not be
encoded using UTF-8.

However, marking such blobs as binary is not correct. If one pushes a
Markdown document with invalid character sequences it's still a text
based Markdown document and not some random binary blob.

This commit overwrites Blob#data so it automatically converts text-based
content to UTF-8 (the encoding we use everywhere else) while taking care
of replacing any invalid sequences with the UTF-8 replacement character.
The data of binary blobs is left as-is.
2016-09-14 14:15:31 +02:00

139 lines
3.5 KiB
Ruby
Raw Blame History

# encoding: utf-8
require 'rails_helper'
describe Blob do
describe '.decorate' do
it 'returns NilClass when given nil' do
expect(described_class.decorate(nil)).to be_nil
end
end
describe '#data' do
context 'using a binary blob' do
it 'returns the data as-is' do
data = "\n\xFF\xB9\xC3"
blob = described_class.new(double(binary?: true, data: data))
expect(blob.data).to eq(data)
end
end
context 'using a text blob' do
it 'converts the data to UTF-8' do
blob = described_class.new(double(binary?: false, data: "\n\xFF\xB9\xC3"))
expect(blob.data).to eq("\n<EFBFBD><EFBFBD><EFBFBD>")
end
end
end
describe '#svg?' do
it 'is falsey when not text' do
git_blob = double(text?: false)
expect(described_class.decorate(git_blob)).not_to be_svg
end
it 'is falsey when no language is detected' do
git_blob = double(text?: true, language: nil)
expect(described_class.decorate(git_blob)).not_to be_svg
end
it' is falsey when language is not SVG' do
git_blob = double(text?: true, language: double(name: 'XML'))
expect(described_class.decorate(git_blob)).not_to be_svg
end
it 'is truthy when language is SVG' do
git_blob = double(text?: true, language: double(name: 'SVG'))
expect(described_class.decorate(git_blob)).to be_svg
end
end
describe '#video?' do
it 'is falsey with image extension' do
git_blob = Gitlab::Git::Blob.new(name: 'image.png')
expect(described_class.decorate(git_blob)).not_to be_video
end
UploaderHelper::VIDEO_EXT.each do |ext|
it "is truthy when extension is .#{ext}" do
git_blob = Gitlab::Git::Blob.new(name: "video.#{ext}")
expect(described_class.decorate(git_blob)).to be_video
end
end
end
describe '#to_partial_path' do
def stubbed_blob(overrides = {})
overrides.reverse_merge!(
image?: false,
language: nil,
lfs_pointer?: false,
svg?: false,
text?: false
)
described_class.decorate(double).tap do |blob|
allow(blob).to receive_messages(overrides)
end
end
it 'handles LFS pointers' do
blob = stubbed_blob(lfs_pointer?: true)
expect(blob.to_partial_path).to eq 'download'
end
it 'handles SVGs' do
blob = stubbed_blob(text?: true, svg?: true)
expect(blob.to_partial_path).to eq 'image'
end
it 'handles images' do
blob = stubbed_blob(image?: true)
expect(blob.to_partial_path).to eq 'image'
end
it 'handles text' do
blob = stubbed_blob(text?: true)
expect(blob.to_partial_path).to eq 'text'
end
it 'defaults to download' do
blob = stubbed_blob
expect(blob.to_partial_path).to eq 'download'
end
end
describe '#size_within_svg_limits?' do
let(:blob) { described_class.decorate(double(:blob)) }
it 'returns true when the blob size is smaller than the SVG limit' do
expect(blob).to receive(:size).and_return(42)
expect(blob.size_within_svg_limits?).to eq(true)
end
it 'returns true when the blob size is equal to the SVG limit' do
expect(blob).to receive(:size).and_return(Blob::MAXIMUM_SVG_SIZE)
expect(blob.size_within_svg_limits?).to eq(true)
end
it 'returns false when the blob size is larger than the SVG limit' do
expect(blob).to receive(:size).and_return(1.terabyte)
expect(blob.size_within_svg_limits?).to eq(false)
end
end
end