rspec-authorization 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +5 -0
- data/.yardopts +3 -0
- data/Gemfile +7 -0
- data/Guardfile +2 -1
- data/HISTORY.md +32 -0
- data/README.md +60 -7
- data/lib/rspec/authorization/adapters/example.rb +32 -9
- data/lib/rspec/authorization/adapters/example_group.rb +78 -0
- data/lib/rspec/authorization/adapters/request.rb +129 -14
- data/lib/rspec/authorization/adapters/route.rb +99 -16
- data/lib/rspec/authorization/adapters.rb +2 -2
- data/lib/rspec/authorization/matchers/have_permission_for.rb +126 -11
- data/lib/rspec/authorization/matchers.rb +1 -1
- data/lib/rspec/authorization/version.rb +2 -2
- data/lib/rspec/authorization.rb +2 -2
- data/rspec-authorization.gemspec +2 -2
- data/spec/controllers/articles_controller_spec.rb +21 -0
- data/spec/lib/rspec/authorization/adapters/example_group_spec.rb +28 -0
- data/spec/lib/rspec/authorization/adapters/example_spec.rb +6 -16
- data/spec/lib/rspec/authorization/adapters/request_spec.rb +3 -3
- data/spec/spec_helper.rb +3 -0
- data/spec/tools/rails_test_app_spec.rb +3 -1
- data/tools/rails_test_app/template.rb +18 -7
- metadata +15 -11
- data/lib/rspec/authorization/adapters/group.rb +0 -14
- data/spec/controllers/posts_controller_spec.rb +0 -11
- data/spec/lib/rspec/authorization/adapters/group_spec.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 79650ca2e93b08c5ebd9008fa9e6f51e59d5245c
|
4
|
+
data.tar.gz: 64f6364b28ef24e98d203b764165201ac2c32a33
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f28d44b4dec4e86ade6980070bebcbfdb0b35a9daded58db14e539c086ba380959ab81aee49a09e30839cfb1d2fcc16138c05ebc4588d1b6ea9cde4d00971262
|
7
|
+
data.tar.gz: f026a6b7e065e16d10e53bad7bfdaf66838abe3952cf421739d113b3334ba76bc077529b2f5d6788f56491fa3e3aa32520f5db42f123b63e1c20ed4652129da8
|
data/.travis.yml
ADDED
data/.yardopts
ADDED
data/Gemfile
CHANGED
@@ -8,7 +8,14 @@ group :development, :test do
|
|
8
8
|
gem 'guard-rspec'
|
9
9
|
gem 'pry'
|
10
10
|
gem 'terminal-notifier-guard' if `uname` =~ /Darwin/
|
11
|
+
gem "codeclimate-test-reporter", require: nil
|
11
12
|
|
12
13
|
gem 'jquery-rails'
|
13
14
|
gem 'turbolinks'
|
14
15
|
end
|
16
|
+
|
17
|
+
group :docs do
|
18
|
+
gem "inch"
|
19
|
+
gem "rdoc"
|
20
|
+
gem "yard"
|
21
|
+
end
|
data/Guardfile
CHANGED
@@ -4,6 +4,7 @@ guard :rspec, cmd: 'bundle exec rspec' do
|
|
4
4
|
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
5
5
|
watch(%r{^tools/(.+)\.rb$}) { |m| "spec/tools/#{m[1]}_spec.rb" }
|
6
6
|
|
7
|
-
watch(%r{^
|
7
|
+
watch(%r{^lib/.+/matchers/.+\.rb$}) { "spec/controllers" }
|
8
|
+
watch(%r{^controllers/(.+)\.rb$}) { |m| "spec/controllers/#{m[1]}_spec.rb" }
|
8
9
|
end
|
9
10
|
|
data/HISTORY.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
|
2
|
+
[v0.0.2 / 2014-11-11] (https://github.com/hendrauzia/rspec-authorization/tree/v0.0.2)
|
3
|
+
=====================
|
4
|
+
|
5
|
+
* Add RESTful methods matcher chaining
|
6
|
+
* Add object, callback and controller action stub
|
7
|
+
* Add documentation to have_permission_for matcher
|
8
|
+
* Add request documentation
|
9
|
+
* Refactor and add documentation to example
|
10
|
+
* Refactor and add documentation to example group
|
11
|
+
* Add documentation to gem requirement
|
12
|
+
* Add documentation to route
|
13
|
+
* Add yard as documentation generator
|
14
|
+
* Add documentation badge
|
15
|
+
* Add coverage, dependencies and security badges
|
16
|
+
* Fix rails test app spec
|
17
|
+
* Fix travis build
|
18
|
+
* Add travis badge and config
|
19
|
+
* Add gem version badge and usage
|
20
|
+
|
21
|
+
[v0.0.1 / 2014-11-05] (https://github.com/hendrauzia/rspec-authorization/tree/v0.0.1)
|
22
|
+
=====================
|
23
|
+
|
24
|
+
* Add have_permission_for matcher for restful actions
|
25
|
+
* Add rails test app template
|
26
|
+
* Add clean and reset rake task
|
27
|
+
* Update dependency to ruby 2.1.4
|
28
|
+
* Add rails test app for spec to run against
|
29
|
+
* Add rspec-rails for specs
|
30
|
+
* Add rspec-authorization gem scaffold using bundler
|
31
|
+
* Initial commit
|
32
|
+
|
data/README.md
CHANGED
@@ -1,22 +1,75 @@
|
|
1
|
-
#
|
1
|
+
# RSpec::Authorization
|
2
2
|
|
3
|
-
|
3
|
+
[![GitHub](http://img.shields.io/badge/github-hendrauzia/rspec--authorization-blue.svg)](http://github.com/hendrauzia/rspec-authorization)
|
4
|
+
[![Documentation](http://img.shields.io/badge/docs-rdoc.info-blue.svg)](http://rubydoc.org/github/hendrauzia/rspec-authorization)
|
5
|
+
|
6
|
+
[![Gem Version](https://badge.fury.io/rb/rspec-authorization.svg)](http://badge.fury.io/rb/rspec-authorization)
|
7
|
+
[![Build Status](https://travis-ci.org/hendrauzia/rspec-authorization.svg)](https://travis-ci.org/hendrauzia/rspec-authorization)
|
8
|
+
[![Code Climate](https://codeclimate.com/github/hendrauzia/rspec-authorization/badges/gpa.svg)](https://codeclimate.com/github/hendrauzia/rspec-authorization)
|
9
|
+
[![Test Coverage](https://codeclimate.com/github/hendrauzia/rspec-authorization/badges/coverage.svg)](https://codeclimate.com/github/hendrauzia/rspec-authorization)
|
10
|
+
[![Dependency Status](https://gemnasium.com/hendrauzia/rspec-authorization.svg)](https://gemnasium.com/hendrauzia/rspec-authorization)
|
11
|
+
[![security](https://hakiri.io/github/hendrauzia/rspec-authorization/master.svg)](https://hakiri.io/github/hendrauzia/rspec-authorization/master)
|
12
|
+
[![Inline docs](http://inch-ci.org/github/hendrauzia/rspec-authorization.svg?branch=master)](http://inch-ci.org/github/hendrauzia/rspec-authorization)
|
13
|
+
|
14
|
+
RSpec matcher for declarative_authorization. A neat way of asserting
|
15
|
+
declarative_authorization's rules inside controller using RSpec matcher.
|
4
16
|
|
5
17
|
## Installation
|
6
18
|
|
7
19
|
Add this line to your application's Gemfile:
|
8
20
|
|
9
|
-
|
10
|
-
gem 'rspec-authorization'
|
11
|
-
|
21
|
+
|
22
|
+
gem 'rspec-authorization', group: :test
|
23
|
+
|
12
24
|
|
13
25
|
And then execute:
|
14
26
|
|
15
|
-
|
27
|
+
bundle
|
16
28
|
|
17
29
|
Or install it yourself as:
|
18
30
|
|
19
|
-
|
31
|
+
gem install rspec-authorization
|
32
|
+
|
33
|
+
## Requirement
|
34
|
+
|
35
|
+
Current development focus is as follows, future development may support other
|
36
|
+
dependencies, following are requirements for this gem:
|
37
|
+
|
38
|
+
- declarative_authorization 1.0.0.pre
|
39
|
+
- rails 4.x
|
40
|
+
- rspec-rails 3.x
|
41
|
+
|
42
|
+
## Usage
|
43
|
+
|
44
|
+
In your controller spec:
|
45
|
+
|
46
|
+
describe ArticlesController do
|
47
|
+
it { is_expected.to have_permission_for(:a_role).to(:restful_action_name) }
|
48
|
+
|
49
|
+
it { is_expected.to have_permission_for(:writer).to(:index) }
|
50
|
+
it { is_expected.to have_permission_for(:writer).to(:show) }
|
51
|
+
it { is_expected.to have_permission_for(:writer).to(:new) }
|
52
|
+
it { is_expected.to have_permission_for(:writer).to(:create) }
|
53
|
+
it { is_expected.not_to have_permission_for(:writer).to(:edit) }
|
54
|
+
it { is_expected.not_to have_permission_for(:writer).to(:update) }
|
55
|
+
it { is_expected.not_to have_permission_for(:writer).to(:destroy) }
|
56
|
+
end
|
57
|
+
|
58
|
+
You can also use convenience RESTful methods matcher:
|
59
|
+
|
60
|
+
describe ArticlesController do
|
61
|
+
it { is_expected.to have_permission_for(:user).to_read }
|
62
|
+
it { is_expected.not_to have_permission_for(:user).to_create }
|
63
|
+
it { is_expected.not_to have_permission_for(:user).to_update }
|
64
|
+
it { is_expected.not_to have_permission_for(:user).to_delete }
|
65
|
+
|
66
|
+
it { is_expected.to have_permission_for(:writer).to_read }
|
67
|
+
it { is_expected.to have_permission_for(:writer).to_create }
|
68
|
+
it { is_expected.to have_permission_for(:writer).to_update }
|
69
|
+
it { is_expected.not_to have_permission_for(:writer).to_delete }
|
70
|
+
|
71
|
+
it { is_expected.to have_permission_for(:editor).to_manage }
|
72
|
+
end
|
20
73
|
|
21
74
|
## Contributing
|
22
75
|
|
@@ -1,27 +1,50 @@
|
|
1
1
|
module RSpec::Authorization
|
2
2
|
module Adapters
|
3
|
+
# Wrapper to generate and immediately run example from +RSpec::Core::Example+.
|
4
|
+
# The purpose of this class is to abstract the running of an example without
|
5
|
+
# unnecessary artifacts from an RSpec example, such as: reporter, generated
|
6
|
+
# description, context and expectation.
|
7
|
+
#
|
8
|
+
# The sole purpose of this class is to generate the minimum required component
|
9
|
+
# needed to create and run an example, for our matcher to run against. The trick
|
10
|
+
# to run the example without producing unnecessary artifacts is to trigger
|
11
|
+
# the example's before and after hook manually without running any expectations.
|
3
12
|
class Example
|
4
|
-
|
13
|
+
# @return [Class] RSpec example group
|
14
|
+
attr_reader :group_target
|
15
|
+
# @return [RSpec::Core::Example] instance of RSpec example
|
16
|
+
attr_reader :target
|
5
17
|
|
6
|
-
|
7
|
-
|
8
|
-
|
18
|
+
# Initialize example using RSpec example group. The RSpec example group can
|
19
|
+
# be retrieved using example group's target, consider the following example:
|
20
|
+
#
|
21
|
+
# group = ExampleGroup.new(ArticlesController)
|
22
|
+
# example = Example.new(group.target)
|
23
|
+
#
|
24
|
+
# @param group_target [Class] RSpec example group from +ExampleGroup#target+
|
25
|
+
# @see ExampleGroup#target
|
26
|
+
def initialize(group_target)
|
27
|
+
@group_target = group_target
|
28
|
+
@target = RSpec::Core::Example.new(group_target, "", {})
|
9
29
|
|
10
30
|
set_example_group_instance
|
11
|
-
end
|
12
|
-
|
13
|
-
def run
|
14
31
|
run_before_example
|
32
|
+
run_after_example
|
15
33
|
end
|
16
34
|
|
17
35
|
private
|
18
36
|
|
19
37
|
def set_example_group_instance
|
20
|
-
|
38
|
+
target.instance_variable_set :@example_group_instance, group_target.new
|
21
39
|
end
|
22
40
|
|
23
41
|
def run_before_example
|
24
|
-
|
42
|
+
target.send :run_before_example
|
43
|
+
end
|
44
|
+
|
45
|
+
def run_after_example
|
46
|
+
target.example_group.hooks.run(:after, :example, target)
|
47
|
+
target.example_group_instance.teardown_mocks_for_rspec
|
25
48
|
end
|
26
49
|
end
|
27
50
|
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module RSpec::Authorization
|
2
|
+
module Adapters
|
3
|
+
# Wrapper to generate +RSpec::Core::ExampleGroup+. The example group
|
4
|
+
# includes +RSpec::Rails::ControllerExampleGroup+ to add behavior testing,
|
5
|
+
# which provides methods to test the controller, such as: +get+, +post+,
|
6
|
+
# +patch+, +put+ and +delete+.
|
7
|
+
#
|
8
|
+
# Consider the following example:
|
9
|
+
#
|
10
|
+
# group = ExampleGroup.new(ArticlesController)
|
11
|
+
# group.target # => RSpec::ExampleGroups::ArticlesController
|
12
|
+
#
|
13
|
+
# Instantiating the class for a second time produce a different result:
|
14
|
+
#
|
15
|
+
# group = ExampleGroup.new(ArticlesController)
|
16
|
+
# group.target # => RSpec::ExampleGroups::ArticlesController_2
|
17
|
+
class ExampleGroup
|
18
|
+
# @return [Class] a class namespaced from +RSPec::ExampleGroups+
|
19
|
+
attr_reader :target
|
20
|
+
|
21
|
+
# Initialize example group using controller's class.
|
22
|
+
#
|
23
|
+
# @param klass [Class] controller's class for an example group
|
24
|
+
def initialize(klass)
|
25
|
+
@target = RSpec::Core::ExampleGroup.describe(klass) do
|
26
|
+
include RSpec::Rails::ControllerExampleGroup
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Run example for our example group. The example is actualy has
|
31
|
+
# no example at all, it is simply a wrapper for +RSpec::Core::Example+,
|
32
|
+
# running an actual example would produce unnecessary artifacts, while all
|
33
|
+
# we need is a simple wrapper on controller behavior.
|
34
|
+
#
|
35
|
+
# @return [Example] example object that has been run
|
36
|
+
# @see Example
|
37
|
+
def run_example
|
38
|
+
Example.new(target)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Add instruction to be run before our example. Instructions added will be
|
42
|
+
# run inside the context of our example group, consider the following
|
43
|
+
# example:
|
44
|
+
#
|
45
|
+
# before do
|
46
|
+
# get :index
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# The above statements behave exactly the same as RSpec +before+ method, and
|
50
|
+
# this method serve as a proxy to RSpec +before+ method call. That means
|
51
|
+
# everything that we can do inside +before+ method will be available inside
|
52
|
+
# +before+ to.
|
53
|
+
#
|
54
|
+
# @return [Array<RSpec::Core::Hooks::BeforeHook>] an array of before hook filter
|
55
|
+
def before(&block)
|
56
|
+
target.before(&block)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Add instruction to be run after our example. Instructions added will be
|
60
|
+
# run inside the context of our example group, consider the following
|
61
|
+
# example:
|
62
|
+
#
|
63
|
+
# after do
|
64
|
+
# get :index
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
# The above statements behave exactly the same as RSpec +after+ method, and
|
68
|
+
# this method serve as a proxy to RSpec +after+ method call. That means
|
69
|
+
# everything that we can do inside +after+ method will be available inside
|
70
|
+
# +after+ to.
|
71
|
+
#
|
72
|
+
# @return [Array<RSpec::Core::Hooks::AfterHook>] an array of after hook filter
|
73
|
+
def after(&block)
|
74
|
+
target.after(&block)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -1,16 +1,86 @@
|
|
1
1
|
module RSpec::Authorization
|
2
2
|
module Adapters
|
3
|
+
# Create a request using wrapper around RSpec example. The request is made
|
4
|
+
# possible through wrapping the call around RSpec example, this approach
|
5
|
+
# is choosen because we need to get as close as possible to how the request
|
6
|
+
# is made inside RSpec.
|
7
|
+
#
|
8
|
+
# Once the request is created, it will immediately run and we can evaluate the
|
9
|
+
# response, consider the following example.
|
10
|
+
#
|
11
|
+
# request = Request.new(ArticlesController, :index, :user)
|
12
|
+
# request.response.status # => 200
|
13
|
+
#
|
14
|
+
# Since the request is actually creating a request to the provided controller,
|
15
|
+
# it will run everything inside the controller, and no stubbing is performed.
|
16
|
+
# Therefore exception inside controller will bubble up to the request and may
|
17
|
+
# cause unexpected result. That is with one exception, there is one exception,
|
18
|
+
# ActiveRecord::RecordNotFound is rescued and bypassed, therefore it will not
|
19
|
+
# affect the request.
|
3
20
|
class Request
|
4
|
-
|
21
|
+
# @return [Class] controller class name
|
22
|
+
attr_reader :klass
|
23
|
+
# @return [Symbol] controller action name
|
24
|
+
attr_reader :action
|
25
|
+
# @return [Symbol] role name from +config/authorization_rules.rb+
|
26
|
+
attr_reader :role
|
27
|
+
# @return [ExampleGroup] example group of the request
|
28
|
+
# @see ExampleGroup
|
29
|
+
attr_reader :group
|
30
|
+
# @return [Route] route object of the action
|
31
|
+
# @see Route
|
32
|
+
attr_reader :route
|
33
|
+
# @return [ActionController::TestResponse] response object of the request
|
34
|
+
attr_reader :response
|
5
35
|
|
36
|
+
# Create request object and immediately run the request. Inside initialization
|
37
|
+
# a lot of stuff get stubbed, it is to allow request to be run with assumptions,
|
38
|
+
# following are the assumptions composed as private method run inside the
|
39
|
+
# initializer:
|
40
|
+
#
|
41
|
+
# +stub_current_user+::
|
42
|
+
# The request is expected to run as a user with provided role. There is
|
43
|
+
# no user created whatsoever, it only creates a double with role_symbols
|
44
|
+
# defined and return it inside +current_user+.
|
45
|
+
#
|
46
|
+
# +stub_authorization_load_controller_object+::
|
47
|
+
# The request is expected to ignore declarative_authorization controller's
|
48
|
+
# object loading.
|
49
|
+
#
|
50
|
+
# +stub_authorization_load_object+::
|
51
|
+
# The request is expected to ignore declarative_authorization object
|
52
|
+
# loading. This is different from the above, and is expected to be called
|
53
|
+
# if controller object isn't loaded.
|
54
|
+
#
|
55
|
+
# +stub_callbacks+::
|
56
|
+
# The request is expected to ignore all callbacks defined inside the
|
57
|
+
# controller.
|
58
|
+
#
|
59
|
+
# +stub_action+::
|
60
|
+
# The request is expected to ignore all statements run inside the action
|
61
|
+
# and configured to render nothing instead.
|
62
|
+
#
|
63
|
+
# All of the above assumptions is expected to run only inside this request
|
64
|
+
# only, and not to change the behavior of the application outside of this
|
65
|
+
# request.
|
66
|
+
#
|
67
|
+
# @param klass [Class] controller class name to request from
|
68
|
+
# @param action [Symbol] action name, currently only support RESTful action
|
69
|
+
# @param role [Symbol] role name from +config/authorization_rules.rb+
|
6
70
|
def initialize(klass, action, role)
|
7
71
|
@klass, @action, @role = klass, action, role
|
8
|
-
@group, @route =
|
72
|
+
@group, @route = ExampleGroup.new(klass), Route.new(action)
|
73
|
+
|
74
|
+
@authorization_stubbed = false
|
9
75
|
|
10
76
|
stub_current_user
|
77
|
+
stub_authorization_load_controller_object
|
78
|
+
stub_authorization_load_object
|
79
|
+
stub_callbacks
|
80
|
+
stub_action
|
11
81
|
|
12
82
|
setup_response_retrieval
|
13
|
-
|
83
|
+
group.run_example
|
14
84
|
end
|
15
85
|
|
16
86
|
private
|
@@ -32,24 +102,69 @@ module RSpec::Authorization
|
|
32
102
|
end
|
33
103
|
end
|
34
104
|
|
35
|
-
def
|
36
|
-
|
37
|
-
|
105
|
+
def stub_authorization_load_controller_object
|
106
|
+
group.before do
|
107
|
+
allow(controller).to receive(:load_controller_object)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def stub_authorization_load_object
|
112
|
+
return if @authorization_stubbed
|
113
|
+
@authorization_stubbed = true
|
38
114
|
|
39
115
|
group.before do
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
116
|
+
Authorization::ControllerPermission.instance_eval do
|
117
|
+
alias_method :load_object_original, :load_object
|
118
|
+
define_method :load_object do |*args, &block|
|
119
|
+
begin
|
120
|
+
load_object_original(*args, &block)
|
121
|
+
rescue ActiveRecord::RecordNotFound
|
122
|
+
end
|
123
|
+
end
|
44
124
|
end
|
125
|
+
end
|
45
126
|
|
46
|
-
|
127
|
+
group.after do
|
128
|
+
Authorization::ControllerPermission.instance_eval do
|
129
|
+
remove_method :load_object
|
130
|
+
|
131
|
+
alias_method :load_object, :load_object_original
|
132
|
+
remove_method :load_object_original
|
133
|
+
end
|
47
134
|
end
|
48
135
|
end
|
49
136
|
|
50
|
-
def
|
51
|
-
|
52
|
-
|
137
|
+
def stub_callbacks
|
138
|
+
group.before do
|
139
|
+
methods = controller._process_action_callbacks.map(&:filter).split(:filter_access_filter).last
|
140
|
+
controller.instance_eval do
|
141
|
+
methods.each do |method|
|
142
|
+
define_singleton_method method do |*args, &block|
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def stub_action
|
150
|
+
args = route
|
151
|
+
group.before do
|
152
|
+
controller.instance_eval do
|
153
|
+
define_singleton_method args.action do |*args, &block|
|
154
|
+
render nothing: true
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def setup_response_retrieval
|
161
|
+
args = route
|
162
|
+
setter = response_setter
|
163
|
+
|
164
|
+
group.before do
|
165
|
+
send *args
|
166
|
+
setter.call(response)
|
167
|
+
end
|
53
168
|
end
|
54
169
|
end
|
55
170
|
end
|
@@ -1,8 +1,107 @@
|
|
1
1
|
module RSpec::Authorization
|
2
2
|
module Adapters
|
3
|
+
# Generate route that defines RESTful method using provided action. It is
|
4
|
+
# used primarily in creating a new request and infered automatically to an
|
5
|
+
# array using the defined +#to_a+ method.
|
6
|
+
#
|
7
|
+
# Route generation has 3 primary part, which are:
|
8
|
+
# - +verb+
|
9
|
+
# - +action+
|
10
|
+
# - +params+
|
11
|
+
#
|
12
|
+
# The first part, +verb+ refers to RESTful method, which is described in
|
13
|
+
# +DICTIONARIES+, +action+ refers to controller action name, and +params+
|
14
|
+
# refers to parameters used in a request. This object can be automatically
|
15
|
+
# inferred as an array.
|
16
|
+
#
|
17
|
+
# Creating a route will generate a route object:
|
18
|
+
#
|
19
|
+
# route = Route.new(:index)
|
20
|
+
# route # => #<Route:...>
|
21
|
+
#
|
22
|
+
# This will infer the object as an array:
|
23
|
+
#
|
24
|
+
# route = Route.new(:show)
|
25
|
+
# send *route # => [:get, :show, { id: 1 }]
|
26
|
+
#
|
27
|
+
# @see #to_a
|
3
28
|
class Route
|
29
|
+
# @return [Symbol] returns route action name
|
4
30
|
attr_reader :action
|
5
31
|
|
32
|
+
# Initializing a route requires a RESTful action name that the route want
|
33
|
+
# to generate. The action that get passed is assigned to +action+ attributes
|
34
|
+
# and is publicly accessible.
|
35
|
+
#
|
36
|
+
# route = Route.new(:index)
|
37
|
+
# route.action # => :index
|
38
|
+
#
|
39
|
+
# Currently +Route+ only support RESTful action, passing non-RESTful action
|
40
|
+
# name is possible, but will result in unexpected result.
|
41
|
+
#
|
42
|
+
# @param action [Symbol] RESTful action name
|
43
|
+
# @see #verb
|
44
|
+
def initialize(action)
|
45
|
+
@action = action
|
46
|
+
end
|
47
|
+
|
48
|
+
# This method is used to retrieve a dummy params that's used for an action.
|
49
|
+
# Tipically an action for a resource member requires a param, while action
|
50
|
+
# for resource collection doesn't need any param.
|
51
|
+
#
|
52
|
+
# This will return a dummy params:
|
53
|
+
#
|
54
|
+
# route = Route.new(:show)
|
55
|
+
# route.params # => { id: 1 }
|
56
|
+
#
|
57
|
+
# This will return nil for a collection resource action:
|
58
|
+
#
|
59
|
+
# route = Route.new(:index)
|
60
|
+
# route.params # => nil
|
61
|
+
#
|
62
|
+
# @return [Hash, nil] a dummy hash params
|
63
|
+
def params
|
64
|
+
PARAMS[action]
|
65
|
+
end
|
66
|
+
|
67
|
+
# Return verb used for the RESTful action. The verb uses +DICTIONARIES+ to
|
68
|
+
# retrieve a valid method for an action. This method intentionally throws
|
69
|
+
# error if a non-RESTful action is used.
|
70
|
+
#
|
71
|
+
# route = Route.new(:index)
|
72
|
+
# route.verb # => :get
|
73
|
+
#
|
74
|
+
# This will throw error:
|
75
|
+
#
|
76
|
+
# route = Route.new(:an_action)
|
77
|
+
# route.verb # => KeyError: key not found: :an_action
|
78
|
+
#
|
79
|
+
# @return [Symbol] RESTful verb to be used for an action
|
80
|
+
def verb
|
81
|
+
DICTIONARIES.fetch(action)
|
82
|
+
end
|
83
|
+
|
84
|
+
# This method is used to convert Route object into an array. This method also
|
85
|
+
# used to automatically infer +Route+ as an array on method that uses +to_a+,
|
86
|
+
# therefore we don't need to manually invoke +#to_a+ on every call that
|
87
|
+
# requires an array object.
|
88
|
+
#
|
89
|
+
# This will return an array:
|
90
|
+
#
|
91
|
+
# route = Route.new(:show)
|
92
|
+
# route.to_a # => [:get, :show, { id: 1 }]
|
93
|
+
#
|
94
|
+
# This will also return an array inferred automatically
|
95
|
+
#
|
96
|
+
# send *route # => [:get, :show, { id: 1 }]
|
97
|
+
#
|
98
|
+
# @return [Array] an array of verb, action and params
|
99
|
+
def to_a
|
100
|
+
[verb, action, params]
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
6
105
|
DICTIONARIES = {
|
7
106
|
index: :get,
|
8
107
|
show: :get,
|
@@ -19,22 +118,6 @@ module RSpec::Authorization
|
|
19
118
|
update: { id: 1 },
|
20
119
|
destroy: { id: 1 }
|
21
120
|
}
|
22
|
-
|
23
|
-
def initialize(action)
|
24
|
-
@action = action
|
25
|
-
end
|
26
|
-
|
27
|
-
def params
|
28
|
-
PARAMS[action]
|
29
|
-
end
|
30
|
-
|
31
|
-
def verb
|
32
|
-
DICTIONARIES.fetch(action)
|
33
|
-
end
|
34
|
-
|
35
|
-
def to_a
|
36
|
-
[verb, action, params]
|
37
|
-
end
|
38
121
|
end
|
39
122
|
end
|
40
123
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
require "rspec/authorization/adapters/example"
|
2
|
-
require "rspec/authorization/adapters/
|
2
|
+
require "rspec/authorization/adapters/example_group"
|
3
3
|
require "rspec/authorization/adapters/request"
|
4
4
|
require "rspec/authorization/adapters/route"
|
5
5
|
|
6
6
|
module RSpec::Authorization
|
7
|
-
module Adapters
|
7
|
+
module Adapters # :nodoc:
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
@@ -1,43 +1,158 @@
|
|
1
1
|
module RSpec::Authorization
|
2
2
|
module Matchers
|
3
|
+
# Include this module to enable the +have_permission_for+ matcher inside RSpec.
|
4
|
+
# The following module is to be included only inside controller spec, this will
|
5
|
+
# add the capability to do a matcher against decalrative_authorization rules as
|
6
|
+
# follows:
|
7
|
+
#
|
8
|
+
# it { is_expected.to have_permission_for(:user).to(:index) }
|
9
|
+
#
|
10
|
+
# For your convenience, the following configuration has been enabled inside
|
11
|
+
# RSpec configuration.
|
12
|
+
#
|
13
|
+
# RSpec.configure do |config|
|
14
|
+
# config.include RSpec::Authorization::Matchers::HavePermissionFor, type: :controller
|
15
|
+
# end
|
3
16
|
module HavePermissionFor
|
17
|
+
# Matcher to check permission of a role for a given controller in a spec. The
|
18
|
+
# following statement shows you how to use this matcher:
|
19
|
+
#
|
20
|
+
# describe ArticlesController do
|
21
|
+
# it { is_expected.to have_permission_for(:user).to(:index) }
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# Currently this matcher only support RESTful action check, to check the
|
25
|
+
# controller against +config/authorization_rules.rb+. Skipping the +#to+
|
26
|
+
# method will result in default action assigned as +:index+.
|
27
|
+
#
|
28
|
+
# Therefore, the following statement is exactly the same as above:
|
29
|
+
#
|
30
|
+
# it { is_expected.to have_permission_for(:user) }
|
31
|
+
#
|
32
|
+
# === RESTful methods
|
33
|
+
#
|
34
|
+
# For your convenience, there are 4 RESTful methods available to be chained
|
35
|
+
# from the matcher, which are:
|
36
|
+
#
|
37
|
+
# - +to_read+
|
38
|
+
# - +to_create+
|
39
|
+
# - +to_update+
|
40
|
+
# - +to_delete+
|
41
|
+
#
|
42
|
+
# Consider the following example:
|
43
|
+
#
|
44
|
+
# it { is_expected.to have_permission_for(:user).to_read }
|
45
|
+
# it { is_expected.to have_permission_for(:user).to_edit }
|
46
|
+
# it { is_expected.not_to have_permission_for(:user).to_update }
|
47
|
+
# it { is_expected.not_to have_permission_for(:user).to_delete }
|
48
|
+
#
|
49
|
+
# The above method is not related to declarative_authorization privileges,
|
50
|
+
# and serve simply as convinience method, below is a table of RESTful actions
|
51
|
+
# for each method mentioned above:
|
52
|
+
#
|
53
|
+
# Method RESTful action
|
54
|
+
# ------------------------------------
|
55
|
+
# to_read [:index, :show]
|
56
|
+
# to_edit [:edit, :update]
|
57
|
+
# to_create [:new, :create]
|
58
|
+
# to_delete [:destroy]
|
59
|
+
#
|
60
|
+
# Matcher for RESTful methods is slightly different than that of a single
|
61
|
+
# method, following is how RESTful methods request results evaluated:
|
62
|
+
#
|
63
|
+
# all_requests (of #to_read) matches? does_not_match?
|
64
|
+
# -------------------------------------------------------------------
|
65
|
+
# {index: true, show: true} true false
|
66
|
+
# {index: true, show: false} false false
|
67
|
+
# {index: false, show: false} false true
|
68
|
+
#
|
69
|
+
# @param role [Symbol] role name to matched against
|
4
70
|
def have_permission_for(role)
|
5
71
|
HavePermissionFor.new(role)
|
6
72
|
end
|
7
73
|
|
8
|
-
#
|
9
|
-
class HavePermissionFor
|
74
|
+
class HavePermissionFor # :nodoc: all
|
10
75
|
include Adapters
|
11
76
|
|
12
|
-
attr_reader :controller, :role, :
|
77
|
+
attr_reader :controller, :role, :behave, :actions, :results
|
13
78
|
|
14
79
|
def initialize(role)
|
15
|
-
@role
|
16
|
-
@action = :index
|
80
|
+
@role = role
|
17
81
|
end
|
18
82
|
|
19
83
|
def to(action)
|
20
|
-
@
|
84
|
+
@behave = action
|
85
|
+
@actions = [behave]
|
86
|
+
|
87
|
+
self
|
88
|
+
end
|
89
|
+
|
90
|
+
def to_read
|
91
|
+
@behave = :read
|
92
|
+
@actions = %i(index show)
|
93
|
+
|
94
|
+
self
|
95
|
+
end
|
96
|
+
|
97
|
+
def to_create
|
98
|
+
@behave = :create
|
99
|
+
@actions = %i(new create)
|
100
|
+
|
21
101
|
self
|
22
102
|
end
|
23
103
|
|
104
|
+
def to_update
|
105
|
+
@behave = :update
|
106
|
+
@actions = %i(edit update)
|
107
|
+
|
108
|
+
self
|
109
|
+
end
|
110
|
+
|
111
|
+
def to_delete
|
112
|
+
@behave = :delete
|
113
|
+
@actions = %i(destroy)
|
114
|
+
|
115
|
+
self
|
116
|
+
end
|
117
|
+
|
118
|
+
def to_manage
|
119
|
+
@behave = :manage
|
120
|
+
@actions = %i(index show new create edit update destroy)
|
121
|
+
|
122
|
+
self
|
123
|
+
end
|
124
|
+
|
125
|
+
def all_requests
|
126
|
+
actions.map do |action|
|
127
|
+
request = Request.new(controller.class, action, role)
|
128
|
+
[action, request.response.status != 403]
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
24
132
|
def matches?(controller)
|
25
133
|
@controller = controller
|
134
|
+
@results = Hash[all_requests]
|
135
|
+
|
136
|
+
true unless results.value? false
|
137
|
+
end
|
138
|
+
|
139
|
+
def does_not_match?(controller)
|
140
|
+
@controller = controller
|
141
|
+
@results = Hash[all_requests]
|
26
142
|
|
27
|
-
|
28
|
-
request.response.status != 403
|
143
|
+
true unless results.value? true
|
29
144
|
end
|
30
145
|
|
31
146
|
def failure_message
|
32
|
-
"Expected #{controller.class} to have permission for #{role} to #{
|
147
|
+
"Expected #{controller.class} to have permission for #{role} to #{behave}. #{results}"
|
33
148
|
end
|
34
149
|
|
35
150
|
def failure_message_when_negated
|
36
|
-
"Did not expect #{controller.class} to have permission for #{role} to #{
|
151
|
+
"Did not expect #{controller.class} to have permission for #{role} to #{behave}. #{results}"
|
37
152
|
end
|
38
153
|
|
39
154
|
def description
|
40
|
-
"have permission for #{role}
|
155
|
+
"have permission for #{role} to #{behave}"
|
41
156
|
end
|
42
157
|
end
|
43
158
|
end
|
data/lib/rspec/authorization.rb
CHANGED
data/rspec-authorization.gemspec
CHANGED
@@ -4,7 +4,7 @@ require 'rspec/authorization/version'
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "rspec-authorization"
|
7
|
-
spec.version =
|
7
|
+
spec.version = RSpec::Authorization::VERSION
|
8
8
|
spec.authors = ["Hendra Uzia"]
|
9
9
|
spec.email = ["hendra.uzia@gmail.com"]
|
10
10
|
spec.summary = %q{RSpec matcher for declarative_authorization.}
|
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
20
|
spec.add_runtime_dependency "declarative_authorization"
|
21
|
-
spec.add_runtime_dependency "rspec-rails"
|
21
|
+
spec.add_runtime_dependency "rspec-rails", "~> 3.0"
|
22
22
|
|
23
23
|
spec.add_development_dependency "bundler", "~> 1.7"
|
24
24
|
spec.add_development_dependency "rails", "~> 4.0"
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
describe ArticlesController do
|
4
|
+
it { is_expected.to have_permission_for(:user).to(:index) }
|
5
|
+
it { is_expected.not_to have_permission_for(:user).to(:show) }
|
6
|
+
it { is_expected.not_to have_permission_for(:user).to_create }
|
7
|
+
it { is_expected.not_to have_permission_for(:user).to_update }
|
8
|
+
it { is_expected.not_to have_permission_for(:user).to_delete }
|
9
|
+
|
10
|
+
it { is_expected.to have_permission_for(:premium).to_read }
|
11
|
+
it { is_expected.not_to have_permission_for(:premium).to_create }
|
12
|
+
it { is_expected.not_to have_permission_for(:premium).to_update }
|
13
|
+
it { is_expected.not_to have_permission_for(:premium).to_delete }
|
14
|
+
|
15
|
+
it { is_expected.to have_permission_for(:writer).to_read }
|
16
|
+
it { is_expected.to have_permission_for(:writer).to_create }
|
17
|
+
it { is_expected.not_to have_permission_for(:writer).to_update }
|
18
|
+
it { is_expected.not_to have_permission_for(:writer).to_delete }
|
19
|
+
|
20
|
+
it { is_expected.to have_permission_for(:editor).to_manage }
|
21
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
include RSpec::Authorization::Adapters
|
4
|
+
|
5
|
+
describe ExampleGroup do
|
6
|
+
let(:klass) { ArticlesController }
|
7
|
+
let(:example_group) { ExampleGroup.new(klass) }
|
8
|
+
|
9
|
+
let(:before_instruction) { ->{ :before } }
|
10
|
+
let(:after_instruction) { ->{ :after } }
|
11
|
+
|
12
|
+
describe "target" do
|
13
|
+
subject { example_group.target }
|
14
|
+
its(:described_class) { is_expected.to eq klass }
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "#before" do
|
18
|
+
specify { expect(example_group.before(&before_instruction).last.block).to eq before_instruction }
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#after" do
|
22
|
+
specify { expect(example_group.after(&after_instruction).first.block).to eq after_instruction }
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#run_example" do
|
26
|
+
specify { expect(example_group.run_example).to be_a_kind_of(Example) }
|
27
|
+
end
|
28
|
+
end
|
@@ -4,23 +4,13 @@ include RSpec::Authorization::Adapters
|
|
4
4
|
|
5
5
|
describe Example do
|
6
6
|
let(:klass) { GroupTestClass }
|
7
|
-
let(:group) {
|
8
|
-
let(:example) { Example.new(group) }
|
7
|
+
let(:group) { ExampleGroup.new(klass) }
|
8
|
+
let(:example) { Example.new(group.target) }
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
its(:group) { is_expected.to eq group }
|
13
|
-
its(:example) { is_expected.to be_a_kind_of RSpec::Core::Example }
|
10
|
+
before { allow_any_instance_of(Example).to receive(:run_before_example) }
|
14
11
|
|
15
|
-
|
16
|
-
describe "#set_example_group_instance" do
|
17
|
-
before { example.send :set_example_group_instance }
|
18
|
-
specify { expect(example.example.instance_variable_get :@example_group_instance).to be_a_kind_of group }
|
19
|
-
end
|
12
|
+
subject { example }
|
20
13
|
|
21
|
-
|
22
|
-
|
23
|
-
specify { expect(example.example.send :run_before_example).to be_present }
|
24
|
-
end
|
25
|
-
end
|
14
|
+
its(:group_target) { is_expected.to eq group.target }
|
15
|
+
its(:target) { is_expected.to be_a_kind_of RSpec::Core::Example }
|
26
16
|
end
|
@@ -3,9 +3,9 @@ require 'rails_helper'
|
|
3
3
|
include RSpec::Authorization::Adapters
|
4
4
|
|
5
5
|
describe Request do
|
6
|
-
let(:klass) {
|
7
|
-
let(:action) { :
|
8
|
-
let(:role) { :
|
6
|
+
let(:klass) { ArticlesController }
|
7
|
+
let(:action) { :update }
|
8
|
+
let(:role) { :editor }
|
9
9
|
let(:request) { Request.new(klass, action, role) }
|
10
10
|
|
11
11
|
subject { request }
|
data/spec/spec_helper.rb
CHANGED
@@ -3,7 +3,8 @@ require 'rails_test_app'
|
|
3
3
|
|
4
4
|
describe RailsTestApp do
|
5
5
|
let(:test_app) { RailsTestApp.new(:version) }
|
6
|
-
let(:
|
6
|
+
let(:temp_path) { "tmp" }
|
7
|
+
let(:dummy_file) { "#{temp_path}/dummy-rails-test-app" }
|
7
8
|
|
8
9
|
describe ".new" do
|
9
10
|
subject(:test_app) { RailsTestApp.new("4.1.6", "--skip-javascript") }
|
@@ -18,6 +19,7 @@ describe RailsTestApp do
|
|
18
19
|
before { allow(test_app).to receive(:create_command).and_return("touch #{dummy_file}") }
|
19
20
|
before { allow(test_app).to receive(:template_param) }
|
20
21
|
before { allow(test_app).to receive(:option) }
|
22
|
+
before { `mkdir #{temp_path}` }
|
21
23
|
after { `rm -rf #{dummy_file}` }
|
22
24
|
|
23
25
|
context "path does not exists" do
|
@@ -5,8 +5,8 @@ rules = "config/authorization_rules.rb"
|
|
5
5
|
run "mkdir ../../../config"
|
6
6
|
run "ln -s ../spec/.rails/rails-#{Rails::VERSION::STRING}/#{rules} ../../../#{rules}"
|
7
7
|
|
8
|
-
generate "scaffold
|
9
|
-
generate "migration
|
8
|
+
generate "scaffold article --skip-assets --skip-helper"
|
9
|
+
generate "migration AddUserIdToArticles user:references"
|
10
10
|
|
11
11
|
rake "db:migrate"
|
12
12
|
run "bundle exec rake db:migrate RAILS_ENV=test"
|
@@ -14,27 +14,38 @@ run "bundle exec rake db:migrate RAILS_ENV=test"
|
|
14
14
|
first_line = /\A.*/
|
15
15
|
last_line = /^.*\Z/
|
16
16
|
|
17
|
-
inject_into_file "app/models/
|
17
|
+
inject_into_file "app/models/article.rb", %q{
|
18
18
|
belongs_to :user
|
19
19
|
}, after: first_line
|
20
20
|
|
21
21
|
inject_into_file "app/models/user.rb", %q{
|
22
|
-
has_many :
|
22
|
+
has_many :articles
|
23
23
|
}, after: first_line
|
24
24
|
|
25
25
|
inject_into_file "config/authorization_rules.rb", %q{
|
26
|
+
role :editor do
|
27
|
+
has_permission_on :articles, to: :manage
|
28
|
+
end
|
29
|
+
|
30
|
+
role :writer do
|
31
|
+
has_permission_on :articles, to: %i(read create)
|
32
|
+
end
|
33
|
+
|
34
|
+
role :premium do
|
35
|
+
has_permission_on :articles, to: :read
|
36
|
+
end
|
37
|
+
|
26
38
|
role :user do
|
27
|
-
has_permission_on :
|
39
|
+
has_permission_on :articles, to: :index
|
28
40
|
end
|
29
41
|
}, after: first_line
|
30
42
|
|
31
43
|
inject_into_file "app/controllers/application_controller.rb", %q{
|
32
44
|
def current_user
|
33
|
-
User.where(id: session[:user_id]).presence
|
34
45
|
end
|
35
46
|
}, before: last_line
|
36
47
|
|
37
|
-
inject_into_file "app/controllers/
|
48
|
+
inject_into_file "app/controllers/articles_controller.rb", %q{
|
38
49
|
filter_resource_access
|
39
50
|
}, after: first_line
|
40
51
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-authorization
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hendra Uzia
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-11-
|
11
|
+
date: 2014-11-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: declarative_authorization
|
@@ -28,16 +28,16 @@ dependencies:
|
|
28
28
|
name: rspec-rails
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
33
|
+
version: '3.0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
40
|
+
version: '3.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -120,15 +120,18 @@ files:
|
|
120
120
|
- ".gitignore"
|
121
121
|
- ".rspec"
|
122
122
|
- ".ruby-version"
|
123
|
+
- ".travis.yml"
|
124
|
+
- ".yardopts"
|
123
125
|
- Gemfile
|
124
126
|
- Guardfile
|
127
|
+
- HISTORY.md
|
125
128
|
- LICENSE.txt
|
126
129
|
- README.md
|
127
130
|
- Rakefile
|
128
131
|
- lib/rspec/authorization.rb
|
129
132
|
- lib/rspec/authorization/adapters.rb
|
130
133
|
- lib/rspec/authorization/adapters/example.rb
|
131
|
-
- lib/rspec/authorization/adapters/
|
134
|
+
- lib/rspec/authorization/adapters/example_group.rb
|
132
135
|
- lib/rspec/authorization/adapters/request.rb
|
133
136
|
- lib/rspec/authorization/adapters/route.rb
|
134
137
|
- lib/rspec/authorization/matchers.rb
|
@@ -136,9 +139,9 @@ files:
|
|
136
139
|
- lib/rspec/authorization/version.rb
|
137
140
|
- rspec-authorization.gemspec
|
138
141
|
- spec/.keep
|
139
|
-
- spec/controllers/
|
142
|
+
- spec/controllers/articles_controller_spec.rb
|
143
|
+
- spec/lib/rspec/authorization/adapters/example_group_spec.rb
|
140
144
|
- spec/lib/rspec/authorization/adapters/example_spec.rb
|
141
|
-
- spec/lib/rspec/authorization/adapters/group_spec.rb
|
142
145
|
- spec/lib/rspec/authorization/adapters/request_spec.rb
|
143
146
|
- spec/lib/rspec/authorization/adapters/route_spec.rb
|
144
147
|
- spec/rails_helper.rb
|
@@ -176,12 +179,13 @@ specification_version: 4
|
|
176
179
|
summary: RSpec matcher for declarative_authorization.
|
177
180
|
test_files:
|
178
181
|
- spec/.keep
|
179
|
-
- spec/controllers/
|
182
|
+
- spec/controllers/articles_controller_spec.rb
|
183
|
+
- spec/lib/rspec/authorization/adapters/example_group_spec.rb
|
180
184
|
- spec/lib/rspec/authorization/adapters/example_spec.rb
|
181
|
-
- spec/lib/rspec/authorization/adapters/group_spec.rb
|
182
185
|
- spec/lib/rspec/authorization/adapters/request_spec.rb
|
183
186
|
- spec/lib/rspec/authorization/adapters/route_spec.rb
|
184
187
|
- spec/rails_helper.rb
|
185
188
|
- spec/spec_helper.rb
|
186
189
|
- spec/support/group_test_class.rb
|
187
190
|
- spec/tools/rails_test_app_spec.rb
|
191
|
+
has_rdoc:
|
@@ -1,11 +0,0 @@
|
|
1
|
-
require 'rails_helper'
|
2
|
-
|
3
|
-
describe PostsController do
|
4
|
-
it { is_expected.to have_permission_for(:user).to(:index) }
|
5
|
-
it { is_expected.to have_permission_for(:user).to(:new) }
|
6
|
-
it { is_expected.to have_permission_for(:user).to(:create) }
|
7
|
-
it { is_expected.to have_permission_for(:user).to(:show) }
|
8
|
-
it { is_expected.to have_permission_for(:user).to(:edit) }
|
9
|
-
it { is_expected.to have_permission_for(:user).to(:update) }
|
10
|
-
it { is_expected.to have_permission_for(:user).to(:destroy) }
|
11
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'rails_helper'
|
2
|
-
|
3
|
-
include RSpec::Authorization::Adapters
|
4
|
-
|
5
|
-
describe Group do
|
6
|
-
let(:klass) { GroupTestClass }
|
7
|
-
let(:group) { Group.new(klass) }
|
8
|
-
|
9
|
-
describe ".new" do
|
10
|
-
subject { group }
|
11
|
-
its(:described_class) { is_expected.to eq GroupTestClass }
|
12
|
-
end
|
13
|
-
end
|