effective_test_bot 0.2.3 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|