diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-08-20 18:42:06 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-08-20 18:42:06 +0000 |
commit | 6e4e1050d9dba2b7b2523fdd1768823ab85feef4 (patch) | |
tree | 78be5963ec075d80116a932011d695dd33910b4e /spec/lib/banzai | |
parent | 1ce776de4ae122aba3f349c02c17cebeaa8ecf07 (diff) | |
download | gitlab-ce-6e4e1050d9dba2b7b2523fdd1768823ab85feef4.tar.gz |
Add latest changes from gitlab-org/gitlab@13-3-stable-ee
Diffstat (limited to 'spec/lib/banzai')
17 files changed, 145 insertions, 157 deletions
diff --git a/spec/lib/banzai/filter/absolute_link_filter_spec.rb b/spec/lib/banzai/filter/absolute_link_filter_spec.rb index 2cb70850dca..0c159e8bac8 100644 --- a/spec/lib/banzai/filter/absolute_link_filter_spec.rb +++ b/spec/lib/banzai/filter/absolute_link_filter_spec.rb @@ -12,6 +12,7 @@ RSpec.describe Banzai::Filter::AbsoluteLinkFilter do let(:only_path_context) do { only_path: false } end + let(:fake_url) { 'http://www.example.com' } before do diff --git a/spec/lib/banzai/filter/ascii_doc_post_processing_filter_spec.rb b/spec/lib/banzai/filter/ascii_doc_post_processing_filter_spec.rb index 334d5c59828..7af22ea7db1 100644 --- a/spec/lib/banzai/filter/ascii_doc_post_processing_filter_spec.rb +++ b/spec/lib/banzai/filter/ascii_doc_post_processing_filter_spec.rb @@ -10,6 +10,12 @@ RSpec.describe Banzai::Filter::AsciiDocPostProcessingFilter do expect(result).to eq('<pre data-math-style="inline" class="code math js-render-math">some code</pre><div data-math>and</div>') end + it "adds class for elements with data-mermaid-style" do + result = filter('<pre data-mermaid-style="display">some code</pre>').to_html + + expect(result).to eq('<pre data-mermaid-style="display" class="js-render-mermaid">some code</pre>') + end + it "keeps content when no data-math-style found" do result = filter('<pre>some code</pre><div data-math>and</div>').to_html expect(result).to eq('<pre>some code</pre><div data-math>and</div>') diff --git a/spec/lib/banzai/filter/gollum_tags_filter_spec.rb b/spec/lib/banzai/filter/gollum_tags_filter_spec.rb index 2576dd1bf07..f39b5280490 100644 --- a/spec/lib/banzai/filter/gollum_tags_filter_spec.rb +++ b/spec/lib/banzai/filter/gollum_tags_filter_spec.rb @@ -6,8 +6,7 @@ RSpec.describe Banzai::Filter::GollumTagsFilter do include FilterSpecHelper let(:project) { create(:project) } - let(:user) { double } - let(:wiki) { ProjectWiki.new(project, user) } + let(:wiki) { ProjectWiki.new(project, nil) } describe 'validation' do it 'ensure that a :wiki key exists in context' do diff --git a/spec/lib/banzai/filter/inline_alert_metrics_filter_spec.rb b/spec/lib/banzai/filter/inline_alert_metrics_filter_spec.rb new file mode 100644 index 00000000000..be40195f001 --- /dev/null +++ b/spec/lib/banzai/filter/inline_alert_metrics_filter_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Banzai::Filter::InlineAlertMetricsFilter do + include FilterSpecHelper + + let(:params) { ['foo', 'bar', 12] } + let(:query_params) { {} } + + let(:trigger_url) { urls.metrics_dashboard_namespace_project_prometheus_alert_url(*params, query_params) } + let(:dashboard_url) { urls.metrics_dashboard_namespace_project_prometheus_alert_url(*params, **query_params, embedded: true, format: :json) } + + it_behaves_like 'a metrics embed filter' + + context 'with query params specified' do + let(:query_params) { { timestamp: 'yesterday' } } + + it_behaves_like 'a metrics embed filter' + end +end diff --git a/spec/lib/banzai/filter/inline_metrics_redactor_filter_spec.rb b/spec/lib/banzai/filter/inline_metrics_redactor_filter_spec.rb index cafcaef8ae2..5f66844f498 100644 --- a/spec/lib/banzai/filter/inline_metrics_redactor_filter_spec.rb +++ b/spec/lib/banzai/filter/inline_metrics_redactor_filter_spec.rb @@ -74,5 +74,20 @@ RSpec.describe Banzai::Filter::InlineMetricsRedactorFilter do end end end + + context 'for an alert embed' do + let_it_be(:alert) { create(:prometheus_alert, project: project) } + let(:url) do + urls.metrics_dashboard_project_prometheus_alert_url( + project, + alert.prometheus_metric_id, + environment_id: alert.environment_id, + embedded: true + ) + end + + it_behaves_like 'redacts the embed placeholder' + it_behaves_like 'retains the embed placeholder when applicable' + end end end diff --git a/spec/lib/banzai/filter/label_reference_filter_spec.rb b/spec/lib/banzai/filter/label_reference_filter_spec.rb index dadf98d9b76..726ef8c57ab 100644 --- a/spec/lib/banzai/filter/label_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/label_reference_filter_spec.rb @@ -31,6 +31,19 @@ RSpec.describe Banzai::Filter::LabelReferenceFilter do expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-label has-tooltip gl-link gl-label-link' end + it 'avoids N+1 cached queries', :use_sql_query_cache, :request_store do + # Run this once to establish a baseline + reference_filter("Label #{reference}") + + control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) do + reference_filter("Label #{reference}") + end + + labels_markdown = Array.new(10, "Label #{reference}").join('\n') + + expect { reference_filter(labels_markdown) }.not_to exceed_all_query_limit(control_count.count) + end + it 'includes a data-project attribute' do doc = reference_filter("Label #{reference}") link = doc.css('a').first diff --git a/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb b/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb index f24fcf98b1f..df78a3321ba 100644 --- a/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb @@ -220,6 +220,7 @@ RSpec.describe Banzai::Filter::MergeRequestReferenceFilter do let(:reference) do urls.project_merge_request_url(mr.project, mr) + "/diffs?commit_id=#{mr.diff_head_sha}" end + let(:commit) { mr.commits.find { |commit| commit.sha == mr.diff_head_sha } } it 'links to a valid reference' do diff --git a/spec/lib/banzai/filter/reference_filter_spec.rb b/spec/lib/banzai/filter/reference_filter_spec.rb index d5978db13c0..2888965dbc4 100644 --- a/spec/lib/banzai/filter/reference_filter_spec.rb +++ b/spec/lib/banzai/filter/reference_filter_spec.rb @@ -110,20 +110,6 @@ RSpec.describe Banzai::Filter::ReferenceFilter do expect(filter.instance_variable_get(:@new_nodes)).to eq({ index => [filter.each_node.to_a[index]] }) end - - context "with update_nodes_for_banzai_reference_filter feature flag disabled" do - before do - stub_feature_flags(update_nodes_for_banzai_reference_filter: false) - end - - it 'does not call replace_and_update_new_nodes' do - expect(filter).not_to receive(:replace_and_update_new_nodes).with(filter.nodes[index], index, html) - - filter.send(method_name, *args) do - html - end - end - end end end @@ -198,49 +184,20 @@ RSpec.describe Banzai::Filter::ReferenceFilter do end describe "#call_and_update_nodes" do - context "with update_nodes_for_banzai_reference_filter feature flag enabled" do - include_context 'new nodes' - let(:document) { Nokogiri::HTML.fragment('<a href="foo">foo</a>') } - let(:filter) { described_class.new(document, project: project) } - - before do - stub_feature_flags(update_nodes_for_banzai_reference_filter: true) - end - - it "updates all new nodes", :aggregate_failures do - filter.instance_variable_set('@nodes', nodes) - - expect(filter).to receive(:call) { filter.instance_variable_set('@new_nodes', new_nodes) } - expect(filter).to receive(:with_update_nodes).and_call_original - expect(filter).to receive(:update_nodes!).and_call_original - - filter.call_and_update_nodes - - expect(filter.result[:reference_filter_nodes]).to eq(expected_nodes) - end - end - - context "with update_nodes_for_banzai_reference_filter feature flag disabled" do - include_context 'new nodes' - - before do - stub_feature_flags(update_nodes_for_banzai_reference_filter: false) - end + include_context 'new nodes' + let(:document) { Nokogiri::HTML.fragment('<a href="foo">foo</a>') } + let(:filter) { described_class.new(document, project: project) } - it "does not change nodes", :aggregate_failures do - document = Nokogiri::HTML.fragment('<a href="foo">foo</a>') - filter = described_class.new(document, project: project) - filter.instance_variable_set('@nodes', nodes) + it "updates all new nodes", :aggregate_failures do + filter.instance_variable_set('@nodes', nodes) - expect(filter).to receive(:call) { filter.instance_variable_set('@new_nodes', new_nodes) } - expect(filter).not_to receive(:with_update_nodes) - expect(filter).not_to receive(:update_nodes!) + expect(filter).to receive(:call) { filter.instance_variable_set('@new_nodes', new_nodes) } + expect(filter).to receive(:with_update_nodes).and_call_original + expect(filter).to receive(:update_nodes!).and_call_original - filter.call_and_update_nodes + filter.call_and_update_nodes - expect(filter.nodes).to eq(nodes) - expect(filter.result[:reference_filter_nodes]).to be nil - end + expect(filter.result[:reference_filter_nodes]).to eq(expected_nodes) end end @@ -251,10 +208,6 @@ RSpec.describe Banzai::Filter::ReferenceFilter do let(:result) { { reference_filter_nodes: nodes } } - before do - stub_feature_flags(update_nodes_for_banzai_reference_filter: true) - end - it "updates all nodes", :aggregate_failures do expect_next_instance_of(described_class) do |filter| expect(filter).to receive(:call_and_update_nodes).and_call_original @@ -267,26 +220,5 @@ RSpec.describe Banzai::Filter::ReferenceFilter do expect(result[:reference_filter_nodes]).to eq(expected_nodes) end - - context "with update_nodes_for_banzai_reference_filter feature flag disabled" do - let(:result) { {} } - - before do - stub_feature_flags(update_nodes_for_banzai_reference_filter: false) - end - - it "updates all nodes", :aggregate_failures do - expect_next_instance_of(described_class) do |filter| - expect(filter).to receive(:call_and_update_nodes).and_call_original - expect(filter).not_to receive(:with_update_nodes) - expect(filter).to receive(:call) { filter.instance_variable_set('@new_nodes', new_nodes) } - expect(filter).not_to receive(:update_nodes!) - end - - described_class.call(document, { project: project }, result) - - expect(result[:reference_filter_nodes]).to be nil - end - end end end diff --git a/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb b/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb index a2875fad421..78f84ee44f7 100644 --- a/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb +++ b/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb @@ -26,6 +26,14 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do include_examples "XSS prevention", "" end + context "when contains mermaid diagrams" do + it "ignores mermaid blocks" do + result = filter('<pre data-mermaid-style="display"><code>mermaid code</code></pre>') + + expect(result.to_html).to eq('<pre data-mermaid-style="display"><code>mermaid code</code></pre>') + end + end + context "when a valid language is specified" do it "highlights as that language" do result = filter('<pre><code lang="ruby">def fun end</code></pre>') diff --git a/spec/lib/banzai/filter/wiki_link_filter_spec.rb b/spec/lib/banzai/filter/wiki_link_filter_spec.rb index 7a4464a2604..d1f6ee49260 100644 --- a/spec/lib/banzai/filter/wiki_link_filter_spec.rb +++ b/spec/lib/banzai/filter/wiki_link_filter_spec.rb @@ -7,8 +7,7 @@ RSpec.describe Banzai::Filter::WikiLinkFilter do let(:namespace) { build_stubbed(:namespace, name: "wiki_link_ns") } let(:project) { build_stubbed(:project, :public, name: "wiki_link_project", namespace: namespace) } - let(:user) { double } - let(:wiki) { ProjectWiki.new(project, user) } + let(:wiki) { ProjectWiki.new(project, nil) } let(:repository_upload_folder) { Wikis::CreateAttachmentService::ATTACHMENT_PATH } it "doesn't rewrite absolute links" do diff --git a/spec/lib/banzai/issuable_extractor_spec.rb b/spec/lib/banzai/issuable_extractor_spec.rb index c4ee7160e12..8fec9691d7f 100644 --- a/spec/lib/banzai/issuable_extractor_spec.rb +++ b/spec/lib/banzai/issuable_extractor_spec.rb @@ -13,6 +13,7 @@ RSpec.describe Banzai::IssuableExtractor do "<a href='' data-issue='#{issue.id}' data-reference-type='issue' class='gfm'>text</a>" ) end + let(:merge_request_link) do html_to_node( "<a href='' data-merge-request='#{merge_request.id}' data-reference-type='merge_request' class='gfm'>text</a>" diff --git a/spec/lib/banzai/object_renderer_spec.rb b/spec/lib/banzai/object_renderer_spec.rb index f8d7acd3148..e64ab5dfce3 100644 --- a/spec/lib/banzai/object_renderer_spec.rb +++ b/spec/lib/banzai/object_renderer_spec.rb @@ -73,6 +73,7 @@ RSpec.describe Banzai::ObjectRenderer do end end end + let(:cacheless_thing) do cacheless_class.new.tap do |thing| thing.title = "Merge branch 'branch-merged' into 'master'" diff --git a/spec/lib/banzai/pipeline/full_pipeline_spec.rb b/spec/lib/banzai/pipeline/full_pipeline_spec.rb index 0127ac11c81..9391ca386cf 100644 --- a/spec/lib/banzai/pipeline/full_pipeline_spec.rb +++ b/spec/lib/banzai/pipeline/full_pipeline_spec.rb @@ -109,6 +109,7 @@ RSpec.describe Banzai::Pipeline::FullPipeline do # Header MARKDOWN end + let(:invalid_markdown) do <<-MARKDOWN.strip_heredoc test [[_TOC_]] diff --git a/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb b/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb index beb760637b0..247f4591632 100644 --- a/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb +++ b/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb @@ -30,34 +30,6 @@ RSpec.describe Banzai::Pipeline::GfmPipeline do described_class.call(markdown, project: project) end - context "with update_nodes_for_banzai_reference_filter feature flag disabled" do - before do - stub_feature_flags(update_nodes_for_banzai_reference_filter: false) - end - - context 'when shorthand pattern #ISSUE_ID is used' do - it 'links an internal issues and doesnt store nodes in result[:reference_filter_nodes]', :aggregate_failures do - issue = create(:issue, project: project) - markdown = "text #{issue.to_reference(project, full: true)}" - result = described_class.call(markdown, project: project) - link = result[:output].css('a').first - - expect(link['href']).to eq(Gitlab::Routing.url_helpers.project_issue_path(project, issue)) - expect(result[:reference_filter_nodes]).to eq nil - end - end - - it 'execute :each_node for each reference_filter', :aggregate_failures do - issue = create(:issue, project: project) - markdown = "text #{issue.to_reference(project, full: true)}" - described_class.reference_filters do |reference_filter| - expect_any_instance_of(reference_filter).to receive(:each_node).once - end - - described_class.call(markdown, project: project) - end - end - context 'when shorthand pattern #ISSUE_ID is used' do it 'links an internal issue if it exists' do issue = create(:issue, project: project) diff --git a/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb b/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb index 4af782c7d73..b102de24041 100644 --- a/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb +++ b/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe Banzai::Pipeline::WikiPipeline do let_it_be(:namespace) { create(:namespace, name: "wiki_link_ns") } let_it_be(:project) { create(:project, :public, name: "wiki_link_project", namespace: namespace) } - let_it_be(:wiki) { ProjectWiki.new(project, double(:user)) } + let_it_be(:wiki) { ProjectWiki.new(project, nil) } let_it_be(:page) { build(:wiki_page, wiki: wiki, title: 'nested/twice/start-page') } describe 'TableOfContents' do diff --git a/spec/lib/banzai/reference_parser/base_parser_spec.rb b/spec/lib/banzai/reference_parser/base_parser_spec.rb index 0eea51262ba..5ab76b2c68b 100644 --- a/spec/lib/banzai/reference_parser/base_parser_spec.rb +++ b/spec/lib/banzai/reference_parser/base_parser_spec.rb @@ -8,13 +8,14 @@ RSpec.describe Banzai::ReferenceParser::BaseParser do let(:user) { create(:user) } let(:project) { create(:project, :public) } let(:context) { Banzai::RenderContext.new(project, user) } - - subject do - klass = Class.new(described_class) do + let(:parser_class) do + Class.new(described_class) do self.reference_type = :foo end + end - klass.new(context) + subject do + parser_class.new(context) end describe '.reference_type=' do @@ -43,12 +44,20 @@ RSpec.describe Banzai::ReferenceParser::BaseParser do let(:link) { empty_html_link } context 'when the link has a data-project attribute' do - it 'checks if user can read the resource' do + before do link['data-project'] = project.id.to_s + end - expect(subject).to receive(:can_read_reference?).with(user, project, link) + it 'includes the link if can_read_reference? returns true' do + expect(subject).to receive(:can_read_reference?).with(user, project, link).and_return(true) - subject.nodes_visible_to_user(user, [link]) + expect(subject.nodes_visible_to_user(user, [link])).to contain_exactly(link) + end + + it 'excludes the link if can_read_reference? returns false' do + expect(subject).to receive(:can_read_reference?).with(user, project, link).and_return(false) + + expect(subject.nodes_visible_to_user(user, [link])).to be_empty end end @@ -178,58 +187,56 @@ RSpec.describe Banzai::ReferenceParser::BaseParser do it 'gathers the references for every node matching the reference type' do dummy = Class.new(described_class) do self.reference_type = :test - end - - instance = dummy.new(Banzai::RenderContext.new(project, user)) - document = Nokogiri::HTML.fragment('<a class="gfm"></a><a class="gfm" data-reference-type="test"></a>') - expect(instance).to receive(:gather_references) - .with([document.children[1]]) - .and_return([user]) + def gather_references(nodes) + nodes + end + end - expect(instance.process([document])).to eq([user]) + instance = dummy.new(context) + document_a = Nokogiri::HTML.fragment(<<-FRAG) + <a class="gfm">one</a> + <a class="gfm" data-reference-type="test">two</a> + <a class="gfm" data-reference-type="other">three</a> + FRAG + document_b = Nokogiri::HTML.fragment(<<-FRAG) + <a class="gfm" data-reference-type="test">four</a> + FRAG + document_c = Nokogiri::HTML.fragment('') + + expect(instance.process([document_a, document_b, document_c])) + .to contain_exactly(document_a.css('a')[1], document_b.css('a')[0]) end end describe '#gather_references' do - let(:link) { double(:link) } + let(:nodes) { (1..10).map { |n| double(:link, id: n) } } - it 'does not process links a user can not reference' do - expect(subject).to receive(:nodes_user_can_reference) - .with(user, [link]) - .and_return([]) + let(:parser_class) do + Class.new(described_class) do + def nodes_user_can_reference(_user, nodes) + nodes.select { |n| n.id.even? } + end - expect(subject).to receive(:referenced_by).with([]) + def nodes_visible_to_user(_user, nodes) + nodes.select { |n| n.id > 5 } + end - subject.gather_references([link]) + def referenced_by(nodes) + nodes.map(&:id) + end + end end - it 'does not process links a user can not see' do - expect(subject).to receive(:nodes_user_can_reference) - .with(user, [link]) - .and_return([link]) - - expect(subject).to receive(:nodes_visible_to_user) - .with(user, [link]) - .and_return([]) - - expect(subject).to receive(:referenced_by).with([]) - - subject.gather_references([link]) + it 'returns referenceable and visible objects, alongside nodes that are referenceable but not visible' do + expect(subject.gather_references(nodes)).to match( + visible: contain_exactly(6, 8, 10), + not_visible: match_array(nodes.select { |n| n.id.even? && n.id <= 5 }) + ) end - it 'returns the references if a user can reference and see a link' do - expect(subject).to receive(:nodes_user_can_reference) - .with(user, [link]) - .and_return([link]) - - expect(subject).to receive(:nodes_visible_to_user) - .with(user, [link]) - .and_return([link]) - - expect(subject).to receive(:referenced_by).with([link]) - - subject.gather_references([link]) + it 'is always empty if the input is empty' do + expect(subject.gather_references([])) .to match(visible: be_empty, not_visible: be_empty) end end diff --git a/spec/lib/banzai/reference_parser/snippet_parser_spec.rb b/spec/lib/banzai/reference_parser/snippet_parser_spec.rb index cdc660b4f4a..3459784708f 100644 --- a/spec/lib/banzai/reference_parser/snippet_parser_spec.rb +++ b/spec/lib/banzai/reference_parser/snippet_parser_spec.rb @@ -33,6 +33,17 @@ RSpec.describe Banzai::ReferenceParser::SnippetParser do project.project_feature.update_attribute(:snippets_access_level, ProjectFeature::ENABLED) end + it 'avoids N+1 cached queries', :use_sql_query_cache do + # Run this once to establish a baseline + visible_references(:public) + + control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) do + subject.nodes_visible_to_user(user, [link]) + end + + expect { subject.nodes_visible_to_user(user, Array.new(10, link)) }.not_to exceed_all_query_limit(control_count.count) + end + it 'creates a reference for guest for a public snippet' do expect(visible_references(:public)).to eq([link]) end |