Open WebIDE in fork when user doesn't have access
When opening the IDE on a project where the user doesn't have push access, we create a fork and then redirect back to the IDE. To make sure the user can actually commit, we need to open the IDE in the forked project rather than the upstream project.
This commit is contained in:
parent
21c372827e
commit
60a6074dc9
4 changed files with 47 additions and 8 deletions
|
@ -18,7 +18,16 @@ module BlobHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def ide_edit_path(project = @project, ref = @ref, path = @path, options = {})
|
def ide_edit_path(project = @project, ref = @ref, path = @path, options = {})
|
||||||
segments = [ide_path, 'project', project.full_path, 'edit', ref]
|
project_path =
|
||||||
|
if !current_user || can?(current_user, :push_code, project)
|
||||||
|
project.full_path
|
||||||
|
else
|
||||||
|
# We currently always fork to the user's namespace
|
||||||
|
# in edit_fork_button_tag
|
||||||
|
"#{current_user.namespace.full_path}/#{project.path}"
|
||||||
|
end
|
||||||
|
|
||||||
|
segments = [ide_path, 'project', project_path, 'edit', ref]
|
||||||
segments.concat(['-', encode_ide_path(path)]) if path.present?
|
segments.concat(['-', encode_ide_path(path)]) if path.present?
|
||||||
File.join(segments)
|
File.join(segments)
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Open WebIDE in fork when user doesn't have access
|
||||||
|
merge_request: 30642
|
||||||
|
author:
|
||||||
|
type: changed
|
|
@ -162,6 +162,7 @@ describe 'Projects > Files > User edits files', :js do
|
||||||
|
|
||||||
expect_fork_status
|
expect_fork_status
|
||||||
|
|
||||||
|
expect(page).to have_css('.ide-sidebar-project-title', text: "#{project2.name} #{user.namespace.full_path}/#{project2.path}")
|
||||||
expect(page).to have_css('.ide .multi-file-tab', text: '.gitignore')
|
expect(page).to have_css('.ide .multi-file-tab', text: '.gitignore')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -29,14 +29,15 @@ describe BlobHelper do
|
||||||
let(:project) { create(:project, :repository, namespace: namespace) }
|
let(:project) { create(:project, :repository, namespace: namespace) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
allow(self).to receive(:current_user).and_return(nil)
|
allow(helper).to receive(:current_user).and_return(nil)
|
||||||
allow(self).to receive(:can_collaborate_with_project?).and_return(true)
|
allow(helper).to receive(:can?).and_return(true)
|
||||||
|
allow(helper).to receive(:can_collaborate_with_project?).and_return(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'verifies blob is text' do
|
it 'verifies blob is text' do
|
||||||
expect(helper).not_to receive(:blob_text_viewable?)
|
expect(helper).not_to receive(:blob_text_viewable?)
|
||||||
|
|
||||||
button = edit_blob_button(project, 'refs/heads/master', 'README.md')
|
button = helper.edit_blob_button(project, 'refs/heads/master', 'README.md')
|
||||||
|
|
||||||
expect(button).to start_with('<button')
|
expect(button).to start_with('<button')
|
||||||
end
|
end
|
||||||
|
@ -46,25 +47,25 @@ describe BlobHelper do
|
||||||
|
|
||||||
expect(project.repository).not_to receive(:blob_at)
|
expect(project.repository).not_to receive(:blob_at)
|
||||||
|
|
||||||
edit_blob_button(project, 'refs/heads/master', 'README.md', blob: blob)
|
helper.edit_blob_button(project, 'refs/heads/master', 'README.md', blob: blob)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns a link with the proper route' do
|
it 'returns a link with the proper route' do
|
||||||
stub_feature_flags(web_ide_default: false)
|
stub_feature_flags(web_ide_default: false)
|
||||||
link = edit_blob_button(project, 'master', 'README.md')
|
link = helper.edit_blob_button(project, 'master', 'README.md')
|
||||||
|
|
||||||
expect(Capybara.string(link).find_link('Edit')[:href]).to eq("/#{project.full_path}/edit/master/README.md")
|
expect(Capybara.string(link).find_link('Edit')[:href]).to eq("/#{project.full_path}/edit/master/README.md")
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns a link with a Web IDE route' do
|
it 'returns a link with a Web IDE route' do
|
||||||
link = edit_blob_button(project, 'master', 'README.md')
|
link = helper.edit_blob_button(project, 'master', 'README.md')
|
||||||
|
|
||||||
expect(Capybara.string(link).find_link('Edit')[:href]).to eq("/-/ide/project/#{project.full_path}/edit/master/-/README.md")
|
expect(Capybara.string(link).find_link('Edit')[:href]).to eq("/-/ide/project/#{project.full_path}/edit/master/-/README.md")
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns a link with the passed link_opts on the expected route' do
|
it 'returns a link with the passed link_opts on the expected route' do
|
||||||
stub_feature_flags(web_ide_default: false)
|
stub_feature_flags(web_ide_default: false)
|
||||||
link = edit_blob_button(project, 'master', 'README.md', link_opts: { mr_id: 10 })
|
link = helper.edit_blob_button(project, 'master', 'README.md', link_opts: { mr_id: 10 })
|
||||||
|
|
||||||
expect(Capybara.string(link).find_link('Edit')[:href]).to eq("/#{project.full_path}/edit/master/README.md?mr_id=10")
|
expect(Capybara.string(link).find_link('Edit')[:href]).to eq("/#{project.full_path}/edit/master/README.md?mr_id=10")
|
||||||
end
|
end
|
||||||
|
@ -203,6 +204,13 @@ describe BlobHelper do
|
||||||
|
|
||||||
describe '#ide_edit_path' do
|
describe '#ide_edit_path' do
|
||||||
let(:project) { create(:project) }
|
let(:project) { create(:project) }
|
||||||
|
let(:current_user) { create(:user) }
|
||||||
|
let(:can_push_code) { true }
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow(helper).to receive(:current_user).and_return(current_user)
|
||||||
|
allow(helper).to receive(:can?).and_return(can_push_code)
|
||||||
|
end
|
||||||
|
|
||||||
around do |example|
|
around do |example|
|
||||||
old_script_name = Rails.application.routes.default_url_options[:script_name]
|
old_script_name = Rails.application.routes.default_url_options[:script_name]
|
||||||
|
@ -243,5 +251,21 @@ describe BlobHelper do
|
||||||
|
|
||||||
expect(helper.ide_edit_path(project, "testing/slashes", "readme.md/")).to eq("/-/ide/project/#{project.namespace.path}/#{project.path}/edit/testing/slashes/-/readme.md/")
|
expect(helper.ide_edit_path(project, "testing/slashes", "readme.md/")).to eq("/-/ide/project/#{project.namespace.path}/#{project.path}/edit/testing/slashes/-/readme.md/")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when user is not logged in' do
|
||||||
|
let(:current_user) { nil }
|
||||||
|
|
||||||
|
it 'returns IDE path inside the project' do
|
||||||
|
expect(helper.ide_edit_path(project, "master", "")).to eq("/-/ide/project/#{project.namespace.path}/#{project.path}/edit/master")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user cannot push to the project' do
|
||||||
|
let(:can_push_code) { false }
|
||||||
|
|
||||||
|
it "returns IDE path with the user's fork" do
|
||||||
|
expect(helper.ide_edit_path(project, "master", "")).to eq("/-/ide/project/#{current_user.namespace.full_path}/#{project.path}/edit/master")
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue