diff options
author | Yorick Peterse <yorickpeterse@gmail.com> | 2015-11-19 10:05:53 +0000 |
---|---|---|
committer | Yorick Peterse <yorickpeterse@gmail.com> | 2015-11-19 10:05:53 +0000 |
commit | a42d469ab2ac13ba40544e4cb40659fb6953d548 (patch) | |
tree | 5e31b299b676f903fda20ed7b497b7804ab09436 /spec | |
parent | 5b30285407a050600c35145632d6901e81d94355 (diff) | |
parent | 96cdacd4eae3fb939f2da4ba0240f7dfa10b63da (diff) | |
download | gitlab-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.rb | 23 | ||||
-rw-r--r-- | spec/finders/contributed_projects_finder_spec.rb | 35 | ||||
-rw-r--r-- | spec/finders/group_finder_spec.rb | 15 | ||||
-rw-r--r-- | spec/finders/groups_finder_spec.rb | 48 | ||||
-rw-r--r-- | spec/finders/joined_groups_finder_spec.rb | 49 | ||||
-rw-r--r-- | spec/finders/personal_projects_finder_spec.rb | 34 | ||||
-rw-r--r-- | spec/finders/projects_finder_spec.rb | 75 | ||||
-rw-r--r-- | spec/lib/gitlab/sql/union_spec.rb | 16 | ||||
-rw-r--r-- | spec/models/event_spec.rb | 38 | ||||
-rw-r--r-- | spec/models/group_spec.rb | 27 | ||||
-rw-r--r-- | spec/models/project_spec.rb | 19 | ||||
-rw-r--r-- | spec/models/user_spec.rb | 34 |
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 |