summaryrefslogtreecommitdiff
path: root/spec/models
diff options
context:
space:
mode:
authorRémy Coutable <remy@rymai.me>2016-04-18 18:53:32 +0200
committerRémy Coutable <remy@rymai.me>2016-06-14 13:07:26 +0200
commitd26f81239a33b80694783ee35f0da0e2ed082c9b (patch)
treef092e818d4b81805a16879b13407a335bbda0054 /spec/models
parent17c22156c5fa5663aae65178ed38cbeef9a80b7e (diff)
downloadgitlab-ce-d26f81239a33b80694783ee35f0da0e2ed082c9b.tar.gz
Add request access for groups
Signed-off-by: Rémy Coutable <remy@rymai.me>
Diffstat (limited to 'spec/models')
-rw-r--r--spec/models/concerns/access_requestable_spec.rb41
-rw-r--r--spec/models/group_spec.rb59
-rw-r--r--spec/models/member_spec.rb89
-rw-r--r--spec/models/members/group_member_spec.rb22
-rw-r--r--spec/models/members/project_member_spec.rb22
-rw-r--r--spec/models/project_spec.rb11
-rw-r--r--spec/models/project_team_spec.rb150
7 files changed, 336 insertions, 58 deletions
diff --git a/spec/models/concerns/access_requestable_spec.rb b/spec/models/concerns/access_requestable_spec.rb
new file mode 100644
index 00000000000..2dfed1eb4c4
--- /dev/null
+++ b/spec/models/concerns/access_requestable_spec.rb
@@ -0,0 +1,41 @@
+require 'spec_helper'
+
+describe AccessRequestable do
+ describe 'Group' do
+ describe '#request_access' do
+ let(:group) { create(:group, :public) }
+ let(:user) { create(:user) }
+
+ it { expect(group.request_access(user)).to be_a(GroupMember) }
+ it { expect(group.request_access(user).user).to be_nil }
+ it { expect(group.request_access(user).created_by).to eq(user) }
+ end
+
+ describe '#access_requested?' do
+ let(:group) { create(:group, :public) }
+ let(:user) { create(:user) }
+
+ before { group.request_access(user) }
+
+ it { expect(group.access_requested?(user)).to be_truthy }
+ end
+ end
+
+ describe 'Project' do
+ describe '#request_access' do
+ let(:project) { create(:empty_project, :public) }
+ let(:user) { create(:user) }
+
+ it { expect(project.request_access(user)).to be_a(ProjectMember) }
+ end
+
+ describe '#access_requested?' do
+ let(:project) { create(:empty_project, :public) }
+ let(:user) { create(:user) }
+
+ before { project.request_access(user) }
+
+ it { expect(project.access_requested?(user)).to be_truthy }
+ end
+ end
+end
diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb
index 6fa16be7f04..52f9d57bc0a 100644
--- a/spec/models/group_spec.rb
+++ b/spec/models/group_spec.rb
@@ -5,7 +5,22 @@ describe Group, models: true do
describe 'associations' do
it { is_expected.to have_many :projects }
- it { is_expected.to have_many :group_members }
+ it { is_expected.to have_many(:group_members).dependent(:destroy) }
+ it { is_expected.to have_many(:users).through(:group_members) }
+ it { is_expected.to have_many(:project_group_links).dependent(:destroy) }
+ it { is_expected.to have_many(:shared_projects).through(:project_group_links) }
+ it { is_expected.to have_many(:notification_settings).dependent(:destroy) }
+
+ describe '#group_members' do
+ let(:user) { create(:user) }
+ let(:group) { create(:group) }
+
+ before { group.request_access(user) }
+
+ it 'does not includes membership requests' do
+ expect(user.group_members).to be_empty
+ end
+ end
end
describe 'modules' do
@@ -131,4 +146,46 @@ describe Group, models: true do
expect(described_class.search(group.path.upcase)).to eq([group])
end
end
+
+ describe '#has_owner?' do
+ before { @members = setup_group_members(group) }
+
+ it { expect(group.has_owner?(@members[:owner])).to be_truthy }
+ it { expect(group.has_owner?(@members[:master])).to be_falsey }
+ it { expect(group.has_owner?(@members[:developer])).to be_falsey }
+ it { expect(group.has_owner?(@members[:reporter])).to be_falsey }
+ it { expect(group.has_owner?(@members[:guest])).to be_falsey }
+ it { expect(group.has_owner?(@members[:requester])).to be_falsey }
+ end
+
+ describe '#has_master?' do
+ before { @members = setup_group_members(group) }
+
+ it { expect(group.has_master?(@members[:owner])).to be_falsey }
+ it { expect(group.has_master?(@members[:master])).to be_truthy }
+ it { expect(group.has_master?(@members[:developer])).to be_falsey }
+ it { expect(group.has_master?(@members[:reporter])).to be_falsey }
+ it { expect(group.has_master?(@members[:guest])).to be_falsey }
+ it { expect(group.has_master?(@members[:requester])).to be_falsey }
+ end
+
+ def setup_group_members(group)
+ members = {
+ owner: create(:user),
+ master: create(:user),
+ developer: create(:user),
+ reporter: create(:user),
+ guest: create(:user),
+ requester: create(:user)
+ }
+
+ group.add_user(members[:owner], GroupMember::OWNER)
+ group.add_user(members[:master], GroupMember::MASTER)
+ group.add_user(members[:developer], GroupMember::DEVELOPER)
+ group.add_user(members[:reporter], GroupMember::REPORTER)
+ group.add_user(members[:guest], GroupMember::GUEST)
+ group.request_access(members[:requester])
+
+ members
+ end
end
diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb
index 6e51730eecd..a3d525d8d56 100644
--- a/spec/models/member_spec.rb
+++ b/spec/models/member_spec.rb
@@ -55,6 +55,47 @@ describe Member, models: true do
end
end
+ describe 'Scopes' do
+ before do
+ project = create(:project)
+ @invited_member = build(:project_member, user: nil).tap { |m| m.generate_invite_token! }
+ @accepted_invite_member = build(:project_member, user: nil).tap { |m| m.generate_invite_token! && m.accept_invite!(build(:user)) }
+
+ requested_user = create(:user).tap { |u| project.request_access(u) }
+ @requested_member = project.project_members.find_by(created_by_id: requested_user.id)
+ accepted_request_user = create(:user).tap { |u| project.request_access(u) }
+ @accepted_request_member = project.project_members.find_by(created_by_id: accepted_request_user.id).tap { |m| m.accept_request }
+ end
+
+ describe '#invite' do
+ it { expect(described_class.invite).to include @invited_member }
+ it { expect(described_class.invite).not_to include @accepted_invite_member }
+ it { expect(described_class.invite).not_to include @requested_member }
+ it { expect(described_class.invite).not_to include @accepted_request_member }
+ end
+
+ describe '#request' do
+ it { expect(described_class.request).not_to include @invited_member }
+ it { expect(described_class.request).not_to include @accepted_invite_member }
+ it { expect(described_class.request).to include @requested_member }
+ it { expect(described_class.request).not_to include @accepted_request_member }
+ end
+
+ describe '#non_request' do
+ it { expect(described_class.non_request).to include @invited_member }
+ it { expect(described_class.non_request).to include @accepted_invite_member }
+ it { expect(described_class.non_request).not_to include @requested_member }
+ it { expect(described_class.non_request).to include @accepted_request_member }
+ end
+
+ describe '#non_pending' do
+ it { expect(described_class.non_pending).not_to include @invited_member }
+ it { expect(described_class.non_pending).to include @accepted_invite_member }
+ it { expect(described_class.non_pending).not_to include @requested_member }
+ it { expect(described_class.non_pending).to include @accepted_request_member }
+ end
+ end
+
describe "Delegate methods" do
it { is_expected.to respond_to(:user_name) }
it { is_expected.to respond_to(:user_email) }
@@ -97,6 +138,54 @@ describe Member, models: true do
end
end
+ describe '#accept_request' do
+ let(:user) { create(:user) }
+ let(:member) { create(:project_member, requested_at: Time.now.utc, user: nil, created_by: user) }
+
+ it 'returns true' do
+ expect(member.accept_request).to be_truthy
+ end
+
+ it 'sets the user' do
+ member.accept_request
+
+ expect(member.user).to eq(user)
+ end
+
+ it 'clears requested_at' do
+ member.accept_request
+
+ expect(member.requested_at).to be_nil
+ end
+
+ it 'calls #after_accept_request' do
+ expect(member).to receive(:after_accept_request)
+
+ member.accept_request
+ end
+ end
+
+ describe '#decline_request' do
+ let(:user) { create(:user) }
+ let(:member) { create(:project_member, requested_at: Time.now.utc, user: nil, created_by: user) }
+
+ it 'returns true' do
+ expect(member.decline_request).to be_truthy
+ end
+
+ it 'destroys the member' do
+ member.decline_request
+
+ expect(member).to be_destroyed
+ end
+
+ it 'calls #after_decline_request' do
+ expect(member).to receive(:after_decline_request)
+
+ member.decline_request
+ end
+ end
+
describe "#accept_invite!" do
let!(:member) { create(:project_member, invite_email: "user@example.com", user: nil) }
let(:user) { create(:user) }
diff --git a/spec/models/members/group_member_spec.rb b/spec/models/members/group_member_spec.rb
index 5424c9b9cba..c3070d4cb78 100644
--- a/spec/models/members/group_member_spec.rb
+++ b/spec/models/members/group_member_spec.rb
@@ -20,7 +20,7 @@
require 'spec_helper'
describe GroupMember, models: true do
- context 'notification' do
+ describe 'notifications' do
describe "#after_create" do
it "should send email to user" do
membership = build(:group_member)
@@ -50,5 +50,25 @@ describe GroupMember, models: true do
@group_member.update_attribute(:access_level, GroupMember::OWNER)
end
end
+
+ describe 'after accept_request' do
+ let(:member) { create(:group_member, user: nil, created_by: build_stubbed(:user), requested_at: Time.now) }
+
+ it "calls #accept_group_access_request" do
+ expect_any_instance_of(NotificationService).to receive(:new_group_member)
+
+ member.accept_request
+ end
+ end
+
+ describe 'after decline_request' do
+ let(:member) { create(:group_member, user: nil, created_by: build_stubbed(:user), requested_at: Time.now) }
+
+ it "calls #decline_group_access_request" do
+ expect_any_instance_of(NotificationService).to receive(:decline_group_access_request)
+
+ member.decline_request
+ end
+ end
end
end
diff --git a/spec/models/members/project_member_spec.rb b/spec/models/members/project_member_spec.rb
index 9f13874b532..99b3c77c6cd 100644
--- a/spec/models/members/project_member_spec.rb
+++ b/spec/models/members/project_member_spec.rb
@@ -135,4 +135,26 @@ describe ProjectMember, models: true do
it { expect(@project_1.users).to be_empty }
it { expect(@project_2.users).to be_empty }
end
+
+ describe 'notifications' do
+ describe 'after accept_request' do
+ let(:member) { create(:project_member, user: nil, created_by: build_stubbed(:user), requested_at: Time.now) }
+
+ it 'calls #accept_project_access_request' do
+ expect_any_instance_of(NotificationService).to receive(:new_project_member)
+
+ member.accept_request
+ end
+ end
+
+ describe 'after decline_request' do
+ let(:member) { create(:project_member, user: nil, created_by: build_stubbed(:user), requested_at: Time.now) }
+
+ it 'calls #decline_project_access_request' do
+ expect_any_instance_of(NotificationService).to receive(:decline_project_access_request)
+
+ member.decline_request
+ end
+ end
+ end
end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index de8815f5a38..d5a4b73affd 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -29,6 +29,17 @@ describe Project, models: true do
it { is_expected.to have_many(:variables) }
it { is_expected.to have_many(:triggers) }
it { is_expected.to have_many(:todos).dependent(:destroy) }
+
+ describe '#project_members' do
+ let(:user) { create(:user) }
+ let(:project) { create(:project) }
+
+ before { project.request_access(user) }
+
+ it 'does not includes membership requests' do
+ expect(user.project_members).to be_empty
+ end
+ end
end
describe 'modules' do
diff --git a/spec/models/project_team_spec.rb b/spec/models/project_team_spec.rb
index 8bebd6a9447..36b1f439955 100644
--- a/spec/models/project_team_spec.rb
+++ b/spec/models/project_team_spec.rb
@@ -73,69 +73,107 @@ describe ProjectTeam, models: true do
end
end
- describe :max_invited_level do
- let(:group) { create(:group) }
- let(:project) { create(:empty_project) }
-
- before do
- project.project_group_links.create(
- group: group,
- group_access: Gitlab::Access::DEVELOPER
- )
-
- group.add_user(master, Gitlab::Access::MASTER)
- group.add_user(reporter, Gitlab::Access::REPORTER)
+ describe '#find_member' do
+ context 'personal project' do
+ let(:project) { create(:empty_project) }
+ let(:requester) { create(:user) }
+
+ before do
+ project.team << [master, :master]
+ project.team << [reporter, :reporter]
+ project.team << [guest, :guest]
+ project.request_access(requester)
+ end
+
+ it { expect(project.team.find_member(master.id)).to be_a(ProjectMember) }
+ it { expect(project.team.find_member(reporter.id)).to be_a(ProjectMember) }
+ it { expect(project.team.find_member(guest.id)).to be_a(ProjectMember) }
+ it { expect(project.team.find_member(nonmember.id)).to be_nil }
+ it { expect(project.team.find_member(requester.id)).to be_nil }
end
- it { expect(project.team.max_invited_level(master.id)).to eq(Gitlab::Access::DEVELOPER) }
- it { expect(project.team.max_invited_level(reporter.id)).to eq(Gitlab::Access::REPORTER) }
- it { expect(project.team.max_invited_level(nonmember.id)).to be_nil }
- end
-
- describe :max_member_access do
- let(:group) { create(:group) }
- let(:project) { create(:empty_project) }
-
- before do
- project.project_group_links.create(
- group: group,
- group_access: Gitlab::Access::DEVELOPER
- )
-
- group.add_user(master, Gitlab::Access::MASTER)
- group.add_user(reporter, Gitlab::Access::REPORTER)
- end
-
- it { expect(project.team.max_member_access(master.id)).to eq(Gitlab::Access::DEVELOPER) }
- it { expect(project.team.max_member_access(reporter.id)).to eq(Gitlab::Access::REPORTER) }
- it { expect(project.team.max_member_access(nonmember.id)).to be_nil }
-
- it "does not have an access" do
- project.namespace.update(share_with_group_lock: true)
- expect(project.team.max_member_access(master.id)).to be_nil
- expect(project.team.max_member_access(reporter.id)).to be_nil
+ context 'group project' do
+ let(:group) { create(:group) }
+ let(:project) { create(:empty_project, group: group) }
+ let(:requester) { create(:user) }
+
+ before do
+ group.add_master(master)
+ group.add_reporter(reporter)
+ group.add_guest(guest)
+ group.request_access(requester)
+ end
+
+ it { expect(project.team.find_member(master.id)).to be_a(GroupMember) }
+ it { expect(project.team.find_member(reporter.id)).to be_a(GroupMember) }
+ it { expect(project.team.find_member(guest.id)).to be_a(GroupMember) }
+ it { expect(project.team.find_member(nonmember.id)).to be_nil }
+ it { expect(project.team.find_member(requester.id)).to be_nil }
end
end
- describe "#human_max_access" do
- it 'returns Master role' do
- user = create(:user)
- group = create(:group)
- group.add_master(user)
-
- project = build_stubbed(:empty_project, namespace: group)
-
- expect(project.team.human_max_access(user.id)).to eq 'Master'
+ describe '#max_member_access' do
+ let(:requester) { create(:user) }
+
+ context 'personal project' do
+ let(:project) { create(:empty_project) }
+
+ context 'when project is not shared with group' do
+ before do
+ project.team << [master, :master]
+ project.team << [reporter, :reporter]
+ project.team << [guest, :guest]
+ project.request_access(requester)
+ end
+
+ it { expect(project.team.max_member_access(master.id)).to eq(Gitlab::Access::MASTER) }
+ it { expect(project.team.max_member_access(reporter.id)).to eq(Gitlab::Access::REPORTER) }
+ it { expect(project.team.max_member_access(guest.id)).to eq(Gitlab::Access::GUEST) }
+ it { expect(project.team.max_member_access(nonmember.id)).to be_nil }
+ it { expect(project.team.max_member_access(requester.id)).to be_nil }
+ end
+
+ context 'when project is shared with group' do
+ before do
+ group = create(:group)
+ project.project_group_links.create(
+ group: group,
+ group_access: Gitlab::Access::DEVELOPER)
+
+ group.add_master(master)
+ group.add_reporter(reporter)
+ end
+
+ it { expect(project.team.max_member_access(master.id)).to eq(Gitlab::Access::DEVELOPER) }
+ it { expect(project.team.max_member_access(reporter.id)).to eq(Gitlab::Access::REPORTER) }
+ it { expect(project.team.max_member_access(nonmember.id)).to be_nil }
+ it { expect(project.team.max_member_access(requester.id)).to be_nil }
+
+ context 'but share_with_group_lock is true' do
+ before { project.namespace.update(share_with_group_lock: true) }
+
+ it { expect(project.team.max_member_access(master.id)).to be_nil }
+ it { expect(project.team.max_member_access(reporter.id)).to be_nil }
+ end
+ end
end
- it 'returns Owner role' do
- user = create(:user)
- group = create(:group)
- group.add_owner(user)
-
- project = build_stubbed(:empty_project, namespace: group)
-
- expect(project.team.human_max_access(user.id)).to eq 'Owner'
+ context 'group project' do
+ let(:group) { create(:group) }
+ let(:project) { create(:empty_project, group: group) }
+
+ before do
+ group.add_master(master)
+ group.add_reporter(reporter)
+ group.add_guest(guest)
+ group.request_access(requester)
+ end
+
+ it { expect(project.team.max_member_access(master.id)).to eq(Gitlab::Access::MASTER) }
+ it { expect(project.team.max_member_access(reporter.id)).to eq(Gitlab::Access::REPORTER) }
+ it { expect(project.team.max_member_access(guest.id)).to eq(Gitlab::Access::GUEST) }
+ it { expect(project.team.max_member_access(nonmember.id)).to be_nil }
+ it { expect(project.team.max_member_access(requester.id)).to be_nil }
end
end
end