Commit 964e7d20 authored by Douwe Maan's avatar Douwe Maan

Add specs

parent b73b1679
...@@ -31,7 +31,7 @@ export default () => { ...@@ -31,7 +31,7 @@ export default () => {
}, },
}, },
template: ` template: `
<div class="container-fluid md prepend-top-default append-bottom-default"> <div class="js-pdf-viewer container-fluid md prepend-top-default append-bottom-default">
<div <div
class="text-center loading" class="text-center loading"
v-if="loading && !error"> v-if="loading && !error">
......
...@@ -100,11 +100,11 @@ class Blob < SimpleDelegator ...@@ -100,11 +100,11 @@ class Blob < SimpleDelegator
end end
def valid_lfs_pointer? def valid_lfs_pointer?
lfs_pointer? && project.lfs_enabled? lfs_pointer? && project&.lfs_enabled?
end end
def invalid_lfs_pointer? def invalid_lfs_pointer?
lfs_pointer? && !project.lfs_enabled? lfs_pointer? && !project&.lfs_enabled?
end end
def simple_viewer def simple_viewer
......
...@@ -56,10 +56,10 @@ module BlobViewer ...@@ -56,10 +56,10 @@ module BlobViewer
end end
def render_error def render_error
if override_max_size ? absolutely_too_large? : too_large? if server_side_but_stored_in_lfs?
:too_large
elsif server_side_but_stored_in_lfs?
:server_side_but_stored_in_lfs :server_side_but_stored_in_lfs
elsif override_max_size ? absolutely_too_large? : too_large?
:too_large
end end
end end
......
include 'spec_helper'
describe Projects::BlobController, RendersBlob, model: true do
# TODO: Test
end
...@@ -104,4 +104,114 @@ describe BlobHelper do ...@@ -104,4 +104,114 @@ describe BlobHelper do
expect(Capybara.string(link).find_link('Edit')[:href]).to eq('/gitlab/gitlabhq/edit/master/README.md?mr_id=10') expect(Capybara.string(link).find_link('Edit')[:href]).to eq('/gitlab/gitlabhq/edit/master/README.md?mr_id=10')
end end
end end
context 'viewer related' do
include FakeBlobHelpers
let(:project) { build(:empty_project) }
let(:viewer_class) do
Class.new(BlobViewer::Base) do
self.max_size = 1.megabyte
self.absolute_max_size = 5.megabytes
self.type = :rich
self.client_side = false
end
end
let(:viewer) { viewer_class.new(blob) }
let(:blob) { fake_blob }
before do
assign(:project, project)
assign(:id, File.join('master', blob.path))
controller.params[:controller] = 'projects/blob'
controller.params[:action] = 'show'
controller.params[:namespace_id] = project.namespace.to_param
controller.params[:project_id] = project.to_param
controller.params[:id] = File.join('master', blob.path)
end
describe '#blob_render_error_reason' do
context 'for error :too_large' do
context 'when the blob size is larger than the absolute max size' do
let(:blob) { fake_blob(size: 10.megabytes) }
it 'returns an error message' do
expect(helper.blob_render_error_reason(viewer, :too_large)).to eq('it is larger than 5 MB')
end
end
context 'when the blob size is larger than the max size' do
let(:blob) { fake_blob(size: 2.megabytes) }
it 'returns an error message' do
expect(helper.blob_render_error_reason(viewer, :too_large)).to eq('it is larger than 1 MB')
end
end
end
context 'for error :server_side_but_stored_in_lfs' do
it 'returns an error message' do
expect(helper.blob_render_error_reason(viewer, :server_side_but_stored_in_lfs)).to eq('it is stored in LFS')
end
end
end
describe '#blob_render_error_options' do
context 'for error :too_large' do
context 'when the max size can be overridden' do
let(:blob) { fake_blob(size: 2.megabytes) }
it 'includes a "load it anyway" link' do
expect(helper.blob_render_error_options(viewer, :too_large)).to include(/load it anyway/)
end
end
context 'when the max size cannot be overridden' do
let(:blob) { fake_blob(size: 10.megabytes) }
it 'does not include a "load it anyway" link' do
expect(helper.blob_render_error_options(viewer, :too_large)).not_to include(/load it anyway/)
end
end
end
context 'when the viewer is rich' do
context 'the blob is rendered as text' do
let(:blob) { fake_blob(path: 'file.md') }
it 'includes a "view the source" link' do
expect(helper.blob_render_error_options(viewer, :server_side_but_stored_in_lfs)).to include(/view the source/)
end
end
context 'the blob is not rendered as text' do
let(:blob) { fake_blob(path: 'file.pdf', binary: true) }
it 'does not include a "view the source" link' do
expect(helper.blob_render_error_options(viewer, :server_side_but_stored_in_lfs)).not_to include(/view the source/)
end
end
end
context 'when the viewer is not rich' do
before do
viewer_class.type = :simple
end
let(:blob) { fake_blob(path: 'file.md') }
it 'does not include a "view the source" link' do
expect(helper.blob_render_error_options(viewer, :server_side_but_stored_in_lfs)).not_to include(/view the source/)
end
end
it 'includes a "download it" link' do
expect(helper.blob_render_error_options(viewer, :server_side_but_stored_in_lfs)).to include(/download it/)
end
end
end
end end
...@@ -2,6 +2,14 @@ ...@@ -2,6 +2,14 @@
require 'rails_helper' require 'rails_helper'
describe Blob do describe Blob do
include FakeBlobHelpers
let(:project) { build(:empty_project, lfs_enabled: true) }
before do
allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
end
describe '.decorate' do describe '.decorate' do
it 'returns NilClass when given nil' do it 'returns NilClass when given nil' do
expect(described_class.decorate(nil)).to be_nil expect(described_class.decorate(nil)).to be_nil
...@@ -12,7 +20,7 @@ describe Blob do ...@@ -12,7 +20,7 @@ describe Blob do
context 'using a binary blob' do context 'using a binary blob' do
it 'returns the data as-is' do it 'returns the data as-is' do
data = "\n\xFF\xB9\xC3" data = "\n\xFF\xB9\xC3"
blob = described_class.new(double(binary?: true, data: data)) blob = fake_blob(binary: true, data: data)
expect(blob.data).to eq(data) expect(blob.data).to eq(data)
end end
...@@ -20,12 +28,176 @@ describe Blob do ...@@ -20,12 +28,176 @@ describe Blob do
context 'using a text blob' do context 'using a text blob' do
it 'converts the data to UTF-8' do it 'converts the data to UTF-8' do
blob = described_class.new(double(binary?: false, data: "\n\xFF\xB9\xC3")) blob = fake_blob(binary: false, data: "\n\xFF\xB9\xC3")
expect(blob.data).to eq("\n���") expect(blob.data).to eq("\n���")
end end
end end
end end
# TODO: Test new methods describe '#raw_binary?' do
context 'if the blob is a valid LFS pointer' do
context 'if the extension has a rich viewer' do
context 'if the viewer is binary' do
it 'return true' do
blob = fake_blob(path: 'file.pdf', lfs: true)
expect(blob.raw_binary?).to be_truthy
end
end
context 'if the viewer is text-based' do
it 'return false' do
blob = fake_blob(path: 'file.md', lfs: true)
expect(blob.raw_binary?).to be_falsey
end
end
end
context "if the extension doesn't have a rich viewer" do
it 'returns true' do
blob = fake_blob(path: 'file.exe', lfs: true)
expect(blob.raw_binary?).to be_truthy
end
end
end
context 'if the blob is not an LFS pointer' do
context 'if the blob is binary' do
it 'return true' do
blob = fake_blob(path: 'file.pdf', binary: true)
expect(blob.raw_binary?).to be_truthy
end
end
context 'if the blob is text-based' do
it 'return false' do
blob = fake_blob(path: 'file.md')
expect(blob.raw_binary?).to be_falsey
end
end
end
end
describe '#extension' do
it 'returns the extension' do
blob = fake_blob(path: 'file.md')
expect(blob.extension).to eq('md')
end
end
describe '#simple_viewer' do
context 'when the blob is empty' do
it 'returns an empty viewer' do
blob = fake_blob(data: '')
expect(blob.simple_viewer).to be_a(BlobViewer::Empty)
end
end
context 'when the file represented by the blob is binary' do
it 'returns a download viewer' do
blob = fake_blob(binary: true)
expect(blob.simple_viewer).to be_a(BlobViewer::Download)
end
end
context 'when the file represented by the blob is text-based' do
it 'returns a text viewer' do
blob = fake_blob
expect(blob.simple_viewer).to be_a(BlobViewer::Text)
end
end
end
describe '#rich_viewer' do
context 'when the blob is an invalid LFS pointer' do
before do
project.lfs_enabled = false
end
it 'returns nil' do
blob = fake_blob(path: 'file.pdf', lfs: true)
expect(blob.rich_viewer).to be_nil
end
end
context 'when the blob is empty' do
it 'returns nil' do
blob = fake_blob(data: '')
expect(blob.rich_viewer).to be_nil
end
end
context 'when the blob is a valid LFS pointer' do
it 'returns a matching viewer' do
blob = fake_blob(path: 'file.pdf', lfs: true)
expect(blob.rich_viewer).to be_a(BlobViewer::PDF)
end
end
context 'when the blob is binary' do
it 'returns a matching binary viewer' do
blob = fake_blob(path: 'file.pdf', binary: true)
expect(blob.rich_viewer).to be_a(BlobViewer::PDF)
end
end
context 'when the blob is text-based' do
it 'returns a matching text-based viewer' do
blob = fake_blob(path: 'file.md')
expect(blob.rich_viewer).to be_a(BlobViewer::Markup)
end
end
end
describe '#rendered_as_text?' do
context 'when ignoring errors' do
context 'when the simple viewer is text-based' do
it 'returns true' do
blob = fake_blob(path: 'file.md', size: 100.megabytes)
expect(blob.rendered_as_text?).to be_truthy
end
end
context 'when the simple viewer is binary' do
it 'returns false' do
blob = fake_blob(path: 'file.pdf', binary: true, size: 100.megabytes)
expect(blob.rendered_as_text?).to be_falsey
end
end
end
context 'when not ignoring errors' do
context 'when the viewer has render errors' do
it 'returns false' do
blob = fake_blob(path: 'file.md', size: 100.megabytes)
expect(blob.rendered_as_text?(ignore_errors: false)).to be_falsey
end
end
context "when the viewer doesn't have render errors" do
it 'returns true' do
blob = fake_blob(path: 'file.md')
expect(blob.rendered_as_text?(ignore_errors: false)).to be_truthy
end
end
end
end
end end
include 'spec_helper' require 'spec_helper'
describe BlobViewer::Base, model: true do describe BlobViewer::Base, model: true do
# TODO: Test include FakeBlobHelpers
let(:project) { build(:empty_project) }
let(:viewer_class) do
Class.new(described_class) do
self.extensions = %w(pdf)
self.max_size = 1.megabyte
self.absolute_max_size = 5.megabytes
self.client_side = false
end
end
let(:viewer) { viewer_class.new(blob) }
describe '.can_render?' do
context 'when the extension is supported' do
let(:blob) { fake_blob(path: 'file.pdf') }
it 'returns true' do
expect(viewer_class.can_render?(blob)).to be_truthy
end
end
context 'when the extension is not supported' do
let(:blob) { fake_blob(path: 'file.txt') }
it 'returns false' do
expect(viewer_class.can_render?(blob)).to be_falsey
end
end
end
describe '#too_large?' do
context 'when the blob size is larger than the max size' do
let(:blob) { fake_blob(path: 'file.pdf', size: 2.megabytes) }
it 'returns true' do
expect(viewer.too_large?).to be_truthy
end
end
context 'when the blob size is smaller than the max size' do
let(:blob) { fake_blob(path: 'file.pdf', size: 10.kilobytes) }
it 'returns false' do
expect(viewer.too_large?).to be_falsey
end
end
end
describe '#absolutely_too_large?' do
context 'when the blob size is larger than the absolute max size' do
let(:blob) { fake_blob(path: 'file.pdf', size: 10.megabytes) }
it 'returns true' do
expect(viewer.absolutely_too_large?).to be_truthy
end
end
context 'when the blob size is smaller than the absolute max size' do
let(:blob) { fake_blob(path: 'file.pdf', size: 2.megabytes) }
it 'returns false' do
expect(viewer.absolutely_too_large?).to be_falsey
end
end
end
describe '#can_override_max_size?' do
context 'when the blob size is larger than the max size' do
context 'when the blob size is larger than the absolute max size' do
let(:blob) { fake_blob(path: 'file.pdf', size: 10.megabytes) }
it 'returns false' do
expect(viewer.can_override_max_size?).to be_falsey
end
end
context 'when the blob size is smaller than the absolute max size' do
let(:blob) { fake_blob(path: 'file.pdf', size: 2.megabytes) }
it 'returns true' do
expect(viewer.can_override_max_size?).to be_truthy
end
end
end
context 'when the blob size is smaller than the max size' do
let(:blob) { fake_blob(path: 'file.pdf', size: 10.kilobytes) }
it 'returns false' do
expect(viewer.can_override_max_size?).to be_falsey
end
end
end
describe '#render_error' do
context 'when the max size is overridden' do
before do
viewer.override_max_size = true
end
context 'when the blob size is larger than the absolute max size' do
let(:blob) { fake_blob(path: 'file.pdf', size: 10.megabytes) }
it 'returns :too_large' do
expect(viewer.render_error).to eq(:too_large)
end
end
context 'when the blob size is smaller than the absolute max size' do
let(:blob) { fake_blob(path: 'file.pdf', size: 2.megabytes) }
it 'returns nil' do
expect(viewer.render_error).to be_nil
end
end
end
context 'when the max size is not overridden' do
context 'when the blob size is larger than the max size' do
let(:blob) { fake_blob(path: 'file.pdf', size: 2.megabytes) }
it 'returns :too_large' do
expect(viewer.render_error).to eq(:too_large)
end
end
context 'when the blob size is smaller than the max size' do
let(:blob) { fake_blob(path: 'file.pdf', size: 10.kilobytes) }
it 'returns nil' do
expect(viewer.render_error).to be_nil
end
end
end
context 'when the viewer is server side but the blob is stored in LFS' do
let(:project) { build(:empty_project, lfs_enabled: true) }
let(:blob) { fake_blob(path: 'file.pdf', lfs: true) }
before do
allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
end
it 'return :server_side_but_stored_in_lfs' do
expect(viewer.render_error).to eq(:server_side_but_stored_in_lfs)
end
end
end
describe '#prepare!' do
context 'when the viewer is server side' do
let(:blob) { fake_blob(path: 'file.md') }
before do
viewer_class.client_side = false
end
it 'loads all blob data' do
expect(blob).to receive(:load_all_data!)
viewer.prepare!
end
end
context 'when the viewer is client side' do
let(:blob) { fake_blob(path: 'file.md') }
before do
viewer_class.client_side = true
end
it "doesn't load all blob data" do
expect(blob).not_to receive(:load_all_data!)
viewer.prepare!
end
end
end
end end
module FakeBlobHelpers
class FakeBlob
include Linguist::BlobHelper
attr_reader :path, :size, :data, :lfs_oid, :lfs_size
def initialize(path: 'file.txt', size: 1.kilobyte, data: 'foo', binary: false, lfs: nil)
@path = path
@size = size
@data = data
@binary = binary
@lfs_pointer = lfs.present?
if @lfs_pointer
@lfs_oid = SecureRandom.hex(20)
@lfs_size = 1.megabyte
end
end
alias_method :name, :path
def mode
nil
end
def id
0
end
def binary?
@binary
end
def load_all_data!(repository)
# No-op
end
def lfs_pointer?
@lfs_pointer
end
def truncated?
false
end
end
def fake_blob(**kwargs)
Blob.decorate(FakeBlob.new(**kwargs), project)
end
end
require 'spec_helper'
describe 'app/views/projects/blob/_render_error.html.haml' do
# TODO: Test
end
require 'spec_helper' require 'spec_helper'
describe 'app/views/projects/blob/_viewer.html.haml' do describe 'projects/blob/_viewer.html.haml', :view do
# TODO: Test include FakeBlobHelpers
let(:project) { build(:empty_project) }
let(:viewer_class) do
Class.new(BlobViewer::Base) do
include BlobViewer::Rich
self.partial_name = 'text'
self.max_size = 1.megabyte
self.absolute_max_size = 5.megabytes
self.client_side = false
end
end
let(:viewer) { viewer_class.new(blob) }
let(:blob) { fake_blob }
before do
assign(:project, project)
assign(:id, File.join('master', blob.path))
controller.params[:controller] = 'projects/blob'
controller.params[:action] = 'show'
controller.params[:namespace_id] = project.namespace.to_param
controller.params[:project_id] = project.to_param
controller.params[:id] = File.join('master', blob.path)
end
def render_view
render partial: 'projects/blob/viewer', locals: { viewer: viewer }
end
context 'when the viewer is server side' do
before do
viewer_class.client_side = false
end
context 'when there is no render error' do
it 'adds a URL to the blob viewer element' do
render_view
expect(rendered).to have_css('.blob-viewer[data-url]')
end
it 'displays a spinner' do
render_view
expect(rendered).to have_css('i[aria-label="Loading content"]')
end
end
context 'when there is a render error' do
let(:blob) { fake_blob(size: 10.megabytes) }
it 'renders the error' do
render_view
expect(view).to render_template('projects/blob/_render_error')
end
end
end
context 'when the viewer is client side' do
before do
viewer_class.client_side = true
end
context 'when there is no render error' do
it 'prepares the viewer' do
expect(viewer).to receive(:prepare!)
render_view
end
it 'renders the viewer' do
render_view
expect(view).to render_template('projects/blob/viewers/_text')
end
end
context 'when there is a render error' do
let(:blob) { fake_blob(size: 10.megabytes) }
it 'renders the error' do
render_view
expect(view).to render_template('projects/blob/_render_error')
end
end
end
end end
require 'spec_helper'
describe 'app/views/projects/blob/_viewer_switcher.html.haml' do
# TODO: Test
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment