summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/controllers/concerns/snippets_actions.rb4
-rw-r--r--app/controllers/snippets_controller.rb14
-rw-r--r--app/helpers/blob_helper.rb8
-rw-r--r--app/views/shared/snippets/_blob.html.haml3
-rw-r--r--app/views/snippets/show.html.haml2
-rw-r--r--changelogs/unreleased/dm-snippet-download-button.yml4
-rw-r--r--config/routes/project.rb2
-rw-r--r--config/routes/snippets.rb3
-rw-r--r--spec/controllers/snippets_controller_spec.rb180
-rw-r--r--spec/features/projects/snippets/show_spec.rb12
-rw-r--r--spec/features/snippets/show_spec.rb12
11 files changed, 129 insertions, 115 deletions
diff --git a/app/controllers/concerns/snippets_actions.rb b/app/controllers/concerns/snippets_actions.rb
index ca6dffe1cc5..ffea712a833 100644
--- a/app/controllers/concerns/snippets_actions.rb
+++ b/app/controllers/concerns/snippets_actions.rb
@@ -5,10 +5,12 @@ module SnippetsActions
end
def raw
+ disposition = params[:inline] == 'false' ? 'attachment' : 'inline'
+
send_data(
convert_line_endings(@snippet.content),
type: 'text/plain; charset=utf-8',
- disposition: 'inline',
+ disposition: disposition,
filename: @snippet.sanitized_file_name
)
end
diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb
index 906833505d1..7fbfa6c2ee4 100644
--- a/app/controllers/snippets_controller.rb
+++ b/app/controllers/snippets_controller.rb
@@ -5,10 +5,10 @@ class SnippetsController < ApplicationController
include MarkdownPreview
include RendersBlob
- before_action :snippet, only: [:show, :edit, :destroy, :update, :raw, :download]
+ before_action :snippet, only: [:show, :edit, :destroy, :update, :raw]
# Allow read snippet
- before_action :authorize_read_snippet!, only: [:show, :raw, :download]
+ before_action :authorize_read_snippet!, only: [:show, :raw]
# Allow modify snippet
before_action :authorize_update_snippet!, only: [:edit, :update]
@@ -16,7 +16,7 @@ class SnippetsController < ApplicationController
# Allow destroy snippet
before_action :authorize_admin_snippet!, only: [:destroy]
- skip_before_action :authenticate_user!, only: [:index, :show, :raw, :download]
+ skip_before_action :authenticate_user!, only: [:index, :show, :raw]
layout 'snippets'
respond_to :html
@@ -83,14 +83,6 @@ class SnippetsController < ApplicationController
redirect_to snippets_path
end
- def download
- send_data(
- convert_line_endings(@snippet.content),
- type: 'text/plain; charset=utf-8',
- filename: @snippet.sanitized_file_name
- )
- end
-
def preview_markdown
render_markdown_preview(params[:text], skip_project_check: true)
end
diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb
index 377b080b3c6..5a8f615fc2d 100644
--- a/app/helpers/blob_helper.rb
+++ b/app/helpers/blob_helper.rb
@@ -118,15 +118,15 @@ module BlobHelper
icon("#{file_type_icon_class('file', mode, name)} fw")
end
- def blob_raw_url
+ def blob_raw_url(params = {})
if @snippet
if @snippet.project_id
- raw_namespace_project_snippet_path(@project.namespace, @project, @snippet)
+ raw_namespace_project_snippet_path(@project.namespace, @project, @snippet, params)
else
- raw_snippet_path(@snippet)
+ raw_snippet_path(@snippet, params)
end
elsif @blob
- namespace_project_raw_path(@project.namespace, @project, @id)
+ namespace_project_raw_path(@project.namespace, @project, @id, params)
end
end
diff --git a/app/views/shared/snippets/_blob.html.haml b/app/views/shared/snippets/_blob.html.haml
index 67d186e2874..fd4ee840a19 100644
--- a/app/views/shared/snippets/_blob.html.haml
+++ b/app/views/shared/snippets/_blob.html.haml
@@ -18,7 +18,6 @@
= copy_blob_source_button(blob)
= open_raw_blob_button(blob)
- - if defined?(download_path) && download_path
- = link_to icon('download'), download_path, class: "btn btn-sm has-tooltip", title: 'Download', data: { container: 'body' }
+ = link_to icon('download'), blob_raw_url(inline: false), target: '_blank', class: "btn btn-sm has-tooltip", title: 'Download', data: { container: 'body' }
= render 'projects/blob/content', blob: blob
diff --git a/app/views/snippets/show.html.haml b/app/views/snippets/show.html.haml
index 8a80013bbfd..ad07985951c 100644
--- a/app/views/snippets/show.html.haml
+++ b/app/views/snippets/show.html.haml
@@ -3,7 +3,7 @@
= render 'shared/snippets/header'
%article.file-holder.snippet-file-content
- = render 'shared/snippets/blob', download_path: download_snippet_path(@snippet)
+ = render 'shared/snippets/blob'
.row-content-block.top-block.content-component-block
= render 'award_emoji/awards_block', awardable: @snippet, inline: true
diff --git a/changelogs/unreleased/dm-snippet-download-button.yml b/changelogs/unreleased/dm-snippet-download-button.yml
new file mode 100644
index 00000000000..09ece1e7f98
--- /dev/null
+++ b/changelogs/unreleased/dm-snippet-download-button.yml
@@ -0,0 +1,4 @@
+---
+title: Add download button to project snippets
+merge_request:
+author:
diff --git a/config/routes/project.rb b/config/routes/project.rb
index 115ae2324b3..e777b9fc6e7 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -44,7 +44,7 @@ constraints(ProjectUrlConstrainer.new) do
resources :snippets, concerns: :awardable, constraints: { id: /\d+/ } do
member do
- get 'raw'
+ get :raw
post :mark_as_spam
end
end
diff --git a/config/routes/snippets.rb b/config/routes/snippets.rb
index 56534f677be..4ce4c11aa65 100644
--- a/config/routes/snippets.rb
+++ b/config/routes/snippets.rb
@@ -1,7 +1,6 @@
resources :snippets, concerns: :awardable do
member do
- get 'raw'
- get 'download'
+ get :raw
post :mark_as_spam
post :preview_markdown
end
diff --git a/spec/controllers/snippets_controller_spec.rb b/spec/controllers/snippets_controller_spec.rb
index 234f3edd3d8..41cd5bdcdd8 100644
--- a/spec/controllers/snippets_controller_spec.rb
+++ b/spec/controllers/snippets_controller_spec.rb
@@ -350,144 +350,138 @@ describe SnippetsController do
end
end
- %w(raw download).each do |action|
- describe "GET #{action}" do
- context 'when the personal snippet is private' do
- let(:personal_snippet) { create(:personal_snippet, :private, author: user) }
+ describe "GET #raw" do
+ context 'when the personal snippet is private' do
+ let(:personal_snippet) { create(:personal_snippet, :private, author: user) }
- context 'when signed in' do
- before do
- sign_in(user)
- end
+ context 'when signed in' do
+ before do
+ sign_in(user)
+ end
- context 'when signed in user is not the author' do
- let(:other_author) { create(:author) }
- let(:other_personal_snippet) { create(:personal_snippet, :private, author: other_author) }
+ context 'when signed in user is not the author' do
+ let(:other_author) { create(:author) }
+ let(:other_personal_snippet) { create(:personal_snippet, :private, author: other_author) }
- it 'responds with status 404' do
- get action, id: other_personal_snippet.to_param
+ it 'responds with status 404' do
+ get :raw, id: other_personal_snippet.to_param
- expect(response).to have_http_status(404)
- end
+ expect(response).to have_http_status(404)
end
+ end
- context 'when signed in user is the author' do
- before { get action, id: personal_snippet.to_param }
+ context 'when signed in user is the author' do
+ before { get :raw, id: personal_snippet.to_param }
- it 'responds with status 200' do
- expect(assigns(:snippet)).to eq(personal_snippet)
- expect(response).to have_http_status(200)
- end
+ it 'responds with status 200' do
+ expect(assigns(:snippet)).to eq(personal_snippet)
+ expect(response).to have_http_status(200)
+ end
- it 'has expected headers' do
- expect(response.header['Content-Type']).to eq('text/plain; charset=utf-8')
+ it 'has expected headers' do
+ expect(response.header['Content-Type']).to eq('text/plain; charset=utf-8')
- if action == :download
- expect(response.header['Content-Disposition']).to match(/attachment/)
- elsif action == :raw
- expect(response.header['Content-Disposition']).to match(/inline/)
- end
- end
+ expect(response.header['Content-Disposition']).to match(/inline/)
end
end
+ end
- context 'when not signed in' do
- it 'redirects to the sign in page' do
- get action, id: personal_snippet.to_param
+ context 'when not signed in' do
+ it 'redirects to the sign in page' do
+ get :raw, id: personal_snippet.to_param
- expect(response).to redirect_to(new_user_session_path)
- end
+ expect(response).to redirect_to(new_user_session_path)
end
end
+ end
- context 'when the personal snippet is internal' do
- let(:personal_snippet) { create(:personal_snippet, :internal, author: user) }
+ context 'when the personal snippet is internal' do
+ let(:personal_snippet) { create(:personal_snippet, :internal, author: user) }
- context 'when signed in' do
- before do
- sign_in(user)
- end
+ context 'when signed in' do
+ before do
+ sign_in(user)
+ end
- it 'responds with status 200' do
- get action, id: personal_snippet.to_param
+ it 'responds with status 200' do
+ get :raw, id: personal_snippet.to_param
- expect(assigns(:snippet)).to eq(personal_snippet)
- expect(response).to have_http_status(200)
- end
+ expect(assigns(:snippet)).to eq(personal_snippet)
+ expect(response).to have_http_status(200)
end
+ end
- context 'when not signed in' do
- it 'redirects to the sign in page' do
- get action, id: personal_snippet.to_param
+ context 'when not signed in' do
+ it 'redirects to the sign in page' do
+ get :raw, id: personal_snippet.to_param
- expect(response).to redirect_to(new_user_session_path)
- end
+ expect(response).to redirect_to(new_user_session_path)
end
end
+ end
- context 'when the personal snippet is public' do
- let(:personal_snippet) { create(:personal_snippet, :public, author: user) }
+ context 'when the personal snippet is public' do
+ let(:personal_snippet) { create(:personal_snippet, :public, author: user) }
- context 'when signed in' do
- before do
- sign_in(user)
- end
+ context 'when signed in' do
+ before do
+ sign_in(user)
+ end
- it 'responds with status 200' do
- get action, id: personal_snippet.to_param
+ it 'responds with status 200' do
+ get :raw, id: personal_snippet.to_param
- expect(assigns(:snippet)).to eq(personal_snippet)
- expect(response).to have_http_status(200)
- end
+ expect(assigns(:snippet)).to eq(personal_snippet)
+ expect(response).to have_http_status(200)
+ end
- context 'CRLF line ending' do
- let(:personal_snippet) do
- create(:personal_snippet, :public, author: user, content: "first line\r\nsecond line\r\nthird line")
- end
+ context 'CRLF line ending' do
+ let(:personal_snippet) do
+ create(:personal_snippet, :public, author: user, content: "first line\r\nsecond line\r\nthird line")
+ end
- it 'returns LF line endings by default' do
- get action, id: personal_snippet.to_param
+ it 'returns LF line endings by default' do
+ get :raw, id: personal_snippet.to_param
- expect(response.body).to eq("first line\nsecond line\nthird line")
- end
+ expect(response.body).to eq("first line\nsecond line\nthird line")
+ end
- it 'does not convert line endings when parameter present' do
- get action, id: personal_snippet.to_param, line_ending: :raw
+ it 'does not convert line endings when parameter present' do
+ get :raw, id: personal_snippet.to_param, line_ending: :raw
- expect(response.body).to eq("first line\r\nsecond line\r\nthird line")
- end
+ expect(response.body).to eq("first line\r\nsecond line\r\nthird line")
end
end
+ end
- context 'when not signed in' do
- it 'responds with status 200' do
- get action, id: personal_snippet.to_param
+ context 'when not signed in' do
+ it 'responds with status 200' do
+ get :raw, id: personal_snippet.to_param
- expect(assigns(:snippet)).to eq(personal_snippet)
- expect(response).to have_http_status(200)
- end
+ expect(assigns(:snippet)).to eq(personal_snippet)
+ expect(response).to have_http_status(200)
end
end
+ end
- context 'when the personal snippet does not exist' do
- context 'when signed in' do
- before do
- sign_in(user)
- end
+ context 'when the personal snippet does not exist' do
+ context 'when signed in' do
+ before do
+ sign_in(user)
+ end
- it 'responds with status 404' do
- get action, id: 'doesntexist'
+ it 'responds with status 404' do
+ get :raw, id: 'doesntexist'
- expect(response).to have_http_status(404)
- end
+ expect(response).to have_http_status(404)
end
+ end
- context 'when not signed in' do
- it 'responds with status 404' do
- get action, id: 'doesntexist'
+ context 'when not signed in' do
+ it 'responds with status 404' do
+ get :raw, id: 'doesntexist'
- expect(response).to have_http_status(404)
- end
+ expect(response).to have_http_status(404)
end
end
end
diff --git a/spec/features/projects/snippets/show_spec.rb b/spec/features/projects/snippets/show_spec.rb
index 7eb1210e307..cedf3778c7e 100644
--- a/spec/features/projects/snippets/show_spec.rb
+++ b/spec/features/projects/snippets/show_spec.rb
@@ -30,6 +30,12 @@ feature 'Project snippet', :js, feature: true do
# shows an enabled copy button
expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)')
+
+ # shows a raw button
+ expect(page).to have_link('Open raw')
+
+ # shows a download button
+ expect(page).to have_link('Download')
end
end
end
@@ -59,6 +65,12 @@ feature 'Project snippet', :js, feature: true do
# shows a disabled copy button
expect(page).to have_selector('.js-copy-blob-source-btn.disabled')
+
+ # shows a raw button
+ expect(page).to have_link('Open raw')
+
+ # shows a download button
+ expect(page).to have_link('Download')
end
end
diff --git a/spec/features/snippets/show_spec.rb b/spec/features/snippets/show_spec.rb
index cebcba6a230..e36cf547f80 100644
--- a/spec/features/snippets/show_spec.rb
+++ b/spec/features/snippets/show_spec.rb
@@ -24,6 +24,12 @@ feature 'Snippet', :js, feature: true do
# shows an enabled copy button
expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)')
+
+ # shows a raw button
+ expect(page).to have_link('Open raw')
+
+ # shows a download button
+ expect(page).to have_link('Download')
end
end
end
@@ -53,6 +59,12 @@ feature 'Snippet', :js, feature: true do
# shows a disabled copy button
expect(page).to have_selector('.js-copy-blob-source-btn.disabled')
+
+ # shows a raw button
+ expect(page).to have_link('Open raw')
+
+ # shows a download button
+ expect(page).to have_link('Download')
end
end