debian-mirror-gitlab/spec/controllers/projects/blob_controller_spec.rb

565 lines
15 KiB
Ruby
Raw Normal View History

2019-07-31 22:56:46 +05:30
# frozen_string_literal: true
2019-12-04 20:38:33 +05:30
require 'spec_helper'
2016-08-24 12:49:21 +05:30
2020-06-23 00:09:42 +05:30
RSpec.describe Projects::BlobController do
2018-03-17 18:26:18 +05:30
include ProjectForksHelper
2017-08-17 22:00:37 +05:30
let(:project) { create(:project, :public, :repository) }
2016-08-24 12:49:21 +05:30
2021-03-08 18:12:59 +05:30
describe "GET new" do
context 'with no jobs' do
let_it_be(:user) { create(:user) }
let_it_be(:file_name) { '.gitlab-ci.yml' }
def request
get(:new, params: { namespace_id: project.namespace, project_id: project, id: 'master', file_name: file_name } )
end
before do
project.add_maintainer(user)
sign_in(user)
2021-04-17 20:07:23 +05:30
stub_experiment(ci_syntax_templates_b: experiment_active)
stub_experiment_for_subject(ci_syntax_templates_b: in_experiment_group)
2021-03-08 18:12:59 +05:30
end
context 'when the experiment is not active' do
let(:experiment_active) { false }
let(:in_experiment_group) { false }
it 'does not record the experiment user' do
expect(Experiment).not_to receive(:add_user)
request
end
end
2021-04-17 20:07:23 +05:30
context 'when the experiment is active' do
2021-03-08 18:12:59 +05:30
let(:experiment_active) { true }
2021-04-17 20:07:23 +05:30
context 'when the user is in the control group' do
let(:in_experiment_group) { false }
2021-03-08 18:12:59 +05:30
2021-04-17 20:07:23 +05:30
it 'records the experiment user in the control group' do
expect(Experiment).to receive(:add_user)
.with(:ci_syntax_templates_b, :control, user, namespace_id: project.namespace_id)
2021-03-08 18:12:59 +05:30
2021-04-17 20:07:23 +05:30
request
end
2021-03-08 18:12:59 +05:30
end
2021-04-17 20:07:23 +05:30
context 'when the user is in the experimental group' do
let(:in_experiment_group) { true }
2021-03-08 18:12:59 +05:30
it 'records the experiment user in the experimental group' do
expect(Experiment).to receive(:add_user)
2021-04-17 20:07:23 +05:30
.with(:ci_syntax_templates_b, :experimental, user, namespace_id: project.namespace_id)
2021-03-08 18:12:59 +05:30
request
end
2021-04-17 20:07:23 +05:30
context 'when requesting a non default config file type' do
let(:file_name) { '.non_default_ci_config' }
let(:project) { create(:project, :public, :repository, ci_config_path: file_name) }
2021-03-08 18:12:59 +05:30
2021-04-17 20:07:23 +05:30
it 'records the experiment user in the experimental group' do
expect(Experiment).to receive(:add_user)
.with(:ci_syntax_templates_b, :experimental, user, namespace_id: project.namespace_id)
2021-03-08 18:12:59 +05:30
2021-04-17 20:07:23 +05:30
request
end
end
context 'when requesting a different file type' do
let(:file_name) { '.gitignore' }
it 'does not record the experiment user' do
expect(Experiment).not_to receive(:add_user)
request
end
end
context 'when the group is created longer than 90 days ago' do
before do
project.namespace.update_attribute(:created_at, 91.days.ago)
end
it 'does not record the experiment user' do
expect(Experiment).not_to receive(:add_user)
request
end
2021-03-08 18:12:59 +05:30
end
end
end
end
end
2017-08-17 22:00:37 +05:30
describe "GET show" do
2020-04-22 19:07:51 +05:30
def request
get(:show, params: { namespace_id: project.namespace, project_id: project, id: id })
end
2017-08-17 22:00:37 +05:30
render_views
context 'with file path' do
before do
2019-07-07 11:18:12 +05:30
expect(::Gitlab::GitalyClient).to receive(:allow_ref_name_caching).and_call_original
2020-04-22 19:07:51 +05:30
request
2017-08-17 22:00:37 +05:30
end
context "valid branch, valid file" do
let(:id) { 'master/README.md' }
2019-12-26 22:10:19 +05:30
2017-08-17 22:00:37 +05:30
it { is_expected.to respond_with(:success) }
end
context "valid branch, invalid file" do
let(:id) { 'master/invalid-path.rb' }
2019-12-26 22:10:19 +05:30
it 'redirects' do
expect(subject)
2020-03-13 15:44:24 +05:30
.to redirect_to("/#{project.full_path}/-/tree/master")
2019-12-26 22:10:19 +05:30
end
2017-08-17 22:00:37 +05:30
end
context "invalid branch, valid file" do
let(:id) { 'invalid-branch/README.md' }
2019-12-26 22:10:19 +05:30
2017-08-17 22:00:37 +05:30
it { is_expected.to respond_with(:not_found) }
end
2016-08-24 12:49:21 +05:30
2017-08-17 22:00:37 +05:30
context "binary file" do
let(:id) { 'binary-encoding/encoding/binary-1.bin' }
2019-12-26 22:10:19 +05:30
2017-08-17 22:00:37 +05:30
it { is_expected.to respond_with(:success) }
end
2019-02-15 15:39:39 +05:30
context "Markdown file" do
let(:id) { 'master/README.md' }
2019-12-26 22:10:19 +05:30
2019-02-15 15:39:39 +05:30
it { is_expected.to respond_with(:success) }
end
2017-08-17 22:00:37 +05:30
end
2017-09-10 17:25:29 +05:30
context 'with file path and JSON format' do
context "valid branch, valid file" do
let(:id) { 'master/README.md' }
before do
get(:show,
2019-02-15 15:39:39 +05:30
params: {
namespace_id: project.namespace,
project_id: project,
id: id
},
2017-09-10 17:25:29 +05:30
format: :json)
end
it do
expect(response).to be_ok
expect(json_response).to have_key 'html'
expect(json_response).to have_key 'raw_path'
end
end
2018-11-08 19:23:39 +05:30
context "with viewer=none" do
let(:id) { 'master/README.md' }
before do
get(:show,
2019-02-15 15:39:39 +05:30
params: {
namespace_id: project.namespace,
project_id: project,
id: id,
viewer: 'none'
},
format: :json)
2018-11-08 19:23:39 +05:30
end
it do
expect(response).to be_ok
expect(json_response).not_to have_key 'html'
expect(json_response).to have_key 'raw_path'
end
end
2017-09-10 17:25:29 +05:30
end
2017-08-17 22:00:37 +05:30
context 'with tree path' do
before do
get(:show,
2019-02-15 15:39:39 +05:30
params: {
namespace_id: project.namespace,
project_id: project,
id: id
})
2017-08-17 22:00:37 +05:30
controller.instance_variable_set(:@blob, nil)
end
context 'redirect to tree' do
let(:id) { 'markdown/doc' }
2019-12-26 22:10:19 +05:30
2017-08-17 22:00:37 +05:30
it 'redirects' do
2017-09-10 17:25:29 +05:30
expect(subject)
2020-03-13 15:44:24 +05:30
.to redirect_to("/#{project.full_path}/-/tree/markdown/doc")
2017-08-17 22:00:37 +05:30
end
end
end
2016-08-24 12:49:21 +05:30
end
describe 'GET diff' do
2017-08-17 22:00:37 +05:30
let(:user) { create(:user) }
2016-08-24 12:49:21 +05:30
render_views
def do_get(opts = {})
2017-08-17 22:00:37 +05:30
params = { namespace_id: project.namespace,
project_id: project,
2016-08-24 12:49:21 +05:30
id: 'master/CHANGELOG' }
2019-02-15 15:39:39 +05:30
get :diff, params: params.merge(opts)
2016-08-24 12:49:21 +05:30
end
2017-08-17 22:00:37 +05:30
before do
2018-11-18 11:00:15 +05:30
project.add_maintainer(user)
2017-08-17 22:00:37 +05:30
sign_in(user)
end
2016-08-24 12:49:21 +05:30
context 'when essential params are missing' do
it 'renders nothing' do
do_get
expect(response.body).to be_blank
end
end
context 'when essential params are present' do
2018-11-08 19:23:39 +05:30
context 'when rendering for commit' do
it 'renders the diff content' do
do_get(since: 1, to: 5, offset: 10)
expect(response.body).to be_present
end
end
context 'when rendering for merge request' do
2019-07-07 11:18:12 +05:30
let(:presenter) { double(:presenter, diff_lines: diff_lines) }
let(:diff_lines) do
Array.new(3, Gitlab::Diff::Line.new('plain', nil, nil, nil, nil, rich_text: 'rich'))
2019-05-18 00:54:41 +05:30
end
2018-11-08 19:23:39 +05:30
2019-07-07 11:18:12 +05:30
before do
allow(Blobs::UnfoldPresenter).to receive(:new).and_return(presenter)
end
2019-05-30 16:15:17 +05:30
2019-07-07 11:18:12 +05:30
it 'renders diff context lines Gitlab::Diff::Line array' do
do_get(since: 1, to: 2, offset: 0, from_merge_request: true)
2019-05-30 16:15:17 +05:30
2019-09-30 21:07:59 +05:30
lines = json_response
2019-05-30 16:15:17 +05:30
2019-07-07 11:18:12 +05:30
expect(lines.size).to eq(diff_lines.size)
lines.each do |line|
expect(line).to have_key('type')
expect(line['text']).to eq('plain')
expect(line['rich_text']).to eq('rich')
2019-05-30 16:15:17 +05:30
end
2019-07-07 11:18:12 +05:30
end
2019-05-30 16:15:17 +05:30
2019-07-07 11:18:12 +05:30
it 'handles full being true' do
do_get(full: true, from_merge_request: true)
2019-05-30 16:15:17 +05:30
2019-09-30 21:07:59 +05:30
lines = json_response
2019-05-30 16:15:17 +05:30
2019-07-07 11:18:12 +05:30
expect(lines.size).to eq(diff_lines.size)
2018-11-08 19:23:39 +05:30
end
2016-08-24 12:49:21 +05:30
end
end
end
2017-01-15 13:20:01 +05:30
2017-08-17 22:00:37 +05:30
describe 'GET edit' do
let(:default_params) do
{
namespace_id: project.namespace,
project_id: project,
id: 'master/CHANGELOG'
}
end
context 'anonymous' do
before do
2019-02-15 15:39:39 +05:30
get :edit, params: default_params
2017-08-17 22:00:37 +05:30
end
it 'redirects to sign in and returns' do
expect(response).to redirect_to(new_user_session_path)
end
end
context 'as guest' do
let(:guest) { create(:user) }
before do
sign_in(guest)
2019-02-15 15:39:39 +05:30
get :edit, params: default_params
2017-08-17 22:00:37 +05:30
end
it 'redirects to blob show' do
2017-09-10 17:25:29 +05:30
expect(response).to redirect_to(project_blob_path(project, 'master/CHANGELOG'))
2017-08-17 22:00:37 +05:30
end
end
context 'as developer' do
let(:developer) { create(:user) }
before do
2018-03-17 18:26:18 +05:30
project.add_developer(developer)
2017-08-17 22:00:37 +05:30
sign_in(developer)
2019-02-15 15:39:39 +05:30
get :edit, params: default_params
2017-08-17 22:00:37 +05:30
end
it 'redirects to blob show' do
2020-03-13 15:44:24 +05:30
expect(response).to have_gitlab_http_status(:ok)
2017-08-17 22:00:37 +05:30
end
end
2018-11-18 11:00:15 +05:30
context 'as maintainer' do
let(:maintainer) { create(:user) }
2017-08-17 22:00:37 +05:30
before do
2018-11-18 11:00:15 +05:30
project.add_maintainer(maintainer)
sign_in(maintainer)
2019-02-15 15:39:39 +05:30
get :edit, params: default_params
2017-08-17 22:00:37 +05:30
end
it 'redirects to blob show' do
2020-03-13 15:44:24 +05:30
expect(response).to have_gitlab_http_status(:ok)
2017-08-17 22:00:37 +05:30
end
end
end
2017-01-15 13:20:01 +05:30
describe 'PUT update' do
2017-08-17 22:00:37 +05:30
let(:user) { create(:user) }
2017-01-15 13:20:01 +05:30
let(:default_params) do
{
2017-08-17 22:00:37 +05:30
namespace_id: project.namespace,
project_id: project,
2017-01-15 13:20:01 +05:30
id: 'master/CHANGELOG',
2017-08-17 22:00:37 +05:30
branch_name: 'master',
2017-01-15 13:20:01 +05:30
content: 'Added changes',
commit_message: 'Update CHANGELOG'
}
end
def blob_after_edit_path
2017-09-10 17:25:29 +05:30
project_blob_path(project, 'master/CHANGELOG')
2017-01-15 13:20:01 +05:30
end
2017-08-17 22:00:37 +05:30
before do
2018-11-18 11:00:15 +05:30
project.add_maintainer(user)
2017-08-17 22:00:37 +05:30
sign_in(user)
end
2017-01-15 13:20:01 +05:30
it 'redirects to blob' do
2019-02-15 15:39:39 +05:30
put :update, params: default_params
2017-01-15 13:20:01 +05:30
expect(response).to redirect_to(blob_after_edit_path)
end
context '?from_merge_request_iid' do
let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
let(:mr_params) { default_params.merge(from_merge_request_iid: merge_request.iid) }
it 'redirects to MR diff' do
2019-02-15 15:39:39 +05:30
put :update, params: mr_params
2017-01-15 13:20:01 +05:30
2017-09-10 17:25:29 +05:30
after_edit_path = diffs_project_merge_request_path(project, merge_request)
2017-08-17 22:00:37 +05:30
file_anchor = "##{Digest::SHA1.hexdigest('CHANGELOG')}"
2017-01-15 13:20:01 +05:30
expect(response).to redirect_to(after_edit_path + file_anchor)
end
context "when user doesn't have access" do
before do
2017-09-10 17:25:29 +05:30
other_project = create(:project, :repository)
2017-01-15 13:20:01 +05:30
merge_request.update!(source_project: other_project, target_project: other_project)
end
2019-07-07 11:18:12 +05:30
it "redirects to blob" do
2019-02-15 15:39:39 +05:30
put :update, params: mr_params
2017-01-15 13:20:01 +05:30
expect(response).to redirect_to(blob_after_edit_path)
end
end
end
2017-08-17 22:00:37 +05:30
context 'when user has forked project' do
2018-03-17 18:26:18 +05:30
let!(:forked_project) { fork_project(project, guest, namespace: guest.namespace, repository: true) }
let(:guest) { create(:user) }
2017-08-17 22:00:37 +05:30
before do
sign_in(guest)
end
context 'when editing on the fork' do
before do
default_params[:namespace_id] = forked_project.namespace
default_params[:project_id] = forked_project
end
2019-12-26 22:10:19 +05:30
it 'redirects to blob', :sidekiq_might_not_need_inline do
2019-02-15 15:39:39 +05:30
put :update, params: default_params
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
expect(response).to redirect_to(project_blob_path(forked_project, 'master/CHANGELOG'))
2017-08-17 22:00:37 +05:30
end
end
context 'when editing on the original repository' do
2019-12-26 22:10:19 +05:30
it "redirects to forked project new merge request", :sidekiq_might_not_need_inline do
2017-08-17 22:00:37 +05:30
default_params[:branch_name] = "fork-test-1"
default_params[:create_merge_request] = 1
2019-02-15 15:39:39 +05:30
put :update, params: default_params
2017-08-17 22:00:37 +05:30
expect(response).to redirect_to(
2017-09-10 17:25:29 +05:30
project_new_merge_request_path(
2017-08-17 22:00:37 +05:30
forked_project,
merge_request: {
source_project_id: forked_project.id,
target_project_id: project.id,
source_branch: "fork-test-1",
target_branch: "master"
}
)
)
end
end
end
2020-11-24 15:15:51 +05:30
2021-03-11 19:13:27 +05:30
it_behaves_like 'tracking unique hll events' do
2021-01-03 14:25:43 +05:30
subject(:request) { put :update, params: default_params }
2020-11-24 15:15:51 +05:30
let(:target_id) { 'g_edit_by_sfe' }
let(:expected_type) { instance_of(Integer) }
end
2017-01-15 13:20:01 +05:30
end
2018-12-13 13:39:08 +05:30
describe 'DELETE destroy' do
let(:user) { create(:user) }
let(:project_root_path) { project_tree_path(project, 'master') }
before do
project.add_maintainer(user)
sign_in(user)
end
context 'for a file in a subdirectory' do
let(:default_params) do
{
namespace_id: project.namespace,
project_id: project,
id: 'master/files/whitespace',
original_branch: 'master',
branch_name: 'master',
commit_message: 'Delete whitespace'
}
end
let(:after_delete_path) { project_tree_path(project, 'master/files') }
it 'redirects to the sub directory' do
2019-02-15 15:39:39 +05:30
delete :destroy, params: default_params
2018-12-13 13:39:08 +05:30
expect(response).to redirect_to(after_delete_path)
end
2020-06-23 00:09:42 +05:30
context 'when a validation failure occurs' do
let(:failure_path) { project_blob_path(project, default_params[:id]) }
render_views
it 'redirects to a valid page' do
expect_next_instance_of(Files::DeleteService) do |instance|
expect(instance).to receive(:validate!).and_raise(Commits::CreateService::ValidationError, "validation error")
end
delete :destroy, params: default_params
expect(response).to redirect_to(failure_path)
end
end
2018-12-13 13:39:08 +05:30
end
context 'if deleted file is the last one in a subdirectory' do
let(:default_params) do
{
namespace_id: project.namespace,
project_id: project,
id: 'master/bar/branch-test.txt',
original_branch: 'master',
branch_name: 'master',
commit_message: 'Delete whitespace'
}
end
it 'redirects to the project root' do
2019-02-15 15:39:39 +05:30
delete :destroy, params: default_params
2018-12-13 13:39:08 +05:30
expect(response).to redirect_to(project_root_path)
end
context 'when deleting a file in a branch other than master' do
let(:default_params) do
{
namespace_id: project.namespace,
project_id: project,
id: 'binary-encoding/foo/bar/.gitkeep',
original_branch: 'binary-encoding',
branch_name: 'binary-encoding',
commit_message: 'Delete whitespace'
}
end
let(:after_delete_path) { project_tree_path(project, 'binary-encoding') }
it 'redirects to the project root of the branch' do
2019-02-15 15:39:39 +05:30
delete :destroy, params: default_params
2018-12-13 13:39:08 +05:30
expect(response).to redirect_to(after_delete_path)
end
end
end
end
2020-11-24 15:15:51 +05:30
describe 'POST create' do
let(:user) { create(:user) }
let(:default_params) do
{
namespace_id: project.namespace,
project_id: project,
id: 'master',
branch_name: 'master',
file_name: 'docs/EXAMPLE_FILE',
content: 'Added changes',
commit_message: 'Create CHANGELOG'
}
end
before do
project.add_developer(user)
sign_in(user)
end
2021-03-11 19:13:27 +05:30
it_behaves_like 'tracking unique hll events' do
2021-01-03 14:25:43 +05:30
subject(:request) { post :create, params: default_params }
2020-11-24 15:15:51 +05:30
let(:target_id) { 'g_edit_by_sfe' }
let(:expected_type) { instance_of(Integer) }
end
end
2016-08-24 12:49:21 +05:30
end