Skip to content

Commit a5ffdfd

Browse files
committed
Move towards new abilities
1 parent 6f42ec1 commit a5ffdfd

File tree

6 files changed

+126
-14
lines changed

6 files changed

+126
-14
lines changed
+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# frozen_string_literal: true
2+
3+
# Copyright (c) 2024, Schweizer Alpen-Club. This file is part of
4+
# hitobito and licensed under the Affero General Public License version 3
5+
# or later. See the COPYING file at the top-level directory or at
6+
# https://github.com/hitobito/hitobito_youth.
7+
8+
class PeopleManagerAbility < AbilityDsl::Base
9+
on(PeopleManager) do
10+
class_side(:index).everybody
11+
permission(:any).may(:new_managed, :new_manager).everybody
12+
permission(:any).may(:create_managed, :destroy_managed).if_can_change_managed
13+
permission(:any).may(:create_manager, :destroy_manager).if_can_change_manager
14+
end
15+
16+
def if_can_change_manager
17+
can?(:change_managers, subject.managed) || creating_new_managed_person?
18+
end
19+
20+
def if_can_change_managed
21+
can?(:update, subject.manager)
22+
end
23+
24+
private
25+
26+
def creating_new_managed_person?
27+
subject.managed&.new_record? &&
28+
FeatureGate.enabled?('people.people_managers.self_service_managed_creation')
29+
end
30+
31+
def can?(action, person)
32+
ability.can?(action, person)
33+
end
34+
35+
def ability
36+
@ability ||= Ability.new(user)
37+
end
38+
end

app/controllers/people_managers_controller.rb

+5-2
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,14 @@ def destroy
3636
private
3737

3838
def authorize_action
39-
authorize!(action_name.to_sym, entry)
39+
kind = assoc.to_s.split("_").last.singularize
40+
action_to_authorize = :"#{action_name}_#{kind}"
41+
42+
authorize!(action_to_authorize, entry)
4043
end
4144

4245
def authorize_class
43-
authorize!(action_name.to_sym, PeopleManager)
46+
authorize!(:index, PeopleManager)
4447
end
4548

4649
def assign_attributes

app/helpers/dropdown/add_people_manager.rb

+13-8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ def initialize(template, person, managers: true)
1111
end
1212

1313
def to_s
14+
return '' if @items.none?
1415
return single_action_button if @items.one?
1516

1617
super
@@ -19,13 +20,13 @@ def to_s
1920
private
2021

2122
def single_action_button
22-
template.action_button(template.ti('link.add'), @items.first.url, :plus, class: 'btn-sm' )
23+
template.action_button(@items.first.label, @items.first.url, :plus, class: 'btn-sm' )
2324
end
2425

2526
def init_items
26-
add_assign_manager_item if change_managers?
27-
add_assign_managed_item
28-
add_create_managed_item if create_managed?
27+
add_assign_manager_item if create_manager?
28+
add_assign_managed_item if create_managed?
29+
add_create_managed_item if create_new_managed?
2930
end
3031

3132
def add_assign_manager_item
@@ -41,12 +42,16 @@ def add_assign_managed_item
4142
end
4243

4344
def create_managed?
44-
cannot?(:lookup_manageds, Person) &&
45-
FeatureGate.enabled?('people.people_managers.self_service_managed_creation')
45+
can?(:create_managed, PeopleManager.new(manager: @person))
46+
end
47+
48+
def create_manager?
49+
can?(:create_manager, PeopleManager.new(managed: @person))
4650
end
4751

48-
def change_managers?
49-
can?(:change_managers, @person) && @managers == true
52+
def create_new_managed?
53+
cannot?(:lookup_manageds, Person) &&
54+
FeatureGate.enabled?('people.people_managers.self_service_managed_creation')
5055
end
5156

5257
def t(key)

lib/hitobito_youth/wagon.rb

+2
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ class Wagon < Rails::Engine
6666
PersonReadables.prepend(Youth::PersonReadables)
6767
PersonLayerWritables.prepend(Youth::PersonLayerWritables)
6868

69+
Ability.store.register PeopleManagerAbility
70+
6971
# decorator
7072
PersonDecorator.include Youth::PersonDecorator
7173
Event::ParticipationDecorator.include Youth::Event::ParticipationDecorator
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# frozen_string_literal: true
2+
3+
# Copyright (c) 2024, Schweizer Alpen-Club. This file is part of
4+
# hitobito and licensed under the Affero General Public License version 3
5+
# or later. See the COPYING file at the top-level directory or at
6+
# https://github.com/hitobito/hitobito_youth.
7+
8+
require 'spec_helper'
9+
10+
describe PeopleManagerAbility do
11+
12+
let(:top_leader) { people(:top_leader) }
13+
let(:bottom_member) { people(:bottom_member) }
14+
15+
subject(:ability) { Ability.new(person) }
16+
17+
def build(managed: nil, manager: nil)
18+
PeopleManager.new(managed: managed, manager: manager)
19+
end
20+
21+
[:create_manager, :destroy_manager].each do |action|
22+
23+
context 'top leader' do
24+
let(:person) { top_leader }
25+
26+
describe "#{action} manager" do
27+
it 'may change manager of bottom_member' do
28+
expect(ability).to be_able_to(action, build(managed: bottom_member))
29+
end
30+
31+
it 'may not change his own manager' do
32+
expect(ability).not_to be_able_to(action, build(managed: top_leader))
33+
end
34+
35+
it 'may change manager of new record' do
36+
expect(ability).to be_able_to(action, build(managed: Person.new))
37+
end
38+
end
39+
end
40+
41+
context 'bottom member' do
42+
let(:person) { bottom_member }
43+
44+
describe "#{action} manager" do
45+
it 'may not change manager of top_leader' do
46+
expect(ability).not_to be_able_to(action, build(managed: top_leader))
47+
end
48+
49+
it 'may not change his own manager' do
50+
expect(ability).not_to be_able_to(action, build(managed: bottom_member))
51+
end
52+
53+
it 'may change manager of new record' do
54+
expect(ability).to be_able_to(action, build(managed: Person.new))
55+
end
56+
57+
end
58+
end
59+
end
60+
end

spec/helpers/dropdown/add_people_manager_spec.rb

+8-4
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,22 @@
2424
let(:person) { people(:top_leader) }
2525
it 'renders single button only to create new managed' do
2626
expect(html).to have_css('a', count: 1)
27-
expect(html).to have_link('Erstellen', href: new_person_managed_path(person))
27+
expect(html).to have_link('Kind zuweisen', href: new_person_managed_path(person))
2828
end
2929
end
3030

31-
context 'person without write permission' do
31+
context 'when person with read permissions only' do
3232
let(:role) { Fabricate(Group::BottomGroup::Member.sti_name, group: groups(:bottom_group_one_one)) }
3333
let(:ability) { Ability.new(role.person) }
3434

35+
it 'renders nothing if creating person feature is disabled' do
36+
allow(FeatureGate).to receive(:enabled?).and_return(false)
37+
expect(dropdown.to_s).to be_blank
38+
end
39+
3540
it 'renders additional button cannot lookup people and create feature gate is enabled' do
3641
allow(FeatureGate).to receive(:enabled?).and_return(true)
37-
expect(html).to have_css('a', count: 3)
38-
expect(html).to have_link('Kind zuweisen', href: new_person_managed_path(person))
42+
expect(html).to have_css('a', count: 1)
3943
expect(html).to have_link('Kind erfassen', href: new_person_managed_path(person, create: true))
4044
end
4145
end

0 commit comments

Comments
 (0)