2019-10-12 21:52:04 +05:30
# frozen_string_literal: true
2019-12-04 20:38:33 +05:30
require 'spec_helper'
2018-03-17 18:26:18 +05:30
2023-03-17 16:20:25 +05:30
RSpec . describe 'Merge request > User sees diff' , :js , feature_category : :code_review_workflow do
2018-03-17 18:26:18 +05:30
include ProjectForksHelper
2018-11-08 19:23:39 +05:30
include RepoHelpers
2022-04-04 11:22:00 +05:30
include MergeRequestDiffHelpers
2016-08-24 12:49:21 +05:30
2017-09-10 17:25:29 +05:30
let ( :project ) { create ( :project , :public , :repository ) }
2017-08-17 22:00:37 +05:30
let ( :merge_request ) { create ( :merge_request , source_project : project ) }
2016-08-24 12:49:21 +05:30
2017-08-17 22:00:37 +05:30
context 'when linking to note' do
describe 'with unresolved note' do
let ( :note ) { create :diff_note_on_merge_request , project : project , noteable : merge_request }
let ( :fragment ) { " # note_ #{ note . id } " }
before do
2017-09-10 17:25:29 +05:30
visit " #{ diffs_project_merge_request_path ( project , merge_request ) } #{ fragment } "
2017-08-17 22:00:37 +05:30
end
it 'shows expanded note' do
expect ( page ) . to have_selector ( fragment , visible : true )
end
end
describe 'with resolved note' do
let ( :note ) { create :diff_note_on_merge_request , :resolved , project : project , noteable : merge_request }
let ( :fragment ) { " # note_ #{ note . id } " }
before do
2017-09-10 17:25:29 +05:30
visit " #{ diffs_project_merge_request_path ( project , merge_request ) } #{ fragment } "
2017-08-17 22:00:37 +05:30
end
2023-04-23 21:23:45 +05:30
it 'shows expanded note' , quarantine : 'https://gitlab.com/gitlab-org/gitlab/-/issues/391239' do
2017-08-17 22:00:37 +05:30
expect ( page ) . to have_selector ( fragment , visible : true )
end
end
end
2023-01-13 00:05:48 +05:30
context 'when linking to a line' do
let ( :note ) { create :diff_note_on_merge_request , project : project , noteable : merge_request }
let ( :line ) { note . diff_file . highlighted_diff_lines . last }
let ( :line_code ) { line . line_code }
before do
visit " #{ diffs_project_merge_request_path ( project , merge_request ) } # #{ line_code } "
end
it 'shows the linked line' do
expect ( page ) . to have_selector ( " [id=' #{ line_code } '] " , visible : true , obscured : false )
end
end
2017-08-17 22:00:37 +05:30
context 'when merge request has overflow' do
it 'displays warning' do
allow ( Commit ) . to receive ( :max_diff_options ) . and_return ( max_files : 3 )
2018-11-08 19:23:39 +05:30
allow_any_instance_of ( DiffHelper ) . to receive ( :render_overflow_warning? ) . and_return ( true )
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
visit diffs_project_merge_request_path ( project , merge_request )
2017-08-17 22:00:37 +05:30
2022-05-07 20:08:51 +05:30
page . within ( '.gl-alert' ) do
2023-06-20 00:43:36 +05:30
expect ( page ) . to have_text ( " Some changes are not shown. For a faster browsing experience, only 3 of 3+ files are shown. Download one of the files below to see all changes. Plain diff Patches " )
2017-08-17 22:00:37 +05:30
end
end
end
context 'when editing file' do
let ( :author_user ) { create ( :user ) }
let ( :user ) { create ( :user ) }
2018-03-17 18:26:18 +05:30
let ( :forked_project ) { fork_project ( project , author_user , repository : true ) }
2017-08-17 22:00:37 +05:30
let ( :merge_request ) { create ( :merge_request_with_diffs , source_project : forked_project , target_project : project , author : author_user ) }
let ( :changelog_id ) { Digest :: SHA1 . hexdigest ( " CHANGELOG " ) }
context 'as author' do
2022-04-04 11:22:00 +05:30
it 'contains direct edit link' , :sidekiq_might_not_need_inline do
2017-09-10 17:25:29 +05:30
sign_in ( author_user )
visit diffs_project_merge_request_path ( project , merge_request )
2017-08-17 22:00:37 +05:30
# Throws `Capybara::Poltergeist::InvalidSelector` if we try to use `#hash` syntax
2022-04-04 11:22:00 +05:30
expect ( page ) . to have_selector ( " .js-edit-blob " , visible : false )
2017-08-17 22:00:37 +05:30
end
end
context 'as user who needs to fork' do
2022-05-07 20:08:51 +05:30
it 'shows fork/cancel confirmation' , :sidekiq_might_not_need_inline , quarantine : 'https://gitlab.com/gitlab-org/gitlab/-/issues/337477' do
2017-09-10 17:25:29 +05:30
sign_in ( user )
visit diffs_project_merge_request_path ( project , merge_request )
2017-08-17 22:00:37 +05:30
2022-04-04 11:22:00 +05:30
find_by_scrolling ( " [id= \" #{ changelog_id } \" ] " )
2017-08-17 22:00:37 +05:30
# Throws `Capybara::Poltergeist::InvalidSelector` if we try to use `#hash` syntax
2021-01-03 14:25:43 +05:30
find ( " [id= \" #{ changelog_id } \" ] .js-diff-more-actions " ) . click
2017-08-17 22:00:37 +05:30
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
2018-11-08 19:23:39 +05:30
context 'when file contains html' do
2022-04-04 11:22:00 +05:30
let ( :current_user ) { project . first_owner }
2022-08-27 11:52:29 +05:30
let ( :branch_name ) { " test_branch " }
2018-11-08 19:23:39 +05:30
it 'escapes any HTML special characters in the diff chunk header' do
file_content =
<< ~ CONTENT
2018-11-20 20:47:30 +05:30
function foo < input > {
let a = 1 ;
let b = 2 ;
let c = 3 ;
let d = 3 ;
2018-11-08 19:23:39 +05:30
}
2020-11-24 15:15:51 +05:30
CONTENT
2018-11-08 19:23:39 +05:30
new_file_content =
<< ~ CONTENT
2018-11-20 20:47:30 +05:30
function foo < input > {
let a = 1 ;
let b = 2 ;
let c = 3 ;
let x = 3 ;
2018-11-08 19:23:39 +05:30
}
2020-11-24 15:15:51 +05:30
CONTENT
2018-11-08 19:23:39 +05:30
2018-11-20 20:47:30 +05:30
file_name = 'xss_file.rs'
2022-04-04 11:22:00 +05:30
file_hash = Digest :: SHA1 . hexdigest ( file_name )
2018-11-08 19:23:39 +05:30
create_file ( 'master' , file_name , file_content )
merge_request = create ( :merge_request , source_project : project )
create_file ( merge_request . source_branch , file_name , new_file_content )
project . commit ( merge_request . source_branch )
visit diffs_project_merge_request_path ( project , merge_request )
2022-04-04 11:22:00 +05:30
find_by_scrolling ( " [id=' #{ file_hash } '] " )
2018-11-08 19:23:39 +05:30
expect ( page ) . to have_text ( " function foo<input> { " )
2018-11-20 20:47:30 +05:30
expect ( page ) . to have_css ( " .line[lang='rust'] .k " )
2018-11-08 19:23:39 +05:30
end
end
2019-02-15 15:39:39 +05:30
context 'when file is stored in LFS' do
let ( :merge_request ) { create ( :merge_request , source_project : project ) }
2022-04-04 11:22:00 +05:30
let ( :current_user ) { project . first_owner }
2019-02-15 15:39:39 +05:30
context 'when LFS is enabled on the project' do
before do
allow ( Gitlab . config . lfs ) . to receive ( :enabled ) . and_return ( true )
project . update_attribute ( :lfs_enabled , true )
create_file ( 'master' , file_name , project . repository . blob_at ( 'master' , 'files/lfs/lfs_object.iso' ) . data )
visit diffs_project_merge_request_path ( project , merge_request )
end
context 'when file is an image' , :js do
2022-04-04 11:22:00 +05:30
let ( :file_name ) { 'a/image.png' }
2019-02-15 15:39:39 +05:30
it 'shows an error message' do
expect ( page ) . not_to have_content ( 'could not be displayed because it is stored in LFS' )
end
end
context 'when file is not an image' do
2022-04-04 11:22:00 +05:30
let ( :file_name ) { 'a/ruby.rb' }
2019-02-15 15:39:39 +05:30
it 'shows an error message' do
expect ( page ) . to have_content ( 'This source diff could not be displayed because it is stored in LFS' )
end
end
end
context 'when LFS is not enabled' do
2022-04-04 11:22:00 +05:30
let ( :file_name ) { 'a/lfs_object.iso' }
2019-02-15 15:39:39 +05:30
before do
2022-04-04 11:22:00 +05:30
allow ( Gitlab . config . lfs ) . to receive ( :disabled ) . and_return ( true )
project . update_attribute ( :lfs_enabled , false )
create_file ( 'master' , file_name , project . repository . blob_at ( 'master' , 'files/lfs/lfs_object.iso' ) . data )
2019-02-15 15:39:39 +05:30
visit diffs_project_merge_request_path ( project , merge_request )
end
it 'displays the diff' do
expect ( page ) . to have_content ( 'size 1575078' )
end
end
end
def create_file ( branch_name , file_name , content )
Files :: CreateService . new (
project ,
current_user ,
start_branch : branch_name ,
branch_name : branch_name ,
commit_message : " Create file " ,
file_path : file_name ,
file_content : content
) . execute
project . commit ( branch_name )
end
2017-08-17 22:00:37 +05:30
end
2016-08-24 12:49:21 +05:30
end