Add specs for showing lfs object in UI.
This commit is contained in:
parent
b2c4675cb0
commit
e53b350cb6
13 changed files with 111 additions and 21 deletions
|
@ -38,18 +38,28 @@ class Projects::RawController < Projects::ApplicationController
|
||||||
type = get_blob_type
|
type = get_blob_type
|
||||||
|
|
||||||
send_data(
|
send_data(
|
||||||
@blob.data,
|
@blob.data,
|
||||||
type: type,
|
type: type,
|
||||||
disposition: 'inline'
|
disposition: 'inline'
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def send_lfs_object
|
def send_lfs_object
|
||||||
lfs_object = LfsObject.find_by_oid(@blob.lfs_oid)
|
lfs_object = find_lfs_object
|
||||||
return nil unless lfs_object && lfs_object.file.exists?
|
|
||||||
|
|
||||||
if lfs_object.projects.exists?(lfs_object.storage_project(@project).id)
|
if lfs_object && lfs_object.project_allowed_access?(@project)
|
||||||
send_file lfs_object.file.path, filename: @blob.name, disposition: 'attachment'
|
send_file lfs_object.file.path, filename: @blob.name, disposition: 'attachment'
|
||||||
|
else
|
||||||
|
render_404
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_lfs_object
|
||||||
|
lfs_object = LfsObject.find_by_oid(@blob.lfs_oid)
|
||||||
|
if lfs_object && lfs_object.file.exists?
|
||||||
|
lfs_object
|
||||||
|
else
|
||||||
|
nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -30,7 +30,7 @@ module BlobHelper
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
if blob && blob.text?
|
if blob && blob.text? && !blob.lfs_pointer?
|
||||||
text = 'Edit'
|
text = 'Edit'
|
||||||
after = options[:after] || ''
|
after = options[:after] || ''
|
||||||
from_mr = options[:from_merge_request_id]
|
from_mr = options[:from_merge_request_id]
|
||||||
|
@ -71,4 +71,16 @@ module BlobHelper
|
||||||
def blob_icon(mode, name)
|
def blob_icon(mode, name)
|
||||||
icon("#{file_type_icon_class('file', mode, name)} fw")
|
icon("#{file_type_icon_class('file', mode, name)} fw")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def viewable?(blob)
|
||||||
|
blob.text? && !blob.lfs_pointer?
|
||||||
|
end
|
||||||
|
|
||||||
|
def blob_size(blob)
|
||||||
|
if blob.lfs_pointer?
|
||||||
|
blob.lfs_size
|
||||||
|
else
|
||||||
|
blob.size
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -54,6 +54,10 @@ module TreeHelper
|
||||||
::Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(ref)
|
::Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(ref)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def can_delete_or_replace?(blob)
|
||||||
|
allowed_tree_edit? && !blob.lfs_pointer?
|
||||||
|
end
|
||||||
|
|
||||||
def tree_breadcrumbs(tree, max_links = 2)
|
def tree_breadcrumbs(tree, max_links = 2)
|
||||||
if @path.present?
|
if @path.present?
|
||||||
part_path = ""
|
part_path = ""
|
||||||
|
|
|
@ -13,4 +13,8 @@ class LfsObject < ActiveRecord::Base
|
||||||
project
|
project
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def project_allowed_access?(project)
|
||||||
|
projects.exists?(storage_project(project).id)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
.btn-group.tree-btn-group
|
.btn-group.tree-btn-group
|
||||||
= edit_blob_link(@project, @ref, @path) unless @blob.lfs_pointer?
|
= edit_blob_link(@project, @ref, @path)
|
||||||
= link_to 'Raw', namespace_project_raw_path(@project.namespace, @project, @id),
|
= link_to 'Raw', namespace_project_raw_path(@project.namespace, @project, @id),
|
||||||
class: 'btn btn-sm', target: '_blank'
|
class: 'btn btn-sm', target: '_blank'
|
||||||
-# only show normal/blame view links for text files
|
-# only show normal/blame view links for text files
|
||||||
- if @blob.text? && !@blob.lfs_pointer?
|
- if viewable?(@blob)
|
||||||
- if current_page? namespace_project_blame_path(@project.namespace, @project, @id)
|
- if current_page? namespace_project_blame_path(@project.namespace, @project, @id)
|
||||||
= link_to 'Normal View', namespace_project_blob_path(@project.namespace, @project, @id),
|
= link_to 'Normal View', namespace_project_blob_path(@project.namespace, @project, @id),
|
||||||
class: 'btn btn-sm'
|
class: 'btn btn-sm'
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
= link_to 'Permalink', namespace_project_blob_path(@project.namespace, @project,
|
= link_to 'Permalink', namespace_project_blob_path(@project.namespace, @project,
|
||||||
tree_join(@commit.sha, @path)), class: 'btn btn-sm'
|
tree_join(@commit.sha, @path)), class: 'btn btn-sm'
|
||||||
|
|
||||||
- if allowed_tree_edit? && !@blob.lfs_pointer?
|
- if can_delete_or_replace?(@blob)
|
||||||
.btn-group{ role: "group" }
|
.btn-group{ role: "group" }
|
||||||
%button.btn.btn-default{ 'data-target' => '#modal-upload-blob', 'data-toggle' => 'modal' } Replace
|
%button.btn.btn-default{ 'data-target' => '#modal-upload-blob', 'data-toggle' => 'modal' } Replace
|
||||||
%button.btn.btn-remove{ 'data-target' => '#modal-remove-blob', 'data-toggle' => 'modal' } Delete
|
%button.btn.btn-remove{ 'data-target' => '#modal-remove-blob', 'data-toggle' => 'modal' } Delete
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
%strong
|
%strong
|
||||||
= blob.name
|
= blob.name
|
||||||
%small
|
%small
|
||||||
= number_to_human_size(blob.size) unless blob.lfs_pointer?
|
= number_to_human_size(blob_size(blob))
|
||||||
.file-actions.hidden-xs
|
.file-actions.hidden-xs
|
||||||
= render "actions"
|
= render "actions"
|
||||||
- if blob.lfs_pointer?
|
- if blob.lfs_pointer?
|
||||||
|
|
|
@ -4,8 +4,4 @@
|
||||||
%h1.light
|
%h1.light
|
||||||
%i.fa.fa-download
|
%i.fa.fa-download
|
||||||
%h4
|
%h4
|
||||||
- if blob.lfs_pointer?
|
Download (#{number_to_human_size blob_size(blob)})
|
||||||
- size = blob.lfs_size
|
|
||||||
- else
|
|
||||||
- size = blob.size
|
|
||||||
Download (#{number_to_human_size size})
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
%div#tree-holder.tree-holder
|
%div#tree-holder.tree-holder
|
||||||
= render 'blob', blob: @blob
|
= render 'blob', blob: @blob
|
||||||
|
|
||||||
- if allowed_tree_edit?
|
- if can_delete_or_replace?(@blob)
|
||||||
= render 'projects/blob/remove'
|
= render 'projects/blob/remove'
|
||||||
|
|
||||||
- title = "Replace #{@blob.name}"
|
- title = "Replace #{@blob.name}"
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
= "#{diff_file.diff.a_mode} → #{diff_file.diff.b_mode}"
|
= "#{diff_file.diff.a_mode} → #{diff_file.diff.b_mode}"
|
||||||
|
|
||||||
.diff-controls
|
.diff-controls
|
||||||
- if blob.text? && !blob.lfs_pointer?
|
- if viewable?(blob)
|
||||||
= link_to '#', class: 'js-toggle-diff-comments btn btn-sm active has_tooltip', title: "Toggle comments for this file" do
|
= link_to '#', class: 'js-toggle-diff-comments btn btn-sm active has_tooltip', title: "Toggle comments for this file" do
|
||||||
%i.fa.fa-comments
|
%i.fa.fa-comments
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
.diff-content.diff-wrap-lines
|
.diff-content.diff-wrap-lines
|
||||||
-# Skipp all non non-supported blobs
|
-# Skipp all non non-supported blobs
|
||||||
- return unless blob.respond_to?('text?')
|
- return unless blob.respond_to?('text?')
|
||||||
- if blob.text? && !blob.lfs_pointer?
|
- if viewable?(blob)
|
||||||
- if diff_view == 'parallel'
|
- if diff_view == 'parallel'
|
||||||
= render "projects/diffs/parallel_view", diff_file: diff_file, project: project, blob: blob, index: i
|
= render "projects/diffs/parallel_view", diff_file: diff_file, project: project, blob: blob, index: i
|
||||||
- else
|
- else
|
||||||
|
|
|
@ -221,3 +221,9 @@ Feature: Project Source Browse Files
|
||||||
Given I switch ref to fix
|
Given I switch ref to fix
|
||||||
And I visit the fix tree
|
And I visit the fix tree
|
||||||
Then I see the commit data for a directory with a leading dot
|
Then I see the commit data for a directory with a leading dot
|
||||||
|
|
||||||
|
Scenario: I browse LFS object
|
||||||
|
Given I click on "files/lfs/lfs_object.iso" file in repo
|
||||||
|
Then I should see download link and object size
|
||||||
|
And I should not see lfs pointer details
|
||||||
|
And I should see buttons for allowed commands
|
||||||
|
|
|
@ -305,6 +305,32 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps
|
||||||
expect(page).not_to have_content('Loading commit data...')
|
expect(page).not_to have_content('Loading commit data...')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
step 'I click on "files/lfs/lfs_object.iso" file in repo' do
|
||||||
|
click_link 'files'
|
||||||
|
click_link "lfs"
|
||||||
|
click_link "lfs_object.iso"
|
||||||
|
end
|
||||||
|
|
||||||
|
step 'I should see download link and object size' do
|
||||||
|
expect(page).to have_content 'Download (1.5 MB)'
|
||||||
|
end
|
||||||
|
|
||||||
|
step 'I should not see lfs pointer details' do
|
||||||
|
expect(page).not_to have_content 'version https://git-lfs.github.com/spec/v1'
|
||||||
|
expect(page).not_to have_content 'oid sha256:91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897'
|
||||||
|
expect(page).not_to have_content 'size 1575078'
|
||||||
|
end
|
||||||
|
|
||||||
|
step 'I should see buttons for allowed commands' do
|
||||||
|
expect(page).to have_content 'Raw'
|
||||||
|
expect(page).to have_content 'History'
|
||||||
|
expect(page).to have_content 'Permalink'
|
||||||
|
expect(page).not_to have_content 'Edit'
|
||||||
|
expect(page).not_to have_content 'Blame'
|
||||||
|
expect(page).not_to have_content 'Delete'
|
||||||
|
expect(page).not_to have_content 'Replace'
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_new_content
|
def set_new_content
|
||||||
|
|
|
@ -33,5 +33,37 @@ describe Projects::RawController do
|
||||||
expect(response.header['Content-Type']).to eq('image/jpeg')
|
expect(response.header['Content-Type']).to eq('image/jpeg')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'lfs object' do
|
||||||
|
let(:id) { 'master/files/lfs/lfs_object.iso' }
|
||||||
|
let!(:lfs_object) { create(:lfs_object, oid: '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', size: '1575078') }
|
||||||
|
|
||||||
|
context 'when project has access' do
|
||||||
|
before do
|
||||||
|
public_project.lfs_objects << lfs_object
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'serves the file' do
|
||||||
|
get(:show,
|
||||||
|
namespace_id: public_project.namespace.to_param,
|
||||||
|
project_id: public_project.to_param,
|
||||||
|
id: id)
|
||||||
|
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
expect(response.header['Content-Type']).to eq('application/octet-stream')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when project does not have access' do
|
||||||
|
it 'does not serve the file' do
|
||||||
|
get(:show,
|
||||||
|
namespace_id: public_project.namespace.to_param,
|
||||||
|
project_id: public_project.to_param,
|
||||||
|
id: id)
|
||||||
|
|
||||||
|
expect(response.status).to eq(404)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,7 +12,7 @@ module TestEnv
|
||||||
'fix' => '48f0be4',
|
'fix' => '48f0be4',
|
||||||
'improve/awesome' => '5937ac0',
|
'improve/awesome' => '5937ac0',
|
||||||
'markdown' => '0ed8c6c',
|
'markdown' => '0ed8c6c',
|
||||||
'master' => '5937ac0',
|
'master' => 'be93687',
|
||||||
"'test'" => 'e56497b',
|
"'test'" => 'e56497b',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue