2019-07-25 01:21:37 -04:00
# frozen_string_literal: true
2015-12-30 20:18:40 -05:00
require 'spec_helper'
2020-06-24 14:09:03 -04:00
RSpec . describe Gitlab :: Diff :: Highlight do
2015-12-30 20:18:40 -05:00
include RepoHelpers
2021-05-06 08:10:38 -04:00
let_it_be ( :project ) { create ( :project , :repository ) }
2015-12-30 20:18:40 -05:00
let ( :commit ) { project . commit ( sample_commit . id ) }
2016-07-27 13:00:34 -04:00
let ( :diff ) { commit . raw_diffs . first }
2016-06-20 12:51:48 -04:00
let ( :diff_file ) { Gitlab :: Diff :: File . new ( diff , diff_refs : commit . diff_refs , repository : project . repository ) }
2015-12-30 20:18:40 -05:00
2018-10-01 12:44:30 -04:00
shared_examples 'without inline diffs' do
let ( :code ) { '<h2 onmouseover="alert(2)">Test</h2>' }
before do
allow ( Gitlab :: Diff :: InlineDiff ) . to receive ( :for_lines ) . and_return ( [ ] )
allow_any_instance_of ( Gitlab :: Diff :: Line ) . to receive ( :text ) . and_return ( code )
end
it 'returns html escaped diff text' do
expect ( subject [ 1 ] . rich_text ) . to eq html_escape ( code )
expect ( subject [ 1 ] . rich_text ) . to be_html_safe
end
end
2016-01-19 08:52:41 -05:00
describe '#highlight' do
2016-01-29 13:37:17 -05:00
context " with a diff file " do
2017-07-25 13:09:00 -04:00
let ( :subject ) { described_class . new ( diff_file , repository : project . repository ) . highlight }
2015-12-30 20:18:40 -05:00
2016-08-11 11:30:18 -04:00
it 'returns Gitlab::Diff::Line elements' do
2016-01-29 13:37:17 -05:00
expect ( subject . first ) . to be_an_instance_of ( Gitlab :: Diff :: Line )
end
2016-01-12 17:49:11 -05:00
2016-08-11 11:30:18 -04:00
it 'does not modify "match" lines' do
2016-01-29 13:37:17 -05:00
expect ( subject [ 0 ] . text ) . to eq ( '@@ -6,12 +6,18 @@ module Popen' )
expect ( subject [ 22 ] . text ) . to eq ( '@@ -19,6 +25,7 @@ module Popen' )
end
2016-01-12 17:49:11 -05:00
2016-01-29 13:37:17 -05:00
it 'highlights and marks unchanged lines' do
2017-03-13 18:39:22 -04:00
code = %Q{ <span id="LC7" class="line" lang="ruby"> <span class="k">def</span> <span class="nf">popen</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="kp">nil</span><span class="p">)</span></span> \n }
2016-01-12 17:49:11 -05:00
2018-08-11 16:33:15 -04:00
expect ( subject [ 2 ] . rich_text ) . to eq ( code )
2016-01-29 13:37:17 -05:00
end
2016-01-12 17:49:11 -05:00
2016-01-29 13:37:17 -05:00
it 'highlights and marks removed lines' do
2017-03-13 18:39:22 -04:00
code = %Q{ -<span id="LC9" class="line" lang="ruby"> <span class="k">raise</span> <span class="s2">"System commands must be given as an array of strings"</span></span> \n }
2016-01-12 17:49:11 -05:00
2018-08-11 16:33:15 -04:00
expect ( subject [ 4 ] . rich_text ) . to eq ( code )
2016-01-29 13:37:17 -05:00
end
2015-12-30 21:44:12 -05:00
2016-01-29 13:37:17 -05:00
it 'highlights and marks added lines' do
2021-03-11 10:09:10 -05:00
code = %Q{ +<span id="LC9" class="line" lang="ruby"> <span class="k">raise</span> <span class="no"><span class="idiff left addition">RuntimeError</span></span><span class="p"><span class="idiff addition">,</span></span><span class="idiff right addition"> </span><span class="s2">"System commands must be given as an array of strings"</span></span> \n }
2015-12-31 01:05:52 -05:00
2018-08-11 16:33:15 -04:00
expect ( subject [ 5 ] . rich_text ) . to eq ( code )
2016-01-29 13:37:17 -05:00
end
2018-10-01 12:44:30 -04:00
2021-03-11 10:09:10 -05:00
context 'when introduce_marker_ranges is false' do
before do
stub_feature_flags ( introduce_marker_ranges : false )
end
it 'keeps the old bevavior (without mode classes)' do
code = %Q{ +<span id="LC9" class="line" lang="ruby"> <span class="k">raise</span> <span class="no"><span class="idiff left">RuntimeError</span></span><span class="p"><span class="idiff">,</span></span><span class="idiff right"> </span><span class="s2">"System commands must be given as an array of strings"</span></span> \n }
expect ( subject [ 5 ] . rich_text ) . to eq ( code )
end
2021-03-17 20:08:58 -04:00
context 'when use_marker_ranges feature flag is false too' do
it 'does not affect the result' do
code = %Q{ +<span id="LC9" class="line" lang="ruby"> <span class="k">raise</span> <span class="no"><span class="idiff left">RuntimeError</span></span><span class="p"><span class="idiff">,</span></span><span class="idiff right"> </span><span class="s2">"System commands must be given as an array of strings"</span></span> \n }
expect ( subject [ 5 ] . rich_text ) . to eq ( code )
end
end
2021-03-11 10:09:10 -05:00
end
2018-10-01 12:44:30 -04:00
context 'when no diff_refs' do
before do
allow ( diff_file ) . to receive ( :diff_refs ) . and_return ( nil )
end
context 'when no inline diffs' do
it_behaves_like 'without inline diffs'
end
end
2016-01-08 18:40:05 -05:00
end
2016-01-29 13:37:17 -05:00
2016-01-30 06:53:12 -05:00
context " with diff lines " do
2017-07-25 13:09:00 -04:00
let ( :subject ) { described_class . new ( diff_file . diff_lines , repository : project . repository ) . highlight }
2016-01-29 13:37:17 -05:00
2016-08-11 11:30:18 -04:00
it 'returns Gitlab::Diff::Line elements' do
2016-01-30 06:53:12 -05:00
expect ( subject . first ) . to be_an_instance_of ( Gitlab :: Diff :: Line )
end
2016-01-29 13:37:17 -05:00
2016-08-11 11:30:18 -04:00
it 'does not modify "match" lines' do
2016-01-30 06:53:12 -05:00
expect ( subject [ 0 ] . text ) . to eq ( '@@ -6,12 +6,18 @@ module Popen' )
expect ( subject [ 22 ] . text ) . to eq ( '@@ -19,6 +25,7 @@ module Popen' )
end
2016-01-29 13:37:17 -05:00
2016-01-30 06:53:12 -05:00
it 'marks unchanged lines' do
2017-02-22 17:39:43 -05:00
code = %q{ def popen(cmd, path=nil) }
2016-01-29 13:37:17 -05:00
2016-01-30 06:53:12 -05:00
expect ( subject [ 2 ] . text ) . to eq ( code )
expect ( subject [ 2 ] . text ) . not_to be_html_safe
end
2016-01-29 13:37:17 -05:00
2016-01-30 06:53:12 -05:00
it 'marks removed lines' do
2017-02-22 17:39:43 -05:00
code = %q{ - raise "System commands must be given as an array of strings" }
2016-01-29 13:37:17 -05:00
2016-01-30 06:53:12 -05:00
expect ( subject [ 4 ] . text ) . to eq ( code )
expect ( subject [ 4 ] . text ) . not_to be_html_safe
end
2016-01-29 13:37:17 -05:00
2016-01-30 06:53:12 -05:00
it 'marks added lines' do
2021-03-11 10:09:10 -05:00
code = %q{ + raise <span class="idiff left right addition">RuntimeError, </span>"System commands must be given as an array of strings" }
2016-01-29 13:37:17 -05:00
2018-08-11 16:33:15 -04:00
expect ( subject [ 5 ] . rich_text ) . to eq ( code )
expect ( subject [ 5 ] . rich_text ) . to be_html_safe
2016-01-29 13:37:17 -05:00
end
2018-02-21 08:42:11 -05:00
context 'when the inline diff marker has an invalid range' do
before do
allow_any_instance_of ( Gitlab :: Diff :: InlineDiffMarker ) . to receive ( :mark ) . and_raise ( RangeError )
end
it 'keeps the original rich line' do
2019-12-16 07:07:43 -05:00
allow ( Gitlab :: ErrorTracking ) . to receive ( :track_and_raise_for_dev_exception )
2018-04-13 12:32:54 -04:00
2018-02-21 08:42:11 -05:00
code = %q{ + raise RuntimeError, "System commands must be given as an array of strings" }
expect ( subject [ 5 ] . text ) . to eq ( code )
expect ( subject [ 5 ] . text ) . not_to be_html_safe
end
it 'reports to Sentry if configured' do
2019-12-16 07:07:43 -05:00
expect ( Gitlab :: ErrorTracking ) . to receive ( :track_and_raise_for_dev_exception ) . and_call_original
2018-02-21 08:42:11 -05:00
2018-04-13 12:32:54 -04:00
expect { subject } . to raise_exception ( RangeError )
2018-02-21 08:42:11 -05:00
end
end
2018-10-01 12:44:30 -04:00
2021-03-17 20:08:58 -04:00
context 'when `use_marker_ranges` feature flag is disabled' do
it 'returns the same result' do
with_feature_flag = described_class . new ( diff_file , repository : project . repository ) . highlight
stub_feature_flags ( use_marker_ranges : false )
without_feature_flag = described_class . new ( diff_file , repository : project . repository ) . highlight
expect ( with_feature_flag . map ( & :rich_text ) ) . to eq ( without_feature_flag . map ( & :rich_text ) )
end
end
2018-10-01 12:44:30 -04:00
context 'when no inline diffs' do
it_behaves_like 'without inline diffs'
end
2016-01-30 06:53:12 -05:00
end
2021-05-06 08:10:38 -04:00
context 'when blob is too large' do
let ( :subject ) { described_class . new ( diff_file , repository : project . repository ) . highlight }
before do
allow ( Gitlab :: Highlight ) . to receive ( :too_large? ) . and_return ( true )
end
it 'blobs are highlighted as plain text without loading all data' do
expect ( diff_file . blob ) . not_to receive ( :load_all_data! )
expect ( subject [ 2 ] . rich_text ) . to eq ( %Q{ <span id="LC7" class="line" lang=""> def popen(cmd, path=nil)</span> \n } )
expect ( subject [ 2 ] . rich_text ) . to be_html_safe
end
context 'when limited_diff_highlighting is disabled' do
before do
stub_feature_flags ( limited_diff_highlighting : false )
stub_feature_flags ( diff_line_syntax_highlighting : false )
end
it 'blobs are highlighted as plain text with loading all data' do
expect ( diff_file . blob ) . to receive ( :load_all_data! ) . twice
code = %Q{ <span id="LC7" class="line" lang=""> def popen(cmd, path=nil)</span> \n }
expect ( subject [ 2 ] . rich_text ) . to eq ( code )
end
end
end
2015-12-30 20:18:40 -05:00
end
end