diff --git a/app/assets/javascripts/merge_request_tabs.js b/app/assets/javascripts/merge_request_tabs.js index f7f6a773036d26213695d026146777882a4b1cc3..6075157ec31c2d922eb1e59e26a19cab004103a9 100644 --- a/app/assets/javascripts/merge_request_tabs.js +++ b/app/assets/javascripts/merge_request_tabs.js @@ -5,6 +5,7 @@ import Cookies from 'js-cookie'; import './breakpoints'; import './flash'; +import BlobForkSuggestion from './blob/blob_fork_suggestion'; /* eslint-disable max-len */ // MergeRequestTabs @@ -266,6 +267,16 @@ import './flash'; new gl.Diff(); this.scrollToElement('#diffs'); + + $('.diff-file').each((i, el) => { + new BlobForkSuggestion({ + openButtons: $(el).find('.js-edit-blob-link-fork-toggler'), + forkButtons: $(el).find('.js-fork-suggestion-button'), + cancelButtons: $(el).find('.js-cancel-fork-suggestion-button'), + suggestionSections: $(el).find('.js-file-fork-suggestion-section'), + actionTextPieces: $(el).find('.js-file-fork-suggestion-section-action'), + }); + }); }, }); } diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb index 3736e1ffcbb6716481f3eb1121c8b1609d1303c9..36b16421e8f0788026ab67d9dbe63f43861e9e7c 100644 --- a/app/helpers/blob_helper.rb +++ b/app/helpers/blob_helper.rb @@ -29,7 +29,7 @@ module BlobHelper link_to 'Edit', edit_path(project, ref, path, options), class: "#{common_classes} btn-sm" elsif current_user && can?(current_user, :fork_project, project) continue_params = { - to: edit_path, + to: edit_path(project, ref, path, options), notice: edit_in_new_fork_notice, notice_now: edit_in_new_fork_notice_now } diff --git a/app/views/projects/_fork_suggestion.html.haml b/app/views/projects/_fork_suggestion.html.haml new file mode 100644 index 0000000000000000000000000000000000000000..c855bfaf06789ad1d94a516541657b7e3f24d2b4 --- /dev/null +++ b/app/views/projects/_fork_suggestion.html.haml @@ -0,0 +1,11 @@ +- if current_user + .js-file-fork-suggestion-section.file-fork-suggestion.hidden + %span.file-fork-suggestion-note + You're not allowed to + %span.js-file-fork-suggestion-section-action + edit + files in this project directly. Please fork this project, + make your changes there, and submit a merge request. + = link_to 'Fork', nil, method: :post, class: 'js-fork-suggestion-button btn btn-grouped btn-inverted btn-new' + %button.js-cancel-fork-suggestion-button.btn.btn-grouped{ type: 'button' } + Cancel diff --git a/app/views/projects/blob/_header.html.haml b/app/views/projects/blob/_header.html.haml index d46e453449724e092c9294dbc178dc735391cb7a..c553db84ee0f7546ba857aec833a00242252d96e 100644 --- a/app/views/projects/blob/_header.html.haml +++ b/app/views/projects/blob/_header.html.haml @@ -39,14 +39,4 @@ = replace_blob_link = delete_blob_link -- if current_user - .js-file-fork-suggestion-section.file-fork-suggestion.hidden - %span.file-fork-suggestion-note - You're not allowed to - %span.js-file-fork-suggestion-section-action - edit - files in this project directly. Please fork this project, - make your changes there, and submit a merge request. - = link_to 'Fork', nil, method: :post, class: 'js-fork-suggestion-button btn btn-grouped btn-inverted btn-new' - %button.js-cancel-fork-suggestion-button.btn.btn-grouped{ type: 'button' } - Cancel += render 'projects/fork_suggestion' diff --git a/app/views/projects/diffs/_file.html.haml b/app/views/projects/diffs/_file.html.haml index 0232a09b4a80792d5ab99de46c0974f94fb2f498..4622b9807549c7fd42a9b7f838c8d3d5ac025e84 100644 --- a/app/views/projects/diffs/_file.html.haml +++ b/app/views/projects/diffs/_file.html.haml @@ -18,4 +18,6 @@ = view_file_button(diff_commit.id, diff_file.new_path, project) = view_on_environment_button(diff_commit.id, diff_file.new_path, environment) if environment + = render 'projects/fork_suggestion' + = render 'projects/diffs/content', diff_file: diff_file, diff_commit: diff_commit, blob: blob, project: project diff --git a/spec/features/merge_requests/diffs_spec.rb b/spec/features/merge_requests/diffs_spec.rb index 4a6c76a5caf906d9182f7e5f951c5be8db2aac41..32a6a4b26820bb7a62a0b84250a54d5351699798 100644 --- a/spec/features/merge_requests/diffs_spec.rb +++ b/spec/features/merge_requests/diffs_spec.rb @@ -1,11 +1,13 @@ require 'spec_helper' feature 'Diffs URL', js: true, feature: true do - before do - login_as :admin - @merge_request = create(:merge_request) - @project = @merge_request.source_project - end + include ApplicationHelper + + let(:author_user) { create(:user) } + let(:user) { create(:user) } + let(:project) { create(:project, :public) } + let(:forked_project) { Projects::ForkService.new(project, author_user).execute } + let(:merge_request) { create(:merge_request_with_diffs, source_project: forked_project, target_project: project, author: author_user) } context 'when visit with */* as accept header' do before(:each) do @@ -13,9 +15,9 @@ feature 'Diffs URL', js: true, feature: true do end it 'renders the notes' do - create :note_on_merge_request, project: @project, noteable: @merge_request, note: 'Rebasing with master' + create :note_on_merge_request, project: project, noteable: merge_request, note: 'Rebasing with master' - visit diffs_namespace_project_merge_request_path(@project.namespace, @project, @merge_request) + visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request) # Load notes and diff through AJAX expect(page).to have_css('.note-text', visible: false, text: 'Rebasing with master') @@ -28,11 +30,38 @@ feature 'Diffs URL', js: true, feature: true do allow_any_instance_of(MergeRequestDiff).to receive(:overflow?).and_return(true) allow(Commit).to receive(:max_diff_options).and_return(max_files: 20, max_lines: 20) - visit diffs_namespace_project_merge_request_path(@project.namespace, @project, @merge_request) + visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request) page.within('.alert') do expect(page).to have_text("Too many changes to show. Plain diff Email patch To preserve - performance only 3 of 3+ files are displayed.") + performance only 3 of 3 files are displayed.") + end + end + end + + describe 'when editing file' do + let(:changelog_id) { hexdigest("CHANGELOG") } + + context 'as author' do + it 'shows direct edit link' do + login_as(author_user) + visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request) + + # Throws `Capybara::Poltergeist::InvalidSelector` if we try to use `#hash` syntax + expect(page).to have_selector("[id=\"#{changelog_id}\"] a.js-edit-blob") + end + end + + context 'as user who needs to fork' do + it 'shows fork/cancel confirmation' do + login_as(user) + visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request) + + # Throws `Capybara::Poltergeist::InvalidSelector` if we try to use `#hash` syntax + find("[id=\"#{changelog_id}\"] .js-edit-blob").click + + expect(page).to have_selector('.js-fork-suggestion-button', count: 1) + expect(page).to have_selector('.js-cancel-fork-suggestion-button', count: 1) end end end