diff options
| -rw-r--r-- | app/decorators/referential_decorator.rb | 54 | ||||
| -rw-r--r-- | app/policies/referential_policy.rb | 4 | ||||
| -rw-r--r-- | lib/html_element.rb | 2 | ||||
| -rw-r--r-- | spec/decorators/referential_decorator_spec.rb | 76 | ||||
| -rw-r--r-- | spec/policies/referential_policy_spec.rb | 97 | ||||
| -rw-r--r-- | spec/support/decorator_helpers.rb | 27 |
6 files changed, 212 insertions, 48 deletions
diff --git a/app/decorators/referential_decorator.rb b/app/decorators/referential_decorator.rb index a230b3d7f..ccb47a654 100644 --- a/app/decorators/referential_decorator.rb +++ b/app/decorators/referential_decorator.rb @@ -2,6 +2,7 @@ class ReferentialDecorator < Draper::Decorator delegate_all def action_links + policy = h.policy(object) links = [ Link.new( content: h.t('time_tables.index.title'), @@ -9,42 +10,41 @@ class ReferentialDecorator < Draper::Decorator ) ] - if h.policy(object).clone? + if policy.clone? links << Link.new( content: h.t('actions.clone'), href: h.new_referential_path(from: object.id) ) end + if policy.archive? + links << Link.new( + content: h.t('actions.archive'), + href: h.archive_referential_path(object.id), + method: :put + ) + end - require 'pry' - binding.pry - if h.policy(object).edit? + if policy.unarchive? + links << Link.new( + content: h.t('actions.unarchive'), + href: h.unarchive_referential_path(object.id), + method: :put + ) + end - if object.archived? - links << Link.new( - content: h.t('actions.unarchive'), - href: h.unarchive_referential_path(object.id), - method: :put - ) - else - links << HTMLElement.new( - :button, - 'Purger', - type: 'button', - data: { - toggle: 'modal', - target: '#purgeModal' - } - ) - links << Link.new( - content: h.t('actions.archive'), - href: h.archive_referential_path(object.id), - method: :put - ) - end + if policy.edit? + links << HTMLElement.new( + :button, + 'Purger', + type: 'button', + data: { + toggle: 'modal', + target: '#purgeModal' + } + ) end - if h.policy(object).destroy? && !object.archived? + if policy.destroy? links << Link.new( content: h.destroy_link_content, href: h.referential_path(object), diff --git a/app/policies/referential_policy.rb b/app/policies/referential_policy.rb index bf970c2b8..9d0a92093 100644 --- a/app/policies/referential_policy.rb +++ b/app/policies/referential_policy.rb @@ -24,11 +24,11 @@ class ReferentialPolicy < ApplicationPolicy end def archive? - record.archived_at.nil? && user.has_permission?('referentials.update') + record.archived_at.nil? && organisation_match? && user.has_permission?('referentials.update') end def unarchive? - !record.archived_at.nil? && user.has_permission?('referentials.update') + !record.archived_at.nil? && organisation_match? && user.has_permission?('referentials.update') end def common_lines? diff --git a/lib/html_element.rb b/lib/html_element.rb index 469fd7565..57b08eb52 100644 --- a/lib/html_element.rb +++ b/lib/html_element.rb @@ -1,4 +1,6 @@ class HTMLElement + attr_reader :content, :options, :tag_name + def initialize(tag_name, content = nil, options = nil) @tag_name = tag_name @content = content diff --git a/spec/decorators/referential_decorator_spec.rb b/spec/decorators/referential_decorator_spec.rb new file mode 100644 index 000000000..5de6b7e95 --- /dev/null +++ b/spec/decorators/referential_decorator_spec.rb @@ -0,0 +1,76 @@ +RSpec.describe ReferentialDecorator, type: [:helper, :decorator] do + + let( :object ){ build_stubbed :referential } + let( :referential ){ object } + let( :user ){ build_stubbed :user } + + describe 'delegation' do + it 'delegates all' do + %i{xx xxx anything save!}.each do |method| + expect( object ).to receive(method) + end + # Almost as powerful as Quicktest :P + %i{xx xxx anything save!}.each do |method| + subject.send method + end + end + end + + describe 'action links for' do + + context 'unarchived referential' do + context 'no rights' do + it 'has only a Calendar action' do + expect_action_link_hrefs.to eq([referential_time_tables_path(object)]) + end + end + + context 'all rights and different organisation' do + + let( :user ){ build_stubbed :allmighty_user } + + it 'has only default actions' do + expect_action_link_elements.to be_empty + expect_action_link_hrefs.to eq([ + referential_time_tables_path(object), + ]) + end + end + context 'all rights and same organisation' do + + let( :user ){ build_stubbed :allmighty_user, organisation: referential.organisation } + + it 'has all actions' do + expect_action_link_elements.to eq(%w{Purger}) + expect_action_link_hrefs.to eq([ + referential_time_tables_path(object), + new_referential_path(from: object), + archive_referential_path(object), + referential_path(object) + ]) + end + end + end + + context 'archived referential' do + before { referential.archived_at = 42.seconds.ago } + context 'no rights' do + it 'has only a Calendar action' do + expect_action_link_hrefs.to eq([referential_time_tables_path(object)]) + end + end + + context 'all rights and different organisation' do + let( :user ){ build_stubbed :allmighty_user } + it 'has only default actions' do + expect_action_link_elements.to be_empty + expect_action_link_hrefs.to eq([ + referential_time_tables_path(object), + ]) + end + end + end + end + + +end diff --git a/spec/policies/referential_policy_spec.rb b/spec/policies/referential_policy_spec.rb index d060317f9..33d8e13e8 100644 --- a/spec/policies/referential_policy_spec.rb +++ b/spec/policies/referential_policy_spec.rb @@ -56,22 +56,52 @@ RSpec.describe ReferentialPolicy, type: :policy do add_permissions('referentials.update', for_user: user) end - it 'allowed for unarchived referentials' do - expect_it.to permit(user_context, record) + context 'same organisation →' do + before do + user.organisation_id = referential.organisation_id + end + it "allows a user with the same organisation" do + expect_it.to permit(user_context, record) + end + describe "archived" do + let( :record ){ build_stubbed :referential, archived_at: 2.minutes.ago } + it 'does remove permission for archived referentials' do + expect_it.not_to permit(user_context, record) + end + end end - it 'forbidden for archived referentials' do - record.archived_at = 1.second.ago - expect_it.not_to permit(user_context, record) + context 'different organisations →' do + it "forbids a user with a different organisation" do + expect_it.not_to permit(user_context, record) + end + + describe "archived" do + let( :record ){ build_stubbed :referential, archived_at: 2.minutes.ago } + it 'forbids for archived referentials' do + expect_it.not_to permit(user_context, record) + end + end + end end - context 'permission absent →' do - it 'is forbidden' do - expect_it.not_to permit(user_context, record) + context 'permission absent →' do + context 'same organisation →' do + before do + user.organisation_id = referential.organisation_id + end + it "forbids a user with the same organisation" do + expect_it.not_to permit(user_context, record) + end + describe "archived" do + let( :record ){ build_stubbed :referential, archived_at: 2.minutes.ago } + it 'forbids for archived referentials' do + expect_it.not_to permit(user_context, record) + end + end end end - end permissions :unarchive? do @@ -81,22 +111,51 @@ RSpec.describe ReferentialPolicy, type: :policy do add_permissions('referentials.update', for_user: user) end - it 'forbidden for unarchived referentials' do - expect_it.not_to permit(user_context, record) + context 'same organisation →' do + before do + user.organisation_id = referential.organisation_id + end + it "forbids a user with the same organisation" do + expect_it.not_to permit(user_context, record) + end + describe "archived" do + let( :record ){ build_stubbed :referential, archived_at: 2.minutes.ago } + it 'adds permission for archived referentials' do + expect_it.to permit(user_context, record) + end + end end - it 'allowed for archived referentials' do - record.archived_at = 1.second.ago - expect_it.to permit(user_context, record) + context 'different organisations →' do + it "forbids a user with a different organisation" do + expect_it.not_to permit(user_context, record) + end + + describe "archived" do + let( :record ){ build_stubbed :referential, archived_at: 2.minutes.ago } + it 'still forbids for archived referentials' do + expect_it.not_to permit(user_context, record) + end + end + end end - context 'permission absent →' do - it 'is forbidden' do - record.archived_at = 1.second.ago - expect_it.not_to permit(user_context, record) + context 'permission absent →' do + context 'same organisation →' do + before do + user.organisation_id = referential.organisation_id + end + it "forbids a user with a different rganisation" do + expect_it.not_to permit(user_context, record) + end + describe "archived" do + let( :record ){ build_stubbed :referential, archived_at: 2.minutes.ago } + it 'still forbids for archived referentials' do + expect_it.not_to permit(user_context, record) + end + end end end - end end diff --git a/spec/support/decorator_helpers.rb b/spec/support/decorator_helpers.rb new file mode 100644 index 000000000..ffedd479b --- /dev/null +++ b/spec/support/decorator_helpers.rb @@ -0,0 +1,27 @@ +module Support + + module DecoratorHelpers + def self.included(into) + into.instance_eval do + subject{ object.decorate } + let( :policy ){ ::Pundit.policy(user_context, object) } + let( :user_context ){ UserContext.new(user, referential: referential) } + + before do + allow_any_instance_of(Draper::HelperProxy).to receive(:policy).and_return policy + end + end + end + + def expect_action_link_hrefs + expect( subject.action_links.select(&Link.method(:===)).map(&:href) ) + end + def expect_action_link_elements + expect( subject.action_links.select(&HTMLElement.method(:===)).map(&:content) ) + end + end +end + +RSpec.configure do | c | + c.include Support::DecoratorHelpers, type: :decorator +end |
