Return content from repo in snippet raw endpoint

This commit fixed the raw endpoints in both
personal and project snippets. We were always
returning the snippet content from db.

If the feature flag is enabled and the repo
is not empty, we must return the content
from the repository.
parent 840b1ea5
---
title: Return content from repo in snippet raw endpoint
merge_request: 29781
author:
type: fixed
# frozen_string_literal: true
module API
module Helpers
module SnippetsHelpers
def content_for(snippet)
if ::Feature.enabled?(:version_snippets, current_user) && !snippet.empty_repo?
blob = snippet.blobs.first
blob.load_all_data!
blob.data
else
snippet.content
end
end
end
end
end
...@@ -11,6 +11,7 @@ module API ...@@ -11,6 +11,7 @@ module API
requires :id, type: String, desc: 'The ID of a project' requires :id, type: String, desc: 'The ID of a project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
helpers Helpers::SnippetsHelpers
helpers do helpers do
def check_snippets_enabled def check_snippets_enabled
forbidden! unless user_project.feature_available?(:snippets, current_user) forbidden! unless user_project.feature_available?(:snippets, current_user)
...@@ -155,7 +156,7 @@ module API ...@@ -155,7 +156,7 @@ module API
env['api.format'] = :txt env['api.format'] = :txt
content_type 'text/plain' content_type 'text/plain'
present snippet.content present content_for(snippet)
end end
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
......
...@@ -8,6 +8,7 @@ module API ...@@ -8,6 +8,7 @@ module API
before { authenticate! } before { authenticate! }
resource :snippets do resource :snippets do
helpers Helpers::SnippetsHelpers
helpers do helpers do
def snippets_for_current_user def snippets_for_current_user
SnippetsFinder.new(current_user, author: current_user).execute SnippetsFinder.new(current_user, author: current_user).execute
...@@ -159,7 +160,7 @@ module API ...@@ -159,7 +160,7 @@ module API
env['api.format'] = :txt env['api.format'] = :txt
content_type 'text/plain' content_type 'text/plain'
header['Content-Disposition'] = 'attachment' header['Content-Disposition'] = 'attachment'
present snippet.content present content_for(snippet)
end end
desc 'Get the user agent details for a snippet' do desc 'Get the user agent details for a snippet' do
......
...@@ -460,14 +460,13 @@ describe API::ProjectSnippets do ...@@ -460,14 +460,13 @@ describe API::ProjectSnippets do
end end
describe 'GET /projects/:project_id/snippets/:id/raw' do describe 'GET /projects/:project_id/snippets/:id/raw' do
let(:snippet) { create(:project_snippet, author: admin, project: project) } let_it_be(:snippet) { create(:project_snippet, :repository, author: admin, project: project) }
it 'returns raw text' do it 'returns raw text' do
get api("/projects/#{snippet.project.id}/snippets/#{snippet.id}/raw", admin) get api("/projects/#{snippet.project.id}/snippets/#{snippet.id}/raw", admin)
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type).to eq 'text/plain' expect(response.content_type).to eq 'text/plain'
expect(response.body).to eq(snippet.content)
end end
it 'returns 404 for invalid snippet id' do it 'returns 404 for invalid snippet id' do
...@@ -482,5 +481,11 @@ describe API::ProjectSnippets do ...@@ -482,5 +481,11 @@ describe API::ProjectSnippets do
let(:request) { get api("/projects/#{project_no_snippets.id}/snippets/123/raw", admin) } let(:request) { get api("/projects/#{project_no_snippets.id}/snippets/123/raw", admin) }
end end
end end
it_behaves_like 'snippet blob content' do
let_it_be(:snippet_with_empty_repo) { create(:project_snippet, :empty_repo, author: admin, project: project) }
subject { get api("/projects/#{snippet.project.id}/snippets/#{snippet.id}/raw", snippet.author) }
end
end end
end end
...@@ -90,7 +90,7 @@ describe API::Snippets do ...@@ -90,7 +90,7 @@ describe API::Snippets do
describe 'GET /snippets/:id/raw' do describe 'GET /snippets/:id/raw' do
let_it_be(:author) { create(:user) } let_it_be(:author) { create(:user) }
let_it_be(:snippet) { create(:personal_snippet, :private, author: author) } let_it_be(:snippet) { create(:personal_snippet, :repository, :private, author: author) }
it 'requires authentication' do it 'requires authentication' do
get api("/snippets/#{snippet.id}", nil) get api("/snippets/#{snippet.id}", nil)
...@@ -103,7 +103,6 @@ describe API::Snippets do ...@@ -103,7 +103,6 @@ describe API::Snippets do
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type).to eq 'text/plain' expect(response.content_type).to eq 'text/plain'
expect(response.body).to eq(snippet.content)
end end
it 'forces attachment content disposition' do it 'forces attachment content disposition' do
...@@ -134,6 +133,12 @@ describe API::Snippets do ...@@ -134,6 +133,12 @@ describe API::Snippets do
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
end end
it_behaves_like 'snippet blob content' do
let_it_be(:snippet_with_empty_repo) { create(:personal_snippet, :empty_repo, :private, author: author) }
subject { get api("/snippets/#{snippet.id}/raw", snippet.author) }
end
end end
describe 'GET /snippets/:id' do describe 'GET /snippets/:id' do
......
...@@ -58,3 +58,31 @@ RSpec.shared_examples 'snippet response without repository URLs' do ...@@ -58,3 +58,31 @@ RSpec.shared_examples 'snippet response without repository URLs' do
expect(json_response).not_to have_key('http_url_to_repo') expect(json_response).not_to have_key('http_url_to_repo')
end end
end end
RSpec.shared_examples 'snippet blob content' do
it 'returns content from repository' do
subject
expect(response.body).to eq(snippet.blobs.first.data)
end
context 'when feature flag :version_snippets is disabled' do
it 'returns content from database' do
stub_feature_flags(version_snippets: false)
subject
expect(response.body).to eq(snippet.content)
end
end
context 'when snippet repository is empty' do
let(:snippet) { snippet_with_empty_repo }
it 'returns content from database' do
subject
expect(response.body).to eq(snippet.content)
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