aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/helpers/newapplication_helper.rb5
-rw-r--r--app/helpers/table_builder_helper/custom_links.rb14
-rw-r--r--app/models/chouette/stop_point.rb5
-rw-r--r--app/models/user.rb2
-rw-r--r--app/policies/application_policy.rb2
-rw-r--r--app/policies/boiv_policy.rb4
-rw-r--r--app/policies/default_policy.rb11
-rw-r--r--app/policies/line_policy.rb5
-rw-r--r--app/policies/time_table_policy.rb4
-rw-r--r--config/environments/development.rb10
-rw-r--r--spec/features/lines_spec.rb144
-rw-r--r--spec/features/routes_spec.rb193
-rw-r--r--spec/features/workbenches_spec.rb7
-rw-r--r--spec/support/pundit/policies.rb14
14 files changed, 232 insertions, 188 deletions
diff --git a/app/helpers/newapplication_helper.rb b/app/helpers/newapplication_helper.rb
index edcad76c3..ac57997d1 100644
--- a/app/helpers/newapplication_helper.rb
+++ b/app/helpers/newapplication_helper.rb
@@ -155,7 +155,10 @@ module NewapplicationHelper
content_tag :li, link_to(t("actions.#{action}"), polymorph_url, method: :put)
end
else
- content_tag :li, link_to(t("actions.#{action}"), polymorph_url)
+ permission = "#{action}?"
+ if !policy(item).respond_to?(permission) || policy(item).public_send(permission)
+ content_tag :li, link_to(t("actions.#{action}"), polymorph_url)
+ end
end
end.join.html_safe
end
diff --git a/app/helpers/table_builder_helper/custom_links.rb b/app/helpers/table_builder_helper/custom_links.rb
index abb907678..e185bf77b 100644
--- a/app/helpers/table_builder_helper/custom_links.rb
+++ b/app/helpers/table_builder_helper/custom_links.rb
@@ -40,6 +40,14 @@ module TableBuilderHelper
def actions_after_policy_check
@actions.select do |action|
+ # TODO: My idea would be to push authorization logic into policies
+ # Eventually the code should look like:
+ # select do |action|
+ # Pundit.policy(@user_context, @obj).send("#{action}?")
+ # end
+ # This puts the responsability where it belongs to and allows
+ # for easy and fast unit testing of the BL, always a goos sign.
+
# Has policy and can destroy
(action == :delete &&
Pundit.policy(@user_context, @obj).present? &&
@@ -64,6 +72,10 @@ module TableBuilderHelper
# Object is archived
(action == :unarchive && @obj.archived?) ||
+ !Pundit.policy(@user_context, @obj).respond_to?("#{action}?") ||
+ Pundit.policy(@user_context, @obj).public_send("#{action}?") ||
+
+
action_is_allowed_regardless_of_policy(action)
end
end
@@ -71,7 +83,7 @@ module TableBuilderHelper
private
def action_is_allowed_regardless_of_policy(action)
- ![:delete, :edit, :archive, :unarchive].include?(action)
+ ![:delete, :edit, :archive, :unarchive, :duplicate, :actualize].include?(action)
end
end
end
diff --git a/app/models/chouette/stop_point.rb b/app/models/chouette/stop_point.rb
index e0f947487..1cc1ed7a3 100644
--- a/app/models/chouette/stop_point.rb
+++ b/app/models/chouette/stop_point.rb
@@ -1,5 +1,10 @@
module Chouette
class StopPoint < TridentActiveRecord
+
+ def self.policy_class
+ DefaultPolicy
+ end
+
include ForBoardingEnumerations
include ForAlightingEnumerations
diff --git a/app/models/user.rb b/app/models/user.rb
index 4ba05b164..31fc4ef78 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -31,7 +31,7 @@ class User < ActiveRecord::Base
@@edit_offer_permissions = ['routes.create', 'routes.edit', 'routes.destroy', 'journey_patterns.create', 'journey_patterns.edit', 'journey_patterns.destroy',
'vehicle_journeys.create', 'vehicle_journeys.edit', 'vehicle_journeys.destroy', 'time_tables.create', 'time_tables.edit', 'time_tables.destroy',
'footnotes.edit', 'footnotes.create', 'footnotes.destroy', 'routing_constraint_zones.create', 'routing_constraint_zones.edit',
- 'routing_constraint_zones.destroy', 'referentials.create', 'referentials.edit', 'referentials.destroy', 'boiv:edit-offer']
+ 'routing_constraint_zones.destroy', 'referentials.create', 'referentials.edit', 'referentials.destroy', 'boiv:edit-offer', 'boiv:read-offer']
mattr_reader :edit_offer_permissions
def self.all_permissions
diff --git a/app/policies/application_policy.rb b/app/policies/application_policy.rb
index f2521fa44..e2c0acd8e 100644
--- a/app/policies/application_policy.rb
+++ b/app/policies/application_policy.rb
@@ -53,7 +53,7 @@ class ApplicationPolicy
end
def boiv_read_offer?
- organisation_match? && user.has_permission?('boiv:read-offer')
+ organisation_match? && !(user.permissions || []).grep(%r{\Aboiv:.}).empty?
end
def organisation_match?
diff --git a/app/policies/boiv_policy.rb b/app/policies/boiv_policy.rb
index 444006aa4..aa3ecc50d 100644
--- a/app/policies/boiv_policy.rb
+++ b/app/policies/boiv_policy.rb
@@ -1,10 +1,6 @@
class BoivPolicy < ApplicationPolicy
- def boiv_read_offer?
- organisation_match? && user.has_permission?('boiv:read-offer')
- end
-
def index?
boiv_read_offer?
end
diff --git a/app/policies/default_policy.rb b/app/policies/default_policy.rb
new file mode 100644
index 000000000..efdac1575
--- /dev/null
+++ b/app/policies/default_policy.rb
@@ -0,0 +1,11 @@
+class DefaultPolicy
+
+ def initialize(*args); end
+
+ def create?; true end
+ def destroy?; true end
+ def edit?; true end
+ def index?; true end
+ def show?; true end
+ def update?; true end
+end
diff --git a/app/policies/line_policy.rb b/app/policies/line_policy.rb
index b829040af..1b0d00cc5 100644
--- a/app/policies/line_policy.rb
+++ b/app/policies/line_policy.rb
@@ -6,9 +6,8 @@ class LinePolicy < BoivPolicy
end
end
- def create?
- false
- end
+ def show?; true end
+ def create?; false end
def update? ; false end
def new? ; create? end
def edit? ; false end
diff --git a/app/policies/time_table_policy.rb b/app/policies/time_table_policy.rb
index e915ede6a..a8f54ad48 100644
--- a/app/policies/time_table_policy.rb
+++ b/app/policies/time_table_policy.rb
@@ -6,6 +6,10 @@ class TimeTablePolicy < BoivPolicy
end
end
+ def actualize?
+ !archived? && organisation_match? && edit?
+ end
+
def create?
!archived? && user.has_permission?('time_tables.create') # organisation match via referential is checked in the view
end
diff --git a/config/environments/development.rb b/config/environments/development.rb
index 0b4eab7d2..c0531594c 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -60,13 +60,13 @@ Rails.application.configure do
config.reflex_api_url = "https://pprod.reflex.stif.info/ws/reflex/V1/service=getData"
config.codifligne_api_url = "https://pprod.codifligne.stif.info/rest/v1/lc/getlist"
- # config.chouette_authentication_settings = {
- # type: "database"
- # }
config.chouette_authentication_settings = {
- type: "cas",
- cas_server: "http://stif-portail-dev.af83.priv/sessions"
+ type: "database"
}
+ # config.chouette_authentication_settings = {
+ # type: "cas",
+ # cas_server: "http://stif-portail-dev.af83.priv/sessions"
+ # }
config.stif_portail_api =
{
key: "Ohphie1Voo6the5hohpi",
diff --git a/spec/features/lines_spec.rb b/spec/features/lines_spec.rb
index a55f30ebc..2a442bd2f 100644
--- a/spec/features/lines_spec.rb
+++ b/spec/features/lines_spec.rb
@@ -8,89 +8,91 @@ describe "Lines", type: :feature do
let!(:group_of_line) { create(:group_of_line) }
subject { lines.first }
- describe "index" do
- before(:each) { visit line_referential_lines_path(line_referential) }
+ with_permissions "boiv:read" do
+ describe "index" do
+ before(:each) { visit line_referential_lines_path(line_referential) }
- it "displays lines" do
- expect(page).to have_content(lines.first.name)
- expect(page).to have_content(lines.last.name)
- end
-
- it 'allows only R in CRUD' do
- expect(page).to have_link(I18n.t('actions.show'))
- expect(page).not_to have_link(I18n.t('actions.edit'), href: edit_referential_line_path(referential, lines.first))
- expect(page).not_to have_link(I18n.t('actions.destroy'), href: referential_line_path(referential, lines.first))
- expect(page).not_to have_link(I18n.t('actions.add'), href: new_referential_line_path(referential))
- end
-
- context 'filtering' do
- it 'supports filtering by name' do
- fill_in 'q[name_or_number_or_objectid_cont]', with: lines.first.name
- click_button 'search-btn'
+ it "displays lines" do
expect(page).to have_content(lines.first.name)
- expect(page).not_to have_content(lines.last.name)
+ expect(page).to have_content(lines.last.name)
end
- it 'supports filtering by number' do
- fill_in 'q[name_or_number_or_objectid_cont]', with: lines.first.number
- click_button 'search-btn'
- expect(page).to have_content(lines.first.name)
- expect(page).not_to have_content(lines.last.name)
+ it 'allows only R in CRUD' do
+ expect(page).to have_link(I18n.t('actions.show'))
+ expect(page).not_to have_link(I18n.t('actions.edit'), href: edit_referential_line_path(referential, lines.first))
+ expect(page).not_to have_link(I18n.t('actions.destroy'), href: referential_line_path(referential, lines.first))
+ expect(page).not_to have_link(I18n.t('actions.add'), href: new_referential_line_path(referential))
end
- it 'supports filtering by objectid' do
- fill_in 'q[name_or_number_or_objectid_cont]', with: lines.first.objectid
- click_button 'search-btn'
- expect(page).to have_content(lines.first.name)
- expect(page).not_to have_content(lines.last.name)
+ context 'filtering' do
+ it 'supports filtering by name' do
+ fill_in 'q[name_or_number_or_objectid_cont]', with: lines.first.name
+ click_button 'search-btn'
+ expect(page).to have_content(lines.first.name)
+ expect(page).not_to have_content(lines.last.name)
+ end
+
+ it 'supports filtering by number' do
+ fill_in 'q[name_or_number_or_objectid_cont]', with: lines.first.number
+ click_button 'search-btn'
+ expect(page).to have_content(lines.first.name)
+ expect(page).not_to have_content(lines.last.name)
+ end
+
+ it 'supports filtering by objectid' do
+ fill_in 'q[name_or_number_or_objectid_cont]', with: lines.first.objectid
+ click_button 'search-btn'
+ expect(page).to have_content(lines.first.name)
+ expect(page).not_to have_content(lines.last.name)
+ end
end
end
- end
- describe "show" do
- it "displays line" do
- visit line_referential_line_path(line_referential, lines.first)
- expect(page).to have_content(lines.first.name)
+ describe "show" do
+ it "displays line" do
+ visit line_referential_line_path(line_referential, lines.first)
+ expect(page).to have_content(lines.first.name)
+ end
end
- end
- # Fixme #1780
- # describe "new" do
- # it "creates line and return to show" do
- # visit line_referential_lines_path(line_referential)
- # click_link "Ajouter une ligne"
- # fill_in "line_name", :with => "Line 1"
- # fill_in "Numéro d'enregistrement", :with => "1"
- # fill_in "Identifiant Neptune", :with => "chouette:test:Line:999"
- # click_button("Créer ligne")
- # expect(page).to have_content("Line 1")
- # end
- # end
+ # Fixme #1780
+ # describe "new" do
+ # it "creates line and return to show" do
+ # visit line_referential_lines_path(line_referential)
+ # click_link "Ajouter une ligne"
+ # fill_in "line_name", :with => "Line 1"
+ # fill_in "Numéro d'enregistrement", :with => "1"
+ # fill_in "Identifiant Neptune", :with => "chouette:test:Line:999"
+ # click_button("Créer ligne")
+ # expect(page).to have_content("Line 1")
+ # end
+ # end
- # Fixme #1780
- # describe "new with group of line", :js => true do
- # it "creates line and return to show" do
- # visit new_line_referential_line_path(line_referential)
- # fill_in "line_name", :with => "Line 1"
- # fill_in "Numéro d'enregistrement", :with => "1"
- # fill_in "Identifiant Neptune", :with => "test:Line:999"
- # fill_in_token_input('line_group_of_line_tokens', :with => "#{group_of_line.name}")
- # find_button("Créer ligne").trigger("click")
- # expect(page).to have_text("Line 1")
- # expect(page).to have_text("#{group_of_line.name}")
- # end
- # end
+ # Fixme #1780
+ # describe "new with group of line", :js => true do
+ # it "creates line and return to show" do
+ # visit new_line_referential_line_path(line_referential)
+ # fill_in "line_name", :with => "Line 1"
+ # fill_in "Numéro d'enregistrement", :with => "1"
+ # fill_in "Identifiant Neptune", :with => "test:Line:999"
+ # fill_in_token_input('line_group_of_line_tokens', :with => "#{group_of_line.name}")
+ # find_button("Créer ligne").trigger("click")
+ # expect(page).to have_text("Line 1")
+ # expect(page).to have_text("#{group_of_line.name}")
+ # end
+ # end
- # Fixme #1780
- # describe "edit and return to show" do
- # it "edit line" do
- # visit line_referential_line_path(line_referential, subject)
- # click_link "Editer cette ligne"
- # fill_in "line_name", :with => "Line Modified"
- # fill_in "Numéro d'enregistrement", :with => "test-1"
- # click_button("Editer ligne")
- # expect(page).to have_content("Line Modified")
- # end
- # end
+ # Fixme #1780
+ # describe "edit and return to show" do
+ # it "edit line" do
+ # visit line_referential_line_path(line_referential, subject)
+ # click_link "Editer cette ligne"
+ # fill_in "line_name", :with => "Line Modified"
+ # fill_in "Numéro d'enregistrement", :with => "test-1"
+ # click_button("Editer ligne")
+ # expect(page).to have_content("Line Modified")
+ # end
+ # end
+ end
end
diff --git a/spec/features/routes_spec.rb b/spec/features/routes_spec.rb
index 28015f011..561725ddd 100644
--- a/spec/features/routes_spec.rb
+++ b/spec/features/routes_spec.rb
@@ -1,6 +1,3 @@
-# -*- coding: utf-8 -*-
-require 'spec_helper'
-
describe "Routes", :type => :feature do
login_user
@@ -13,130 +10,132 @@ describe "Routes", :type => :feature do
before { @user.update(organisation: referential.organisation) }
- describe "from lines page to a line page" do
- it "display line's routes" do
- visit referential_lines_path(referential)
- first(:link, 'Consulter').click
- expect(page).to have_content(route.name)
- expect(page).to have_content(route2.name)
+ with_permissions "boiv:read" do
+ context "from lines page to a line page" do
+ it "display line's routes" do
+ visit referential_lines_path(referential)
+ first(:link, 'Consulter').click
+ expect(page).to have_content(route.name)
+ expect(page).to have_content(route2.name)
+ end
end
- end
- describe "from line's page to route's page" do
- it "display route properties" do
- visit referential_line_path(referential, line)
- click_link "#{route.name}"
- expect(page).to have_content(route.name)
- expect(page).to have_content(route.number)
+ describe "from line's page to route's page" do
+ it "display route properties" do
+ visit referential_line_path(referential, line)
+ click_link "#{route.name}"
+ expect(page).to have_content(route.name)
+ expect(page).to have_content(route.number)
+ end
end
- end
- describe "from line's page, create a new route" do
- it "return to line's page that display new route" do
- visit referential_line_path(referential, line)
- click_link "Ajouter un itinéraire"
- fill_in "route_name", :with => "A to B"
- fill_in "route_published_name", :with => "Published A to B"
- # select 'Aller', :from => "route_direction"
- check('route[wayback]')
- click_button("Valider")
- expect(page).to have_content("A to B")
- expect(page).to have_content("Published A to B")
-
+ describe "from line's page, create a new route" do
+ it "return to line's page that display new route" do
+ visit referential_line_path(referential, line)
+ click_link "Ajouter un itinéraire"
+ fill_in "route_name", :with => "A to B"
+ fill_in "route_published_name", :with => "Published A to B"
+ # select 'Aller', :from => "route_direction"
+ check('route[wayback]')
+ click_button("Valider")
+ expect(page).to have_content("A to B")
+ expect(page).to have_content("Published A to B")
+
+ end
end
- end
- describe "Modifies boarding/alighting properties on route stops" do
- xit "Puts (http) an update request" do
- #visit edit_boarding_alighting_referential_line_route_path(referential, line, route)
- visit referential_line_route_path(referential, line, route)
-
- click_link I18n.t('routes.actions.edit_boarding_alighting')
- #select('', :from => '')
- # Changes the boarding of the first stop
- # Changes the alighting of the last stop
- # save
- #click_button(I18n.t('helpers.submit.update', model: I18n.t('activerecord.models.route.one')))
- click_button(I18n.t('helpers.submit.update', model: I18n.t('activerecord.models.route.one')))
+ describe "Modifies boarding/alighting properties on route stops" do
+ xit "Puts (http) an update request" do
+ #visit edit_boarding_alighting_referential_line_route_path(referential, line, route)
+ visit referential_line_route_path(referential, line, route)
+
+ click_link I18n.t('routes.actions.edit_boarding_alighting')
+ #select('', :from => '')
+ # Changes the boarding of the first stop
+ # Changes the alighting of the last stop
+ # save
+ #click_button(I18n.t('helpers.submit.update', model: I18n.t('activerecord.models.route.one')))
+ click_button(I18n.t('helpers.submit.update', model: I18n.t('activerecord.models.route.one')))
+ end
end
- end
- describe 'show' do
- before(:each) { visit referential_line_route_path(referential, line, route) }
+ describe 'show' do
+ before(:each) { visit referential_line_route_path(referential, line, route) }
- context 'user has permission to edit journey patterns' do
- skip "not sure the spec is correct or the code" do
- it 'shows edit links for journey patterns' do
- expect(page).to have_link(I18n.t('actions.edit'), href: edit_referential_line_route_journey_pattern_path(referential, line, route, journey_pattern))
+ context 'user has permission to edit journey patterns' do
+ skip "not sure the spec is correct or the code" do
+ it 'shows edit links for journey patterns' do
+ expect(page).to have_link(I18n.t('actions.edit'), href: edit_referential_line_route_journey_pattern_path(referential, line, route, journey_pattern))
+ end
end
end
- end
- context 'user does not have permission to edit journey patterns' do
- it 'does not show edit links for journey patterns' do
- @user.update_attribute(:permissions, [])
- visit referential_line_route_path(referential, line, route)
- expect(page).not_to have_link(I18n.t('actions.edit'), href: edit_referential_line_route_journey_pattern_path(referential, line, route, journey_pattern))
+ context 'user does not have permission to edit journey patterns' do
+ it 'does not show edit links for journey patterns' do
+ @user.update_attribute(:permissions, [])
+ visit referential_line_route_path(referential, line, route)
+ expect(page).not_to have_link(I18n.t('actions.edit'), href: edit_referential_line_route_journey_pattern_path(referential, line, route, journey_pattern))
+ end
end
- end
- context 'user has permission to destroy journey patterns' do
- it 'shows destroy links for journey patterns' do
- expect(page).to have_content(I18n.t('actions.destroy'))
+ context 'user has permission to destroy journey patterns' do
+ it 'shows destroy links for journey patterns' do
+ expect(page).to have_content(I18n.t('actions.destroy'))
+ end
end
- end
- context 'user does not have permission to destroy journey patterns' do
- it 'does not show destroy links for journey patterns' do
- @user.update_attribute(:permissions, [])
- visit referential_line_route_path(referential, line, route)
- expect(page).not_to have_link(I18n.t('actions.destroy'), href: referential_line_route_journey_pattern_path(referential, line, route, journey_pattern))
+ context 'user does not have permission to destroy journey patterns' do
+ it 'does not show destroy links for journey patterns' do
+ @user.update_attribute(:permissions, [])
+ visit referential_line_route_path(referential, line, route)
+ expect(page).not_to have_link(I18n.t('actions.destroy'), href: referential_line_route_journey_pattern_path(referential, line, route, journey_pattern))
+ end
end
end
- end
- describe 'referential line show' do
- before(:each) { visit referential_line_path(referential, line) }
+ describe 'referential line show' do
+ before(:each) { visit referential_line_path(referential, line) }
- context 'user has permission to edit routes' do
- it 'shows edit buttons for routes' do
- expect(page).to have_content(I18n.t('actions.edit'))
+ context 'user has permission to edit routes' do
+ it 'shows edit buttons for routes' do
+ expect(page).to have_content(I18n.t('actions.edit'))
+ end
end
- end
- context 'user does not have permission to edit routes' do
- it 'does not show edit buttons for routes' do
- @user.update_attribute(:permissions, [])
- visit referential_line_path(referential, line)
- expect(page).not_to have_link(I18n.t('actions.edit'), href: edit_referential_line_route_path(referential, line, route))
+ context 'user does not have permission to edit routes' do
+ it 'does not show edit buttons for routes' do
+ @user.update_attribute(:permissions, [])
+ visit referential_line_path(referential, line)
+ expect(page).not_to have_link(I18n.t('actions.edit'), href: edit_referential_line_route_path(referential, line, route))
+ end
end
- end
- context 'user has permission to create routes' do
- it 'shows link to a create route page' do
- expect(page).to have_content(I18n.t('routes.actions.new'))
+ context 'user has permission to create routes' do
+ it 'shows link to a create route page' do
+ expect(page).to have_content(I18n.t('routes.actions.new'))
+ end
end
- end
- context 'user belongs to another organisation' do
- xit 'does not show link to a create route page' do
- expect(page).not_to have_content(I18n.t('routes.actions.new'))
+ context 'user belongs to another organisation' do
+ xit 'does not show link to a create route page' do
+ expect(page).not_to have_content(I18n.t('routes.actions.new'))
+ end
end
- end
- context 'user does not have permission to create routes' do
- it 'does not show link to a create route page' do
- @user.update_attribute(:permissions, [])
- visit referential_line_path(referential, line)
- expect(page).not_to have_content(I18n.t('routes.actions.new'))
+ context 'user does not have permission to create routes' do
+ it 'does not show link to a create route page' do
+ @user.update_attribute(:permissions, [])
+ visit referential_line_path(referential, line)
+ expect(page).not_to have_content(I18n.t('routes.actions.new'))
+ end
end
- end
- context 'user does not have permission to destroy routes' do
- it 'does not show destroy buttons for routes' do
- @user.update_attribute(:permissions, [])
- visit referential_line_path(referential, line)
- expect(page).not_to have_link(I18n.t('actions.destroy'), href: referential_line_route_path(referential, line, route))
+ context 'user does not have permission to destroy routes' do
+ it 'does not show destroy buttons for routes' do
+ @user.update_attribute(:permissions, [])
+ visit referential_line_path(referential, line)
+ expect(page).not_to have_link(I18n.t('actions.destroy'), href: referential_line_route_path(referential, line, route))
+ end
end
end
end
diff --git a/spec/features/workbenches_spec.rb b/spec/features/workbenches_spec.rb
index 9a40a8376..cad70624f 100644
--- a/spec/features/workbenches_spec.rb
+++ b/spec/features/workbenches_spec.rb
@@ -156,7 +156,6 @@ describe 'Workbenches', type: :feature do
end
end
end
- end
context 'permissions' do
before(:each) do
@@ -177,7 +176,6 @@ describe 'Workbenches', type: :feature do
end
end
end
- end
describe 'create new Referential' do
it "create a new Referential with a specifed line and period" do
@@ -188,8 +186,9 @@ describe 'Workbenches', type: :feature do
fill_in "referential[name]", with: "Referential to test creation"
select workbench.lines.first.id, from: 'referential[metadatas_attributes][0][lines][]'
- click_button "Valider"
- expect(page).to have_css("h1", text: "Referential to test creation")
+ click_button "Valider"
+ expect(page).to have_css("h1", text: "Referential to test creation")
+ end
end
end
end
diff --git a/spec/support/pundit/policies.rb b/spec/support/pundit/policies.rb
index 02fea2944..d5bb63243 100644
--- a/spec/support/pundit/policies.rb
+++ b/spec/support/pundit/policies.rb
@@ -35,10 +35,24 @@ module Support
end
end
end
+
+ module FeaturePermissionMacros
+ def with_permissions(*permissions, &blk)
+ perms, options = permissions.partition{|x| String === x}
+ context "with permissions #{perms.inspect}...", *options do
+ before do
+ add_permissions(*permissions, for_user: @user)
+ end
+ instance_eval(&blk)
+ end
+ end
+ end
end
end
RSpec.configure do | c |
c.include Support::Pundit::Policies, type: :policy
c.extend Support::Pundit::PoliciesMacros, type: :policy
+ c.include Support::Pundit::Policies, type: :feature
+ c.extend Support::Pundit::FeaturePermissionMacros, type: :feature
end