effective_test_bot 0.2.3 → 0.3.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/README.md +4 -0
- data/app/helpers/effective_test_bot_controller_helper.rb +25 -0
- data/lib/effective_test_bot/engine.rb +17 -6
- data/lib/effective_test_bot/version.rb +1 -1
- data/lib/generators/templates/test_helper.rb +1 -0
- data/lib/tasks/effective_test_bot_tasks.rake +5 -1
- data/test/concerns/test_botable/crud_test.rb +135 -0
- data/test/support/effective_test_bot_assertions.rb +29 -2
- data/test/support/effective_test_bot_test_helper.rb +14 -0
- data/test/test_bot/integration/devise_test.rb +3 -0
- data/test/test_bot/integration/minitest_test.rb +31 -9
- data/test/test_botable/crud_test.rb +45 -26
- metadata +4 -3
- data/test/concerns/acts_as_test_botable.rb +0 -57
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 50ef005db97e70ce2576d749a0a4542409319da7
|
4
|
+
data.tar.gz: c12dc73aacd70b89fc4d4bcdde5b875c723f7c90
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4c71082a5e0e90643d1bb90ceca1f01d9aaa37200c4d5a31cbc71dcfc59faa224c0572d1f13ceef05643b75d8df99665f816bf815617a4d2786402cc1418c047
|
7
|
+
data.tar.gz: 820f5070944df5997434796a7ce0d775fd809c3b686c19ac03e95589b80b1b74fef6b7b6bf17741c9bc3e4353422f58860664dfcb5227df8c164fdcff645881a
|
data/README.md
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
module EffectiveTestBotControllerHelper
|
2
|
+
def assign_test_bot_http_headers
|
3
|
+
response.headers['Test-Bot-Flash'] = Base64.encode64(flash.to_hash.to_json)
|
4
|
+
|
5
|
+
# Assign the Assigns now
|
6
|
+
# With the assigns, we're a little bit more selective
|
7
|
+
# Anything that's a simple object can be serialized
|
8
|
+
test_bot_assigns = {}
|
9
|
+
|
10
|
+
view_assigns.each do |key, object|
|
11
|
+
case object
|
12
|
+
when ActiveRecord::Base
|
13
|
+
test_bot_assigns[key] = object.attributes
|
14
|
+
test_bot_assigns[key][:errors] = object.errors.messages.delete_if { |_, v| v.blank? } if object.errors.present?
|
15
|
+
when TrueClass, FalseClass, NilClass, String, Symbol, Numeric
|
16
|
+
test_bot_assigns[key] = object
|
17
|
+
else
|
18
|
+
# We don't want to serialize them, but they should be present
|
19
|
+
test_bot_assigns[key] = :present_but_not_serialized
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
response.headers['Test-Bot-Assigns'] = Base64.encode64(test_bot_assigns.to_hash.to_json)
|
24
|
+
end
|
25
|
+
end
|
@@ -2,9 +2,9 @@ module EffectiveTestBot
|
|
2
2
|
class Engine < ::Rails::Engine
|
3
3
|
engine_name 'effective_test_bot'
|
4
4
|
|
5
|
+
config.autoload_paths += Dir["#{config.root}/test/test_botable/**/"]
|
5
6
|
config.autoload_paths += Dir["#{config.root}/test/concerns/**/"]
|
6
7
|
config.autoload_paths += Dir["#{config.root}/test/support/**/"]
|
7
|
-
config.autoload_paths += Dir["#{config.root}/test/test_botable/**/"]
|
8
8
|
|
9
9
|
# Set up our default configuration options.
|
10
10
|
initializer "effective_test_bot.defaults", :before => :load_config_initializers do |app|
|
@@ -14,12 +14,23 @@ module EffectiveTestBot
|
|
14
14
|
|
15
15
|
initializer 'effective_test_bot.test_suite' do |app|
|
16
16
|
Rails.application.config.to_prepare do
|
17
|
-
ActionDispatch::IntegrationTest.
|
17
|
+
ActionDispatch::IntegrationTest.include CrudTest
|
18
|
+
ActionDispatch::IntegrationTest.include TestBotable::CrudTest
|
19
|
+
|
20
|
+
# A whole bunch of helper methods
|
21
|
+
ActionDispatch::IntegrationTest.include EffectiveTestBotAssertions
|
22
|
+
ActionDispatch::IntegrationTest.include EffectiveTestBotFormHelper
|
23
|
+
ActionDispatch::IntegrationTest.include EffectiveTestBotLoginHelper
|
24
|
+
ActionDispatch::IntegrationTest.include EffectiveTestBotTestHelper
|
25
|
+
end
|
26
|
+
end
|
18
27
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
28
|
+
initializer 'effective_test_bot.assign_assign_headers' do
|
29
|
+
ActiveSupport.on_load :action_controller do
|
30
|
+
if Rails.env.test?
|
31
|
+
ActionController::Base.send :include, ::EffectiveTestBotControllerHelper
|
32
|
+
ActionController::Base.send :after_filter, :assign_test_bot_http_headers
|
33
|
+
end
|
23
34
|
end
|
24
35
|
end
|
25
36
|
|
@@ -63,6 +63,7 @@ ActiveRecord::Migration.maintain_test_schema!
|
|
63
63
|
|
64
64
|
Rake::Task['db:fixtures:load'].invoke # There's just no way to get the seeds first, as this has to delete everything
|
65
65
|
Rake::Task['db:seed'].invoke
|
66
|
+
Rake::Task['test:load_fixture_seeds'].invoke # This is included by effective_test_bot. It just runs the app's test/fixtures/seeds.rb if it exists
|
66
67
|
|
67
68
|
# Make all database transactions use the same thread, otherwise signing up in capybara won't get rolled back
|
68
69
|
# This must be run after the Rake::Tasks above
|
@@ -12,7 +12,11 @@ namespace :test do
|
|
12
12
|
t.test_files = FileList["#{File.dirname(__FILE__)}/../../test/test_bot/**/*_test.rb"]
|
13
13
|
end
|
14
14
|
|
15
|
+
desc 'loads test/fixtures/seeds.rb'
|
16
|
+
task :load_fixture_seeds => :environment do
|
17
|
+
seeds = "#{Rails.root}/test/fixtures/seeds.rb"
|
18
|
+
load(seeds) if File.exists?(seeds)
|
19
|
+
end
|
15
20
|
|
16
21
|
|
17
22
|
end
|
18
|
-
|
@@ -0,0 +1,135 @@
|
|
1
|
+
module TestBotable
|
2
|
+
module CrudTest
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
CRUD_TESTS = [:new, :create_valid, :create_invalid, :edit, :update_valid, :update_invalid, :index, :show, :destroy]
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
|
9
|
+
# All this does is define a 'test_bot' method for each required action on this class
|
10
|
+
# So that MiniTest will see the test functions and run them
|
11
|
+
def crud_test(obj, user, options = {})
|
12
|
+
# Check for expected usage
|
13
|
+
unless (obj.kind_of?(Class) || obj.kind_of?(ActiveRecord::Base)) && user.kind_of?(User) && options.kind_of?(Hash)
|
14
|
+
raise 'invalid parameters passed to crud_test(), expecting crud_test(Post || Post.new(), User.first, options_hash)'
|
15
|
+
end
|
16
|
+
|
17
|
+
test_options = crud_test_options(obj, user, options) # returns a Hash of let! options
|
18
|
+
tests_prefix = crud_tests_prefix(options) # returns a string something like "test_bot (3)"
|
19
|
+
|
20
|
+
crud_tests_to_define(options).each do |test|
|
21
|
+
test_name = case test
|
22
|
+
when :new ; "#{tests_prefix} #new"
|
23
|
+
when :create_valid ; "#{tests_prefix} #create valid"
|
24
|
+
when :create_invalid ; "#{tests_prefix} #create invalid"
|
25
|
+
when :edit ; "#{tests_prefix} #edit"
|
26
|
+
when :update_valid ; "#{tests_prefix} #update valid"
|
27
|
+
when :update_invalid ; "#{tests_prefix} #update invalid"
|
28
|
+
when :index ; "#{tests_prefix} #index"
|
29
|
+
when :show ; "#{tests_prefix} #show"
|
30
|
+
when :destroy ; "#{tests_prefix} #destroy"
|
31
|
+
end
|
32
|
+
|
33
|
+
define_method(test_name) { crud_action_test(test, test_options) }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Parses and validates lots of options
|
38
|
+
# The output is what gets sent to each test and defined as lets
|
39
|
+
def crud_test_options(obj, user, options = {})
|
40
|
+
# Make sure Obj.new() works
|
41
|
+
if obj.kind_of?(Class) && (obj.new() rescue false) == false
|
42
|
+
raise "effective_test_bot: failed to initialize object with #{obj}.new(), unable to proceed"
|
43
|
+
end
|
44
|
+
|
45
|
+
# Parse the resource and resource class
|
46
|
+
resource = obj.kind_of?(Class) ? obj.new() : obj
|
47
|
+
resource_class = obj.kind_of?(Class) ? obj : obj.class
|
48
|
+
|
49
|
+
# If obj is an ActiveRecord object with attributes, Post.new(:title => 'My Title')
|
50
|
+
# then compute any explicit attributes, so forms will be filled with those values
|
51
|
+
resource_attributes = if obj.kind_of?(ActiveRecord::Base)
|
52
|
+
empty = resource_class.new()
|
53
|
+
{}.tap { |atts| resource.attributes.each { |k, v| atts[k] = v if empty.attributes[k] != v } }
|
54
|
+
end || {}
|
55
|
+
|
56
|
+
# Final options to call each test with
|
57
|
+
{
|
58
|
+
resource: resource,
|
59
|
+
resource_class: resource_class,
|
60
|
+
resource_name: resource_class.name.underscore,
|
61
|
+
resource_attributes: resource_attributes,
|
62
|
+
controller_namespace: options[:namespace],
|
63
|
+
user: user
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
# Run any test_bot tests first, in the order they're defined
|
68
|
+
# then the rest of the tests with whatever order they come in
|
69
|
+
def runnable_methods
|
70
|
+
self.public_instance_methods.select { |name| name.to_s.starts_with?('test_bot') }.map(&:to_s) +
|
71
|
+
super.reject { |name| name.starts_with?('test_bot') }
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
# Parses the incoming options[:only] and [:except]
|
77
|
+
# To only define the appropriate methods
|
78
|
+
# This guarantees the functions will be defined in the same order as CRUD_TESTS
|
79
|
+
def crud_tests_to_define(options)
|
80
|
+
to_run = if options[:only]
|
81
|
+
options[:only] = Array(options[:only]).flatten.compact.map(&:to_sym)
|
82
|
+
options[:only] = options[:only] + [:create_valid, :create_invalid] if options[:only].delete(:create)
|
83
|
+
options[:only] = options[:only] + [:update_valid, :update_invalid] if options[:only].delete(:update)
|
84
|
+
|
85
|
+
CRUD_TESTS & options[:only]
|
86
|
+
elsif options[:except]
|
87
|
+
options[:except] = Array(options[:except]).flatten.compact.map(&:to_sym)
|
88
|
+
options[:except] = options[:except] + [:create_valid, :create_invalid] if options[:except].delete(:create)
|
89
|
+
options[:except] = options[:except] + [:update_valid, :update_invalid] if options[:except].delete(:update)
|
90
|
+
|
91
|
+
CRUD_TESTS - options[:except]
|
92
|
+
else
|
93
|
+
CRUD_TESTS
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# You can't define multiple methods with the same name
|
98
|
+
# So we need to create a unique name, where appropriate, that still looks good in MiniTest output
|
99
|
+
def crud_tests_prefix(options)
|
100
|
+
@num_defined_crud_tests = (@num_defined_crud_tests || 0) + 1
|
101
|
+
|
102
|
+
if options[:label].present?
|
103
|
+
"test_bot: (#{options[:label]})"
|
104
|
+
elsif @num_defined_crud_tests > 1
|
105
|
+
"test_bot: (#{@num_defined_crud_tests})"
|
106
|
+
else
|
107
|
+
'test_bot:'
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
# Instance Methods
|
114
|
+
|
115
|
+
# This should allow you to run a crud_test method in a test
|
116
|
+
# crud_action_test(:create_valid, Clinic, User.first)
|
117
|
+
#
|
118
|
+
# If obj is a Hash {:resource => ...} just skip over parsing options
|
119
|
+
# And assume it's already been done (by the ClassMethod crud_test)
|
120
|
+
def crud_action_test(test, obj, user = nil, options = {})
|
121
|
+
if obj.kind_of?(Hash) && obj.key?(:resource)
|
122
|
+
obj
|
123
|
+
else
|
124
|
+
# Check for expected usage
|
125
|
+
unless (obj.kind_of?(Class) || obj.kind_of?(ActiveRecord::Base)) && user.kind_of?(User) && options.kind_of?(Hash)
|
126
|
+
raise 'invalid parameters passed to crud_action_test(), expecting crud_action_test(:new, Post || Post.new(), User.first, options_hash)'
|
127
|
+
end
|
128
|
+
|
129
|
+
self.class.crud_test_options(obj, user, options)
|
130
|
+
end.each { |k, v| self.class.let(k) { v } } # Using the regular let(:foo) { 'bar'} syntax
|
131
|
+
|
132
|
+
self.send(test)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -11,7 +11,7 @@ module EffectiveTestBotAssertions
|
|
11
11
|
assert page.has_selector?('form#new_user')
|
12
12
|
end
|
13
13
|
|
14
|
-
def assert_page_title(title = :any, message = 'page title
|
14
|
+
def assert_page_title(title = :any, message = 'expected page title to be present')
|
15
15
|
if title.present? && title != :any
|
16
16
|
assert_title(title) # Capybara TitleQuery, match this text
|
17
17
|
else
|
@@ -21,7 +21,7 @@ module EffectiveTestBotAssertions
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def assert_page_status(status = 200)
|
24
|
-
assert_equal status, page.status_code, "page
|
24
|
+
assert_equal status, page.status_code, "expected page to load with #{status} HTTP status code"
|
25
25
|
end
|
26
26
|
|
27
27
|
def assert_no_js_errors
|
@@ -29,4 +29,31 @@ module EffectiveTestBotAssertions
|
|
29
29
|
assert_equal 0, errors.size, errors.ai
|
30
30
|
end
|
31
31
|
|
32
|
+
# assert_flash
|
33
|
+
# assert_flash :success
|
34
|
+
# assert_flash :error, 'there was a specific error'
|
35
|
+
def assert_flash(key = nil, value = nil)
|
36
|
+
if key.present? && value.present?
|
37
|
+
assert_equal value, flash[key.to_s]
|
38
|
+
elsif key.present?
|
39
|
+
assert flash[key.to_s].present?, "expected flash[#{key}] to be present"
|
40
|
+
else
|
41
|
+
assert flash.present?, 'expected flash to be present'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# assert_assigns
|
46
|
+
# assert_assigns :current_user
|
47
|
+
# assert_assigns :current_user, true
|
48
|
+
def assert_assigns(key = nil, value = nil)
|
49
|
+
if key.present? && value.present?
|
50
|
+
assert_equal value, assigns[key.to_s]
|
51
|
+
elsif key.present?
|
52
|
+
assert assigns[key.to_s].present?, "expected @#{key} to be assigned"
|
53
|
+
else
|
54
|
+
assert assigns.present?, 'expected assigns to be present'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
|
32
59
|
end
|
@@ -13,6 +13,20 @@ module EffectiveTestBotTestHelper
|
|
13
13
|
sign_in(user)
|
14
14
|
session.driver.submit :delete, path, {}
|
15
15
|
session.document.find('html')
|
16
|
+
|
17
|
+
# Assign the Flash and Assigns
|
18
|
+
@flash = (JSON.parse(Base64.decode64(session.driver.response_headers['Test-Bot-Flash'])) rescue {})
|
19
|
+
@assigns = (JSON.parse(Base64.decode64(session.driver.response_headers['Test-Bot-Assigns'])) rescue {})
|
20
|
+
end
|
21
|
+
|
22
|
+
# EffectiveTestBot includes an after_filter on ApplicationController to set an http header
|
23
|
+
# that encodes the flash message, and some of the assigns
|
24
|
+
def flash
|
25
|
+
@flash ||= (JSON.parse(Base64.decode64(page.driver.browser.response_headers['Test-Bot-Flash'])) rescue {})
|
26
|
+
end
|
27
|
+
|
28
|
+
def assigns
|
29
|
+
@assigns ||= (JSON.parse(Base64.decode64(page.driver.browser.response_headers['Test-Bot-Assigns'])) rescue {})
|
16
30
|
end
|
17
31
|
|
18
32
|
end
|
@@ -18,6 +18,7 @@ if defined?(Devise) && defined?(User)
|
|
18
18
|
assert_equal page.status_code, 200
|
19
19
|
assert_content I18n.t('devise.registrations.signed_up')
|
20
20
|
assert User.find_by_email(email).present?
|
21
|
+
assert_assigns :current_user
|
21
22
|
end
|
22
23
|
|
23
24
|
test 'sign in' do
|
@@ -32,6 +33,7 @@ if defined?(Devise) && defined?(User)
|
|
32
33
|
assert_equal 200, page.status_code
|
33
34
|
assert_content I18n.t('devise.sessions.signed_in')
|
34
35
|
assert_equal 1, User.find_by_email(email).sign_in_count
|
36
|
+
assert_assigns :current_user
|
35
37
|
end
|
36
38
|
|
37
39
|
test 'invalid sign in' do
|
@@ -45,6 +47,7 @@ if defined?(Devise) && defined?(User)
|
|
45
47
|
|
46
48
|
assert_equal 200, page.status_code
|
47
49
|
assert_content I18n.t('devise.failure.invalid', authentication_keys: Devise.authentication_keys.join(', '))
|
50
|
+
assert assigns[:current_user].blank?
|
48
51
|
end
|
49
52
|
end
|
50
53
|
end
|
@@ -13,20 +13,37 @@ module TestBot
|
|
13
13
|
:alpha
|
14
14
|
end
|
15
15
|
|
16
|
-
test '
|
16
|
+
test '01: seeds and fixtures loaded' do
|
17
17
|
assert_normal
|
18
18
|
end
|
19
19
|
|
20
|
-
test '
|
20
|
+
test '02: all fixtures and seeds valid' do
|
21
|
+
ActiveRecord::Base.descendants.each do |model|
|
22
|
+
begin
|
23
|
+
(model.unscoped.all rescue []).each do |resource|
|
24
|
+
assert resource.valid?, "fixture or seed data is invalid (#{model.to_s} id=#{resource.id} #{resource.errors.full_messages.join(', ')})"
|
25
|
+
end
|
26
|
+
rescue ActiveRecord::StatementInvalid
|
27
|
+
; # Not entirely sure why I'm getting this error
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# I could remove this if sign_in checks for and creates a user with devise or not
|
33
|
+
test '03: at least one user is seeded' do
|
34
|
+
assert (User.all.count > 0), 'please create at least 1 seed or fixture user for effective_test_bot to function'
|
35
|
+
end
|
36
|
+
|
37
|
+
test '04: activerecord can create a user' do
|
21
38
|
create_user!
|
22
39
|
assert_equal (original_users_count + 1), User.count
|
23
40
|
end
|
24
41
|
|
25
|
-
test '
|
42
|
+
test '05: test database is back to normal' do
|
26
43
|
assert_normal
|
27
44
|
end
|
28
45
|
|
29
|
-
test '
|
46
|
+
test '06: capybara can create a user' do
|
30
47
|
user = sign_up()
|
31
48
|
assert user.kind_of?(User)
|
32
49
|
|
@@ -34,26 +51,26 @@ module TestBot
|
|
34
51
|
assert_signed_in
|
35
52
|
end
|
36
53
|
|
37
|
-
test '
|
54
|
+
test '07: test database is back to normal' do
|
38
55
|
assert_normal
|
39
56
|
end
|
40
57
|
|
41
|
-
test '
|
58
|
+
test '08: capybara session has been reset after manual sign up' do
|
42
59
|
assert_signed_out
|
43
60
|
create_user!
|
44
61
|
sign_in(email)
|
45
62
|
assert_signed_in
|
46
63
|
end
|
47
64
|
|
48
|
-
test '
|
65
|
+
test '09: test database is back to normal' do
|
49
66
|
assert_normal
|
50
67
|
end
|
51
68
|
|
52
|
-
test '
|
69
|
+
test '10: capybara session has been reset after warden login_as' do
|
53
70
|
assert_signed_out
|
54
71
|
end
|
55
72
|
|
56
|
-
test '
|
73
|
+
test '11: test database is back to normal' do
|
57
74
|
assert_normal
|
58
75
|
end
|
59
76
|
|
@@ -63,6 +80,11 @@ module TestBot
|
|
63
80
|
visit root_path
|
64
81
|
assert_equal page.status_code, 200
|
65
82
|
assert_equal original_users_count, User.count
|
83
|
+
|
84
|
+
# Someitmes it's nice to assert your environment...
|
85
|
+
#assert users(:normal).present?
|
86
|
+
#assert 2, User.count
|
87
|
+
#assert 3, Physician.count
|
66
88
|
end
|
67
89
|
|
68
90
|
end
|
@@ -1,12 +1,11 @@
|
|
1
1
|
module CrudTest
|
2
|
-
|
3
|
-
should_skip!(:new)
|
4
|
-
|
2
|
+
def new
|
5
3
|
sign_in(user) and visit(new_resource_path)
|
6
4
|
|
7
5
|
assert_page_status
|
8
6
|
assert_page_title
|
9
7
|
assert_no_js_errors
|
8
|
+
assert_assigns resource_name
|
10
9
|
|
11
10
|
# Make sure there's a form with a submit button
|
12
11
|
form_selector = "form#new_#{resource_name}"
|
@@ -17,9 +16,7 @@ module CrudTest
|
|
17
16
|
end
|
18
17
|
end
|
19
18
|
|
20
|
-
|
21
|
-
should_skip!(:create)
|
22
|
-
|
19
|
+
def create_valid
|
23
20
|
sign_in(user) and visit(new_resource_path)
|
24
21
|
|
25
22
|
before = { count: resource_class.count, path: page.current_path }
|
@@ -33,11 +30,14 @@ module CrudTest
|
|
33
30
|
|
34
31
|
refute_equal before[:count], after[:count], "unable to create #{resource_class} object"
|
35
32
|
refute_equal before[:path], after[:path], "unable to create #{resource_class} object"
|
36
|
-
end
|
37
33
|
|
38
|
-
|
39
|
-
|
34
|
+
# In a rails controller, if i redirect to resources_path it may not assign the instance variable
|
35
|
+
# Wheras if I redirect to edit_resource_path I must ensure that the instance variable is set
|
36
|
+
assert_assigns(resource_name) if after[:path].include?('/edit/')
|
37
|
+
assert(assigns[resource_name]['errors'].blank?) if assigns[resource_name].present?
|
38
|
+
end
|
40
39
|
|
40
|
+
def create_invalid
|
41
41
|
sign_in(user) and visit(new_resource_path)
|
42
42
|
before = { count: resource_class.count }
|
43
43
|
|
@@ -50,16 +50,21 @@ module CrudTest
|
|
50
50
|
assert_equal before[:count], after[:count], 'unexpectedly created object anyway'
|
51
51
|
assert_equal resources_path, page.current_path, 'did not return to #create url'
|
52
52
|
assert_page_title :any, 'page title missing after failed validation'
|
53
|
+
|
54
|
+
assert_flash :danger
|
55
|
+
assert_assigns resource_name
|
56
|
+
assert assigns[resource_name]['errors'].present?
|
53
57
|
end
|
54
58
|
|
55
|
-
|
56
|
-
|
59
|
+
def edit
|
60
|
+
sign_in(user) and (resource = find_or_create_resource!)
|
57
61
|
|
58
62
|
visit(edit_resource_path(resource))
|
59
63
|
|
60
64
|
assert_page_status
|
61
65
|
assert_page_title
|
62
66
|
assert_no_js_errors
|
67
|
+
assert_assigns resource_name
|
63
68
|
|
64
69
|
# Make sure there's a form with a submit button
|
65
70
|
form_selector = "form#edit_#{resource_name}_#{resource.id}"
|
@@ -68,10 +73,12 @@ module CrudTest
|
|
68
73
|
within(form_selector) do
|
69
74
|
assert_selector 'input[type=submit]', 'page form does not contain a submit button'
|
70
75
|
end
|
76
|
+
|
77
|
+
assert_assigns resource_name
|
71
78
|
end
|
72
79
|
|
73
|
-
|
74
|
-
|
80
|
+
def update_valid
|
81
|
+
sign_in(user) and (resource = find_or_create_resource!)
|
75
82
|
|
76
83
|
visit(edit_resource_path(resource))
|
77
84
|
|
@@ -87,10 +94,16 @@ module CrudTest
|
|
87
94
|
|
88
95
|
assert_equal before[:count], after[:count], "updating resource unexpectedly changed #{resource_class}.count"
|
89
96
|
assert(after[:updated_at] > before[:updated_at], "failed to update resource") if resource.respond_to?(:updated_at)
|
97
|
+
|
98
|
+
assert_flash :success
|
99
|
+
# In a rails controller, if i redirect to resources_path it may not assign the instance variable
|
100
|
+
# Wheras if I redirect to edit_resource_path I must ensure that the instance variable is set
|
101
|
+
assert_assigns(resource_name) if after[:path] == edit_resource_path(resource)
|
102
|
+
assert(assigns[resource_name]['errors'].blank?) if assigns[resource_name].present?
|
90
103
|
end
|
91
104
|
|
92
|
-
|
93
|
-
|
105
|
+
def update_invalid
|
106
|
+
sign_in(user) and (resource = find_or_create_resource!)
|
94
107
|
|
95
108
|
visit(edit_resource_path(resource))
|
96
109
|
|
@@ -108,30 +121,36 @@ module CrudTest
|
|
108
121
|
assert_equal(after[:updated_at], before[:updated_at], 'unexpectedly updated object anyway') if resource.respond_to?(:updated_at)
|
109
122
|
assert_equal resource_path(resource), page.current_path, 'did not return to #update url'
|
110
123
|
assert_page_title :any, 'page title missing after failed validation'
|
124
|
+
|
125
|
+
assert_flash :danger
|
126
|
+
assert_assigns resource_name
|
127
|
+
assert assigns[resource_name]['errors'].present?
|
111
128
|
end
|
112
129
|
|
113
|
-
|
114
|
-
|
130
|
+
def index
|
131
|
+
sign_in(user) and (resource = find_or_create_resource!)
|
115
132
|
|
116
133
|
visit resources_path
|
117
134
|
|
118
135
|
assert_page_status
|
119
136
|
assert_page_title
|
120
137
|
assert_no_js_errors
|
138
|
+
assert (assigns['datatable'].present? || assigns[resource_name.pluralize].present?), "expected @datatable or @#{resource_name.pluralize} to be set"
|
121
139
|
end
|
122
140
|
|
123
|
-
|
124
|
-
|
141
|
+
def show
|
142
|
+
sign_in(user) and (resource = create_resource!)
|
125
143
|
|
126
144
|
visit resource_path(resource)
|
127
145
|
|
128
146
|
assert_page_status
|
129
147
|
assert_page_title
|
130
148
|
assert_no_js_errors
|
149
|
+
assert_assigns resource_name
|
131
150
|
end
|
132
151
|
|
133
|
-
|
134
|
-
|
152
|
+
def destroy
|
153
|
+
sign_in(user) and (resource = find_or_create_resource!)
|
135
154
|
|
136
155
|
before = { count: resource_class.count, archived: (resource.archived rescue nil) }
|
137
156
|
|
@@ -139,6 +158,8 @@ module CrudTest
|
|
139
158
|
|
140
159
|
after = { count: resource_class.count, archived: (resource_class.find(resource.id).archived rescue nil) }
|
141
160
|
|
161
|
+
assert_flash :success
|
162
|
+
|
142
163
|
if resource.respond_to?(:archived)
|
143
164
|
assert after[:archived] == true, "expected #{resource_class}.archived == true"
|
144
165
|
else
|
@@ -148,9 +169,9 @@ module CrudTest
|
|
148
169
|
|
149
170
|
protected
|
150
171
|
|
151
|
-
def
|
152
|
-
|
153
|
-
|
172
|
+
def find_or_create_resource!
|
173
|
+
existing = resource_class.last
|
174
|
+
existing.present? ? existing : create_resource!
|
154
175
|
end
|
155
176
|
|
156
177
|
def create_resource!
|
@@ -160,7 +181,6 @@ module CrudTest
|
|
160
181
|
fill_form(resource_attributes) and submit_form
|
161
182
|
end
|
162
183
|
|
163
|
-
refute_equal new_resource_path, page.current_url
|
164
184
|
resource_class.last
|
165
185
|
end
|
166
186
|
|
@@ -181,5 +201,4 @@ module CrudTest
|
|
181
201
|
def edit_resource_path(resource) # edit
|
182
202
|
edit_polymorphic_path([*controller_namespace, resource])
|
183
203
|
end
|
184
|
-
|
185
204
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: effective_test_bot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Code and Effect
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-06-
|
11
|
+
date: 2015-06-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -203,6 +203,7 @@ files:
|
|
203
203
|
- MIT-LICENSE
|
204
204
|
- README.md
|
205
205
|
- Rakefile
|
206
|
+
- app/helpers/effective_test_bot_controller_helper.rb
|
206
207
|
- lib/effective_test_bot.rb
|
207
208
|
- lib/effective_test_bot/engine.rb
|
208
209
|
- lib/effective_test_bot/version.rb
|
@@ -210,7 +211,7 @@ files:
|
|
210
211
|
- lib/generators/templates/effective_test_bot.rb
|
211
212
|
- lib/generators/templates/test_helper.rb
|
212
213
|
- lib/tasks/effective_test_bot_tasks.rake
|
213
|
-
- test/concerns/
|
214
|
+
- test/concerns/test_botable/crud_test.rb
|
214
215
|
- test/support/effective_assets_upload_file._test
|
215
216
|
- test/support/effective_test_bot_assertions.rb
|
216
217
|
- test/support/effective_test_bot_form_helper.rb
|
@@ -1,57 +0,0 @@
|
|
1
|
-
module ActsAsTestBotable
|
2
|
-
extend ActiveSupport::Concern
|
3
|
-
|
4
|
-
module ClassMethods
|
5
|
-
CRUD_ACTIONS = [:index, :new, :create, :edit, :update, :show, :destroy]
|
6
|
-
|
7
|
-
def crud_test(obj, user, options = {})
|
8
|
-
# Check for expected usage
|
9
|
-
unless (obj.kind_of?(Class) || obj.kind_of?(ActiveRecord::Base)) && user.kind_of?(User) && options.kind_of?(Hash)
|
10
|
-
puts 'invalid parameters passed to crud_test(), expecting crud_test(Post || Post.new(), User.first, options_hash)' and return
|
11
|
-
end
|
12
|
-
|
13
|
-
# Make sure Obj.new() works
|
14
|
-
if obj.kind_of?(Class) && (obj.new() rescue false) == false
|
15
|
-
puts "effective_test_bot: failed to initialize object with #{obj}.new(), unable to proceed" and return
|
16
|
-
end
|
17
|
-
|
18
|
-
# Set up the crud_actions_to_test
|
19
|
-
crud_actions_to_test = if options[:only]
|
20
|
-
Array(options[:only]).flatten.compact.map(&:to_sym)
|
21
|
-
elsif options[:except]
|
22
|
-
(CRUD_ACTIONS - Array(options[:except]).flatten.compact.map(&:to_sym))
|
23
|
-
else
|
24
|
-
CRUD_ACTIONS
|
25
|
-
end
|
26
|
-
|
27
|
-
# Parse the resource and resourece class
|
28
|
-
resource = obj.kind_of?(Class) ? obj.new() : obj
|
29
|
-
resource_class = obj.kind_of?(Class) ? obj : obj.class
|
30
|
-
|
31
|
-
# If obj is an ActiveRecord object with attributes, Post.new(:title => 'My Title')
|
32
|
-
# then compute any explicit attributes, so forms will be filled with those values
|
33
|
-
resource_attributes = if obj.kind_of?(ActiveRecord::Base)
|
34
|
-
empty = resource_class.new()
|
35
|
-
{}.tap { |atts| resource.attributes.each { |k, v| atts[k] = v if empty.attributes[k] != v } }
|
36
|
-
end || {}
|
37
|
-
|
38
|
-
# Assign variables to be used in test/test_botable/crud_test.rb
|
39
|
-
let(:resource) { resource }
|
40
|
-
let(:resource_class) { resource_class }
|
41
|
-
let(:resource_name) { resource_class.name.underscore }
|
42
|
-
let(:resource_attributes) { resource_attributes }
|
43
|
-
let(:user) { user }
|
44
|
-
let(:controller_namespace) { options[:namespace] }
|
45
|
-
let(:crud_actions_to_test) { crud_actions_to_test }
|
46
|
-
|
47
|
-
include ::CrudTest
|
48
|
-
|
49
|
-
# This will run any CrudTest methods, in order, as it's defined in the file
|
50
|
-
# Then the rest of the methods in whatever order they occur originally (:random, :alpha, :sorted)
|
51
|
-
def self.runnable_methods
|
52
|
-
::CrudTest.public_instance_methods.map { |name| name.to_s if name.to_s.starts_with?('test_bot') }.compact + super.select { |name| !name.starts_with?('test_bot') }
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
end
|
57
|
-
end
|