Commit 6a4d84fc authored by Francisco Javier López's avatar Francisco Javier López Committed by Imre Farkas

Refactoring snippet views code

There are some views in our codebase where we duplicate
the logic. In this MR we try to simplify them.
parent 3eabe600
...@@ -141,11 +141,7 @@ module BlobHelper ...@@ -141,11 +141,7 @@ module BlobHelper
if @build && @entry if @build && @entry
raw_project_job_artifacts_url(@project, @build, path: @entry.path, **kwargs) raw_project_job_artifacts_url(@project, @build, path: @entry.path, **kwargs)
elsif @snippet elsif @snippet
if @snippet.project_id reliable_raw_snippet_url(@snippet)
raw_project_snippet_url(@project, @snippet, **kwargs)
else
raw_snippet_url(@snippet, **kwargs)
end
elsif @blob elsif @blob
project_raw_url(@project, @id, **kwargs) project_raw_url(@project, @id, **kwargs)
end end
......
...@@ -11,22 +11,40 @@ module SnippetsHelper ...@@ -11,22 +11,40 @@ module SnippetsHelper
end end
end end
def reliable_snippet_path(snippet, opts = nil) def reliable_snippet_path(snippet, opts = {})
reliable_snippet_url(snippet, opts.merge(only_path: true))
end
def reliable_raw_snippet_path(snippet, opts = {})
reliable_raw_snippet_url(snippet, opts.merge(only_path: true))
end
def reliable_snippet_url(snippet, opts = {})
if snippet.project_id? if snippet.project_id?
project_snippet_path(snippet.project, snippet, opts) project_snippet_url(snippet.project, snippet, nil, opts)
else else
snippet_path(snippet, opts) snippet_url(snippet, nil, opts)
end end
end end
def download_snippet_path(snippet) def reliable_raw_snippet_url(snippet, opts = {})
if snippet.project_id if snippet.project_id?
raw_project_snippet_path(@project, snippet, inline: false) raw_project_snippet_url(snippet.project, snippet, nil, opts)
else else
raw_snippet_path(snippet, inline: false) raw_snippet_url(snippet, nil, opts)
end end
end end
def download_raw_snippet_button(snippet)
link_to(icon('download'),
reliable_raw_snippet_path(snippet, inline: false),
target: '_blank',
rel: 'noopener noreferrer',
class: "btn btn-sm has-tooltip",
title: 'Download',
data: { container: 'body' })
end
# Return the path of a snippets index for a user or for a project # Return the path of a snippets index for a user or for a project
# #
# @returns String, path to snippet index # @returns String, path to snippet index
...@@ -114,30 +132,45 @@ module SnippetsHelper ...@@ -114,30 +132,45 @@ module SnippetsHelper
{ snippet_object: snippet, snippet_chunks: snippet_chunks } { snippet_object: snippet, snippet_chunks: snippet_chunks }
end end
def snippet_embed def snippet_embed_tag(snippet)
"<script src=\"#{url_for(only_path: false, overwrite_params: nil)}.js\"></script>" content_tag(:script, nil, src: reliable_snippet_url(snippet, format: :js, only_path: false))
end end
def embedded_snippet_raw_button def snippet_badge(snippet)
blob = @snippet.blob return unless attrs = snippet_badge_attributes(snippet)
return if blob.empty? || blob.binary? || blob.stored_externally?
snippet_raw_url = if @snippet.is_a?(PersonalSnippet) css_class, text = attrs
raw_snippet_url(@snippet) tag.span(class: ['badge', 'badge-gray']) do
else concat(tag.i(class: ['fa', css_class]))
raw_project_snippet_url(@snippet.project, @snippet) concat(' ')
concat(text)
end
end end
link_to external_snippet_icon('doc-code'), snippet_raw_url, class: 'btn', target: '_blank', rel: 'noopener noreferrer', title: 'Open raw' def snippet_badge_attributes(snippet)
if snippet.private?
['fa-lock', _('private')]
end
end end
def embedded_snippet_download_button def embedded_raw_snippet_button
download_url = if @snippet.is_a?(PersonalSnippet) blob = @snippet.blob
raw_snippet_url(@snippet, inline: false) return if blob.empty? || blob.binary? || blob.stored_externally?
else
raw_project_snippet_url(@snippet.project, @snippet, inline: false) link_to(external_snippet_icon('doc-code'),
reliable_raw_snippet_url(@snippet),
class: 'btn',
target: '_blank',
rel: 'noopener noreferrer',
title: 'Open raw')
end end
link_to external_snippet_icon('download'), download_url, class: 'btn', target: '_blank', title: 'Download', rel: 'noopener noreferrer' def embedded_snippet_download_button
link_to(external_snippet_icon('download'),
reliable_raw_snippet_url(@snippet, inline: false),
class: 'btn',
target: '_blank',
title: 'Download',
rel: 'noopener noreferrer')
end end
end end
- snippet_blob = chunk_snippet(snippet_blob, @search_term) - snippet_blob = chunk_snippet(snippet_blob, @search_term)
- snippet = snippet_blob[:snippet_object] - snippet = snippet_blob[:snippet_object]
- snippet_chunks = snippet_blob[:snippet_chunks] - snippet_chunks = snippet_blob[:snippet_chunks]
- snippet_path = reliable_snippet_path(snippet)
.search-result-row .search-result-row
%span %span
...@@ -11,7 +12,6 @@ ...@@ -11,7 +12,6 @@
= snippet.author_name = snippet.author_name
%span.light= time_ago_with_tooltip(snippet.created_at) %span.light= time_ago_with_tooltip(snippet.created_at)
%h4.snippet-title %h4.snippet-title
- snippet_path = reliable_snippet_path(snippet)
.file-holder .file-holder
.js-file-title.file-title .js-file-title.file-title
= link_to snippet_path do = link_to snippet_path do
......
...@@ -2,10 +2,7 @@ ...@@ -2,10 +2,7 @@
%h4.snippet-title.term %h4.snippet-title.term
= link_to reliable_snippet_path(snippet_title) do = link_to reliable_snippet_path(snippet_title) do
= truncate(snippet_title.title, length: 60) = truncate(snippet_title.title, length: 60)
- if snippet_title.private? = snippet_badge(snippet_title)
%span.badge.badge-gray
%i.fa.fa-lock
= _("private")
%span.cgray.monospace.tiny.float-right.term %span.cgray.monospace.tiny.float-right.term
= snippet_title.file_name = snippet_title.file_name
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
.btn-group{ role: "group" }< .btn-group{ role: "group" }<
= copy_blob_source_button(blob) = copy_blob_source_button(blob)
= open_raw_blob_button(blob) = open_raw_blob_button(blob)
= download_raw_snippet_button(@snippet)
= link_to icon('download'), download_snippet_path(@snippet), target: '_blank', class: "btn btn-sm has-tooltip", title: 'Download', data: { container: 'body' }
= render 'projects/blob/content', blob: blob = render 'projects/blob/content', blob: blob
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
.file-actions.d-none.d-sm-block .file-actions.d-none.d-sm-block
.btn-group{ role: "group" }< .btn-group{ role: "group" }<
= embedded_snippet_raw_button = embedded_raw_snippet_button
= embedded_snippet_download_button = embedded_snippet_download_button
%article.file-holder.snippet-file-content %article.file-holder.snippet-file-content
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
%li %li
%button.js-share-btn.btn.btn-transparent{ type: 'button' } %button.js-share-btn.btn.btn-transparent{ type: 'button' }
%strong.embed-toggle-list-item= _("Share") %strong.embed-toggle-list-item= _("Share")
%input.js-snippet-url-area.snippet-embed-input.form-control{ type: "text", autocomplete: 'off', value: snippet_embed } %input.js-snippet-url-area.snippet-embed-input.form-control{ type: "text", autocomplete: 'off', value: snippet_embed_tag(@snippet) }
.input-group-append .input-group-append
= clipboard_button(title: _('Copy'), class: 'js-clipboard-btn snippet-clipboard-btn btn btn-default', target: '.js-snippet-url-area') = clipboard_button(title: _('Copy'), class: 'js-clipboard-btn snippet-clipboard-btn btn btn-default', target: '.js-snippet-url-area')
.clearfix .clearfix
...@@ -3,33 +3,217 @@ ...@@ -3,33 +3,217 @@
require 'spec_helper' require 'spec_helper'
describe SnippetsHelper do describe SnippetsHelper do
include Gitlab::Routing
include IconsHelper include IconsHelper
describe '#embedded_snippet_raw_button' do let_it_be(:public_personal_snippet) { create(:personal_snippet, :public) }
it 'gives view raw button of embedded snippets for project snippets' do let_it_be(:public_project_snippet) { create(:project_snippet, :public) }
@snippet = create(:project_snippet, :public)
describe '#reliable_snippet_path' do
subject { reliable_snippet_path(snippet) }
context 'personal snippets' do
let(:snippet) { public_personal_snippet }
context 'public' do
it 'returns a full path' do
expect(subject).to eq("/snippets/#{snippet.id}")
end
end
end
context 'project snippets' do
let(:snippet) { public_project_snippet }
it 'returns a full path' do
expect(subject).to eq("/#{snippet.project.full_path}/snippets/#{snippet.id}")
end
end
end
describe '#reliable_snippet_url' do
subject { reliable_snippet_url(snippet) }
context 'personal snippets' do
let(:snippet) { public_personal_snippet }
context 'public' do
it 'returns a full url' do
expect(subject).to eq("http://test.host/snippets/#{snippet.id}")
end
end
end
context 'project snippets' do
let(:snippet) { public_project_snippet }
it 'returns a full url' do
expect(subject).to eq("http://test.host/#{snippet.project.full_path}/snippets/#{snippet.id}")
end
end
end
describe '#reliable_raw_snippet_path' do
subject { reliable_raw_snippet_path(snippet) }
expect(embedded_snippet_raw_button.to_s).to eq("<a class=\"btn\" target=\"_blank\" rel=\"noopener noreferrer\" title=\"Open raw\" href=\"#{raw_project_snippet_url(@snippet.project, @snippet)}\">#{external_snippet_icon('doc-code')}</a>") context 'personal snippets' do
let(:snippet) { public_personal_snippet }
context 'public' do
it 'returns a full path' do
expect(subject).to eq("/snippets/#{snippet.id}/raw")
end
end
end
context 'project snippets' do
let(:snippet) { public_project_snippet }
it 'returns a full path' do
expect(subject).to eq("/#{snippet.project.full_path}/snippets/#{snippet.id}/raw")
end
end
end
describe '#reliable_raw_snippet_url' do
subject { reliable_raw_snippet_url(snippet) }
context 'personal snippets' do
let(:snippet) { public_personal_snippet }
context 'public' do
it 'returns a full url' do
expect(subject).to eq("http://test.host/snippets/#{snippet.id}/raw")
end end
end
end
context 'project snippets' do
let(:snippet) { public_project_snippet }
it 'returns a full url' do
expect(subject).to eq("http://test.host/#{snippet.project.full_path}/snippets/#{snippet.id}/raw")
end
end
end
describe '#embedded_raw_snippet_button' do
subject { embedded_raw_snippet_button.to_s }
it 'gives view raw button of embedded snippets for personal snippets' do it 'returns view raw button of embedded snippets for personal snippets' do
@snippet = create(:personal_snippet, :public) @snippet = create(:personal_snippet, :public)
expect(embedded_snippet_raw_button.to_s).to eq("<a class=\"btn\" target=\"_blank\" rel=\"noopener noreferrer\" title=\"Open raw\" href=\"#{raw_snippet_url(@snippet)}\">#{external_snippet_icon('doc-code')}</a>") expect(subject).to eq(download_link("http://test.host/snippets/#{@snippet.id}/raw"))
end
it 'returns view raw button of embedded snippets for project snippets' do
@snippet = create(:project_snippet, :public)
expect(subject).to eq(download_link("http://test.host/#{@snippet.project.path_with_namespace}/snippets/#{@snippet.id}/raw"))
end
def download_link(url)
"<a class=\"btn\" target=\"_blank\" rel=\"noopener noreferrer\" title=\"Open raw\" href=\"#{url}\">#{external_snippet_icon('doc-code')}</a>"
end end
end end
describe '#embedded_snippet_download_button' do describe '#embedded_snippet_download_button' do
it 'gives download button of embedded snippets for project snippets' do subject { embedded_snippet_download_button }
it 'returns download button of embedded snippets for personal snippets' do
@snippet = create(:personal_snippet, :public)
expect(subject).to eq(download_link("http://test.host/snippets/#{@snippet.id}/raw"))
end
it 'returns download button of embedded snippets for project snippets' do
@snippet = create(:project_snippet, :public) @snippet = create(:project_snippet, :public)
expect(embedded_snippet_download_button.to_s).to eq("<a class=\"btn\" target=\"_blank\" title=\"Download\" rel=\"noopener noreferrer\" href=\"#{raw_project_snippet_url(@snippet.project, @snippet, inline: false)}\">#{external_snippet_icon('download')}</a>") expect(subject).to eq(download_link("http://test.host/#{@snippet.project.path_with_namespace}/snippets/#{@snippet.id}/raw"))
end end
it 'gives download button of embedded snippets for personal snippets' do def download_link(url)
@snippet = create(:personal_snippet, :public) "<a class=\"btn\" target=\"_blank\" title=\"Download\" rel=\"noopener noreferrer\" href=\"#{url}?inline=false\">#{external_snippet_icon('download')}</a>"
end
end
describe '#snippet_embed_tag' do
subject { snippet_embed_tag(snippet) }
context 'personal snippets' do
let(:snippet) { public_personal_snippet }
context 'public' do
it 'returns a script tag with the snippet full url' do
expect(subject).to eq(script_embed("http://test.host/snippets/#{snippet.id}"))
end
end
end
context 'project snippets' do
let(:snippet) { public_project_snippet }
it 'returns a script tag with the snippet full url' do
expect(subject).to eq(script_embed("http://test.host/#{snippet.project.path_with_namespace}/snippets/#{snippet.id}"))
end
end
def script_embed(url)
"<script src=\"#{url}.js\"></script>"
end
end
describe '#download_raw_snippet_button' do
subject { download_raw_snippet_button(snippet) }
expect(embedded_snippet_download_button.to_s).to eq("<a class=\"btn\" target=\"_blank\" title=\"Download\" rel=\"noopener noreferrer\" href=\"#{raw_snippet_url(@snippet, inline: false)}\">#{external_snippet_icon('download')}</a>") context 'with personal snippet' do
let(:snippet) { public_personal_snippet }
it 'returns the download button' do
expect(subject).to eq(download_link("/snippets/#{snippet.id}/raw"))
end
end
context 'with project snippet' do
let(:snippet) { public_project_snippet }
it 'returns the download button' do
expect(subject).to eq(download_link("/#{snippet.project.path_with_namespace}/snippets/#{snippet.id}/raw"))
end
end
def download_link(url)
"<a target=\"_blank\" rel=\"noopener noreferrer\" class=\"btn btn-sm has-tooltip\" title=\"Download\" data-container=\"body\" href=\"#{url}?inline=false\"><i aria-hidden=\"true\" data-hidden=\"true\" class=\"fa fa-download\"></i></a>"
end
end
describe '#snippet_badge' do
let(:snippet) { build(:personal_snippet, visibility) }
subject { snippet_badge(snippet) }
context 'when snippet is private' do
let(:visibility) { :private }
it 'returns the snippet badge' do
expect(subject).to eq "<span class=\"badge badge-gray\"><i class=\"fa fa-lock\"></i> private</span>"
end
end
context 'when snippet is public' do
let(:visibility) { :public }
it 'does not return anything' do
expect(subject).to be_nil
end
end
context 'when snippet is internal' do
let(:visibility) { :internal }
it 'does not return anything' do
expect(subject).to be_nil
end
end end
end end
end end
# frozen_string_literal: true
require 'spec_helper'
describe PersonalSnippet do
describe '#embeddable?' do
[
{ snippet: :public, embeddable: true },
{ snippet: :internal, embeddable: false },
{ snippet: :private, embeddable: false }
].each do |combination|
it 'returns true when snippet is public' do
snippet = build(:personal_snippet, combination[:snippet])
expect(snippet.embeddable?).to eq(combination[:embeddable])
end
end
end
end
...@@ -10,4 +10,25 @@ describe ProjectSnippet do ...@@ -10,4 +10,25 @@ describe ProjectSnippet do
describe "Validation" do describe "Validation" do
it { is_expected.to validate_presence_of(:project) } it { is_expected.to validate_presence_of(:project) }
end end
describe '#embeddable?' do
[
{ project: :public, snippet: :public, embeddable: true },
{ project: :internal, snippet: :public, embeddable: false },
{ project: :private, snippet: :public, embeddable: false },
{ project: :public, snippet: :internal, embeddable: false },
{ project: :internal, snippet: :internal, embeddable: false },
{ project: :private, snippet: :internal, embeddable: false },
{ project: :public, snippet: :private, embeddable: false },
{ project: :internal, snippet: :private, embeddable: false },
{ project: :private, snippet: :private, embeddable: false }
].each do |combination|
it 'only returns true when both project and snippet are public' do
project = create(:project, combination[:project])
snippet = build(:project_snippet, combination[:snippet], project: project)
expect(snippet.embeddable?).to eq(combination[:embeddable])
end
end
end
end end
...@@ -451,41 +451,4 @@ describe Snippet do ...@@ -451,41 +451,4 @@ describe Snippet do
expect(blob.data).to eq(snippet.content) expect(blob.data).to eq(snippet.content)
end end
end end
describe '#embeddable?' do
context 'project snippet' do
[
{ project: :public, snippet: :public, embeddable: true },
{ project: :internal, snippet: :public, embeddable: false },
{ project: :private, snippet: :public, embeddable: false },
{ project: :public, snippet: :internal, embeddable: false },
{ project: :internal, snippet: :internal, embeddable: false },
{ project: :private, snippet: :internal, embeddable: false },
{ project: :public, snippet: :private, embeddable: false },
{ project: :internal, snippet: :private, embeddable: false },
{ project: :private, snippet: :private, embeddable: false }
].each do |combination|
it 'only returns true when both project and snippet are public' do
project = create(:project, combination[:project])
snippet = create(:project_snippet, combination[:snippet], project: project)
expect(snippet.embeddable?).to eq(combination[:embeddable])
end
end
end
context 'personal snippet' do
[
{ snippet: :public, embeddable: true },
{ snippet: :internal, embeddable: false },
{ snippet: :private, embeddable: false }
].each do |combination|
it 'only returns true when snippet is public' do
snippet = create(:personal_snippet, combination[:snippet])
expect(snippet.embeddable?).to eq(combination[:embeddable])
end
end
end
end
end 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