wor-simple_crud 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/README.md +36 -12
- data/lib/simple_crud/rspec/helpers/controller_options.rb +6 -1
- data/lib/simple_crud/rspec/helpers/models.rb +16 -1
- data/lib/simple_crud/simple_crud_controller.rb +22 -7
- data/lib/simple_crud/version.rb +1 -1
- data/lib/simple_crud.rb +1 -0
- data/lib/spec/shared_examples/authorization_adapter_authorize.rb +1 -1
- data/lib/spec/shared_examples/simple_crud_for_create.rb +1 -1
- data/lib/spec/shared_examples/simple_crud_for_create_with_block.rb +1 -1
- data/lib/spec/shared_examples/simple_crud_for_create_with_build.rb +1 -1
- data/lib/spec/shared_examples/simple_crud_for_destroy.rb +1 -1
- data/lib/spec/shared_examples/simple_crud_for_destroy_with_block.rb +1 -1
- data/lib/spec/shared_examples/simple_crud_for_destroy_with_finder.rb +1 -1
- data/lib/spec/shared_examples/simple_crud_for_edit.rb +1 -1
- data/lib/spec/shared_examples/simple_crud_for_index.rb +1 -1
- data/lib/spec/shared_examples/simple_crud_for_index_with_block.rb +1 -1
- data/lib/spec/shared_examples/simple_crud_for_index_with_scope.rb +1 -1
- data/lib/spec/shared_examples/simple_crud_for_new.rb +1 -1
- data/lib/spec/shared_examples/simple_crud_for_new_with_block.rb +1 -1
- data/lib/spec/shared_examples/simple_crud_for_new_with_build.rb +1 -1
- data/lib/spec/shared_examples/simple_crud_for_show.rb +1 -1
- data/lib/spec/shared_examples/simple_crud_for_show_with_block.rb +1 -1
- data/lib/spec/shared_examples/simple_crud_for_show_with_finder.rb +1 -1
- data/lib/spec/shared_examples/simple_crud_for_update.rb +1 -1
- data/lib/spec/shared_examples/simple_crud_for_update_with_finder.rb +1 -1
- data/lib/spec/shared_examples/simple_crud_not_found_with_finder.rb +1 -1
- data/lib/spec/shared_examples/simple_crud_renders_template.rb +1 -1
- data/lib/spec/shared_examples/simple_crud_when_not_authorized.rb +1 -1
- data/lib/spec/shared_examples/simple_crud_without_authenticated_user.rb +1 -1
- data/lib/spec/shared_examples/unauthorized_when_not_logged_in.rb +1 -1
- data/spec/dummy/app/controllers/block/dummy_models_controller.rb +1 -6
- data/spec/dummy/app/controllers/block_new/dummy_models_controller.rb +1 -1
- data/spec/dummy/app/controllers/block_redirect/dummy_models_controller.rb +1 -1
- data/spec/dummy/app/controllers/block_show/dummy_models_controller.rb +1 -1
- data/spec/dummy/app/controllers/built/dummy_models_controller.rb +0 -5
- data/spec/dummy/app/controllers/dummy_models_controller.rb +0 -5
- data/spec/dummy/app/controllers/finder/dummy_models_controller.rb +0 -5
- data/spec/dummy/app/controllers/html_modes/base_controller.rb +0 -5
- data/spec/dummy/app/controllers/invalid_status/dummy_models_controller.rb +1 -1
- data/spec/dummy/app/controllers/nested/dummy_models_controller.rb +0 -5
- data/spec/dummy/app/controllers/nested_route/dummy_models_controller.rb +0 -5
- data/spec/dummy/app/controllers/redirect_auth/dummy_models_controller.rb +0 -5
- data/spec/dummy/app/controllers/scoped/dummy_models_controller.rb +0 -5
- data/spec/dummy/app/controllers/scoped_params/dummy_models_controller.rb +0 -5
- data/spec/dummy/app/controllers/strict/dummy_models_controller.rb +0 -5
- data/spec/dummy/app/controllers/unpaginated_scoped/dummy_models_controller.rb +0 -5
- data/spec/dummy/app/controllers/without_pagination/dummy_models_controller.rb +0 -5
- data/spec/simple_crud/rspec_config_spec.rb +6 -0
- data/spec/simple_crud_controller_spec.rb +38 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dbcb6881c359fa3b5c4ce518871a4f378d92e0698ab7d57dc489315f2f25b80b
|
|
4
|
+
data.tar.gz: 62cf8cbd6df845cd23a388e9b2a1f8ebfdae784ff91f4e57268688bce0c0bf87
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4406326eab40876599274e927df02c9c3470d3f753dcd5f0f150b67a7b3087e2a965ec0fd18ad1e007bada514954f9a665d573d18da98bf7c93aee3ffebc1637
|
|
7
|
+
data.tar.gz: 1deddc698fb6008531d59e5656675086a309dbc26177b403c023e7743463425626b8e977785f6ef2cbe122d4f251ad697944d1c71f665e498666feecedbae792
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
## Change log
|
|
2
2
|
|
|
3
|
+
### V0.4.0
|
|
4
|
+
|
|
5
|
+
Breaking:
|
|
6
|
+
* Blocks given to `simple_crud_for` no longer imply `html: true`. HTML controllers with render blocks must pass `html: true` explicitly.
|
|
7
|
+
|
|
8
|
+
New options:
|
|
9
|
+
* `authenticate_headers:` controls whether shared examples set auth headers and run the unauthorized test, independent of `authenticate:`. Defaults to `authenticate:`. Set `authenticate: false, authenticate_headers: true` when a base-controller `before_action` handles auth so the lambda skips the call but tests still cover the auth path.
|
|
10
|
+
* `simple_crud_defaults(options)` sets option defaults at the controller level. Subclasses inherit. Per-action options override. Precedence: gem defaults < controller defaults < per-action options.
|
|
11
|
+
|
|
12
|
+
Fixes:
|
|
13
|
+
* Use `RSpec.shared_examples` instead of the top-level alias, which is unavailable with `config.disable_monkey_patching!`.
|
|
14
|
+
* Auto-require `SimpleCrud::Authorization::Adapter` on `require 'simple_crud'`.
|
|
15
|
+
* Remove `cattr_accessor :params, :permitted` (thread-unsafe, never read by the gem). Remove the `set_params` boilerplate from host controllers.
|
|
16
|
+
* Raise a clear error when `owner_association` names an attribute the model doesn't have, instead of a bare `NoMethodError` from FactoryBot.
|
|
17
|
+
|
|
3
18
|
### V0.3.1
|
|
4
19
|
|
|
5
20
|
Shared examples configuration:
|
data/README.md
CHANGED
|
@@ -18,6 +18,7 @@ SimpleCrud
|
|
|
18
18
|
- [Serializer](#serializer)
|
|
19
19
|
- [HTML](#html)
|
|
20
20
|
- [Finder](#finder)
|
|
21
|
+
- [Controller-level defaults](#controller-level-defaults)
|
|
21
22
|
- [Shared examples](#shared-examples)
|
|
22
23
|
- [Contributing](#contributing)
|
|
23
24
|
- [Releases](#releases)
|
|
@@ -68,12 +69,6 @@ Before SimpleCrud can be used, some boilerplate is needed. Add the following to
|
|
|
68
69
|
include Pundit::Authorization
|
|
69
70
|
include Wor::Paginate
|
|
70
71
|
extend SimpleCrudController
|
|
71
|
-
|
|
72
|
-
before_action :set_params
|
|
73
|
-
|
|
74
|
-
def set_params
|
|
75
|
-
SimpleCrudController.params = params
|
|
76
|
-
end
|
|
77
72
|
```
|
|
78
73
|
|
|
79
74
|
(Skip `include Pundit::Authorization` / `include Wor::Paginate` if you're using a different adapter, or `authorize: false` / `paginate: false` everywhere.)
|
|
@@ -105,7 +100,8 @@ simple_crud_for :index, paginate: false, authorize: false, serializer: CustomSer
|
|
|
105
100
|
|
|
106
101
|
- Paginate: whether it should paginate or not. `true` paginates via the configured pagination adapter (wor-paginate by default), `false` doesn't paginate
|
|
107
102
|
- Authorize: whether it should check authorization via the configured authorization adapter (Pundit by default)
|
|
108
|
-
- Authenticate: whether
|
|
103
|
+
- Authenticate: whether the generated action calls `authenticate_user!`. `true` (default) or `false`
|
|
104
|
+
- Authenticate_headers: whether shared examples set auth headers and run the unauthorized test. Defaults to `authenticate:`. Set independently when a base-controller `before_action` handles auth and the lambda should skip `authenticate_user!`
|
|
109
105
|
- Serializer: specify a particular serializer you should use
|
|
110
106
|
- Html: renders the action's ERB template instead of JSON (valid for `:index`, `:show`, `:new`, `:edit`, `:create`, `:update` and `:destroy`). Only meaningful in controllers that render templates
|
|
111
107
|
- Scope: only valid for `:index`. A `Proc`/`lambda` taking `current_user` (plus the controller's `params` if it takes a second argument) that returns the relation to list, overriding the default `policy_scope`. The user is resolved via `SimpleCrud::Config.user_method` (`:current_user` by default; set it to e.g. `:current_admin`)
|
|
@@ -114,6 +110,22 @@ simple_crud_for :index, paginate: false, authorize: false, serializer: CustomSer
|
|
|
114
110
|
- Raise_on_invalid: only valid for `:create` and `:update`. Keeps the strict `create!`/`update!` semantics (raising on invalid input) instead of returning `422` with the validation errors
|
|
115
111
|
- Redirect: only valid for HTML-mode `:create`, `:update` and `:destroy`. A `Proc`/`lambda` (called with the record) or a literal path used as the success redirect target. Defaults to the record (`:create`/`:update`) or the model's collection path (`:destroy`)
|
|
116
112
|
|
|
113
|
+
#### Controller-level defaults
|
|
114
|
+
|
|
115
|
+
`simple_crud_defaults` sets option defaults for every `simple_crud_for` in the controller. Subclasses inherit; per-action options override.
|
|
116
|
+
|
|
117
|
+
```ruby
|
|
118
|
+
class Api::BaseController < ActionController::API
|
|
119
|
+
extend SimpleCrudController
|
|
120
|
+
simple_crud_defaults authorize: false, authenticate: false, authenticate_headers: true
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
class Api::PostsController < Api::BaseController
|
|
124
|
+
simple_crud_for :show # inherits defaults
|
|
125
|
+
simple_crud_for :create, authorize: true # overrides for this action only
|
|
126
|
+
end
|
|
127
|
+
```
|
|
128
|
+
|
|
117
129
|
You'll need a few things so they work correctly:
|
|
118
130
|
|
|
119
131
|
### Options
|
|
@@ -247,7 +259,13 @@ end
|
|
|
247
259
|
```
|
|
248
260
|
|
|
249
261
|
#### Authenticate
|
|
250
|
-
|
|
262
|
+
`authenticate: true` (default) calls `authenticate_user!` inside the generated action. `authenticate: false` skips it.
|
|
263
|
+
|
|
264
|
+
If your base controller already runs `before_action :authenticate_user!`, set `authenticate: false` to avoid a double call and `authenticate_headers: true` so shared examples still cover the auth path:
|
|
265
|
+
|
|
266
|
+
```ruby
|
|
267
|
+
simple_crud_defaults authenticate: false, authenticate_headers: true
|
|
268
|
+
```
|
|
251
269
|
|
|
252
270
|
#### Serializer
|
|
253
271
|
The name of the serializer, by default, is the name of the model followed by Serializer, as is the standard for [ActiveModelSerializers](https://github.com/rails-api/active_model_serializers). It's possible to just pass a custom serializer class though. As for the serializer itself, it's a standard serializer, with the gotcha that you need to include `:id` for the SimpleCrud examples to work.
|
|
@@ -279,16 +297,22 @@ simple_crud_for :update, html: true
|
|
|
279
297
|
simple_crud_for :destroy, html: true
|
|
280
298
|
```
|
|
281
299
|
|
|
282
|
-
Or pass a block that renders explicitly, overriding the auto-render. The block receives the records for `:index`, the record for `:show`/`:new`, or the record plus a saved flag for `:create`/`:update`/`:destroy`.
|
|
300
|
+
Or pass a block that renders explicitly, overriding the auto-render. The block receives the records for `:index`, the record for `:show`/`:new`, or the record plus a saved flag for `:create`/`:update`/`:destroy`. Blocks do not change the `html:` default; pass it explicitly so the shared examples know which request format to use:
|
|
283
301
|
|
|
284
302
|
```ruby
|
|
285
|
-
|
|
303
|
+
# Server-rendered block: pass html: true so shared examples send HTML requests
|
|
304
|
+
simple_crud_for :index, html: true do |records|
|
|
286
305
|
render :index, locals: { models: records }
|
|
287
306
|
end
|
|
288
307
|
|
|
289
|
-
simple_crud_for :create do |record, saved|
|
|
308
|
+
simple_crud_for :create, html: true do |record, saved|
|
|
290
309
|
saved ? redirect_to(record) : render(:new, locals: { model: record })
|
|
291
310
|
end
|
|
311
|
+
|
|
312
|
+
# API block: html: false is the default
|
|
313
|
+
simple_crud_for :show, html: false do |record|
|
|
314
|
+
render json: record.as_json(only: %i[id name])
|
|
315
|
+
end
|
|
292
316
|
```
|
|
293
317
|
|
|
294
318
|
#### Build
|
|
@@ -320,7 +344,7 @@ simple_crud_for :destroy, finder: ->(params) { current_user.models.find(params[:
|
|
|
320
344
|
When omitted it defaults to `klass.find(params[:id])`, and `not_found` is still returned whenever the finder finds no record.
|
|
321
345
|
|
|
322
346
|
### Shared examples
|
|
323
|
-
While optional, using the included shared examples saves you from writing the standard test cases for the methods. You can even use them if you didn't use `simple_crud_for`, as a set of basic tests. To include them,
|
|
347
|
+
While optional, using the included shared examples saves you from writing the standard test cases for the methods. You can even use them if you didn't use `simple_crud_for`, as a set of basic tests. To include them, add `require 'simple_crud/rspec'` to your `rails_helper.rb` **after** `require "rspec/rails"`, then add the lines you need to your `*_spec.rb` files:
|
|
324
348
|
```ruby
|
|
325
349
|
require 'rails_helper'
|
|
326
350
|
|
|
@@ -10,9 +10,14 @@ module SimpleCrud
|
|
|
10
10
|
described_class.instance_variable_get(:@simple_crud_metadata)[method][option]
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
%i[paginate authorize authenticate serializer html finder scope build raise_on_invalid block
|
|
13
|
+
%i[paginate authorize authenticate serializer html finder scope build raise_on_invalid block
|
|
14
|
+
authenticate_headers].each do |option|
|
|
14
15
|
define_method("check_#{option}") { |method| get_option(method, option) }
|
|
15
16
|
end
|
|
17
|
+
|
|
18
|
+
def check_authenticate(method)
|
|
19
|
+
check_authenticate_headers(method)
|
|
20
|
+
end
|
|
16
21
|
end
|
|
17
22
|
end
|
|
18
23
|
end
|
|
@@ -15,7 +15,22 @@ module SimpleCrud
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def model
|
|
18
|
-
@model ||=
|
|
18
|
+
@model ||= begin
|
|
19
|
+
validate_owner_association!
|
|
20
|
+
create_record(model_class, model_attributes)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def validate_owner_association!
|
|
25
|
+
assoc = owner_association
|
|
26
|
+
return unless assoc
|
|
27
|
+
|
|
28
|
+
klass = model_class_object
|
|
29
|
+
return if klass.method_defined?("#{assoc}=") || klass.column_names.include?(assoc.to_s)
|
|
30
|
+
|
|
31
|
+
raise "simple_crud: owner_association is :#{assoc} but #{klass} has no #{assoc}= setter. " \
|
|
32
|
+
'Set `simple_crud: { owner_association: nil }` in your describe block or ' \
|
|
33
|
+
'override model_attributes directly.'
|
|
19
34
|
end
|
|
20
35
|
|
|
21
36
|
def model_attributes
|
|
@@ -11,12 +11,12 @@ module SimpleCrudController
|
|
|
11
11
|
# Include, not extend: controllers gain these by extending SimpleCrudController.
|
|
12
12
|
include SimpleCrud::ActionLambdas
|
|
13
13
|
|
|
14
|
-
cattr_accessor :params, :permitted
|
|
15
|
-
|
|
16
14
|
# Possible options:
|
|
17
15
|
### authorize: check authorization via Config.authorization_adapter (Pundit by default)
|
|
18
16
|
### paginate: paginate the list via Config.pagination_adapter (wor-paginate by default)
|
|
19
|
-
### authenticate:
|
|
17
|
+
### authenticate: true calls authenticate_user! inside the action lambda; false skips it
|
|
18
|
+
### authenticate_headers: whether shared examples set auth headers and run the unauthorized
|
|
19
|
+
### test (defaults to authenticate:); set independently when a base-controller before_action handles auth
|
|
20
20
|
### serializer: use a particular serializer (both each_serializer and serializer)
|
|
21
21
|
### html: render the action's ERB template instead of JSON (index/show/new/edit/create/update/destroy)
|
|
22
22
|
### finder: custom record lookup (Proc/lambda or Symbol) for :show/:update/:destroy/:edit
|
|
@@ -26,7 +26,6 @@ module SimpleCrudController
|
|
|
26
26
|
### A block given to simple_crud_for renders explicitly: it receives the records for :index,
|
|
27
27
|
### the record for :show/:new/:edit, or the record and a saved flag for :create/:update/:destroy
|
|
28
28
|
def simple_crud_for(method, parameters = {}, &block)
|
|
29
|
-
parameters[:html] = true if block && !parameters.key?(:html)
|
|
30
29
|
parameters[:block] = true if block
|
|
31
30
|
parameters = parameters_with_defaults(parameters)
|
|
32
31
|
klass = simple_crud_controller_model
|
|
@@ -37,12 +36,28 @@ module SimpleCrudController
|
|
|
37
36
|
write_metadata(method, parameters)
|
|
38
37
|
end
|
|
39
38
|
|
|
39
|
+
def simple_crud_defaults(options = {})
|
|
40
|
+
@simple_crud_defaults = simple_crud_inherited_defaults.merge(options)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def simple_crud_inherited_defaults
|
|
44
|
+
ancestors.each do |ancestor|
|
|
45
|
+
next unless ancestor.instance_variable_defined?(:@simple_crud_defaults)
|
|
46
|
+
|
|
47
|
+
return ancestor.instance_variable_get(:@simple_crud_defaults)
|
|
48
|
+
end
|
|
49
|
+
{}
|
|
50
|
+
end
|
|
51
|
+
|
|
40
52
|
def parameters_with_defaults(parameters)
|
|
41
53
|
defaults = {
|
|
42
|
-
authorize: true, paginate: true, authenticate: true,
|
|
43
|
-
html: false, finder: nil, scope: nil, build: nil, raise_on_invalid: false
|
|
54
|
+
authorize: true, paginate: true, authenticate: true, authenticate_headers: nil,
|
|
55
|
+
serializer: nil, html: false, finder: nil, scope: nil, build: nil, raise_on_invalid: false
|
|
44
56
|
}
|
|
45
|
-
defaults.each
|
|
57
|
+
defaults.merge(simple_crud_inherited_defaults).each do |key, value|
|
|
58
|
+
parameters[key] = value unless parameters.key?(key)
|
|
59
|
+
end
|
|
60
|
+
parameters[:authenticate_headers] = parameters[:authenticate] if parameters[:authenticate_headers].nil?
|
|
46
61
|
parameters
|
|
47
62
|
end
|
|
48
63
|
|
data/lib/simple_crud/version.rb
CHANGED
data/lib/simple_crud.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
shared_examples 'authorization adapter #authorize' do |record_class, denied_error|
|
|
3
|
+
RSpec.shared_examples 'authorization adapter #authorize' do |record_class, denied_error|
|
|
4
4
|
it 'passes for a record the adapter allows' do
|
|
5
5
|
expect { adapter.authorize(controller, record_class.new(1)) }.not_to raise_error
|
|
6
6
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
shared_examples 'simple crud for create with block' do
|
|
3
|
+
RSpec.shared_examples 'simple crud for create with block' do
|
|
4
4
|
describe 'POST #create with a render block' do
|
|
5
5
|
context 'when successfully creating a record' do
|
|
6
6
|
include_context 'with authenticated user' if check_authenticate(:create)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
shared_examples 'simple crud for create with build' do
|
|
3
|
+
RSpec.shared_examples 'simple crud for create with build' do
|
|
4
4
|
describe 'POST #create with a build hook' do
|
|
5
5
|
include_context 'with authenticated user' if check_authenticate(:create)
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
shared_examples 'simple crud for destroy with block' do
|
|
3
|
+
RSpec.shared_examples 'simple crud for destroy with block' do
|
|
4
4
|
describe 'DELETE #destroy with a render block' do
|
|
5
5
|
include_context 'with authenticated user' if check_authenticate(:destroy)
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
shared_examples 'simple crud for destroy with finder' do
|
|
3
|
+
RSpec.shared_examples 'simple crud for destroy with finder' do
|
|
4
4
|
describe 'DELETE #destroy with a custom finder' do
|
|
5
5
|
include_context 'with authenticated user' if check_authenticate(:destroy)
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
shared_examples 'simple crud for index with block' do
|
|
3
|
+
RSpec.shared_examples 'simple crud for index with block' do
|
|
4
4
|
describe 'GET #index with a render block' do
|
|
5
5
|
let(:created_models) { create_records(model_class, 2, model_attributes) }
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
shared_examples 'simple crud for index with scope' do
|
|
3
|
+
RSpec.shared_examples 'simple crud for index with scope' do
|
|
4
4
|
let(:request_params) { {} }
|
|
5
5
|
let(:my_models) { create_records(model_class, 2, scoped_attributes) }
|
|
6
6
|
let(:other_models) { create_records(model_class, 3, other_scoped_attributes) }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
shared_examples 'simple crud for new' do
|
|
3
|
+
RSpec.shared_examples 'simple crud for new' do
|
|
4
4
|
describe 'GET #new' do
|
|
5
5
|
include_examples 'simple crud without authenticated user', :new
|
|
6
6
|
include_examples 'simple crud when not authorized', :new, :get
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
shared_examples 'simple crud for show with block' do
|
|
3
|
+
RSpec.shared_examples 'simple crud for show with block' do
|
|
4
4
|
describe 'GET #show with a render block' do
|
|
5
5
|
include_context 'with authenticated user' if check_authenticate(:show)
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
shared_examples 'simple crud for show with finder' do
|
|
3
|
+
RSpec.shared_examples 'simple crud for show with finder' do
|
|
4
4
|
describe 'GET #show with a custom finder' do
|
|
5
5
|
include_context 'with authenticated user' if check_authenticate(:show)
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
shared_examples 'simple crud for update with finder' do
|
|
3
|
+
RSpec.shared_examples 'simple crud for update with finder' do
|
|
4
4
|
describe 'PUT #update with a custom finder' do
|
|
5
5
|
include_context 'with authenticated user' if check_authenticate(:update)
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
shared_examples 'simple crud not found with finder' do |http_method, action|
|
|
3
|
+
RSpec.shared_examples 'simple crud not found with finder' do |http_method, action|
|
|
4
4
|
context 'when the model does not exist' do
|
|
5
5
|
before do
|
|
6
6
|
send(http_method, action, params: with_route_params(finder_key => "nonexistent-#{finder_key}"),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
shared_examples 'simple crud renders template' do |template, status = :ok|
|
|
3
|
+
RSpec.shared_examples 'simple crud renders template' do |template, status = :ok|
|
|
4
4
|
it "renders the #{template} template", :aggregate_failures do
|
|
5
5
|
expect(response).to have_http_status(resolve(status))
|
|
6
6
|
expect(response).to render_template(template) if assert_html_template
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
shared_examples 'simple crud when not authorized' do |action, verb, request_params = {}|
|
|
3
|
+
RSpec.shared_examples 'simple crud when not authorized' do |action, verb, request_params = {}|
|
|
4
4
|
if check_authorize(action)
|
|
5
5
|
context 'when not authorized' do
|
|
6
6
|
include_context 'with authenticated user' if check_authenticate(action)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
shared_examples 'simple crud without authenticated user' do |action|
|
|
3
|
+
RSpec.shared_examples 'simple crud without authenticated user' do |action|
|
|
4
4
|
context 'without authenticated user' do
|
|
5
5
|
subject!(:req) { get action, params: with_route_params({}) }
|
|
6
6
|
|
|
@@ -5,12 +5,7 @@ module Block
|
|
|
5
5
|
include Wor::Paginate
|
|
6
6
|
extend SimpleCrudController
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
def set_params
|
|
10
|
-
SimpleCrudController.params = params
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
simple_crud_for :index, paginate: false, authenticate: false, authorize: false do |records|
|
|
8
|
+
simple_crud_for :index, html: true, paginate: false, authenticate: false, authorize: false do |records|
|
|
14
9
|
render :index, locals: { models: records }
|
|
15
10
|
end
|
|
16
11
|
end
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module BlockNew
|
|
4
4
|
class DummyModelsController < BlockModes::BaseController
|
|
5
|
-
simple_crud_for :new, authenticate: false, authorize: false do |record|
|
|
5
|
+
simple_crud_for :new, html: true, authenticate: false, authorize: false do |record|
|
|
6
6
|
render_model(record, :new)
|
|
7
7
|
end
|
|
8
8
|
end
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module BlockRedirect
|
|
4
4
|
class DummyModelsController < HtmlModes::BaseController
|
|
5
|
-
simple_crud_for :destroy, authenticate: false, authorize: false do |_record, destroyed|
|
|
5
|
+
simple_crud_for :destroy, html: true, authenticate: false, authorize: false do |_record, destroyed|
|
|
6
6
|
if destroyed
|
|
7
7
|
redirect_to action: :show, notice: 'removed'
|
|
8
8
|
else
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module BlockShow
|
|
4
4
|
class DummyModelsController < BlockModes::BaseController
|
|
5
|
-
simple_crud_for :show, authenticate: false, authorize: false do |record|
|
|
5
|
+
simple_crud_for :show, html: true, authenticate: false, authorize: false do |record|
|
|
6
6
|
render_model(record, :show)
|
|
7
7
|
end
|
|
8
8
|
end
|
|
@@ -6,11 +6,6 @@ class DummyModelsController < ApplicationController
|
|
|
6
6
|
include Pundit::Authorization
|
|
7
7
|
extend SimpleCrudController
|
|
8
8
|
|
|
9
|
-
before_action :set_params
|
|
10
|
-
def set_params
|
|
11
|
-
SimpleCrudController.params = params
|
|
12
|
-
end
|
|
13
|
-
|
|
14
9
|
def dummy_model_params
|
|
15
10
|
params.permit(:name, :something, :user_id, :slug)
|
|
16
11
|
end
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module InvalidStatus
|
|
4
4
|
class DummyModelsController < HtmlModes::BaseController
|
|
5
|
-
simple_crud_for :create, authenticate: false, authorize: false do |record, saved|
|
|
5
|
+
simple_crud_for :create, html: true, authenticate: false, authorize: false do |record, saved|
|
|
6
6
|
if saved
|
|
7
7
|
redirect_to(record)
|
|
8
8
|
else
|
|
@@ -6,11 +6,6 @@ module Nested
|
|
|
6
6
|
include Pundit::Authorization
|
|
7
7
|
extend SimpleCrudController
|
|
8
8
|
|
|
9
|
-
before_action :set_params
|
|
10
|
-
def set_params
|
|
11
|
-
SimpleCrudController.params = params
|
|
12
|
-
end
|
|
13
|
-
|
|
14
9
|
def dummy_model_params
|
|
15
10
|
params.require(:dummy_model).permit(:name, :something, :user_id, :slug)
|
|
16
11
|
end
|
|
@@ -6,11 +6,6 @@ module NestedRoute
|
|
|
6
6
|
include Pundit::Authorization
|
|
7
7
|
extend SimpleCrudController
|
|
8
8
|
|
|
9
|
-
before_action :set_params
|
|
10
|
-
def set_params
|
|
11
|
-
SimpleCrudController.params = params
|
|
12
|
-
end
|
|
13
|
-
|
|
14
9
|
def dummy_model_params
|
|
15
10
|
params.require(:dummy_model).permit(:name, :something, :user_id, :slug, :classroom_slug)
|
|
16
11
|
end
|
|
@@ -10,11 +10,6 @@ module RedirectAuth
|
|
|
10
10
|
|
|
11
11
|
rescue_from UnauthenticatedError, with: :redirect_to_login
|
|
12
12
|
|
|
13
|
-
before_action :set_params
|
|
14
|
-
def set_params
|
|
15
|
-
SimpleCrudController.params = params
|
|
16
|
-
end
|
|
17
|
-
|
|
18
13
|
def authenticate_user!
|
|
19
14
|
raise UnauthenticatedError unless current_user
|
|
20
15
|
end
|
|
@@ -6,11 +6,6 @@ module Scoped
|
|
|
6
6
|
include Pundit::Authorization
|
|
7
7
|
extend SimpleCrudController
|
|
8
8
|
|
|
9
|
-
before_action :set_params
|
|
10
|
-
def set_params
|
|
11
|
-
SimpleCrudController.params = params
|
|
12
|
-
end
|
|
13
|
-
|
|
14
9
|
simple_crud_for :index, scope: ->(user) { DummyModel.where(user: user) }
|
|
15
10
|
end
|
|
16
11
|
end
|
|
@@ -6,11 +6,6 @@ module ScopedParams
|
|
|
6
6
|
include Pundit::Authorization
|
|
7
7
|
extend SimpleCrudController
|
|
8
8
|
|
|
9
|
-
before_action :set_params
|
|
10
|
-
def set_params
|
|
11
|
-
SimpleCrudController.params = params
|
|
12
|
-
end
|
|
13
|
-
|
|
14
9
|
simple_crud_for :index, scope: ->(user, params) { DummyModel.where(user: user, something: params[:something]) }
|
|
15
10
|
end
|
|
16
11
|
end
|
|
@@ -6,11 +6,6 @@ module Strict
|
|
|
6
6
|
include Pundit::Authorization
|
|
7
7
|
extend SimpleCrudController
|
|
8
8
|
|
|
9
|
-
before_action :set_params
|
|
10
|
-
def set_params
|
|
11
|
-
SimpleCrudController.params = params
|
|
12
|
-
end
|
|
13
|
-
|
|
14
9
|
def dummy_model_params
|
|
15
10
|
params.permit(:name, :something, :user_id, :slug)
|
|
16
11
|
end
|
|
@@ -6,11 +6,6 @@ module UnpaginatedScoped
|
|
|
6
6
|
include Pundit::Authorization
|
|
7
7
|
extend SimpleCrudController
|
|
8
8
|
|
|
9
|
-
before_action :set_params
|
|
10
|
-
def set_params
|
|
11
|
-
SimpleCrudController.params = params
|
|
12
|
-
end
|
|
13
|
-
|
|
14
9
|
simple_crud_for :index, paginate: false, scope: ->(user) { DummyModel.where(user: user) }
|
|
15
10
|
end
|
|
16
11
|
end
|
|
@@ -82,6 +82,12 @@ describe SimpleCrud::RSpec do
|
|
|
82
82
|
expect(model_attributes).to eq(user: current_user)
|
|
83
83
|
end
|
|
84
84
|
|
|
85
|
+
it 'raises a clear error when owner_association has no setter on the model' do
|
|
86
|
+
klass = Class.new { def self.column_names = [] }
|
|
87
|
+
allow(self).to receive_messages(owner_association: :nonexistent, model_class_object: klass)
|
|
88
|
+
expect { validate_owner_association! }.to raise_error(/owner_association is :nonexistent/)
|
|
89
|
+
end
|
|
90
|
+
|
|
85
91
|
describe 'with simple_crud metadata',
|
|
86
92
|
simple_crud: { finder_key: :token, model_attributes: -> { { overridden: true } } } do
|
|
87
93
|
it 'prefers metadata for overridden settings' do
|
|
@@ -8,6 +8,14 @@ class UnpoliceableThingsController
|
|
|
8
8
|
extend SimpleCrudController
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
+
class BaseWithDefaultsController
|
|
12
|
+
extend SimpleCrudController
|
|
13
|
+
simple_crud_defaults authorize: false, authenticate: false, authenticate_headers: true
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
class InheritingController < BaseWithDefaultsController
|
|
17
|
+
end
|
|
18
|
+
|
|
11
19
|
describe SimpleCrudController do
|
|
12
20
|
describe '.check_policies' do
|
|
13
21
|
it 'returns when a matching policy exists' do
|
|
@@ -21,6 +29,36 @@ describe SimpleCrudController do
|
|
|
21
29
|
end
|
|
22
30
|
end
|
|
23
31
|
|
|
32
|
+
describe '.simple_crud_defaults' do
|
|
33
|
+
it 'applies to parameters_with_defaults', :aggregate_failures do
|
|
34
|
+
params = BaseWithDefaultsController.parameters_with_defaults({})
|
|
35
|
+
expect(params[:authorize]).to be false
|
|
36
|
+
expect(params[:authenticate]).to be false
|
|
37
|
+
expect(params[:authenticate_headers]).to be true
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'are inherited by subclasses', :aggregate_failures do
|
|
41
|
+
params = InheritingController.parameters_with_defaults({})
|
|
42
|
+
expect(params[:authorize]).to be false
|
|
43
|
+
expect(params[:authenticate]).to be false
|
|
44
|
+
expect(params[:authenticate_headers]).to be true
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it 'can be overridden per action', :aggregate_failures do
|
|
48
|
+
params = InheritingController.parameters_with_defaults(authorize: true)
|
|
49
|
+
expect(params[:authorize]).to be true
|
|
50
|
+
expect(params[:authenticate]).to be false
|
|
51
|
+
expect(params[:authenticate_headers]).to be true
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'does not affect unrelated controllers', :aggregate_failures do
|
|
55
|
+
params = DummyModelsController.parameters_with_defaults({})
|
|
56
|
+
expect(params[:authorize]).to be true
|
|
57
|
+
expect(params[:authenticate]).to be true
|
|
58
|
+
expect(params[:authenticate_headers]).to be true
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
24
62
|
describe '.check_serializer' do
|
|
25
63
|
it 'returns when the serializer option is blank' do
|
|
26
64
|
expect { DummyModelsController.check_serializer({}) }.not_to raise_error
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: wor-simple_crud
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- icoluccio
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-08-
|
|
10
|
+
date: 2026-08-30 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: rails
|