rails_stuff 0.5.1 → 0.6.0.rc1
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/.gitignore +1 -0
- data/CHANGELOG.md +29 -0
- data/Gemfile +1 -0
- data/README.md +37 -16
- data/gemfiles/rails_4.gemfile +1 -0
- data/gemfiles/rails_5.gemfile +1 -0
- data/lib/rails_stuff/engine.rb +1 -1
- data/lib/rails_stuff/resources_controller/actions.rb +3 -3
- data/lib/rails_stuff/resources_controller/basic_helpers.rb +1 -1
- data/lib/rails_stuff/resources_controller/resource_helper.rb +32 -14
- data/lib/rails_stuff/resources_controller.rb +0 -2
- data/lib/rails_stuff/responders/turbolinks.rb +13 -0
- data/lib/rails_stuff/responders.rb +19 -0
- data/lib/rails_stuff/rspec_helpers/concurrency.rb +45 -0
- data/lib/rails_stuff/rspec_helpers/groups/feature.rb +25 -0
- data/lib/rails_stuff/rspec_helpers/groups/request.rb +79 -0
- data/lib/rails_stuff/rspec_helpers/matchers/be_valid_js.rb +12 -0
- data/lib/rails_stuff/rspec_helpers/matchers/redirect_with_turbolinks.rb +53 -0
- data/lib/rails_stuff/rspec_helpers/signinable.rb +21 -0
- data/lib/rails_stuff/rspec_helpers.rb +123 -0
- data/lib/rails_stuff/sort_scope.rb +19 -0
- data/lib/rails_stuff/statusable/builder.rb +114 -0
- data/lib/rails_stuff/statusable/helper.rb +64 -0
- data/lib/rails_stuff/statusable/mapped_builder.rb +48 -0
- data/lib/rails_stuff/statusable/mapped_helper.rb +46 -0
- data/lib/rails_stuff/statusable.rb +53 -199
- data/lib/rails_stuff/test_helpers/concurrency.rb +1 -32
- data/lib/rails_stuff/test_helpers/integration_session.rb +18 -0
- data/lib/rails_stuff/test_helpers/response.rb +10 -0
- data/lib/rails_stuff/test_helpers.rb +50 -0
- data/lib/rails_stuff/types_tracker.rb +1 -1
- data/lib/rails_stuff/version.rb +13 -3
- data/lib/rails_stuff.rb +3 -0
- metadata +20 -8
- data/lib/rails_stuff/resources_controller/responder.rb +0 -21
- data/lib/rails_stuff/test_helpers/configurator.rb +0 -60
- data/lib/rails_stuff/test_helpers/rails.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 56cd33390b1d0c5cce251aba39698ef115de3c6c
|
4
|
+
data.tar.gz: 8e7032d8717fae0d1fa44c5f6ea308a150a2e73f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9abf798f564088d2bb174e955efdf0cce9b47528b8f0dac7095516a35fcd11752772cd3d691266235698fd5281622db8ce9f5f9d32a3d66a75c8efde2c5da87c
|
7
|
+
data.tar.gz: 3dbbc5a6052014726fba018811d5615d9e9527e913fb14a492d615527f4bbe6bb5312815d55549e613e38c6103728447e7b558c8f1bbf630c18d65eb897bfc13
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,34 @@
|
|
1
1
|
## Unreleased
|
2
2
|
|
3
|
+
## 0.6.0.rc1
|
4
|
+
|
5
|
+
### Controllers
|
6
|
+
|
7
|
+
- Don't overwrite :location option if present.
|
8
|
+
- Don't overwrite responder and `respond_with`'s mimes.
|
9
|
+
- `#current_sort_scope` to access applied sorting rules.
|
10
|
+
- `.resource_helper` has `source` option, which accepts lambdas and strings.
|
11
|
+
`class` option is deprecated now in favour of `source`.
|
12
|
+
|
13
|
+
### Models
|
14
|
+
|
15
|
+
- Improved Statusable:
|
16
|
+
|
17
|
+
- Model are now clear from lot of helper methods.
|
18
|
+
There is single `statuses` method for statusable field which holds all helpers.
|
19
|
+
- `.select_options` supports `:only` option.
|
20
|
+
- Helpers to map/unmap values for mapped statuses from external code.
|
21
|
+
|
22
|
+
### Tests
|
23
|
+
|
24
|
+
- A lot of new test and rspec helpers and configs (see RSpecHelpers, TestHelpers).
|
25
|
+
- `RSpecHelpers.setup` & `TestHelpers.setup` to setup helpers instead of requiring
|
26
|
+
files. This methods accepts `only` & `except` options.
|
27
|
+
|
28
|
+
### Misc
|
29
|
+
|
30
|
+
- Use AR#update instead of #update_attributes.
|
31
|
+
|
3
32
|
## 0.5.1
|
4
33
|
|
5
34
|
Rails 5 support.
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -58,8 +58,7 @@ __[Helpers usage](#helpers-usage)__
|
|
58
58
|
|
59
59
|
- __Response__
|
60
60
|
`#json_body` to test json responses.
|
61
|
-
-
|
62
|
-
Provides useful basic configuration for RSpec.
|
61
|
+
- Useful RSpec configurations, helpers and matchers for better experience.
|
63
62
|
- __Concurrency__
|
64
63
|
Helpers for testing with concurrent requests.
|
65
64
|
|
@@ -166,6 +165,9 @@ has_sort_scope by: [:name, :created_at, :balance], default: [:name]
|
|
166
165
|
# - `sort=name&sort_desc=true`
|
167
166
|
# - `sort[name]&sort[created_at]`
|
168
167
|
# - `sort[name]&sort[created_at]=desc
|
168
|
+
|
169
|
+
# access current sort scope hash with
|
170
|
+
current_sort_scope # => {'name' => :desc} or {'name' => :asc, 'id' => :desc}
|
169
171
|
```
|
170
172
|
|
171
173
|
Requires `gem 'has_scope'`.
|
@@ -249,10 +251,12 @@ User.with_status(param[:status]).with_subscription_status(params[:subs_status])
|
|
249
251
|
Order.with_status(:confirmed)
|
250
252
|
|
251
253
|
# Translation & select helpers (requires activemodel_translation gem)
|
252
|
-
User.
|
254
|
+
User.statuses.translate(:active)
|
253
255
|
user.subscription_status_name # translates current status
|
254
|
-
User.
|
255
|
-
User.
|
256
|
+
User.statuses.select_options
|
257
|
+
User.subscription_statuses.select_options except: [:expired]
|
258
|
+
Order.statuses.map([:submitted, :delivered]) # => [1, 3]
|
259
|
+
Order.statuses.unmap([1, 3]) # => [:submitted, :delivered]
|
256
260
|
|
257
261
|
# Accessors
|
258
262
|
user.status = 'confirmed' or user.confirmed!
|
@@ -409,8 +413,13 @@ switch locales while rendering single view.
|
|
409
413
|
|
410
414
|
### Test helpers usage
|
411
415
|
|
412
|
-
Add `
|
416
|
+
Add `RailsStuff::RSpec.setup` to `rails_helper.rb` to load all the stuff or
|
417
|
+
pick from `rails_stuff/test_helpers/` and `rails_stuff/rspec`.
|
418
|
+
|
419
|
+
Please check the source for complete list of helpers, while this section is not
|
420
|
+
well-documented.
|
413
421
|
|
422
|
+
#### `json_body`
|
414
423
|
```ruby
|
415
424
|
assert_equal({'id' => 1, 'name' => 'John'}, response.json_body)
|
416
425
|
assert_equal('John', response.json_body['name'])
|
@@ -430,17 +439,29 @@ Use `json_body['key']` instead.
|
|
430
439
|
|
431
440
|
There is `Configurator` with useful RSpec configs:
|
432
441
|
|
442
|
+
#### RSpec configurations
|
443
|
+
|
433
444
|
```ruby
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
445
|
+
# Setup DatabaseCleaner with basic settings:
|
446
|
+
RailsStuff::RSpec.database_cleaner
|
447
|
+
|
448
|
+
# Flush redis after suite and exampes with `flush_redis: true`:
|
449
|
+
RailsStuff::RSpec.redis
|
450
|
+
|
451
|
+
# Run debugger after failed tests:
|
452
|
+
RailsStuff::RSpec.debug
|
453
|
+
|
454
|
+
# Clear log/test.log after suite:
|
455
|
+
RailsStuff::RSpec.clear_logs
|
456
|
+
|
457
|
+
# Raise errors from threads:
|
458
|
+
RailsStuff::RSpec.thread
|
459
|
+
|
460
|
+
# Raise errors for all missing I18n translation:
|
461
|
+
RailsStuff::RSpec.i18n
|
462
|
+
|
463
|
+
# Freeze time with for group/example with `:frozen_time` metadata (requires timecop gem):
|
464
|
+
RailsStuff::RSpec.frozen_time
|
444
465
|
```
|
445
466
|
|
446
467
|
### PluginManager
|
data/gemfiles/rails_4.gemfile
CHANGED
data/gemfiles/rails_5.gemfile
CHANGED
data/lib/rails_stuff/engine.rb
CHANGED
@@ -8,7 +8,7 @@ module RailsStuff
|
|
8
8
|
random_uniq_attr: :model,
|
9
9
|
statusable: :model,
|
10
10
|
resources_controller: [
|
11
|
-
:controller,
|
11
|
+
-> { defined?(::Responders) && :controller },
|
12
12
|
-> { ResourcesController.use_kaminari! if defined?(::Kaminari) },
|
13
13
|
],
|
14
14
|
sort_scope: -> { defined?(::HasScope) && :controller },
|
@@ -8,21 +8,21 @@ module RailsStuff
|
|
8
8
|
|
9
9
|
def create(options = {}, &block)
|
10
10
|
if create_resource
|
11
|
-
options[:location]
|
11
|
+
options[:location] ||= after_save_url
|
12
12
|
end
|
13
13
|
respond_with(resource, options, &block)
|
14
14
|
end
|
15
15
|
|
16
16
|
def update(options = {}, &block)
|
17
17
|
if update_resource
|
18
|
-
options[:location]
|
18
|
+
options[:location] ||= after_save_url
|
19
19
|
end
|
20
20
|
respond_with(resource, options, &block)
|
21
21
|
end
|
22
22
|
|
23
23
|
def destroy(options = {}, &block)
|
24
24
|
resource.destroy
|
25
|
-
options[:location]
|
25
|
+
options[:location] ||= after_destroy_url
|
26
26
|
flash_errors!
|
27
27
|
respond_with(resource, options, &block)
|
28
28
|
end
|
@@ -2,6 +2,15 @@ module RailsStuff
|
|
2
2
|
module ResourcesController
|
3
3
|
# Defines resource helper and finder method.
|
4
4
|
module ResourceHelper
|
5
|
+
class << self
|
6
|
+
def deprecation
|
7
|
+
@deprecation ||= begin
|
8
|
+
require 'active_support/deprecation'
|
9
|
+
ActiveSupport::Deprecation.new('0.7', 'RailsStuff')
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
5
14
|
# Defines protected helper method. Ex. for `:user`
|
6
15
|
#
|
7
16
|
# helper_method :user
|
@@ -12,26 +21,35 @@ module RailsStuff
|
|
12
21
|
#
|
13
22
|
# #### Options
|
14
23
|
#
|
15
|
-
# - `
|
24
|
+
# - `source` - class name or Proc returning relation, default to `resource_name.classify`.
|
16
25
|
# - `param` - param name, default to `resource_name.foreign_key`
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
param_key = options[:param] || resource_name.foreign_key
|
26
|
+
#
|
27
|
+
# rubocop:disable CyclomaticComplexity, PerceivedComplexity, AbcSize
|
28
|
+
def resource_helper(name, param: nil, source: nil, **options)
|
29
|
+
ResourceHelper.deprecation.warn('use :source instead of :class') if options.key?(:class)
|
22
30
|
|
23
|
-
|
24
|
-
|
31
|
+
param ||= name.to_s.foreign_key.to_sym
|
32
|
+
define_method("#{name}?") { params.key?(param) }
|
25
33
|
|
26
|
-
|
27
|
-
|
34
|
+
ivar = :"@#{name}"
|
35
|
+
source ||= options[:class] || name.to_s.classify
|
36
|
+
if source.is_a?(Proc)
|
37
|
+
define_method(name) do
|
38
|
+
instance_variable_get(ivar) ||
|
39
|
+
instance_variable_set(ivar, instance_exec(&source).find(params[param]))
|
28
40
|
end
|
29
|
-
|
30
|
-
|
31
|
-
|
41
|
+
else
|
42
|
+
source = Object.const_get(source) unless source.is_a?(Class)
|
43
|
+
define_method(name) do
|
44
|
+
instance_variable_get(ivar) ||
|
45
|
+
instance_variable_set(ivar, source.find(params[param]))
|
32
46
|
end
|
33
|
-
|
47
|
+
end
|
48
|
+
|
49
|
+
helper_method name, :"#{name}?"
|
50
|
+
protected name, :"#{name}?"
|
34
51
|
end
|
52
|
+
# rubocop:enable CyclomaticComplexity, PerceivedComplexity, AbcSize
|
35
53
|
end
|
36
54
|
end
|
37
55
|
end
|
@@ -41,8 +41,6 @@ module RailsStuff
|
|
41
41
|
def resources_controller(**options)
|
42
42
|
ResourcesController.inject(self, **options)
|
43
43
|
|
44
|
-
respond_to :html
|
45
|
-
self.responder = Responder
|
46
44
|
self.after_save_action = options[:after_save_action] || after_save_action
|
47
45
|
|
48
46
|
resource_belongs_to(*options[:belongs_to]) if options[:belongs_to]
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module RailsStuff
|
2
|
+
module Responders
|
3
|
+
module Turbolinks
|
4
|
+
# Bypasses `:turbolinks` from options.
|
5
|
+
def redirect_to(url, opts = {})
|
6
|
+
if !opts.key?(:turbolinks) && options.key?(:turbolinks)
|
7
|
+
opts[:turbolinks] = options[:turbolinks]
|
8
|
+
end
|
9
|
+
super
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rails_stuff/responders/turbolinks'
|
2
|
+
|
3
|
+
module RailsStuff
|
4
|
+
# Here are some useful responders extensions.
|
5
|
+
#
|
6
|
+
# Previous versions had responder with SJR helpers, which has been removed.
|
7
|
+
# To achieve same result define responder with:
|
8
|
+
#
|
9
|
+
# class CustomResponder < ActionController::Responder
|
10
|
+
# include Responders::HttpCacheResponder
|
11
|
+
# include RailsStuff::Responders::Turbolinks
|
12
|
+
#
|
13
|
+
# # SJR: render action on failures, redirect on success
|
14
|
+
# alias_method :to_js, :to_html
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
module Responders
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'rails_stuff/test_helpers/concurrency'
|
3
|
+
|
4
|
+
module RailsStuff
|
5
|
+
module RSpecHelpers
|
6
|
+
module Concurrency
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
include RailsStuff::TestHelpers::Concurrency
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
# Defines subject which runs parent's value in multiple threads concurrently.
|
12
|
+
# Define `thread_args` or `threads_count` with `let` to configure it.
|
13
|
+
#
|
14
|
+
# Sets metadata `concurrent: true` so database cleaner uses right strategy.
|
15
|
+
def concurrent_subject!
|
16
|
+
metadata[:concurrent] = true
|
17
|
+
subject do
|
18
|
+
super_proc = super()
|
19
|
+
args = defined?(thread_args) && thread_args
|
20
|
+
args ||= defined?(threads_count) && threads_count
|
21
|
+
-> { concurrently(args, &super_proc) }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Runs given block in current context and nested context with concurrent subject.
|
26
|
+
#
|
27
|
+
# subject { -> { increment_value_once } }
|
28
|
+
# # This will create 2 examples. One for current contex, and one
|
29
|
+
# # for current context where subject will run multiple times concurrently.
|
30
|
+
# check_concurrent do
|
31
|
+
# it { should change { value }.by(1) }
|
32
|
+
# end
|
33
|
+
def check_concurrent(&block)
|
34
|
+
instance_eval(&block)
|
35
|
+
context 'running multiple times concurrently' do
|
36
|
+
concurrent_subject!
|
37
|
+
instance_eval(&block)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
::RSpec.configuration.include(self) if defined?(::RSpec)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module RailsStuff
|
2
|
+
module RSpecHelpers
|
3
|
+
module Groups
|
4
|
+
module Feature
|
5
|
+
def wait_for_ajax
|
6
|
+
Timeout.timeout(Capybara.default_max_wait_time) do
|
7
|
+
loop until finished_all_ajax_requests?
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
# Tuned for jQuery, override it if you don't use jQuery.
|
12
|
+
def finished_all_ajax_requests?
|
13
|
+
page.evaluate_script('jQuery.active').zero?
|
14
|
+
end
|
15
|
+
|
16
|
+
def pause
|
17
|
+
$stderr.write 'Press enter to continue'
|
18
|
+
$stdin.gets
|
19
|
+
end
|
20
|
+
|
21
|
+
::RSpec.configuration.include self, type: :feature
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module RailsStuff
|
4
|
+
module RSpecHelpers
|
5
|
+
module Groups
|
6
|
+
module Request
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
# Define default params for ResourcesController.
|
11
|
+
#
|
12
|
+
# subject { -> { patch(resource_path, params: params) } }
|
13
|
+
# let(:resource) { create(:user) }
|
14
|
+
# let(:resource_params) { {name: 'new name'} }
|
15
|
+
# # params will be {user: {name: 'new name'}}
|
16
|
+
if described_class.respond_to?(:resource_param_name)
|
17
|
+
let(:params) { {described_class.resource_param_name => resource_params} }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module ClassMethods
|
22
|
+
# Adds `referer`, `referer_path` and `headers` with `let`.
|
23
|
+
# Requires `root_url`
|
24
|
+
def set_referer
|
25
|
+
let(:referer) { root_url.sub(%r{/$}, referer_path) }
|
26
|
+
let(:referer_path) { '/test_referer' }
|
27
|
+
let(:headers) do
|
28
|
+
headers = {Referer: referer}
|
29
|
+
defined?(super) ? super().merge(headers) : headers
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Perform simple request to initialize session.
|
34
|
+
# Useful for `change` matchers.
|
35
|
+
def init_session
|
36
|
+
before do
|
37
|
+
path = defined?(init_session_path) ? init_session_path : '/'
|
38
|
+
get(path)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def with_csrf_protection!
|
43
|
+
around do |ex|
|
44
|
+
begin
|
45
|
+
old = ActionController::Base.allow_forgery_protection
|
46
|
+
ActionController::Base.allow_forgery_protection = true
|
47
|
+
ex.run
|
48
|
+
ensure
|
49
|
+
ActionController::Base.allow_forgery_protection = old
|
50
|
+
end
|
51
|
+
end
|
52
|
+
let(:csrf_response) do
|
53
|
+
path = defined?(csrf_response_path) ? csrf_response_path : '/'
|
54
|
+
get(path) && response.body
|
55
|
+
end
|
56
|
+
let(:csrf_param) { csrf_response.match(/meta name="csrf-param" content="([^"]*)"/)[1] }
|
57
|
+
let(:csrf_token) { csrf_response.match(/<meta name="csrf-token" content="([^"]*)"/)[1] }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Generate url to current controller.
|
62
|
+
def controller_path(**options)
|
63
|
+
url_for(controller: described_class.controller_path, only_path: true, **options)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Generate url to current controller with resource and default action to `:show`.
|
67
|
+
# It uses `resource` method by default:
|
68
|
+
#
|
69
|
+
# expect(resource_path).to eq resource_path(resource)
|
70
|
+
# resource_path(other_user, action: :edit)
|
71
|
+
def resource_path(resource = self.resource, **options)
|
72
|
+
controller_path(action: :show, id: resource, **options)
|
73
|
+
end
|
74
|
+
|
75
|
+
::RSpec.configuration.include self, type: :request
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
RSpec::Matchers.define :be_valid_js do
|
2
|
+
match_unless_raises do |actual|
|
3
|
+
ExecJS.exec("var test = function(){\n#{actual}\n}")
|
4
|
+
end
|
5
|
+
|
6
|
+
failure_message do |actual|
|
7
|
+
js_error = rescued_exception.message
|
8
|
+
line = js_error.lines[0].split(':').last.to_i - 1
|
9
|
+
js_error = /SyntaxError.*$/.match(js_error)[0] if js_error.include?('SyntaxError')
|
10
|
+
"expected string to be valid js, got '#{js_error}' on line #{line} for\n\n#{actual}"
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module RailsStuff
|
2
|
+
module RSpecHelpers
|
3
|
+
module Matchers
|
4
|
+
module RedirectWithTurbolinks
|
5
|
+
include ::RSpec::Matchers
|
6
|
+
|
7
|
+
class XhrFailure < StandardError; end
|
8
|
+
|
9
|
+
def matches?(response)
|
10
|
+
return unless @scope.request
|
11
|
+
if @scope.request.xhr?
|
12
|
+
match_unless_raises(XhrFailure) { matches_xhr?(response) }
|
13
|
+
else
|
14
|
+
super
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def failure_message
|
19
|
+
@scope.request ? super : 'Request was not performed'
|
20
|
+
end
|
21
|
+
|
22
|
+
def matches_xhr?(response)
|
23
|
+
unless be_ok.matches?(response)
|
24
|
+
raise XhrFailure, "Expect #{response.inspect} to be OK for Turbolinks redirect"
|
25
|
+
end
|
26
|
+
location, _options = turbolinks_location(response)
|
27
|
+
raise XhrFailure, "No Turbolinks redirect in\n\n#{response.body}" unless location
|
28
|
+
active_support_assertion(location)
|
29
|
+
end
|
30
|
+
|
31
|
+
def turbolinks_location(response)
|
32
|
+
body = response.body
|
33
|
+
return unless body
|
34
|
+
match_data = /Turbolinks\.visit\(([^,]+)(,\s*([^)]+))?\)/.match(body)
|
35
|
+
return unless match_data
|
36
|
+
[match_data[1], match_data[3]].map { |x| JSON.parse("[#{x}]")[0] }
|
37
|
+
end
|
38
|
+
|
39
|
+
def active_support_assertion(location)
|
40
|
+
redirect_is = @scope.send(:normalize_argument_to_redirection, location)
|
41
|
+
redirect_expected = @scope.send(:normalize_argument_to_redirection, @expected)
|
42
|
+
message = "Expected response to be a Turbolinks redirect to <#{redirect_expected}>" \
|
43
|
+
" but was a redirect to <#{redirect_is}>"
|
44
|
+
@scope.assert_operator redirect_expected, :===, redirect_is, message
|
45
|
+
rescue ActiveSupport::TestCase::Assertion => e
|
46
|
+
raise XhrFailure, e
|
47
|
+
end
|
48
|
+
|
49
|
+
::RSpec::Rails::Matchers::RedirectTo::RedirectTo.prepend(self) if defined?(::RSpec::Rails)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module RailsStuff
|
2
|
+
module RSpecHelpers
|
3
|
+
module Signinable
|
4
|
+
# Context-level helper to add before filter to sign in user.
|
5
|
+
# Adds `current_user` with let if not defined yet or with gven block.
|
6
|
+
#
|
7
|
+
# Instance-level `sign_in(user_or_nil)` method must be defined, so
|
8
|
+
# this module can be used in any of feature, request or controller groups.
|
9
|
+
#
|
10
|
+
# sign_in { owner }
|
11
|
+
# sign_in # will call current_user or define it with nil
|
12
|
+
def sign_in(&block)
|
13
|
+
if block || !instance_methods.include?(:current_user)
|
14
|
+
block ||= ->(*) {}
|
15
|
+
let(:current_user, &block)
|
16
|
+
end
|
17
|
+
before { sign_in(instance_eval { current_user }) }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|