Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
gitlab-ce
Commits
50d7c356
Commit
50d7c356
authored
Dec 05, 2017
by
Rémy Coutable
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Present member collection at the controller level
Signed-off-by:
Rémy Coutable
<
remy@rymai.me
>
parent
2cf3fc18
Changes
15
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
95 additions
and
42 deletions
+95
-42
app/controllers/admin/groups_controller.rb
app/controllers/admin/groups_controller.rb
+6
-2
app/controllers/admin/projects_controller.rb
app/controllers/admin/projects_controller.rb
+8
-3
app/controllers/concerns/members_presentation.rb
app/controllers/concerns/members_presentation.rb
+11
-0
app/controllers/groups/group_members_controller.rb
app/controllers/groups/group_members_controller.rb
+5
-2
app/controllers/projects/project_members_controller.rb
app/controllers/projects/project_members_controller.rb
+4
-2
app/presenters/member_presenter.rb
app/presenters/member_presenter.rb
+4
-6
app/presenters/members_presenter.rb
app/presenters/members_presenter.rb
+15
-0
app/views/projects/project_members/_team.html.haml
app/views/projects/project_members/_team.html.haml
+6
-4
app/views/projects/project_members/index.html.haml
app/views/projects/project_members/index.html.haml
+1
-1
app/views/shared/members/_member.html.haml
app/views/shared/members/_member.html.haml
+11
-13
app/views/shared/members/_requests.html.haml
app/views/shared/members/_requests.html.haml
+11
-8
lib/gitlab/view/presenter/factory.rb
lib/gitlab/view/presenter/factory.rb
+1
-1
spec/lib/gitlab/view/presenter/factory_spec.rb
spec/lib/gitlab/view/presenter/factory_spec.rb
+8
-0
spec/presenters/group_member_presenter_spec.rb
spec/presenters/group_member_presenter_spec.rb
+2
-0
spec/presenters/project_member_presenter_spec.rb
spec/presenters/project_member_presenter_spec.rb
+2
-0
No files found.
app/controllers/admin/groups_controller.rb
View file @
50d7c356
class
Admin::GroupsController
<
Admin
::
ApplicationController
class
Admin::GroupsController
<
Admin
::
ApplicationController
include
MembersPresentation
before_action
:group
,
only:
[
:edit
,
:update
,
:destroy
,
:project_update
,
:members_update
]
before_action
:group
,
only:
[
:edit
,
:update
,
:destroy
,
:project_update
,
:members_update
]
def
index
def
index
...
@@ -10,8 +12,10 @@ class Admin::GroupsController < Admin::ApplicationController
...
@@ -10,8 +12,10 @@ class Admin::GroupsController < Admin::ApplicationController
def
show
def
show
@group
=
Group
.
with_statistics
.
joins
(
:route
).
group
(
'routes.path'
).
find_by_full_path
(
params
[
:id
])
@group
=
Group
.
with_statistics
.
joins
(
:route
).
group
(
'routes.path'
).
find_by_full_path
(
params
[
:id
])
@members
=
@group
.
members
.
order
(
"access_level DESC"
).
page
(
params
[
:members_page
])
@members
=
present_members
(
@requesters
=
AccessRequestsFinder
.
new
(
@group
).
execute
(
current_user
)
@group
.
members
.
order
(
"access_level DESC"
).
page
(
params
[
:members_page
]))
@requesters
=
present_members
(
AccessRequestsFinder
.
new
(
@group
).
execute
(
current_user
))
@projects
=
@group
.
projects
.
with_statistics
.
page
(
params
[
:projects_page
])
@projects
=
@group
.
projects
.
with_statistics
.
page
(
params
[
:projects_page
])
end
end
...
...
app/controllers/admin/projects_controller.rb
View file @
50d7c356
class
Admin::ProjectsController
<
Admin
::
ApplicationController
class
Admin::ProjectsController
<
Admin
::
ApplicationController
include
MembersPresentation
before_action
:project
,
only:
[
:show
,
:transfer
,
:repository_check
]
before_action
:project
,
only:
[
:show
,
:transfer
,
:repository_check
]
before_action
:group
,
only:
[
:show
,
:transfer
]
before_action
:group
,
only:
[
:show
,
:transfer
]
...
@@ -19,11 +21,14 @@ class Admin::ProjectsController < Admin::ApplicationController
...
@@ -19,11 +21,14 @@ class Admin::ProjectsController < Admin::ApplicationController
def
show
def
show
if
@group
if
@group
@group_members
=
@group
.
members
.
order
(
"access_level DESC"
).
page
(
params
[
:group_members_page
])
@group_members
=
present_members
(
@group
.
members
.
order
(
"access_level DESC"
).
page
(
params
[
:group_members_page
]))
end
end
@project_members
=
@project
.
members
.
page
(
params
[
:project_members_page
])
@project_members
=
present_members
(
@requesters
=
AccessRequestsFinder
.
new
(
@project
).
execute
(
current_user
)
@project
.
members
.
page
(
params
[
:project_members_page
]))
@requesters
=
present_members
(
AccessRequestsFinder
.
new
(
@project
).
execute
(
current_user
))
end
end
def
transfer
def
transfer
...
...
app/controllers/concerns/members_presentation.rb
0 → 100644
View file @
50d7c356
module
MembersPresentation
extend
ActiveSupport
::
Concern
def
present_members
(
members
)
Gitlab
::
View
::
Presenter
::
Factory
.
new
(
members
,
current_user:
current_user
,
presenter_class:
MembersPresenter
).
fabricate!
end
end
app/controllers/groups/group_members_controller.rb
View file @
50d7c356
class
Groups::GroupMembersController
<
Groups
::
ApplicationController
class
Groups::GroupMembersController
<
Groups
::
ApplicationController
include
MembershipActions
include
MembershipActions
include
MembersPresentation
include
SortingHelper
include
SortingHelper
# Authorize
# Authorize
...
@@ -14,15 +15,17 @@ class Groups::GroupMembersController < Groups::ApplicationController
...
@@ -14,15 +15,17 @@ class Groups::GroupMembersController < Groups::ApplicationController
@members
=
@members
.
search
(
params
[
:search
])
if
params
[
:search
].
present?
@members
=
@members
.
search
(
params
[
:search
])
if
params
[
:search
].
present?
@members
=
@members
.
sort
(
@sort
)
@members
=
@members
.
sort
(
@sort
)
@members
=
@members
.
page
(
params
[
:page
]).
per
(
50
)
@members
=
@members
.
page
(
params
[
:page
]).
per
(
50
)
@members
.
includes
(
:user
)
@members
=
present_members
(
@members
.
includes
(
:user
)
)
@requesters
=
AccessRequestsFinder
.
new
(
@group
).
execute
(
current_user
)
@requesters
=
present_members
(
AccessRequestsFinder
.
new
(
@group
).
execute
(
current_user
))
@group_member
=
@group
.
group_members
.
new
@group_member
=
@group
.
group_members
.
new
end
end
def
update
def
update
@group_member
=
@group
.
members_and_requesters
.
find
(
params
[
:id
])
@group_member
=
@group
.
members_and_requesters
.
find
(
params
[
:id
])
.
present
(
current_user:
current_user
)
return
render_403
unless
can?
(
current_user
,
:update_group_member
,
@group_member
)
return
render_403
unless
can?
(
current_user
,
:update_group_member
,
@group_member
)
...
...
app/controllers/projects/project_members_controller.rb
View file @
50d7c356
class
Projects::ProjectMembersController
<
Projects
::
ApplicationController
class
Projects::ProjectMembersController
<
Projects
::
ApplicationController
include
MembershipActions
include
MembershipActions
include
MembersPresentation
include
SortingHelper
include
SortingHelper
# Authorize
# Authorize
...
@@ -20,13 +21,14 @@ class Projects::ProjectMembersController < Projects::ApplicationController
...
@@ -20,13 +21,14 @@ class Projects::ProjectMembersController < Projects::ApplicationController
@group_links
=
@group_links
.
where
(
group_id:
@project
.
invited_groups
.
search
(
params
[
:search
]).
select
(
:id
))
@group_links
=
@group_links
.
where
(
group_id:
@project
.
invited_groups
.
search
(
params
[
:search
]).
select
(
:id
))
end
end
@project_members
=
@project_members
.
sort
(
@sort
).
page
(
params
[
:page
]
)
@project_members
=
present_members
(
@project_members
.
sort
(
@sort
).
page
(
params
[
:page
])
)
@requesters
=
AccessRequestsFinder
.
new
(
@project
).
execute
(
current_user
)
@requesters
=
present_members
(
AccessRequestsFinder
.
new
(
@project
).
execute
(
current_user
)
)
@project_member
=
@project
.
project_members
.
new
@project_member
=
@project
.
project_members
.
new
end
end
def
update
def
update
@project_member
=
@project
.
members_and_requesters
.
find
(
params
[
:id
])
@project_member
=
@project
.
members_and_requesters
.
find
(
params
[
:id
])
.
present
(
current_user:
current_user
)
return
render_403
unless
can?
(
current_user
,
:update_project_member
,
@project_member
)
return
render_403
unless
can?
(
current_user
,
:update_project_member
,
@project_member
)
...
...
app/presenters/member_presenter.rb
View file @
50d7c356
class
MemberPresenter
<
Gitlab
::
View
::
Presenter
::
Delegated
class
MemberPresenter
<
Gitlab
::
View
::
Presenter
::
Delegated
include
Gitlab
::
Allowable
presents
:member
presents
:member
def
access_level_roles
member
.
class
.
access_level_roles
end
def
can_resend_invite?
def
can_resend_invite?
invite?
&&
invite?
&&
can?
(
current_user
,
admin_member_permission
,
source
)
can?
(
current_user
,
admin_member_permission
,
source
)
...
@@ -12,10 +14,6 @@ class MemberPresenter < Gitlab::View::Presenter::Delegated
...
@@ -12,10 +14,6 @@ class MemberPresenter < Gitlab::View::Presenter::Delegated
can?
(
current_user
,
update_member_permission
,
member
)
can?
(
current_user
,
update_member_permission
,
member
)
end
end
def
cannot_update?
!
can_update?
end
def
can_remove?
def
can_remove?
can?
(
current_user
,
destroy_member_permission
,
member
)
can?
(
current_user
,
destroy_member_permission
,
member
)
end
end
...
...
app/presenters/members_presenter.rb
0 → 100644
View file @
50d7c356
class
MembersPresenter
<
Gitlab
::
View
::
Presenter
::
Delegated
include
Enumerable
presents
:members
def
to_ary
to_a
end
def
each
members
.
each
do
|
member
|
yield
member
.
present
(
current_user:
current_user
)
end
end
end
app/views/projects/project_members/_team.html.haml
View file @
50d7c356
-
project
=
local_assigns
.
fetch
(
:project
)
-
members
=
local_assigns
.
fetch
(
:members
)
.panel.panel-default
.panel.panel-default
.panel-heading.flex-project-members-panel
.panel-heading.flex-project-members-panel
%span
.flex-project-title
%span
.flex-project-title
Members of
Members of
%strong
%strong
=
project
.
name
#{
@project
.
name
}
%span
.badge
=
members
.
total_count
%span
.badge
=
@project_members
.
total_count
=
form_tag
project_project_members_path
(
project
),
method: :get
,
class:
'form-inline member-search-form flex-project-members-form'
do
=
form_tag
project_project_members_path
(
@project
),
method: :get
,
class:
'form-inline member-search-form flex-project-members-form'
do
.form-group
.form-group
=
search_field_tag
:search
,
params
[
:search
],
{
placeholder:
'Find existing members by name'
,
class:
'form-control'
,
spellcheck:
false
}
=
search_field_tag
:search
,
params
[
:search
],
{
placeholder:
'Find existing members by name'
,
class:
'form-control'
,
spellcheck:
false
}
%button
.member-search-btn
{
type:
"submit"
,
"aria-label"
=>
"Submit search"
}
%button
.member-search-btn
{
type:
"submit"
,
"aria-label"
=>
"Submit search"
}
...
...
app/views/projects/project_members/index.html.haml
View file @
50d7c356
...
@@ -37,5 +37,5 @@
...
@@ -37,5 +37,5 @@
-
if
@group_links
.
any?
-
if
@group_links
.
any?
=
render
'projects/project_members/groups'
,
group_links:
@group_links
=
render
'projects/project_members/groups'
,
group_links:
@group_links
=
render
'projects/project_members/team'
,
members:
@project_members
=
render
'projects/project_members/team'
,
project:
@project
,
members:
@project_members
=
paginate
@project_members
,
theme:
"gitlab"
=
paginate
@project_members
,
theme:
"gitlab"
app/views/shared/members/_member.html.haml
View file @
50d7c356
-
show_roles
=
local_assigns
.
fetch
(
:show_roles
,
true
)
-
show_roles
=
local_assigns
.
fetch
(
:show_roles
,
true
)
-
show_controls
=
local_assigns
.
fetch
(
:show_controls
,
true
)
-
show_controls
=
local_assigns
.
fetch
(
:show_controls
,
true
)
-
force_mobile_view
=
local_assigns
.
fetch
(
:force_mobile_view
,
false
)
-
force_mobile_view
=
local_assigns
.
fetch
(
:force_mobile_view
,
false
)
-
member
=
local_assigns
.
fetch
(
:member
)
-
user
=
local_assigns
.
fetch
(
:user
,
member
.
user
)
-
user
=
local_assigns
.
fetch
(
:user
,
member
.
user
)
-
source
=
member
.
source
-
source
=
member
.
source
-
member_presenter
=
member
.
present
(
current_user:
current_user
)
%li
.member
{
class:
dom_class
(
member
),
id:
dom_id
(
member
)
}
%li
.member
{
class:
dom_class
(
member
),
id:
dom_id
(
member
)
}
%span
.list-item-name
%span
.list-item-name
...
@@ -50,18 +50,17 @@
...
@@ -50,18 +50,17 @@
.controls.member-controls
.controls.member-controls
-
if
show_controls
&&
member
.
source
==
current_resource
-
if
show_controls
&&
member
.
source
==
current_resource
-
if
member
_presenter
.
can_resend_invite?
-
if
member
.
can_resend_invite?
=
link_to
icon
(
'paper-plane'
),
polymorphic_path
([
:resend_invite
,
member
]),
=
link_to
icon
(
'paper-plane'
),
polymorphic_path
([
:resend_invite
,
member
]),
method: :post
,
method: :post
,
class:
'btn btn-default prepend-left-10 hidden-xs'
,
class:
'btn btn-default prepend-left-10 hidden-xs'
,
title:
'Resend invite'
title:
'Resend invite'
-
if
user
!=
current_user
&&
member
_presenter
.
can_update?
-
if
user
!=
current_user
&&
member
.
can_update?
=
form_for
member
,
remote:
true
,
html:
{
class:
'form-horizontal js-edit-member-form'
}
do
|
f
|
=
form_for
member
,
remote:
true
,
html:
{
class:
'form-horizontal js-edit-member-form'
}
do
|
f
|
=
f
.
hidden_field
:access_level
=
f
.
hidden_field
:access_level
.member-form-control.dropdown.append-right-5
.member-form-control.dropdown.append-right-5
%button
.dropdown-menu-toggle.js-member-permissions-dropdown
{
type:
"button"
,
%button
.dropdown-menu-toggle.js-member-permissions-dropdown
{
type:
"button"
,
disabled:
member_presenter
.
cannot_update?
,
data:
{
toggle:
"dropdown"
,
field_name:
"#{f.object_name}[access_level]"
}
}
data:
{
toggle:
"dropdown"
,
field_name:
"#{f.object_name}[access_level]"
}
}
%span
.dropdown-toggle-text
%span
.dropdown-toggle-text
=
member
.
human_access
=
member
.
human_access
...
@@ -70,23 +69,22 @@
...
@@ -70,23 +69,22 @@
=
dropdown_title
(
"Change permissions"
)
=
dropdown_title
(
"Change permissions"
)
.dropdown-content
.dropdown-content
%ul
%ul
-
member
.
class
.
access_level_roles
.
each
do
|
role
,
role_id
|
-
member
.
access_level_roles
.
each
do
|
role
,
role_id
|
%li
%li
=
link_to
role
,
"javascript:void(0)"
,
=
link_to
role
,
"javascript:void(0)"
,
class:
(
"is-active"
if
member
.
access_level
==
role_id
),
class:
(
"is-active"
if
member
.
access_level
==
role_id
),
data:
{
id:
role_id
,
el_id:
dom_id
(
member
)
}
data:
{
id:
role_id
,
el_id:
dom_id
(
member
)
}
.prepend-left-5.clearable-input.member-form-control
.prepend-left-5.clearable-input.member-form-control
=
f
.
text_field
:expires_at
,
class:
'form-control js-access-expiration-date js-member-update-control'
,
placeholder:
'Expiration date'
,
id:
"member_expires_at_
#{
member
.
id
}
"
,
disabled:
member_presenter
.
cannot_update?
,
data:
{
el_id:
dom_id
(
member
)
}
=
f
.
text_field
:expires_at
,
class:
'form-control js-access-expiration-date js-member-update-control'
,
placeholder:
'Expiration date'
,
id:
"member_expires_at_
#{
member
.
id
}
"
,
data:
{
el_id:
dom_id
(
member
)
}
%i
.clear-icon.js-clear-input
%i
.clear-icon.js-clear-input
-
else
-
else
%span
.member-access-text
=
member
.
human_access
%span
.member-access-text
=
member
.
human_access
-
if
member_presenter
.
can_resend_invite?
-
if
member
.
can_approve?
=
link_to
'Resend invite'
,
polymorphic_path
([
:resend_invite
,
member
]),
method: :post
,
class:
'btn btn-default prepend-left-10 visible-xs-block'
-
elsif
member_presenter
.
can_approve?
=
link_to
polymorphic_path
([
:approve_access_request
,
member
]),
=
link_to
polymorphic_path
([
:approve_access_request
,
member
]),
method: :post
,
method: :post
,
class:
'btn btn-success prepend-left-10'
,
class:
'btn btn-success prepend-left-10'
,
...
@@ -96,7 +94,7 @@
...
@@ -96,7 +94,7 @@
-
unless
force_mobile_view
-
unless
force_mobile_view
=
icon
(
'check inverse'
,
class:
'hidden-xs'
)
=
icon
(
'check inverse'
,
class:
'hidden-xs'
)
-
if
member
_presenter
.
can_remove?
-
if
member
.
can_remove?
-
if
current_user
==
user
-
if
current_user
==
user
=
link_to
icon
(
'sign-out'
,
text:
'Leave'
),
polymorphic_path
([
:leave
,
member
.
source
,
:members
]),
=
link_to
icon
(
'sign-out'
,
text:
'Leave'
),
polymorphic_path
([
:leave
,
member
.
source
,
:members
]),
method: :delete
,
method: :delete
,
...
...
app/views/shared/members/_requests.html.haml
View file @
50d7c356
-
membership_source
=
local_assigns
.
fetch
(
:membership_source
)
-
requesters
=
local_assigns
.
fetch
(
:requesters
)
-
force_mobile_view
=
local_assigns
.
fetch
(
:force_mobile_view
,
false
)
-
force_mobile_view
=
local_assigns
.
fetch
(
:force_mobile_view
,
false
)
-
if
requesters
.
any?
-
return
if
requesters
.
empty?
.panel.panel-default.prepend-top-default
{
class:
(
'panel-mobile'
if
force_mobile_view
)
}
.panel.panel-default.prepend-top-default
{
class:
(
'panel-mobile'
if
force_mobile_view
)
}
.panel-heading
.panel-heading
Users requesting access to
Users requesting access to
%strong
=
membership_source
.
name
%strong
=
membership_source
.
name
...
...
lib/gitlab/view/presenter/factory.rb
View file @
50d7c356
...
@@ -16,7 +16,7 @@ module Gitlab
...
@@ -16,7 +16,7 @@ module Gitlab
attr_reader
:subject
,
:attributes
attr_reader
:subject
,
:attributes
def
presenter_class
def
presenter_class
"
#{
subject
.
class
.
name
}
Presenter"
.
constantize
attributes
.
delete
(
:presenter_class
)
{
"
#{
subject
.
class
.
name
}
Presenter"
.
constantize
}
end
end
end
end
end
end
...
...
spec/lib/gitlab/view/presenter/factory_spec.rb
View file @
50d7c356
...
@@ -27,5 +27,13 @@ describe Gitlab::View::Presenter::Factory do
...
@@ -27,5 +27,13 @@ describe Gitlab::View::Presenter::Factory do
expect
(
presenter
).
to
be_a
(
Ci
::
BuildPresenter
)
expect
(
presenter
).
to
be_a
(
Ci
::
BuildPresenter
)
end
end
it
'uses the presenter_class if given on #initialize'
do
MyCustomPresenter
=
Class
.
new
(
described_class
)
presenter
=
described_class
.
new
(
build
,
presenter_class:
MyCustomPresenter
).
fabricate!
expect
(
presenter
).
to
be_a
(
MyCustomPresenter
)
end
end
end
end
end
spec/presenters/group_member_presenter_spec.rb
View file @
50d7c356
...
@@ -64,6 +64,7 @@ describe GroupMemberPresenter do
...
@@ -64,6 +64,7 @@ describe GroupMemberPresenter do
context
'when user cannot update_group_member'
do
context
'when user cannot update_group_member'
do
before
do
before
do
allow
(
presenter
).
to
receive
(
:can?
).
with
(
user
,
:update_group_member
,
presenter
).
and_return
(
false
)
allow
(
presenter
).
to
receive
(
:can?
).
with
(
user
,
:update_group_member
,
presenter
).
and_return
(
false
)
allow
(
presenter
).
to
receive
(
:can?
).
with
(
user
,
:override_group_member
,
presenter
).
and_return
(
false
)
end
end
it
{
expect
(
presenter
.
can_update?
).
to
eq
(
false
)
}
it
{
expect
(
presenter
.
can_update?
).
to
eq
(
false
)
}
...
@@ -105,6 +106,7 @@ describe GroupMemberPresenter do
...
@@ -105,6 +106,7 @@ describe GroupMemberPresenter do
context
'when user cannot update_group_member'
do
context
'when user cannot update_group_member'
do
before
do
before
do
allow
(
presenter
).
to
receive
(
:can?
).
with
(
user
,
:update_group_member
,
presenter
).
and_return
(
false
)
allow
(
presenter
).
to
receive
(
:can?
).
with
(
user
,
:update_group_member
,
presenter
).
and_return
(
false
)
allow
(
presenter
).
to
receive
(
:can?
).
with
(
user
,
:override_group_member
,
presenter
).
and_return
(
false
)
end
end
it
{
expect
(
presenter
.
can_approve?
).
to
eq
(
false
)
}
it
{
expect
(
presenter
.
can_approve?
).
to
eq
(
false
)
}
...
...
spec/presenters/project_member_presenter_spec.rb
View file @
50d7c356
...
@@ -64,6 +64,7 @@ describe ProjectMemberPresenter do
...
@@ -64,6 +64,7 @@ describe ProjectMemberPresenter do
context
'when user cannot update_project_member'
do
context
'when user cannot update_project_member'
do
before
do
before
do
allow
(
presenter
).
to
receive
(
:can?
).
with
(
user
,
:update_project_member
,
presenter
).
and_return
(
false
)
allow
(
presenter
).
to
receive
(
:can?
).
with
(
user
,
:update_project_member
,
presenter
).
and_return
(
false
)
allow
(
presenter
).
to
receive
(
:can?
).
with
(
user
,
:override_project_member
,
presenter
).
and_return
(
false
)
end
end
it
{
expect
(
presenter
.
can_update?
).
to
eq
(
false
)
}
it
{
expect
(
presenter
.
can_update?
).
to
eq
(
false
)
}
...
@@ -105,6 +106,7 @@ describe ProjectMemberPresenter do
...
@@ -105,6 +106,7 @@ describe ProjectMemberPresenter do
context
'and user cannot update_project_member'
do
context
'and user cannot update_project_member'
do
before
do
before
do
allow
(
presenter
).
to
receive
(
:can?
).
with
(
user
,
:update_project_member
,
presenter
).
and_return
(
false
)
allow
(
presenter
).
to
receive
(
:can?
).
with
(
user
,
:update_project_member
,
presenter
).
and_return
(
false
)
allow
(
presenter
).
to
receive
(
:can?
).
with
(
user
,
:override_project_member
,
presenter
).
and_return
(
false
)
end
end
it
{
expect
(
presenter
.
can_approve?
).
to
eq
(
false
)
}
it
{
expect
(
presenter
.
can_approve?
).
to
eq
(
false
)
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment