Permalink
Browse files

Add policy and specs

For the policy specs, we use pundit-matchers, as the policy is specified
according to Pundit's convention. Also, factories are adjusted to
reflect the current data model.
  • Loading branch information...
1 parent c78d4ea commit 0b6d401691400622d9eaa56ae891d0e2a68230f2 @aviav aviav committed with tf Mar 10, 2016
@@ -0,0 +1,30 @@
+module Pageflow
+ module Policies
+ class EntryPolicy
+ def initialize(user, entry)
+ @user = user
+ @entry = entry
+ end
+
+ def preview?
+ @user.memberships.where(entity: @entry, role: ['previewer', 'editor', 'publisher', 'manager']).any? ||
+ @user.memberships.where(entity: @entry.account, role: ['previewer', 'editor', 'publisher', 'manager']).any?
+ end
+
+ def edit?
+ @user.memberships.where(entity: @entry, role: ['editor', 'publisher', 'manager']).any? ||
+ @user.memberships.where(entity: @entry.account, role: ['editor', 'publisher', 'manager']).any?
+ end
+
+ def publish?
+ @user.memberships.where(entity: @entry, role: ['publisher', 'manager']).any? ||
+ @user.memberships.where(entity: @entry.account, role: ['publisher', 'manager']).any?
+ end
+
+ def configure?
+ @user.memberships.where(entity: @entry, role: 'manager').any? ||
+ @user.memberships.where(entity: @entry.account, role: 'manager').any?
+ end
+ end
+ end
+end
View
@@ -139,6 +139,9 @@ Gem::Specification.new do |s|
# Fixture replacement
s.add_development_dependency 'factory_girl_rails', '~> 4.5'
+ # Matchers for Pundit policies
+ s.add_development_dependency 'pundit-matchers', '~> 1.0'
+
# Clean database in integration tests
s.add_development_dependency 'database_cleaner', '~> 1.2'
@@ -20,7 +20,7 @@ module Pageflow
end
after(:create) do |entry, evaluator|
- create(:membership, :entry => entry, :user => evaluator.with_member) if evaluator.with_member
+ create(:membership, entity: entry, user: evaluator.with_member) if evaluator.with_member
end
trait :published do
@@ -1,8 +1,9 @@
module Pageflow
FactoryGirl.define do
- factory :membership, :class => Membership do
+ factory :membership, class: Membership do
user
- entry
+ association :entity, factory: :entry
+ role 'editor'
end
end
end
@@ -0,0 +1,34 @@
+require 'spec_helper'
+
+module Pageflow
+ module Policies
+ describe EntryPolicy do
+ describe :configure do
+ include_examples 'for entry and account',
+ permission_type: :configure,
+ minimum_required_role: 'manager',
+ maximum_forbidden_role: 'publisher'
+ end
+
+ describe :publish do
+ include_examples 'for entry and account',
+ permission_type: :publish,
+ minimum_required_role: 'publisher',
+ maximum_forbidden_role: 'editor'
+ end
+
+ describe :edit do
+ include_examples 'for entry and account',
+ permission_type: :edit,
+ minimum_required_role: 'editor',
+ maximum_forbidden_role: 'previewer'
+ end
+
+ describe :preview do
+ include_examples 'for entry and account',
+ permission_type: :preview,
+ minimum_required_role: 'previewer'
+ end
+ end
+ end
+end
@@ -0,0 +1,49 @@
+require 'spec_helper'
+
+module Pageflow
+ module Policies
+ shared_examples 'a membership-based permission that' do |params|
+ let(:user) { create(:user) }
+ let(:entry) { create(:entry) }
+ let(:entity) { params[:entity] == :entry ? entry : entry.account }
+ let(:policy) { EntryPolicy.new(user, entry) }
+
+ it "allows #{params[:entity]} #{params[:minimum_required_role]} " \
+ "to #{params[:permission_type]} respective entry" do
+ create(:membership, user: user, entity: entity, role: params[:minimum_required_role])
+
+ expect(policy).to permit_action(params[:permission_type])
+ end
+
+ it "does not allow #{params[:entity]} #{params[:minimum_required_role]} " \
+ "to #{params[:permission_type]} off-limits entry" do
+ params[:entity] == :entry ? other_entity = create(:entry) : other_entity = create(:account)
+ create(:membership, user: user, entity: other_entity, role: params[:minimum_required_role])
+
+ expect(policy).not_to permit_action(params[:permission_type])
+ end
+
+ if params[:maximum_forbidden_role].present?
+ it "does not allow #{params[:entity]} #{params[:maximum_forbidden_role]} " \
+ "to #{params[:permission_type]} respective entry" do
+ create(:membership, user: user, entity: entity, role: params[:maximum_forbidden_role])
+
+ expect(policy).not_to permit_action(params[:permission_type])
+ end
+ else
+ it 'does not allow user without membership ' \
+ "to #{params[:permission_type]} respective entry" do
+ expect(policy).not_to permit_action(params[:permission_type])
+ end
+ end
+ end
+
+ shared_examples 'for entry and account' do |params|
+ params_entry = params.merge(entity: :entry)
+ it_behaves_like 'a membership-based permission that', params_entry
+
+ params_account = params.merge(entity: :account)
+ it_behaves_like 'a membership-based permission that', params_account
+ end
+ end
+end
View
@@ -7,6 +7,7 @@
require 'rspec/collection_matchers'
require 'domino'
require 'ammeter/init'
+require 'pundit/matchers'
Dir[File.join(File.dirname(__FILE__), 'support/{config,dominos,helpers,matchers}/**/*.rb')].each { |file| require(file) }
Dir[Pageflow::Engine.root.join("spec/**/*_examples.rb")].each { |file| require(file) }

0 comments on commit 0b6d401

Please sign in to comment.