Skip to content
Snippets Groups Projects
Commit 9ec3a8b0 authored by Douwe Maan's avatar Douwe Maan
Browse files

Merge branch 'rendering-markdown-multiple-projects' into 'master'

Optimise rendering of Markdown documents that belong to different projects

See merge request gitlab-org/gitlab-ce!18157
parents ef44ebf8 daad7144
No related branches found
No related tags found
No related merge requests found
Showing
with 101 additions and 31 deletions
Loading
Loading
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Banzai::IssuableExtractor do
let(:project) { create(:project) }
let(:user) { create(:user) }
let(:extractor) { described_class.new(project, user) }
let(:extractor) { described_class.new(Banzai::RenderContext.new(project, user)) }
let(:issue) { create(:issue, project: project) }
let(:merge_request) { create(:merge_request, source_project: project) }
let(:issue_link) do
Loading
Loading
Loading
Loading
@@ -3,7 +3,14 @@ require 'spec_helper'
describe Banzai::ObjectRenderer do
let(:project) { create(:project, :repository) }
let(:user) { project.owner }
let(:renderer) { described_class.new(project, user, custom_value: 'value') }
let(:renderer) do
described_class.new(
default_project: project,
user: user,
redaction_context: { custom_value: 'value' }
)
end
let(:object) { Note.new(note: 'hello', note_html: '<p dir="auto">hello</p>', cached_markdown_version: CacheMarkdownField::CACHE_VERSION) }
 
describe '#render' do
Loading
Loading
Loading
Loading
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Banzai::Redactor do
let(:user) { create(:user) }
let(:project) { build(:project) }
let(:redactor) { described_class.new(project, user) }
let(:redactor) { described_class.new(Banzai::RenderContext.new(project, user)) }
 
describe '#redact' do
context 'when reference not visible to user' do
Loading
Loading
@@ -54,7 +54,7 @@ describe Banzai::Redactor do
 
context 'when project is in pending delete' do
let!(:issue) { create(:issue, project: project) }
let(:redactor) { described_class.new(project, user) }
let(:redactor) { described_class.new(Banzai::RenderContext.new(project, user)) }
 
before do
project.update(pending_delete: true)
Loading
Loading
Loading
Loading
@@ -5,13 +5,14 @@ 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
self.reference_type = :foo
end
 
klass.new(project, user)
klass.new(context)
end
 
describe '.reference_type=' do
Loading
Loading
@@ -23,6 +24,19 @@ describe Banzai::ReferenceParser::BaseParser do
end
end
 
describe '#project_for_node' do
it 'returns the Project for a node' do
document = instance_double('document', fragment?: false)
project = instance_double('project')
object = instance_double('object', project: project)
node = instance_double('node', document: document)
context.associate_document(document, object)
expect(subject.project_for_node(node)).to eq(project)
end
end
describe '#nodes_visible_to_user' do
let(:link) { empty_html_link }
 
Loading
Loading
@@ -164,7 +178,7 @@ describe Banzai::ReferenceParser::BaseParser do
self.reference_type = :test
end
 
instance = dummy.new(project, user)
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)
Loading
Loading
Loading
Loading
@@ -5,7 +5,7 @@ describe Banzai::ReferenceParser::CommitParser do
 
let(:project) { create(:project, :public) }
let(:user) { create(:user) }
subject { described_class.new(project, user) }
subject { described_class.new(Banzai::RenderContext.new(project, user)) }
let(:link) { empty_html_link }
 
describe '#nodes_visible_to_user' do
Loading
Loading
Loading
Loading
@@ -5,7 +5,7 @@ describe Banzai::ReferenceParser::CommitRangeParser do
 
let(:project) { create(:project, :public) }
let(:user) { create(:user) }
subject { described_class.new(project, user) }
subject { described_class.new(Banzai::RenderContext.new(project, user)) }
let(:link) { empty_html_link }
 
describe '#nodes_visible_to_user' do
Loading
Loading
Loading
Loading
@@ -5,7 +5,7 @@ describe Banzai::ReferenceParser::ExternalIssueParser do
 
let(:project) { create(:project, :public) }
let(:user) { create(:user) }
subject { described_class.new(project, user) }
subject { described_class.new(Banzai::RenderContext.new(project, user)) }
let(:link) { empty_html_link }
 
describe '#nodes_visible_to_user' do
Loading
Loading
Loading
Loading
@@ -7,7 +7,7 @@ describe Banzai::ReferenceParser::IssueParser do
let(:user) { create(:user) }
let(:issue) { create(:issue, project: project) }
let(:link) { empty_html_link }
subject { described_class.new(project, user) }
subject { described_class.new(Banzai::RenderContext.new(project, user)) }
 
describe '#nodes_visible_to_user' do
context 'when the link has a data-issue attribute' do
Loading
Loading
Loading
Loading
@@ -6,7 +6,7 @@ describe Banzai::ReferenceParser::LabelParser do
let(:project) { create(:project, :public) }
let(:user) { create(:user) }
let(:label) { create(:label, project: project) }
subject { described_class.new(project, user) }
subject { described_class.new(Banzai::RenderContext.new(project, user)) }
let(:link) { empty_html_link }
 
describe '#nodes_visible_to_user' do
Loading
Loading
Loading
Loading
@@ -6,7 +6,7 @@ describe Banzai::ReferenceParser::MergeRequestParser do
let(:user) { create(:user) }
let(:project) { create(:project, :public) }
let(:merge_request) { create(:merge_request, source_project: project) }
subject { described_class.new(project, user) }
subject { described_class.new(Banzai::RenderContext.new(merge_request.target_project, user)) }
let(:link) { empty_html_link }
 
