spec/pundit_spec.rb in pundit-1.0.1 vs spec/pundit_spec.rb in pundit-1.1.0

- old
+ new

@@ -1,17 +1,22 @@ require "spec_helper" describe Pundit do let(:user) { double } let(:post) { Post.new(user) } + let(:customer_post) { Customer::Post.new(user) } + let(:post_four_five_six) { PostFourFiveSix.new(user) } let(:comment) { Comment.new } + let(:comment_four_five_six) { CommentFourFiveSix.new } let(:article) { Article.new } - let(:controller) { Controller.new(user, { :action => 'update' }) } + let(:controller) { Controller.new(user, action: "update") } let(:artificial_blog) { ArtificialBlog.new } let(:article_tag) { ArticleTag.new } let(:comments_relation) { CommentsRelation.new } let(:empty_comments_relation) { CommentsRelation.new(true) } + let(:tag_four_five_six) { ProjectOneTwoThree::TagFourFiveSix.new(user) } + let(:avatar_four_five_six) { ProjectOneTwoThree::AvatarFourFiveSix.new } describe ".authorize" do it "infers the policy and authorizes based on it" do expect(Pundit.authorize(user, post, :update?)).to be_truthy end @@ -20,11 +25,14 @@ expect(Pundit.authorize(user, article_tag, :show?)).to be_truthy expect { Pundit.authorize(user, article_tag, :destroy?) }.to raise_error(Pundit::NotAuthorizedError) end it "raises an error with a query and action" do - expect { Pundit.authorize(user, post, :destroy?) }.to raise_error(Pundit::NotAuthorizedError, "not allowed to destroy? this #<Post>") do |error| + # rubocop:disable Style/MultilineBlockChain + expect do + Pundit.authorize(user, post, :destroy?) + end.to raise_error(Pundit::NotAuthorizedError, "not allowed to destroy? this #<Post>") do |error| expect(error.query).to eq :destroy? expect(error.record).to eq post expect(error.policy).to eq Pundit.policy(user, post) end end @@ -72,11 +80,13 @@ it "throws an exception if the given policy scope can't be found" do expect { Pundit.policy_scope!(user, ArticleTag) }.to raise_error(Pundit::NotDefinedError) end it "throws an exception if the given policy scope is nil" do - expect { Pundit.policy_scope!(user, nil) }.to raise_error(Pundit::NotDefinedError, "unable to find policy scope of nil") + expect do + Pundit.policy_scope!(user, nil) + end.to raise_error(Pundit::NotDefinedError, "unable to find policy scope of nil") end end describe ".policy" do it "returns an instantiated policy given a plain model instance" do @@ -101,10 +111,97 @@ policy = Pundit.policy(user, Comment) expect(policy.user).to eq user expect(policy.comment).to eq Comment end + it "returns an instantiated policy given a symbol" do + policy = Pundit.policy(user, :criteria) + expect(policy.class).to eq CriteriaPolicy + expect(policy.user).to eq user + expect(policy.criteria).to eq :criteria + end + + it "returns an instantiated policy given an array of symbols" do + policy = Pundit.policy(user, [:project, :criteria]) + expect(policy.class).to eq Project::CriteriaPolicy + expect(policy.user).to eq user + expect(policy.criteria).to eq [:project, :criteria] + end + + it "returns an instantiated policy given an array of a symbol and plain model instance" do + policy = Pundit.policy(user, [:project, post]) + expect(policy.class).to eq Project::PostPolicy + expect(policy.user).to eq user + expect(policy.post).to eq [:project, post] + end + + it "returns an instantiated policy given an array of a symbol and an active model instance" do + policy = Pundit.policy(user, [:project, comment]) + expect(policy.class).to eq Project::CommentPolicy + expect(policy.user).to eq user + expect(policy.post).to eq [:project, comment] + end + + it "returns an instantiated policy given an array of a symbol and a plain model class" do + policy = Pundit.policy(user, [:project, Post]) + expect(policy.class).to eq Project::PostPolicy + expect(policy.user).to eq user + expect(policy.post).to eq [:project, Post] + end + + it "returns an instantiated policy given an array of a symbol and an active model class" do + policy = Pundit.policy(user, [:project, Comment]) + expect(policy.class).to eq Project::CommentPolicy + expect(policy.user).to eq user + expect(policy.post).to eq [:project, Comment] + end + + it "returns correct policy class for an array of a multi-word symbols" do + policy = Pundit.policy(user, [:project_one_two_three, :criteria_four_five_six]) + expect(policy.class).to eq ProjectOneTwoThree::CriteriaFourFiveSixPolicy + end + + it "returns correct policy class for an array of a multi-word symbol and a multi-word plain model instance" do + policy = Pundit.policy(user, [:project_one_two_three, post_four_five_six]) + expect(policy.class).to eq ProjectOneTwoThree::PostFourFiveSixPolicy + end + + it "returns correct policy class for an array of a multi-word symbol and a multi-word active model instance" do + policy = Pundit.policy(user, [:project_one_two_three, comment_four_five_six]) + expect(policy.class).to eq ProjectOneTwoThree::CommentFourFiveSixPolicy + end + + it "returns correct policy class for an array of a multi-word symbol and a multi-word plain model class" do + policy = Pundit.policy(user, [:project_one_two_three, PostFourFiveSix]) + expect(policy.class).to eq ProjectOneTwoThree::PostFourFiveSixPolicy + end + + it "returns correct policy class for an array of a multi-word symbol and a multi-word active model class" do + policy = Pundit.policy(user, [:project_one_two_three, CommentFourFiveSix]) + expect(policy.class).to eq ProjectOneTwoThree::CommentFourFiveSixPolicy + end + + it "returns correct policy class for a multi-word scoped plain model class" do + policy = Pundit.policy(user, ProjectOneTwoThree::TagFourFiveSix) + expect(policy.class).to eq ProjectOneTwoThree::TagFourFiveSixPolicy + end + + it "returns correct policy class for a multi-word scoped plain model instance" do + policy = Pundit.policy(user, tag_four_five_six) + expect(policy.class).to eq ProjectOneTwoThree::TagFourFiveSixPolicy + end + + it "returns correct policy class for a multi-word scoped active model class" do + policy = Pundit.policy(user, ProjectOneTwoThree::AvatarFourFiveSix) + expect(policy.class).to eq ProjectOneTwoThree::AvatarFourFiveSixPolicy + end + + it "returns correct policy class for a multi-word scoped active model instance" do + policy = Pundit.policy(user, avatar_four_five_six) + expect(policy.class).to eq ProjectOneTwoThree::AvatarFourFiveSixPolicy + end + it "returns nil if the given policy can't be found" do expect(Pundit.policy(user, article)).to be_nil expect(Pundit.policy(user, Article)).to be_nil end @@ -134,24 +231,10 @@ it "returns an instantiated policy given a plain model class providing an anonymous class" do policy = Pundit.policy(user, ArticleTag) expect(policy.user).to eq user expect(policy.tag).to eq ArticleTag end - - it "returns an instantiated policy given a symbol" do - policy = Pundit.policy(user, :criteria) - expect(policy.class).to eq CriteriaPolicy - expect(policy.user).to eq user - expect(policy.criteria).to eq :criteria - end - - it "returns an instantiated policy given an array" do - policy = Pundit.policy(user, [:project, :criteria]) - expect(policy.class).to eq Project::CriteriaPolicy - expect(policy.user).to eq user - expect(policy.criteria).to eq [:project, :criteria] - end end end describe ".policy!" do it "returns an instantiated policy given a plain model instance" do @@ -183,11 +266,11 @@ expect(policy.class).to eq CriteriaPolicy expect(policy.user).to eq user expect(policy.criteria).to eq :criteria end - it "returns an instantiated policy given an array" do + it "returns an instantiated policy given an array of symbols" do policy = Pundit.policy!(user, [:project, :criteria]) expect(policy.class).to eq Project::CriteriaPolicy expect(policy.user).to eq user expect(policy.criteria).to eq [:project, :criteria] end @@ -293,11 +376,11 @@ expect { controller.verify_policy_scoped }.not_to raise_error end end describe "#pundit_user" do - it 'returns the same thing as current_user' do + it "returns the same thing as current_user" do expect(controller.pundit_user).to eq controller.current_user end end describe "#policy" do @@ -336,13 +419,52 @@ end end describe "#permitted_attributes" do it "checks policy for permitted attributes" do - params = ActionController::Parameters.new({ action: 'update', post: { title: 'Hello', votes: 5, admin: true } }) + params = ActionController::Parameters.new(action: "update", post: { + title: "Hello", + votes: 5, + admin: true + }) - expect(Controller.new(user, params).permitted_attributes(post)).to eq({ 'title' => 'Hello', 'votes' => 5 }) - expect(Controller.new(double, params).permitted_attributes(post)).to eq({ 'votes' => 5 }) + expect(Controller.new(user, params).permitted_attributes(post)).to eq("title" => "Hello", "votes" => 5) + expect(Controller.new(double, params).permitted_attributes(post)).to eq("votes" => 5) + end + + it "checks policy for permitted attributes for record of a ActiveModel type" do + params = ActionController::Parameters.new(action: "update", customer_post: { + title: "Hello", + votes: 5, + admin: true + }) + + expect(Controller.new(user, params).permitted_attributes(customer_post)).to eq("title" => "Hello", "votes" => 5) + expect(Controller.new(double, params).permitted_attributes(customer_post)).to eq("votes" => 5) + end + end + + describe "#permitted_attributes_for_action" do + it "is checked if it is defined in the policy" do + params = ActionController::Parameters.new(action: "revise", post: { + title: "Hello", + body: "blah", + votes: 5, + admin: true + }) + + expect(Controller.new(user, params).permitted_attributes(post)).to eq("body" => "blah") + end + + it "can be explicitly set" do + params = ActionController::Parameters.new(action: "update", post: { + title: "Hello", + body: "blah", + votes: 5, + admin: true + }) + + expect(Controller.new(user, params).permitted_attributes(post, :revise)).to eq("body" => "blah") end end describe "Pundit::NotAuthorizedError" do it "can be initialized with a string as message" do