summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorSean McGivern <sean@mcgivern.me.uk>2017-02-13 11:43:26 +0000
committerSean McGivern <sean@mcgivern.me.uk>2017-02-13 11:43:26 +0000
commit7d4d9365c0d9025d5c08ec503be304b4d3f63997 (patch)
tree4373f47e3a71451f52cdf10757fefaaea0d34c30 /spec
parent6a1b3ef73f57d58d159e343f79e1f74418c2f763 (diff)
parent0b14b654b6e5d936f7241dcc0c249e0d4cc42728 (diff)
downloadgitlab-ce-7d4d9365c0d9025d5c08ec503be304b4d3f63997.tar.gz
Merge branch 'issue_25900_2' into 'master'
Gather issuable metadata to avoid n+ queries on index view Closes #25900 See merge request !9006
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/dashboard_controller_spec.rb19
-rw-r--r--spec/controllers/projects/issues_controller_spec.rb2
-rw-r--r--spec/controllers/projects/merge_requests_controller_spec.rb4
-rw-r--r--spec/features/issuables/issuable_list_spec.rb57
-rw-r--r--spec/support/issuables_list_metadata_shared_examples.rb35
5 files changed, 117 insertions, 0 deletions
diff --git a/spec/controllers/dashboard_controller_spec.rb b/spec/controllers/dashboard_controller_spec.rb
new file mode 100644
index 00000000000..566d8515198
--- /dev/null
+++ b/spec/controllers/dashboard_controller_spec.rb
@@ -0,0 +1,19 @@
+require 'spec_helper'
+
+describe DashboardController do
+ let(:user) { create(:user) }
+ let(:project) { create(:project) }
+
+ before do
+ project.team << [user, :master]
+ sign_in(user)
+ end
+
+ describe 'GET issues' do
+ it_behaves_like 'issuables list meta-data', :issue, :issues
+ end
+
+ describe 'GET merge requests' do
+ it_behaves_like 'issuables list meta-data', :merge_request, :merge_requests
+ end
+end
diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb
index 4b89381eb96..e576bf9ef79 100644
--- a/spec/controllers/projects/issues_controller_spec.rb
+++ b/spec/controllers/projects/issues_controller_spec.rb
@@ -24,6 +24,8 @@ describe Projects::IssuesController do
project.team << [user, :developer]
end
+ it_behaves_like "issuables list meta-data", :issue
+
it "returns index" do
get :index, namespace_id: project.namespace.path, project_id: project.path
diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb
index 63780802cfa..bfd134e406e 100644
--- a/spec/controllers/projects/merge_requests_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests_controller_spec.rb
@@ -147,6 +147,8 @@ describe Projects::MergeRequestsController do
end
describe 'GET index' do
+ let!(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) }
+
def get_merge_requests(page = nil)
get :index,
namespace_id: project.namespace.to_param,
@@ -154,6 +156,8 @@ describe Projects::MergeRequestsController do
state: 'opened', page: page.to_param
end
+ it_behaves_like "issuables list meta-data", :merge_request
+
context 'when page param' do
let(:last_page) { project.merge_requests.page().total_pages }
let!(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) }
diff --git a/spec/features/issuables/issuable_list_spec.rb b/spec/features/issuables/issuable_list_spec.rb
new file mode 100644
index 00000000000..e31bc40adc3
--- /dev/null
+++ b/spec/features/issuables/issuable_list_spec.rb
@@ -0,0 +1,57 @@
+require 'rails_helper'
+
+describe 'issuable list', feature: true do
+ let(:project) { create(:empty_project) }
+ let(:user) { create(:user) }
+
+ issuable_types = [:issue, :merge_request]
+
+ before do
+ project.add_user(user, :developer)
+ login_as(user)
+ issuable_types.each { |type| create_issuables(type) }
+ end
+
+ issuable_types.each do |issuable_type|
+ it "avoids N+1 database queries for #{issuable_type.to_s.humanize.pluralize}" do
+ control_count = ActiveRecord::QueryRecorder.new { visit_issuable_list(issuable_type) }.count
+
+ create_issuables(issuable_type)
+
+ expect { visit_issuable_list(issuable_type) }.not_to exceed_query_limit(control_count)
+ end
+
+ it "counts upvotes, downvotes and notes count for each #{issuable_type.to_s.humanize}" do
+ visit_issuable_list(issuable_type)
+
+ expect(first('.fa-thumbs-up').find(:xpath, '..')).to have_content(1)
+ expect(first('.fa-thumbs-down').find(:xpath, '..')).to have_content(1)
+ expect(first('.fa-comments').find(:xpath, '..')).to have_content(2)
+ end
+ end
+
+ def visit_issuable_list(issuable_type)
+ if issuable_type == :issue
+ visit namespace_project_issues_path(project.namespace, project)
+ else
+ visit namespace_project_merge_requests_path(project.namespace, project)
+ end
+ end
+
+ def create_issuables(issuable_type)
+ 3.times do
+ if issuable_type == :issue
+ issuable = create(:issue, project: project, author: user)
+ else
+ issuable = create(:merge_request, title: FFaker::Lorem.sentence, source_project: project, source_branch: FFaker::Name.name)
+ end
+
+ 2.times do
+ create(:note_on_issue, noteable: issuable, project: project, note: 'Test note')
+ end
+
+ create(:award_emoji, :downvote, awardable: issuable)
+ create(:award_emoji, :upvote, awardable: issuable)
+ end
+ end
+end
diff --git a/spec/support/issuables_list_metadata_shared_examples.rb b/spec/support/issuables_list_metadata_shared_examples.rb
new file mode 100644
index 00000000000..dac94dfc31e
--- /dev/null
+++ b/spec/support/issuables_list_metadata_shared_examples.rb
@@ -0,0 +1,35 @@
+shared_examples 'issuables list meta-data' do |issuable_type, action = nil|
+ before do
+ @issuable_ids = []
+
+ 2.times do
+ if issuable_type == :issue
+ issuable = create(issuable_type, project: project)
+ else
+ issuable = create(issuable_type, title: FFaker::Lorem.sentence, source_project: project, source_branch: FFaker::Name.name)
+ end
+
+ @issuable_ids << issuable.id
+
+ issuable.id.times { create(:note, noteable: issuable, project: issuable.project) }
+ (issuable.id + 1).times { create(:award_emoji, :downvote, awardable: issuable) }
+ (issuable.id + 2).times { create(:award_emoji, :upvote, awardable: issuable) }
+ end
+ end
+
+ it "creates indexed meta-data object for issuable notes and votes count" do
+ if action
+ get action
+ else
+ get :index, namespace_id: project.namespace.path, project_id: project.path
+ end
+
+ meta_data = assigns(:issuable_meta_data)
+
+ @issuable_ids.each do |id|
+ expect(meta_data[id].notes_count).to eq(id)
+ expect(meta_data[id].downvotes).to eq(id + 1)
+ expect(meta_data[id].upvotes).to eq(id + 2)
+ end
+ end
+end