describe '#nodes_visible_to_user' do
Loading
Loading
Loading
Loading
@@ -6,7 +6,7 @@ describe Banzai::ReferenceParser::MilestoneParser do
let(:project) { create(:project, :public) }
let(:user) { create(:user) }
let(:milestone) { create(:milestone, project: project) }
subject { described_class.new(project, user) }
subject { described_class.new(Banzai::RenderContext.new(project, user)) }
let(:link) { empty_html_link }
 
describe '#nodes_visible_to_user' do
Loading
Loading
Loading
Loading
@@ -9,7 +9,7 @@ describe Banzai::ReferenceParser::SnippetParser do
let(:external_user) { create(:user, :external) }
let(:project_member) { create(:user) }
 
subject { described_class.new(project, user) }
subject { described_class.new(Banzai::RenderContext.new(project, user)) }
let(:link) { empty_html_link }
 
def visible_references(snippet_visibility, user = nil)
Loading
Loading
Loading
Loading
@@ -6,7 +6,7 @@ describe Banzai::ReferenceParser::UserParser do
let(:group) { create(:group) }
let(:user) { create(:user) }
let(:project) { create(:project, :public, group: group, creator: user) }
subject { described_class.new(project, user) }
subject { described_class.new(Banzai::RenderContext.new(project, user)) }
let(:link) { empty_html_link }
 
describe '#referenced_by' do
Loading
Loading
# frozen_string_literal: true
require 'spec_helper'
describe Banzai::RenderContext do
let(:document) { Nokogiri::HTML.fragment('<p>hello</p>') }
describe '#project_for_node' do
it 'returns the default project if no associated project was found' do
project = instance_double('project')
context = described_class.new(project)
expect(context.project_for_node(document)).to eq(project)
end
it 'returns the associated project if one was associated explicitly' do
project = instance_double('project')
obj = instance_double('object', project: project)
context = described_class.new
context.associate_document(document, obj)
expect(context.project_for_node(document)).to eq(project)
end
it 'returns the project associated with a DocumentFragment when using a node' do
project = instance_double('project')
obj = instance_double('object', project: project)
context = described_class.new
node = document.children.first
context.associate_document(document, obj)
expect(context.project_for_node(node)).to eq(project)
end
end
end
Loading
Loading
@@ -9,9 +9,7 @@ describe Events::RenderService do
context 'when the request format is atom' do
it 'renders the note inside events' do
expect(Banzai::ObjectRenderer).to receive(:new)
.with(event.project, user,
only_path: false,
xhtml: true)
.with(user: user, redaction_context: { only_path: false, xhtml: true })
.and_call_original
 
expect_any_instance_of(Banzai::ObjectRenderer)
Loading
Loading
@@ -24,7 +22,7 @@ describe Events::RenderService do
context 'when the request format is not atom' do
it 'renders the note inside events' do
expect(Banzai::ObjectRenderer).to receive(:new)
.with(event.project, user, {})
.with(user: user, redaction_context: {})
.and_call_original
 
expect_any_instance_of(Banzai::ObjectRenderer)
Loading
Loading
Loading
Loading
@@ -4,23 +4,28 @@ describe Notes::RenderService do
describe '#execute' do
it 'renders a Note' do
note = double(:note)
project = double(:project)
wiki = double(:wiki)
user = double(:user)
 
expect(Banzai::ObjectRenderer).to receive(:new)
.with(project, user,
requested_path: 'foo',
project_wiki: wiki,
ref: 'bar',
only_path: nil,
xhtml: false)
expect(Banzai::ObjectRenderer)
.to receive(:new)
.with(
user: user,
redaction_context: {
requested_path: 'foo',
project_wiki: wiki,
ref: 'bar',
only_path: nil,
xhtml: false
}
)
.and_call_original
 
expect_any_instance_of(Banzai::ObjectRenderer)
.to receive(:render).with([note], :note)
.to receive(:render)
.with([note], :note)
 
described_class.new(user).execute([note], project,
described_class.new(user).execute([note],
requested_path: 'foo',
project_wiki: wiki,
ref: 'bar',
Loading
Loading
Loading
Loading
@@ -18,6 +18,11 @@ module FilterSpecHelper
context.reverse_merge!(project: project)
end
 
render_context = Banzai::RenderContext
.new(context[:project], context[:current_user])
context = context.merge(render_context: render_context)
described_class.call(html, context)
end
 
Loading
Loading
Loading
Loading
@@ -5,9 +5,11 @@ module ReferenceParserHelpers
 
shared_examples 'no N+1 queries' do
it 'avoids N+1 queries in #nodes_visible_to_user', :request_store do
context = Banzai::RenderContext.new(project, user)
record_queries = lambda do |links|
ActiveRecord::QueryRecorder.new do
described_class.new(project, user).nodes_visible_to_user(user, links)
described_class.new(context).nodes_visible_to_user(user, links)
end
end
 
Loading
Loading
@@ -19,9 +21,11 @@ module ReferenceParserHelpers
end
 
it 'avoids N+1 queries in #records_for_nodes', :request_store do
context = Banzai::RenderContext.new(project, user)
record_queries = lambda do |links|
ActiveRecord::QueryRecorder.new do
described_class.new(project, user).records_for_nodes(links)
described_class.new(context).records_for_nodes(links)
end
end
 
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment