Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minitest? #204

Closed
epinault opened this issue Sep 3, 2014 · 6 comments
Closed

Minitest? #204

epinault opened this issue Sep 3, 2014 · 6 comments

Comments

@epinault
Copy link

epinault commented Sep 3, 2014

Do you have an example of how you would test it with minitest? Or minitest spec?

@pbougie
Copy link

pbougie commented Oct 22, 2014

This is how I'm testing my policies using MiniTest. I've created a few helper functions:

# test_helper.rb
def assert_permit(user, record, action)
  msg = "User #{user.inspect} should be permitted to #{action} #{record}, but isn't permitted"
  assert permit(user, record, action), msg
end

def refute_permit(user, record, action)
  msg = "User #{user.inspect} should NOT be permitted to #{action} #{record}, but is permitted"
  refute permit(user, record, action), msg
end

def permit(user, record, action)
  cls = self.class.superclass.to_s.gsub(/Test/, '')
  cls.constantize.new(user, record).public_send("#{action.to_s}?")
end

And then for each policy file:

# post_policy_test.rb
require 'test_helper'

class PostPolicyTest < ActiveSupport::TestCase
  before do
    @account = build_stubbed(:account)
    @administrator = build_stubbed(:administrator, account: @account)
    @employee = build_stubbed(:employee, account: @account)
    @post = build_stubbed(:post, account: @account)
  end

  describe "for an administrator" do
    it { assert_permit @administrator, :post, :index }
    it { assert_permit @administrator, @post, :show }
    it { assert_permit @administrator, @post, :new }
    it { assert_permit @administrator, @post, :create }
    it { assert_permit @administrator, @post, :edit }
    it { assert_permit @administrator, @post, :update }
    it { assert_permit @administrator, @post, :destroy }
  end

  describe "for an employee" do
    it { refute_permit @employee, :post, :index }
    it { refute_permit @employee, @post, :show }
    it { refute_permit @employee, @post, :new }
    it { refute_permit @employee, @post, :create }
    it { refute_permit @employee, @post, :edit }
    it { refute_permit @employee, @post, :update }
    it { refute_permit @employee, @post, :destroy }
  end

  describe "for a guest" do
    it { refute_permit nil, :post, :index }
    it { refute_permit nil, @post, :show }
    it { refute_permit nil, @post, :new }
    it { refute_permit nil, @post, :create }
    it { refute_permit nil, @post, :edit }
    it { refute_permit nil, @post, :update }
    it { refute_permit nil, @post, :destroy }
  end
end

Hope this helps. If anybody has improvements, please share.

@epinault
Copy link
Author

ah cool! Looks really nice. Will give it a try

@thomasklemm
Copy link
Collaborator

👍 @pbougie Thanks for sharing!

@michaelfeihstel
Copy link

It comes close to the Gist I found here: https://gist.github.com/promisedlandt/9800713

However I actually prefer your approach. Thank you.

@rpearce
Copy link

rpearce commented Mar 4, 2016

For anybody who has nested describe issues in the future, based on the issue described here and the solution I came up with, if you're having nested describe problems, then try changing your permit method to

def permit(user, record, action)
  test_name = self.class.ancestors.select { |a| a.to_s.match(/PolicyTest/) }.first
  klass = test_name.to_s.gsub(/Test/, '')
  klass.constantize.new(user, record).public_send("#{action.to_s}?")
end

Hope that helps!

@pbougie
Copy link

pbougie commented May 20, 2016

Unfortunately this didn't work as expected. My test classes also use a describe block at the top-level (unlike the above example), i.e.

describe PostPolicy do
  ...
end

Therefore my permit() method is as follows:

def permit(user, record, action)
  index = self.class.name.index('Policy')
  klass = self.class.name[0, index+6]
  klass.constantize.new(user, record).public_send("#{action.to_s}?")
end

This solution seems to work for namespaced policies and nested describe blocks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants