summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorYorick Peterse <yorickpeterse@gmail.com>2015-11-19 10:05:53 +0000
committerYorick Peterse <yorickpeterse@gmail.com>2015-11-19 10:05:53 +0000
commita42d469ab2ac13ba40544e4cb40659fb6953d548 (patch)
tree5e31b299b676f903fda20ed7b497b7804ab09436 /spec
parent5b30285407a050600c35145632d6901e81d94355 (diff)
parent96cdacd4eae3fb939f2da4ba0240f7dfa10b63da (diff)
downloadgitlab-ce-a42d469ab2ac13ba40544e4cb40659fb6953d548.tar.gz
Merge branch 'atom-feed-latest-update' into 'master'
Improve performance of user profiles, finding groups, and finding projects This MR improves the following: * Rendering of profile pages and Atom feeds * Finding groups (using GroupsFinder & friends) * Finding projects (using ProjectsFinder & friends) Initially this MR was intended to only improve rendering of Atom feeds, but over time other fixes were introduced as well as the same code was the cause of all these problems. See merge request !1790
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/users_controller_spec.rb23
-rw-r--r--spec/finders/contributed_projects_finder_spec.rb35
-rw-r--r--spec/finders/group_finder_spec.rb15
-rw-r--r--spec/finders/groups_finder_spec.rb48
-rw-r--r--spec/finders/joined_groups_finder_spec.rb49
-rw-r--r--spec/finders/personal_projects_finder_spec.rb34
-rw-r--r--spec/finders/projects_finder_spec.rb75
-rw-r--r--spec/lib/gitlab/sql/union_spec.rb16
-rw-r--r--spec/models/event_spec.rb38
-rw-r--r--spec/models/group_spec.rb27
-rw-r--r--spec/models/project_spec.rb19
-rw-r--r--spec/models/user_spec.rb34
12 files changed, 354 insertions, 59 deletions
diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb
index 9f89101d7f7..104a5f50143 100644
--- a/spec/controllers/users_controller_spec.rb
+++ b/spec/controllers/users_controller_spec.rb
@@ -16,13 +16,26 @@ describe UsersController do
context 'with rendered views' do
render_views
- it 'renders the show template' do
- sign_in(user)
+ describe 'when logged in' do
+ before do
+ sign_in(user)
+ end
- get :show, username: user.username
+ it 'renders the show template' do
+ get :show, username: user.username
- expect(response).to be_success
- expect(response).to render_template('show')
+ expect(response).to be_success
+ expect(response).to render_template('show')
+ end
+ end
+
+ describe 'when logged out' do
+ it 'renders the show template' do
+ get :show, username: user.username
+
+ expect(response).to be_success
+ expect(response).to render_template('show')
+ end
end
end
end
diff --git a/spec/finders/contributed_projects_finder_spec.rb b/spec/finders/contributed_projects_finder_spec.rb
new file mode 100644
index 00000000000..65d7f14c721
--- /dev/null
+++ b/spec/finders/contributed_projects_finder_spec.rb
@@ -0,0 +1,35 @@
+require 'spec_helper'
+
+describe ContributedProjectsFinder do
+ let(:source_user) { create(:user) }
+ let(:current_user) { create(:user) }
+
+ let(:finder) { described_class.new(source_user) }
+
+ let!(:public_project) { create(:project, :public) }
+ let!(:private_project) { create(:project, :private) }
+
+ before do
+ private_project.team << [source_user, Gitlab::Access::MASTER]
+ private_project.team << [current_user, Gitlab::Access::DEVELOPER]
+ public_project.team << [source_user, Gitlab::Access::MASTER]
+
+ create(:event, action: Event::PUSHED, project: public_project,
+ target: public_project, author: source_user)
+
+ create(:event, action: Event::PUSHED, project: private_project,
+ target: private_project, author: source_user)
+ end
+
+ describe 'without a current user' do
+ subject { finder.execute }
+
+ it { is_expected.to eq([public_project]) }
+ end
+
+ describe 'with a current user' do
+ subject { finder.execute(current_user) }
+
+ it { is_expected.to eq([private_project, public_project]) }
+ end
+end
diff --git a/spec/finders/group_finder_spec.rb b/spec/finders/group_finder_spec.rb
deleted file mode 100644
index 78dc027837c..00000000000
--- a/spec/finders/group_finder_spec.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-require 'spec_helper'
-
-describe GroupsFinder do
- let(:user) { create :user }
- let!(:group) { create :group }
- let!(:public_group) { create :group, public: true }
-
- describe :execute do
- it 'finds public group' do
- groups = GroupsFinder.new.execute(user)
- expect(groups.size).to eq(1)
- expect(groups.first).to eq(public_group)
- end
- end
-end
diff --git a/spec/finders/groups_finder_spec.rb b/spec/finders/groups_finder_spec.rb
new file mode 100644
index 00000000000..4f6a000822e
--- /dev/null
+++ b/spec/finders/groups_finder_spec.rb
@@ -0,0 +1,48 @@
+require 'spec_helper'
+
+describe GroupsFinder do
+ describe '#execute' do
+ let(:user) { create(:user) }
+
+ let(:group1) { create(:group) }
+ let(:group2) { create(:group) }
+ let(:group3) { create(:group) }
+ let(:group4) { create(:group, public: true) }
+
+ let!(:public_project) { create(:project, :public, group: group1) }
+ let!(:internal_project) { create(:project, :internal, group: group2) }
+ let!(:private_project) { create(:project, :private, group: group3) }
+
+ let(:finder) { described_class.new }
+
+ describe 'with a user' do
+ subject { finder.execute(user) }
+
+ describe 'when the user is not a member of any groups' do
+ it { is_expected.to eq([group4, group2, group1]) }
+ end
+
+ describe 'when the user is a member of a group' do
+ before do
+ group3.add_user(user, Gitlab::Access::DEVELOPER)
+ end
+
+ it { is_expected.to eq([group4, group3, group2, group1]) }
+ end
+
+ describe 'when the user is a member of a private project' do
+ before do
+ private_project.team.add_user(user, Gitlab::Access::DEVELOPER)
+ end
+
+ it { is_expected.to eq([group4, group3, group2, group1]) }
+ end
+ end
+
+ describe 'without a user' do
+ subject { finder.execute }
+
+ it { is_expected.to eq([group4, group1]) }
+ end
+ end
+end
diff --git a/spec/finders/joined_groups_finder_spec.rb b/spec/finders/joined_groups_finder_spec.rb
new file mode 100644
index 00000000000..2d9068cc720
--- /dev/null
+++ b/spec/finders/joined_groups_finder_spec.rb
@@ -0,0 +1,49 @@
+require 'spec_helper'
+
+describe JoinedGroupsFinder do
+ describe '#execute' do
+ let(:source_user) { create(:user) }
+ let(:current_user) { create(:user) }
+
+ let(:group1) { create(:group) }
+ let(:group2) { create(:group) }
+ let(:group3) { create(:group) }
+ let(:group4) { create(:group, public: true) }
+
+ let!(:public_project) { create(:project, :public, group: group1) }
+ let!(:internal_project) { create(:project, :internal, group: group2) }
+ let!(:private_project) { create(:project, :private, group: group3) }
+
+ let(:finder) { described_class.new(source_user) }
+
+ before do
+ [group1, group2, group3, group4].each do |group|
+ group.add_user(source_user, Gitlab::Access::MASTER)
+ end
+ end
+
+ describe 'with a current user' do
+ describe 'when the current user has access to the projects of the source user' do
+ before do
+ private_project.team.add_user(current_user, Gitlab::Access::DEVELOPER)
+ end
+
+ subject { finder.execute(current_user) }
+
+ it { is_expected.to eq([group4, group3, group2, group1]) }
+ end
+
+ describe 'when the current user does not have access to the projects of the source user' do
+ subject { finder.execute(current_user) }
+
+ it { is_expected.to eq([group4, group2, group1]) }
+ end
+ end
+
+ describe 'without a current user' do
+ subject { finder.execute }
+
+ it { is_expected.to eq([group4, group1]) }
+ end
+ end
+end
diff --git a/spec/finders/personal_projects_finder_spec.rb b/spec/finders/personal_projects_finder_spec.rb
new file mode 100644
index 00000000000..38817add456
--- /dev/null
+++ b/spec/finders/personal_projects_finder_spec.rb
@@ -0,0 +1,34 @@
+require 'spec_helper'
+
+describe PersonalProjectsFinder do
+ let(:source_user) { create(:user) }
+ let(:current_user) { create(:user) }
+
+ let(:finder) { described_class.new(source_user) }
+
+ let!(:public_project) do
+ create(:project, :public, namespace: source_user.namespace, name: 'A',
+ path: 'A')
+ end
+
+ let!(:private_project) do
+ create(:project, :private, namespace: source_user.namespace, name: 'B',
+ path: 'B')
+ end
+
+ before do
+ private_project.team << [current_user, Gitlab::Access::DEVELOPER]
+ end
+
+ describe 'without a current user' do
+ subject { finder.execute }
+
+ it { is_expected.to eq([public_project]) }
+ end
+
+ describe 'with a current user' do
+ subject { finder.execute(current_user) }
+
+ it { is_expected.to eq([private_project, public_project]) }
+ end
+end
diff --git a/spec/finders/projects_finder_spec.rb b/spec/finders/projects_finder_spec.rb
index de9d4cd6128..d1dede78f74 100644
--- a/spec/finders/projects_finder_spec.rb
+++ b/spec/finders/projects_finder_spec.rb
@@ -1,51 +1,56 @@
require 'spec_helper'
describe ProjectsFinder do
- let(:user) { create :user }
- let(:group) { create :group }
+ describe '#execute' do
+ let(:user) { create(:user) }
- let(:project1) { create(:empty_project, :public, group: group) }
- let(:project2) { create(:empty_project, :internal, group: group) }
- let(:project3) { create(:empty_project, :private, group: group) }
- let(:project4) { create(:empty_project, :private, group: group) }
+ let!(:private_project) { create(:project, :private) }
+ let!(:internal_project) { create(:project, :internal) }
+ let!(:public_project) { create(:project, :public) }
- context 'non authenticated' do
- subject { ProjectsFinder.new.execute(nil, group: group) }
+ let(:finder) { described_class.new }
- it { is_expected.to include(project1) }
- it { is_expected.not_to include(project2) }
- it { is_expected.not_to include(project3) }
- it { is_expected.not_to include(project4) }
- end
+ describe 'without a group' do
+ describe 'without a user' do
+ subject { finder.execute }
- context 'authenticated' do
- subject { ProjectsFinder.new.execute(user, group: group) }
+ it { is_expected.to eq([public_project]) }
+ end
- it { is_expected.to include(project1) }
- it { is_expected.to include(project2) }
- it { is_expected.not_to include(project3) }
- it { is_expected.not_to include(project4) }
- end
+ describe 'with a user' do
+ subject { finder.execute(user) }
- context 'authenticated, project member' do
- before { project3.team << [user, :developer] }
+ describe 'without private projects' do
+ it { is_expected.to eq([public_project, internal_project]) }
+ end
- subject { ProjectsFinder.new.execute(user, group: group) }
+ describe 'with private projects' do
+ before do
+ private_project.team.add_user(user, Gitlab::Access::MASTER)
+ end
- it { is_expected.to include(project1) }
- it { is_expected.to include(project2) }
- it { is_expected.to include(project3) }
- it { is_expected.not_to include(project4) }
- end
+ it do
+ is_expected.to eq([public_project, internal_project,
+ private_project])
+ end
+ end
+ end
+ end
+
+ describe 'with a group' do
+ let(:group) { public_project.group }
+
+ describe 'without a user' do
+ subject { finder.execute(nil, group: group) }
- context 'authenticated, group member' do
- before { group.add_developer(user) }
+ it { is_expected.to eq([public_project]) }
+ end
- subject { ProjectsFinder.new.execute(user, group: group) }
+ describe 'with a user' do
+ subject { finder.execute(user, group: group) }
- it { is_expected.to include(project1) }
- it { is_expected.to include(project2) }
- it { is_expected.to include(project3) }
- it { is_expected.to include(project4) }
+ it { is_expected.to eq([public_project, internal_project]) }
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/sql/union_spec.rb b/spec/lib/gitlab/sql/union_spec.rb
new file mode 100644
index 00000000000..9e1cd4419e0
--- /dev/null
+++ b/spec/lib/gitlab/sql/union_spec.rb
@@ -0,0 +1,16 @@
+require 'spec_helper'
+
+describe Gitlab::SQL::Union do
+ describe '#to_sql' do
+ it 'returns a String joining relations together using a UNION' do
+ rel1 = User.where(email: 'alice@example.com')
+ rel2 = User.where(email: 'bob@example.com')
+ union = described_class.new([rel1, rel2])
+
+ sql1 = rel1.reorder(nil).to_sql
+ sql2 = rel2.reorder(nil).to_sql
+
+ expect(union.to_sql).to eq("#{sql1}\nUNION\n#{sql2}")
+ end
+ end
+end
diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb
index 0f32f162a10..ae53f7a536b 100644
--- a/spec/models/event_spec.rb
+++ b/spec/models/event_spec.rb
@@ -64,4 +64,42 @@ describe Event do
it { expect(@event.branch_name).to eq("master") }
it { expect(@event.author).to eq(@user) }
end
+
+ describe '.latest_update_time' do
+ describe 'when events are present' do
+ let(:time) { Time.utc(2015, 1, 1) }
+
+ before do
+ create(:closed_issue_event, updated_at: time)
+ create(:closed_issue_event, updated_at: time + 5)
+ end
+
+ it 'returns the latest update time' do
+ expect(Event.latest_update_time).to eq(time + 5)
+ end
+ end
+
+ describe 'when no events exist' do
+ it 'returns nil' do
+ expect(Event.latest_update_time).to be_nil
+ end
+ end
+ end
+
+ describe '.limit_recent' do
+ let!(:event1) { create(:closed_issue_event) }
+ let!(:event2) { create(:closed_issue_event) }
+
+ describe 'without an explicit limit' do
+ subject { Event.limit_recent }
+
+ it { is_expected.to eq([event2, event1]) }
+ end
+
+ describe 'with an explicit limit' do
+ subject { Event.limit_recent(1) }
+
+ it { is_expected.to eq([event2]) }
+ end
+ end
end
diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb
index bbfc5535eec..6f166b5ab75 100644
--- a/spec/models/group_spec.rb
+++ b/spec/models/group_spec.rb
@@ -38,6 +38,33 @@ describe Group do
it { is_expected.not_to validate_presence_of :owner }
end
+ describe '.public_and_given_groups' do
+ let!(:public_group) { create(:group, public: true) }
+
+ subject { described_class.public_and_given_groups([group.id]) }
+
+ it { is_expected.to eq([public_group, group]) }
+ end
+
+ describe '.visible_to_user' do
+ let!(:group) { create(:group) }
+ let!(:user) { create(:user) }
+
+ subject { described_class.visible_to_user(user) }
+
+ describe 'when the user has access to a group' do
+ before do
+ group.add_user(user, Gitlab::Access::MASTER)
+ end
+
+ it { is_expected.to eq([group]) }
+ end
+
+ describe 'when the user does not have access to any groups' do
+ it { is_expected.to eq([]) }
+ end
+ end
+
describe '#to_reference' do
it 'returns a String reference to the object' do
expect(group.to_reference).to eq "@#{group.name}"
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 8d7e6e76766..c42e8870f8c 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -464,4 +464,23 @@ describe Project do
end
end
end
+
+ describe '.visible_to_user' do
+ let!(:project) { create(:project, :private) }
+ let!(:user) { create(:user) }
+
+ subject { described_class.visible_to_user(user) }
+
+ describe 'when a user has access to a project' do
+ before do
+ project.team.add_user(user, Gitlab::Access::MASTER)
+ end
+
+ it { is_expected.to eq([project]) }
+ end
+
+ describe 'when a user does not have access to any projects' do
+ it { is_expected.to eq([]) }
+ end
+ end
end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 7d716c23120..4631b12faf1 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -686,7 +686,7 @@ describe User do
end
end
- describe "#contributed_projects_ids" do
+ describe "#contributed_projects" do
subject { create(:user) }
let!(:project1) { create(:project) }
let!(:project2) { create(:project, forked_from_project: project3) }
@@ -701,15 +701,15 @@ describe User do
end
it "includes IDs for projects the user has pushed to" do
- expect(subject.contributed_projects_ids).to include(project1.id)
+ expect(subject.contributed_projects).to include(project1)
end
it "includes IDs for projects the user has had merge requests merged into" do
- expect(subject.contributed_projects_ids).to include(project3.id)
+ expect(subject.contributed_projects).to include(project3)
end
it "doesn't include IDs for unrelated projects" do
- expect(subject.contributed_projects_ids).not_to include(project2.id)
+ expect(subject.contributed_projects).not_to include(project2)
end
end
@@ -758,4 +758,30 @@ describe User do
expect(subject.recent_push).to eq(nil)
end
end
+
+ describe '#authorized_groups' do
+ let!(:user) { create(:user) }
+ let!(:private_group) { create(:group) }
+
+ before do
+ private_group.add_user(user, Gitlab::Access::MASTER)
+ end
+
+ subject { user.authorized_groups }
+
+ it { is_expected.to eq([private_group]) }
+ end
+
+ describe '#authorized_projects' do
+ let!(:user) { create(:user) }
+ let!(:private_project) { create(:project, :private) }
+
+ before do
+ private_project.team << [user, Gitlab::Access::MASTER]
+ end
+
+ subject { user.authorized_projects }
+
+ it { is_expected.to eq([private_project]) }
+ end
end