summaryrefslogtreecommitdiff
path: root/spec/lib
diff options
context:
space:
mode:
authorDouwe Maan <douwe@selenight.nl>2017-04-07 20:03:55 -0500
committerDouwe Maan <douwe@selenight.nl>2017-04-07 20:03:55 -0500
commitf058b52b50c76de9557b167a1a31a5c9ba446f31 (patch)
tree047f04c2b0ed83ed71a6b39e64f55c40eded838b /spec/lib
parent130a1e86e215d5d43cd3c53a44589aa5b8c69aab (diff)
parent7d3f37b0b879af562dc7c499bdbfcb230ed718a4 (diff)
downloadgitlab-ce-f058b52b50c76de9557b167a1a31a5c9ba446f31.tar.gz
Merge branch 'master' into new-resolvable-discussion
Diffstat (limited to 'spec/lib')
-rw-r--r--spec/lib/banzai/filter/issuable_state_filter_spec.rb95
-rw-r--r--spec/lib/banzai/filter/redactor_filter_spec.rb10
-rw-r--r--spec/lib/banzai/issuable_extractor_spec.rb52
-rw-r--r--spec/lib/banzai/object_renderer_spec.rb139
-rw-r--r--spec/lib/banzai/reference_parser/base_parser_spec.rb18
-rw-r--r--spec/lib/banzai/reference_parser/issue_parser_spec.rb12
-rw-r--r--spec/lib/banzai/reference_parser/user_parser_spec.rb9
7 files changed, 222 insertions, 113 deletions
diff --git a/spec/lib/banzai/filter/issuable_state_filter_spec.rb b/spec/lib/banzai/filter/issuable_state_filter_spec.rb
new file mode 100644
index 00000000000..603b79a323c
--- /dev/null
+++ b/spec/lib/banzai/filter/issuable_state_filter_spec.rb
@@ -0,0 +1,95 @@
+require 'spec_helper'
+
+describe Banzai::Filter::IssuableStateFilter, lib: true do
+ include ActionView::Helpers::UrlHelper
+ include FilterSpecHelper
+
+ let(:user) { create(:user) }
+
+ def create_link(data)
+ link_to('text', '', class: 'gfm has-tooltip', data: data)
+ end
+
+ it 'ignores non-GFM links' do
+ html = %(See <a href="https://google.com/">Google</a>)
+ doc = filter(html, current_user: user)
+
+ expect(doc.css('a').last.text).to eq('Google')
+ end
+
+ it 'ignores non-issuable links' do
+ project = create(:empty_project, :public)
+ link = create_link(project: project, reference_type: 'issue')
+ doc = filter(link, current_user: user)
+
+ expect(doc.css('a').last.text).to eq('text')
+ end
+
+ context 'for issue references' do
+ it 'ignores open issue references' do
+ issue = create(:issue)
+ link = create_link(issue: issue.id, reference_type: 'issue')
+ doc = filter(link, current_user: user)
+
+ expect(doc.css('a').last.text).to eq('text')
+ end
+
+ it 'ignores reopened issue references' do
+ reopened_issue = create(:issue, :reopened)
+ link = create_link(issue: reopened_issue.id, reference_type: 'issue')
+ doc = filter(link, current_user: user)
+
+ expect(doc.css('a').last.text).to eq('text')
+ end
+
+ it 'appends [closed] to closed issue references' do
+ closed_issue = create(:issue, :closed)
+ link = create_link(issue: closed_issue.id, reference_type: 'issue')
+ doc = filter(link, current_user: user)
+
+ expect(doc.css('a').last.text).to eq('text [closed]')
+ end
+ end
+
+ context 'for merge request references' do
+ it 'ignores open merge request references' do
+ mr = create(:merge_request)
+ link = create_link(merge_request: mr.id, reference_type: 'merge_request')
+ doc = filter(link, current_user: user)
+
+ expect(doc.css('a').last.text).to eq('text')
+ end
+
+ it 'ignores reopened merge request references' do
+ mr = create(:merge_request, :reopened)
+ link = create_link(merge_request: mr.id, reference_type: 'merge_request')
+ doc = filter(link, current_user: user)
+
+ expect(doc.css('a').last.text).to eq('text')
+ end
+
+ it 'ignores locked merge request references' do
+ mr = create(:merge_request, :locked)
+ link = create_link(merge_request: mr.id, reference_type: 'merge_request')
+ doc = filter(link, current_user: user)
+
+ expect(doc.css('a').last.text).to eq('text')
+ end
+
+ it 'appends [closed] to closed merge request references' do
+ mr = create(:merge_request, :closed)
+ link = create_link(merge_request: mr.id, reference_type: 'merge_request')
+ doc = filter(link, current_user: user)
+
+ expect(doc.css('a').last.text).to eq('text [closed]')
+ end
+
+ it 'appends [merged] to merged merge request references' do
+ mr = create(:merge_request, :merged)
+ link = create_link(merge_request: mr.id, reference_type: 'merge_request')
+ doc = filter(link, current_user: user)
+
+ expect(doc.css('a').last.text).to eq('text [merged]')
+ end
+ end
+end
diff --git a/spec/lib/banzai/filter/redactor_filter_spec.rb b/spec/lib/banzai/filter/redactor_filter_spec.rb
index 0140a91c7ba..8a6fe1ad6a3 100644
--- a/spec/lib/banzai/filter/redactor_filter_spec.rb
+++ b/spec/lib/banzai/filter/redactor_filter_spec.rb
@@ -15,6 +15,16 @@ describe Banzai::Filter::RedactorFilter, lib: true do
link_to('text', '', class: 'gfm', data: data)
end
+ it 'skips when the skip_redaction flag is set' do
+ user = create(:user)
+ project = create(:empty_project)
+
+ link = reference_link(project: project.id, reference_type: 'test')
+ doc = filter(link, current_user: user, skip_redaction: true)
+
+ expect(doc.css('a').length).to eq 1
+ end
+
context 'with data-project' do
let(:parser_class) do
Class.new(Banzai::ReferenceParser::BaseParser) do
diff --git a/spec/lib/banzai/issuable_extractor_spec.rb b/spec/lib/banzai/issuable_extractor_spec.rb
new file mode 100644
index 00000000000..e5d332efb08
--- /dev/null
+++ b/spec/lib/banzai/issuable_extractor_spec.rb
@@ -0,0 +1,52 @@
+require 'spec_helper'
+
+describe Banzai::IssuableExtractor, lib: true do
+ let(:project) { create(:empty_project) }
+ let(:user) { create(:user) }
+ let(:extractor) { described_class.new(project, user) }
+ let(:issue) { create(:issue, project: project) }
+ let(:merge_request) { create(:merge_request, source_project: project) }
+ let(:issue_link) do
+ html_to_node(
+ "<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>"
+ )
+ end
+
+ def html_to_node(html)
+ Nokogiri::HTML.fragment(
+ html
+ ).children[0]
+ end
+
+ it 'returns instances of issuables for nodes with references' do
+ result = extractor.extract([issue_link, merge_request_link])
+
+ expect(result).to eq(issue_link => issue, merge_request_link => merge_request)
+ end
+
+ describe 'caching' do
+ before do
+ RequestStore.begin!
+ end
+
+ after do
+ RequestStore.end!
+ RequestStore.clear!
+ end
+
+ it 'saves records to cache' do
+ extractor.extract([issue_link, merge_request_link])
+
+ second_call_queries = ActiveRecord::QueryRecorder.new do
+ extractor.extract([issue_link, merge_request_link])
+ end.count
+
+ expect(second_call_queries).to eq 0
+ end
+ end
+end
diff --git a/spec/lib/banzai/object_renderer_spec.rb b/spec/lib/banzai/object_renderer_spec.rb
index 6bcda87c999..4817fcd031a 100644
--- a/spec/lib/banzai/object_renderer_spec.rb
+++ b/spec/lib/banzai/object_renderer_spec.rb
@@ -3,128 +3,51 @@ require 'spec_helper'
describe Banzai::ObjectRenderer do
let(:project) { create(:empty_project) }
let(:user) { project.owner }
-
- def fake_object(attrs = {})
- object = double(attrs.merge("new_record?" => true, "destroyed?" => true))
- allow(object).to receive(:markdown_cache_field_for).with(:note).and_return(:note_html)
- allow(object).to receive(:banzai_render_context).with(:note).and_return(project: nil, author: nil)
- allow(object).to receive(:update_column).with(:note_html, anything).and_return(true)
- object
- end
+ let(:renderer) { described_class.new(project, user, custom_value: 'value') }
+ let(:object) { Note.new(note: 'hello', note_html: '<p>hello</p>') }
describe '#render' do
it 'renders and redacts an Array of objects' do
- renderer = described_class.new(project, user)
- object = fake_object(note: 'hello', note_html: nil)
-
- expect(renderer).to receive(:render_objects).with([object], :note).
- and_call_original
-
- expect(renderer).to receive(:redact_documents).
- with(an_instance_of(Array)).
- and_call_original
-
- expect(object).to receive(:redacted_note_html=).with('<p dir="auto">hello</p>')
- expect(object).to receive(:user_visible_reference_count=).with(0)
-
renderer.render([object], :note)
- end
- end
-
- describe '#render_objects' do
- it 'renders an Array of objects' do
- object = fake_object(note: 'hello', note_html: nil)
-
- renderer = described_class.new(project, user)
- expect(renderer).to receive(:render_attributes).with([object], :note).
- and_call_original
-
- rendered = renderer.render_objects([object], :note)
-
- expect(rendered).to be_an_instance_of(Array)
- expect(rendered[0]).to be_an_instance_of(Nokogiri::HTML::DocumentFragment)
- end
- end
-
- describe '#redact_documents' do
- it 'redacts a set of documents and returns them as an Array of Hashes' do
- doc = Nokogiri::HTML.fragment('<p>hello</p>')
- renderer = described_class.new(project, user)
-
- expect_any_instance_of(Banzai::Redactor).to receive(:redact).
- with([doc]).
- and_call_original
-
- redacted = renderer.redact_documents([doc])
-
- expect(redacted.count).to eq(1)
- expect(redacted.first[:visible_reference_count]).to eq(0)
- expect(redacted.first[:document].to_html).to eq('<p>hello</p>')
+ expect(object.redacted_note_html).to eq '<p>hello</p>'
+ expect(object.user_visible_reference_count).to eq 0
end
- end
- describe '#context_for' do
- let(:object) { fake_object(note: 'hello') }
- let(:renderer) { described_class.new(project, user) }
+ it 'calls Banzai::Redactor to perform redaction' do
+ expect_any_instance_of(Banzai::Redactor).to receive(:redact).and_call_original
- it 'returns a Hash' do
- expect(renderer.context_for(object, :note)).to be_an_instance_of(Hash)
- end
-
- it 'includes the banzai render context for the object' do
- expect(object).to receive(:banzai_render_context).with(:note).and_return(foo: :bar)
- context = renderer.context_for(object, :note)
- expect(context).to have_key(:foo)
- expect(context[:foo]).to eq(:bar)
- end
- end
-
- describe '#render_attributes' do
- it 'renders the attribute of a list of objects' do
- objects = [fake_object(note: 'hello', note_html: nil), fake_object(note: 'bye', note_html: nil)]
- renderer = described_class.new(project, user)
-
- objects.each do |object|
- expect(Banzai).to receive(:render_field).with(object, :note).and_call_original
- end
-
- docs = renderer.render_attributes(objects, :note)
-
- expect(docs[0]).to be_an_instance_of(Nokogiri::HTML::DocumentFragment)
- expect(docs[0].to_html).to eq('<p dir="auto">hello</p>')
-
- expect(docs[1]).to be_an_instance_of(Nokogiri::HTML::DocumentFragment)
- expect(docs[1].to_html).to eq('<p dir="auto">bye</p>')
- end
-
- it 'returns when no objects to render' do
- objects = []
- renderer = described_class.new(project, user, pipeline: :note)
-
- expect(renderer.render_attributes(objects, :note)).to eq([])
+ renderer.render([object], :note)
end
- end
- describe '#base_context' do
- let(:context) do
- described_class.new(project, user, foo: :bar).base_context
- end
+ it 'retrieves field content using Banzai.render_field' do
+ expect(Banzai).to receive(:render_field).with(object, :note).and_call_original
- it 'returns a Hash' do
- expect(context).to be_an_instance_of(Hash)
- end
-
- it 'includes the custom attributes' do
- expect(context[:foo]).to eq(:bar)
+ renderer.render([object], :note)
end
- it 'includes the current user' do
- expect(context[:current_user]).to eq(user)
- end
+ it 'passes context to PostProcessPipeline' do
+ another_user = create(:user)
+ another_project = create(:empty_project)
+ object = Note.new(
+ note: 'hello',
+ note_html: 'hello',
+ author: another_user,
+ project: another_project
+ )
+
+ expect(Banzai::Pipeline::PostProcessPipeline).to receive(:to_document).with(
+ anything,
+ hash_including(
+ skip_redaction: true,
+ current_user: user,
+ project: another_project,
+ author: another_user,
+ custom_value: 'value'
+ )
+ ).and_call_original
- it 'includes the current project' do
- expect(context[:project]).to eq(project)
+ renderer.render([object], :note)
end
end
end
diff --git a/spec/lib/banzai/reference_parser/base_parser_spec.rb b/spec/lib/banzai/reference_parser/base_parser_spec.rb
index aa127f0179d..a3141894c74 100644
--- a/spec/lib/banzai/reference_parser/base_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/base_parser_spec.rb
@@ -92,16 +92,26 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do
end
describe '#grouped_objects_for_nodes' do
- it 'returns a Hash grouping objects per ID' do
- nodes = [double(:node)]
+ it 'returns a Hash grouping objects per node' do
+ link = double(:link)
+
+ expect(link).to receive(:has_attribute?).
+ with('data-user').
+ and_return(true)
+
+ expect(link).to receive(:attr).
+ with('data-user').
+ and_return(user.id.to_s)
+
+ nodes = [link]
expect(subject).to receive(:unique_attribute_values).
with(nodes, 'data-user').
- and_return([user.id])
+ and_return([user.id.to_s])
hash = subject.grouped_objects_for_nodes(nodes, User, 'data-user')
- expect(hash).to eq({ user.id => user })
+ expect(hash).to eq({ link => user })
end
it 'returns an empty Hash when the list of nodes is empty' do
diff --git a/spec/lib/banzai/reference_parser/issue_parser_spec.rb b/spec/lib/banzai/reference_parser/issue_parser_spec.rb
index 6873b7b85f9..7031c47231c 100644
--- a/spec/lib/banzai/reference_parser/issue_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/issue_parser_spec.rb
@@ -67,6 +67,16 @@ describe Banzai::ReferenceParser::IssueParser, lib: true do
expect(subject.referenced_by([])).to eq([])
end
end
+
+ context 'when issue with given ID does not exist' do
+ before do
+ link['data-issue'] = '-1'
+ end
+
+ it 'returns an empty Array' do
+ expect(subject.referenced_by([link])).to eq([])
+ end
+ end
end
end
@@ -75,7 +85,7 @@ describe Banzai::ReferenceParser::IssueParser, lib: true do
link['data-issue'] = issue.id.to_s
nodes = [link]
- expect(subject.issues_for_nodes(nodes)).to eq({ issue.id => issue })
+ expect(subject.issues_for_nodes(nodes)).to eq({ link => issue })
end
end
end
diff --git a/spec/lib/banzai/reference_parser/user_parser_spec.rb b/spec/lib/banzai/reference_parser/user_parser_spec.rb
index 31ca9d27b0b..4ec998efe53 100644
--- a/spec/lib/banzai/reference_parser/user_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/user_parser_spec.rb
@@ -180,6 +180,15 @@ describe Banzai::ReferenceParser::UserParser, lib: true do
expect(subject.nodes_user_can_reference(user, [link])).to eq([])
end
+
+ it 'returns the nodes if the project attribute value equals the current project ID' do
+ other_user = create(:user)
+
+ link['data-project'] = project.id.to_s
+ link['data-author'] = other_user.id.to_s
+
+ expect(subject.nodes_user_can_reference(user, [link])).to eq([link])
+ end
end
context 'when the link does not have a data-author attribute' do