1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
require 'spec_helper'
describe Banzai::Redactor do
let(:user) { create(:user) }
let(:project) { build(:project) }
let(:redactor) { described_class.new(project, user) }
describe '#redact' do
context 'when reference not visible to user' do
before do
expect(redactor).to receive(:nodes_visible_to_user).and_return([])
end
it 'redacts an array of documents' do
doc1 = Nokogiri::HTML
.fragment('<a class="gfm" data-reference-type="issue">foo</a>')
doc2 = Nokogiri::HTML
.fragment('<a class="gfm" data-reference-type="issue">bar</a>')
redacted_data = redactor.redact([doc1, doc2])
expect(redacted_data.map { |data| data[:document] }).to eq([doc1, doc2])
expect(redacted_data.map { |data| data[:visible_reference_count] }).to eq([0, 0])
expect(doc1.to_html).to eq('foo')
expect(doc2.to_html).to eq('bar')
end
it 'replaces redacted reference with inner HTML' do
doc = Nokogiri::HTML.fragment("<a class='gfm' data-reference-type='issue'>foo</a>")
redactor.redact([doc])
expect(doc.to_html).to eq('foo')
end
context 'when data-original attribute provided' do
let(:original_content) { '<code>foo</code>' }
it 'replaces redacted reference with original content' do
doc = Nokogiri::HTML.fragment("<a class='gfm' data-reference-type='issue' data-original='#{original_content}'>bar</a>")
redactor.redact([doc])
expect(doc.to_html).to eq(original_content)
end
end
end
context 'when project is in pending delete' do
let!(:issue) { create(:issue, project: project) }
let(:redactor) { described_class.new(project, user) }
before do
project.update(pending_delete: true)
end
it 'redacts an issue attached' do
doc = Nokogiri::HTML.fragment("<a class='gfm' data-reference-type='issue' data-issue='#{issue.id}'>foo</a>")
redactor.redact([doc])
expect(doc.to_html).to eq('foo')
end
it 'redacts an external issue' do
doc = Nokogiri::HTML.fragment("<a class='gfm' data-reference-type='issue' data-external-issue='#{issue.id}' data-project='#{project.id}'>foo</a>")
redactor.redact([doc])
expect(doc.to_html).to eq('foo')
end
end
context 'when reference visible to user' do
it 'does not redact an array of documents' do
doc1_html = '<a class="gfm" data-reference-type="issue">foo</a>'
doc1 = Nokogiri::HTML.fragment(doc1_html)
doc2_html = '<a class="gfm" data-reference-type="issue">bar</a>'
doc2 = Nokogiri::HTML.fragment(doc2_html)
nodes = redactor.document_nodes([doc1, doc2]).map { |x| x[:nodes] }
expect(redactor).to receive(:nodes_visible_to_user).and_return(nodes.flatten)
redacted_data = redactor.redact([doc1, doc2])
expect(redacted_data.map { |data| data[:document] }).to eq([doc1, doc2])
expect(redacted_data.map { |data| data[:visible_reference_count] }).to eq([1, 1])
expect(doc1.to_html).to eq(doc1_html)
expect(doc2.to_html).to eq(doc2_html)
end
end
end
context 'when the user cannot read cross project' do
include ActionView::Helpers::UrlHelper
let(:project) { create(:project) }
let(:other_project) { create(:project, :public) }
def create_link(issuable)
type = issuable.class.name.underscore.downcase
link_to(issuable.to_reference, '',
class: 'gfm has-tooltip',
title: issuable.title,
data: {
reference_type: type,
"#{type}": issuable.id
})
end
before do
project.add_developer(user)
allow(Ability).to receive(:allowed?).and_call_original
allow(Ability).to receive(:allowed?).with(user, :read_cross_project, :global) { false }
allow(Ability).to receive(:allowed?).with(user, :read_cross_project) { false }
end
it 'skips links to issues within the same project' do
issue = create(:issue, project: project)
link = create_link(issue)
doc = Nokogiri::HTML.fragment(link)
redactor.redact([doc])
result = doc.css('a').last
expect(result['class']).to include('has-tooltip')
expect(result['title']).to eq(issue.title)
end
it 'removes info from a cross project reference' do
issue = create(:issue, project: other_project)
link = create_link(issue)
doc = Nokogiri::HTML.fragment(link)
redactor.redact([doc])
result = doc.css('a').last
expect(result['class']).not_to include('has-tooltip')
expect(result['title']).to be_empty
end
end
describe '#redact_nodes' do
it 'redacts an Array of nodes' do
doc = Nokogiri::HTML.fragment('<a href="foo">foo</a>')
node = doc.children[0]
expect(redactor).to receive(:nodes_visible_to_user)
.with([node])
.and_return(Set.new)
redactor.redact_document_nodes([{ document: doc, nodes: [node] }])
expect(doc.to_html).to eq('foo')
end
end
describe '#nodes_visible_to_user' do
it 'returns a Set containing the visible nodes' do
doc = Nokogiri::HTML.fragment('<a data-reference-type="issue"></a>')
node = doc.children[0]
expect_any_instance_of(Banzai::ReferenceParser::IssueParser)
.to receive(:nodes_visible_to_user)
.with(user, [node])
.and_return([node])
expect(redactor.nodes_visible_to_user([node])).to eq(Set.new([node]))
end
end
end
|