active_scaffold 3.4.43 → 3.5.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.
Files changed (216) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +39 -0
  3. data/{LICENSE → LICENSE.md} +1 -1
  4. data/README.md +27 -19
  5. data/app/assets/javascripts/active_scaffold.js.erb +1 -1
  6. data/app/assets/javascripts/jquery/active_scaffold.js +95 -43
  7. data/app/assets/javascripts/jquery/tiny_mce_bridge.js +30 -6
  8. data/app/assets/javascripts/prototype/tiny_mce_bridge.js +11 -1
  9. data/app/assets/stylesheets/active_scaffold_colors.scss +2 -2
  10. data/app/assets/stylesheets/active_scaffold_layout.css +36 -28
  11. data/app/views/active_scaffold_overrides/_base_form.html.erb +2 -3
  12. data/app/views/active_scaffold_overrides/_field_search.html.erb +8 -7
  13. data/app/views/active_scaffold_overrides/_form_association.html.erb +9 -9
  14. data/app/views/active_scaffold_overrides/_form_association_footer.html.erb +6 -6
  15. data/app/views/active_scaffold_overrides/_form_association_record.html.erb +52 -50
  16. data/app/views/active_scaffold_overrides/_horizontal_subform.html.erb +1 -1
  17. data/app/views/active_scaffold_overrides/_horizontal_subform_header.html.erb +1 -1
  18. data/app/views/active_scaffold_overrides/_human_conditions.html.erb +3 -1
  19. data/app/views/active_scaffold_overrides/_list_calculations.html.erb +1 -1
  20. data/app/views/active_scaffold_overrides/_list_column_headings.html.erb +2 -0
  21. data/app/views/active_scaffold_overrides/_list_messages.html.erb +5 -3
  22. data/app/views/active_scaffold_overrides/_list_record.html.erb +3 -1
  23. data/app/views/active_scaffold_overrides/_list_with_header.html.erb +9 -9
  24. data/app/views/active_scaffold_overrides/_messages.html.erb +1 -1
  25. data/app/views/active_scaffold_overrides/_refresh_list.js.erb +18 -10
  26. data/app/views/active_scaffold_overrides/_render_field.js.erb +3 -3
  27. data/app/views/active_scaffold_overrides/_search.html.erb +7 -6
  28. data/app/views/active_scaffold_overrides/_show_actions.html.erb +14 -0
  29. data/app/views/active_scaffold_overrides/_show_association.html.erb +1 -1
  30. data/app/views/active_scaffold_overrides/_update_actions.html.erb +6 -2
  31. data/app/views/active_scaffold_overrides/_update_column.js.erb +1 -1
  32. data/app/views/active_scaffold_overrides/_update_form.html.erb +1 -1
  33. data/app/views/active_scaffold_overrides/destroy.js.erb +2 -3
  34. data/app/views/active_scaffold_overrides/edit_associated.js.erb +4 -3
  35. data/app/views/active_scaffold_overrides/on_action_update.js.erb +5 -3
  36. data/app/views/active_scaffold_overrides/on_create.js.erb +4 -4
  37. data/app/views/active_scaffold_overrides/on_update.js.erb +6 -6
  38. data/app/views/active_scaffold_overrides/show.html.erb +6 -0
  39. data/app/views/active_scaffold_overrides/update.html.erb +1 -1
  40. data/app/views/active_scaffold_overrides/update_column.js.erb +1 -1
  41. data/config/brakeman.ignore +26 -0
  42. data/config/brakeman.yml +3 -0
  43. data/config/i18n-tasks.yml +121 -0
  44. data/config/locales/de.yml +81 -70
  45. data/config/locales/en.yml +83 -74
  46. data/config/locales/es.yml +82 -73
  47. data/config/locales/fr.yml +86 -75
  48. data/config/locales/hu.yml +81 -70
  49. data/config/locales/ja.yml +71 -60
  50. data/config/locales/ru.yml +85 -74
  51. data/lib/active_scaffold.rb +3 -0
  52. data/lib/active_scaffold/actions/common_search.rb +11 -7
  53. data/lib/active_scaffold/actions/core.rb +119 -47
  54. data/lib/active_scaffold/actions/create.rb +1 -1
  55. data/lib/active_scaffold/actions/delete.rb +11 -8
  56. data/lib/active_scaffold/actions/field_search.rb +104 -6
  57. data/lib/active_scaffold/actions/list.rb +25 -21
  58. data/lib/active_scaffold/actions/mark.rb +12 -4
  59. data/lib/active_scaffold/actions/nested.rb +26 -26
  60. data/lib/active_scaffold/actions/search.rb +2 -2
  61. data/lib/active_scaffold/actions/show.rb +4 -5
  62. data/lib/active_scaffold/actions/subform.rb +9 -7
  63. data/lib/active_scaffold/actions/update.rb +20 -13
  64. data/lib/active_scaffold/active_record_permissions.rb +24 -5
  65. data/lib/active_scaffold/attribute_params.rb +68 -49
  66. data/lib/active_scaffold/bridges.rb +1 -1
  67. data/lib/active_scaffold/bridges/ancestry/ancestry_bridge.rb +15 -19
  68. data/lib/active_scaffold/bridges/bitfields.rb +1 -1
  69. data/lib/active_scaffold/bridges/bitfields/bitfields_bridge.rb +10 -14
  70. data/lib/active_scaffold/bridges/calendar_date_select.rb +0 -7
  71. data/lib/active_scaffold/bridges/calendar_date_select/as_cds_bridge.rb +19 -22
  72. data/lib/active_scaffold/bridges/cancan.rb +4 -3
  73. data/lib/active_scaffold/bridges/cancan/cancan_bridge.rb +11 -21
  74. data/lib/active_scaffold/bridges/carrierwave.rb +2 -1
  75. data/lib/active_scaffold/bridges/carrierwave/carrierwave_bridge.rb +2 -6
  76. data/lib/active_scaffold/bridges/carrierwave/form_ui.rb +6 -39
  77. data/lib/active_scaffold/bridges/carrierwave/list_ui.rb +1 -1
  78. data/lib/active_scaffold/bridges/chosen.rb +4 -1
  79. data/lib/active_scaffold/bridges/chosen/helpers.rb +3 -2
  80. data/lib/active_scaffold/bridges/country_select/country_select_bridge_helper.rb +2 -2
  81. data/lib/active_scaffold/bridges/date_picker.rb +3 -0
  82. data/lib/active_scaffold/bridges/date_picker/ext.rb +43 -38
  83. data/lib/active_scaffold/bridges/date_picker/helper.rb +24 -23
  84. data/lib/active_scaffold/bridges/dragonfly.rb +1 -1
  85. data/lib/active_scaffold/bridges/dragonfly/dragonfly_bridge.rb +3 -7
  86. data/lib/active_scaffold/bridges/dragonfly/form_ui.rb +3 -25
  87. data/lib/active_scaffold/bridges/dragonfly/list_ui.rb +2 -2
  88. data/lib/active_scaffold/bridges/file_column/as_file_column_bridge.rb +6 -8
  89. data/lib/active_scaffold/bridges/file_column/file_column_helpers.rb +1 -1
  90. data/lib/active_scaffold/bridges/file_column/form_ui.rb +0 -2
  91. data/lib/active_scaffold/bridges/file_column/list_ui.rb +2 -1
  92. data/lib/active_scaffold/bridges/file_column/test/test_helper.rb +1 -1
  93. data/lib/active_scaffold/bridges/paper_trail/actions.rb +1 -1
  94. data/lib/active_scaffold/bridges/paper_trail/helper.rb +1 -2
  95. data/lib/active_scaffold/bridges/paper_trail/paper_trail_bridge.rb +3 -7
  96. data/lib/active_scaffold/bridges/paperclip.rb +1 -1
  97. data/lib/active_scaffold/bridges/paperclip/form_ui.rb +3 -28
  98. data/lib/active_scaffold/bridges/paperclip/list_ui.rb +1 -1
  99. data/lib/active_scaffold/bridges/paperclip/paperclip_bridge.rb +3 -7
  100. data/lib/active_scaffold/bridges/record_select.rb +2 -0
  101. data/lib/active_scaffold/bridges/record_select/helpers.rb +14 -18
  102. data/lib/active_scaffold/bridges/semantic_attributes/column.rb +4 -8
  103. data/lib/active_scaffold/bridges/shared/date_bridge.rb +20 -20
  104. data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +7 -22
  105. data/lib/active_scaffold/bridges/usa_state_select/usa_state_select_helper.rb +14 -14
  106. data/lib/active_scaffold/config/base.rb +9 -6
  107. data/lib/active_scaffold/config/core.rb +30 -21
  108. data/lib/active_scaffold/config/create.rb +2 -1
  109. data/lib/active_scaffold/config/delete.rb +2 -2
  110. data/lib/active_scaffold/config/field_search.rb +9 -3
  111. data/lib/active_scaffold/config/form.rb +4 -4
  112. data/lib/active_scaffold/config/list.rb +27 -23
  113. data/lib/active_scaffold/config/nested.rb +4 -4
  114. data/lib/active_scaffold/config/search.rb +6 -6
  115. data/lib/active_scaffold/config/show.rb +11 -1
  116. data/lib/active_scaffold/config/subform.rb +1 -1
  117. data/lib/active_scaffold/config/update.rb +4 -2
  118. data/lib/active_scaffold/constraints.rb +39 -36
  119. data/lib/active_scaffold/core.rb +36 -15
  120. data/lib/active_scaffold/data_structures/action_columns.rb +14 -9
  121. data/lib/active_scaffold/data_structures/action_link.rb +4 -5
  122. data/lib/active_scaffold/data_structures/action_links.rb +5 -4
  123. data/lib/active_scaffold/data_structures/actions.rb +2 -2
  124. data/lib/active_scaffold/data_structures/association.rb +8 -0
  125. data/lib/active_scaffold/data_structures/association/abstract.rb +147 -0
  126. data/lib/active_scaffold/data_structures/association/active_mongoid.rb +42 -0
  127. data/lib/active_scaffold/data_structures/association/active_record.rb +94 -0
  128. data/lib/active_scaffold/data_structures/association/mongoid.rb +45 -0
  129. data/lib/active_scaffold/data_structures/bridge.rb +3 -6
  130. data/lib/active_scaffold/data_structures/column.rb +100 -82
  131. data/lib/active_scaffold/data_structures/columns.rb +21 -3
  132. data/lib/active_scaffold/data_structures/nested_info.rb +22 -37
  133. data/lib/active_scaffold/data_structures/set.rb +4 -4
  134. data/lib/active_scaffold/data_structures/sorting.rb +29 -15
  135. data/lib/active_scaffold/engine.rb +3 -1
  136. data/lib/active_scaffold/extensions/action_controller_rendering.rb +10 -5
  137. data/lib/active_scaffold/extensions/action_view_rendering.rb +65 -59
  138. data/lib/active_scaffold/extensions/left_outer_joins.rb +48 -53
  139. data/lib/active_scaffold/extensions/localize.rb +3 -4
  140. data/lib/active_scaffold/extensions/name_option_for_datetime.rb +7 -11
  141. data/lib/active_scaffold/extensions/paginator_extensions.rb +20 -18
  142. data/lib/active_scaffold/extensions/routing_mapper.rb +104 -40
  143. data/lib/active_scaffold/extensions/to_label.rb +1 -1
  144. data/lib/active_scaffold/extensions/unsaved_associated.rb +4 -13
  145. data/lib/active_scaffold/extensions/unsaved_record.rb +12 -1
  146. data/lib/active_scaffold/finder.rb +200 -134
  147. data/lib/active_scaffold/helpers/action_link_helpers.rb +398 -0
  148. data/lib/active_scaffold/helpers/association_helpers.rb +12 -30
  149. data/lib/active_scaffold/helpers/controller_helpers.rb +74 -24
  150. data/lib/active_scaffold/helpers/form_column_helpers.rb +205 -112
  151. data/lib/active_scaffold/helpers/human_condition_helpers.rb +21 -11
  152. data/lib/active_scaffold/helpers/id_helpers.rb +1 -1
  153. data/lib/active_scaffold/helpers/list_column_helpers.rb +117 -39
  154. data/lib/active_scaffold/helpers/pagination_helpers.rb +11 -14
  155. data/lib/active_scaffold/helpers/search_column_helpers.rb +69 -32
  156. data/lib/active_scaffold/helpers/show_column_helpers.rb +9 -3
  157. data/lib/active_scaffold/helpers/view_helpers.rb +41 -426
  158. data/lib/active_scaffold/orm_checks.rb +109 -0
  159. data/lib/active_scaffold/paginator.rb +1 -1
  160. data/lib/active_scaffold/responds_to_parent.rb +12 -10
  161. data/lib/active_scaffold/tableless.rb +81 -43
  162. data/lib/active_scaffold/version.rb +2 -2
  163. data/lib/generators/active_scaffold/controller_generator.rb +49 -0
  164. data/lib/generators/active_scaffold/install_generator.rb +45 -0
  165. data/lib/generators/active_scaffold/resource_generator.rb +56 -0
  166. data/lib/generators/{active_scaffold_controller/templates → templates}/controller.rb +0 -0
  167. data/lib/generators/{active_scaffold_controller/templates → templates}/helper.rb +0 -0
  168. data/shoulda_macros/macros.rb +3 -3
  169. data/test/active_scaffold_config_mock.rb +33 -0
  170. data/test/bridges/bridge_test.rb +9 -9
  171. data/test/bridges/date_picker_test.rb +3 -1
  172. data/test/bridges/paper_trail_test.rb +2 -3
  173. data/test/bridges/paperclip_test.rb +21 -10
  174. data/test/bridges/tiny_mce_test.rb +20 -21
  175. data/test/class_with_finder.rb +42 -0
  176. data/test/company.rb +6 -4
  177. data/test/config/core_test.rb +1 -1
  178. data/test/config/create_test.rb +1 -1
  179. data/test/config/list_test.rb +3 -3
  180. data/test/config/update_test.rb +3 -3
  181. data/test/data_structures/action_columns_test.rb +3 -3
  182. data/test/data_structures/association_column_test.rb +5 -5
  183. data/test/data_structures/column_test.rb +14 -14
  184. data/test/data_structures/columns_test.rb +2 -2
  185. data/test/data_structures/set_test.rb +2 -2
  186. data/test/data_structures/sorting_test.rb +6 -4
  187. data/test/extensions/active_record_test.rb +1 -1
  188. data/test/extensions/routing_mapper_test.rb +64 -13
  189. data/test/helpers/form_column_helpers_test.rb +6 -6
  190. data/test/helpers/list_column_helpers_test.rb +9 -5
  191. data/test/helpers/pagination_helpers_test.rb +1 -0
  192. data/test/misc/active_record_permissions_test.rb +18 -1
  193. data/test/misc/attribute_params_test.rb +26 -17
  194. data/test/misc/calculation_test.rb +8 -31
  195. data/test/misc/configurable_test.rb +3 -2
  196. data/test/misc/constraints_test.rb +33 -22
  197. data/test/misc/convert_numbers_format_test.rb +28 -10
  198. data/test/misc/finder_test.rb +6 -29
  199. data/test/misc/parse_datetime_test.rb +160 -0
  200. data/test/misc/render_test.rb +1 -1
  201. data/test/misc/tableless_test.rb +24 -0
  202. data/test/mock_app/app/models/building.rb +2 -1
  203. data/test/mock_app/config.ru +1 -1
  204. data/test/mock_app/config/environments/test.rb +1 -1
  205. data/test/mock_app/config/routes.rb +11 -3
  206. data/test/model_stub.rb +11 -6
  207. data/test/run_all.rb +1 -1
  208. data/test/test_helper.rb +19 -4
  209. metadata +42 -23
  210. data/lib/active_scaffold/data_structures/error_message.rb +0 -22
  211. data/lib/active_scaffold/extensions/reverse_associations.rb +0 -119
  212. data/lib/generators/active_scaffold/USAGE +0 -29
  213. data/lib/generators/active_scaffold/active_scaffold_generator.rb +0 -21
  214. data/lib/generators/active_scaffold_controller/USAGE +0 -19
  215. data/lib/generators/active_scaffold_controller/active_scaffold_controller_generator.rb +0 -29
  216. data/test/data_structures/error_message_test.rb +0 -25
@@ -1,27 +1,5 @@
1
1
  require 'test_helper'
2
-
3
- class ClassWithFinder
4
- include ActiveScaffold::Finder
5
- def conditions_for_collection; end
6
-
7
- def conditions_from_params; end
8
-
9
- def conditions_from_constraints; end
10
-
11
- def joins_for_collection; end
12
-
13
- def custom_finder_options
14
- {}
15
- end
16
-
17
- def beginning_of_chain
18
- active_scaffold_config.model
19
- end
20
-
21
- def conditional_get_support?; end
22
-
23
- def params; {}; end
24
- end
2
+ require 'class_with_finder'
25
3
 
26
4
  class CalculationTest < MiniTest::Test
27
5
  def setup
@@ -31,8 +9,7 @@ class CalculationTest < MiniTest::Test
31
9
  @buildings << Building.create
32
10
 
33
11
  @klass = ClassWithFinder.new
34
- @klass.stubs(:active_scaffold_config).returns(mock { stubs(:model).returns(Building) })
35
- @klass.stubs(:active_scaffold_session_storage).returns({})
12
+ @klass.active_scaffold_config.stubs(:model).returns(Building)
36
13
  end
37
14
 
38
15
  def teardown
@@ -42,20 +19,20 @@ class CalculationTest < MiniTest::Test
42
19
  def test_calculation_with_conditions
43
20
  @klass.expects(:conditions_for_collection).returns(['"buildings"."name" LIKE ? OR "people"."first_name" LIKE ?', '%foo%', '%foo%'])
44
21
  @klass.expects(:active_scaffold_references).returns([:owner])
45
- @klass.active_scaffold_config.expects(:list).returns(mock { stubs(:count_includes).returns(nil) })
22
+ @klass.active_scaffold_config.expects(:list).returns(mock.tap { |m| m.stubs(:count_includes).returns(nil) })
46
23
 
47
- column = mock { stubs(:field).returns('"buildings"."id"') }
48
- @klass.active_scaffold_config.expects(:columns).returns(mock { stubs(:"[]").returns(column) })
24
+ column = mock.tap { |m| m.stubs(:field).returns('"buildings"."id"') }
25
+ @klass.active_scaffold_config.expects(:columns).returns(mock.tap { |m| m.stubs(:"[]").returns(column) })
49
26
  query = @klass.send :calculate_query
50
27
  assert_equal 2, query.count
51
28
  end
52
29
 
53
30
  def test_calculation_without_conditions
54
31
  @klass.stubs(:active_scaffold_references).returns([:owner])
55
- @klass.active_scaffold_config.expects(:list).returns(mock { stubs(:count_includes).returns(nil) })
32
+ @klass.active_scaffold_config.expects(:list).returns(mock.tap { |m| m.stubs(:count_includes).returns(nil) })
56
33
 
57
- column = mock { stubs(:field).returns('"buildings"."id"') }
58
- @klass.active_scaffold_config.expects(:columns).returns(mock { stubs(:"[]").returns(column) })
34
+ column = mock.tap { |m| m.stubs(:field).returns('"buildings"."id"') }
35
+ @klass.active_scaffold_config.expects(:columns).returns(mock.tap { |m| m.stubs(:"[]").returns(column) })
59
36
  query = @klass.send :calculate_query
60
37
  assert_equal Building.count, query.count
61
38
  end
@@ -1,8 +1,9 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class ConfigurableClass
4
- FOO = 'bar'
4
+ FOO = 'bar'.freeze
5
5
  def foo; FOO end
6
+
6
7
  def self.foo; FOO end
7
8
  end
8
9
 
@@ -19,7 +20,7 @@ class ConfigurableTest < MiniTest::Test
19
20
  ## constants and methods for tests to check against
20
21
  ##
21
22
  def hello; 'world' end
22
- HELLO = 'world'
23
+ HELLO = 'world'.freeze
23
24
 
24
25
  def test_instance_configuration
25
26
  configurable_class = IncludedClass.new
@@ -4,7 +4,15 @@ module ModelStubs
4
4
  class ModelStub < ActiveRecord::Base
5
5
  self.abstract_class = true
6
6
  def self.columns; @columns ||= [ColumnMock.new('foo', '')] end
7
+
7
8
  def self.columns_hash; @hash ||= Hash[@columns.map { |c| [c.name, c] }] end
9
+
10
+ if respond_to? :type_for_attribute
11
+ def self.type_for_attribute(column_name)
12
+ defined?(ActiveModel::Type) ? ActiveModel::Type::String.new : super
13
+ end
14
+ end
15
+
8
16
  def self.table_name
9
17
  @table_name || to_s.split('::').last.underscore.pluralize
10
18
  end
@@ -83,7 +91,8 @@ end
83
91
 
84
92
  class ConstraintsTestObject
85
93
  # stub out what the mixin expects to find ...
86
- def self.before_filter(*); end
94
+ def self.before_action(*); end
95
+
87
96
  def self.helper_method(*); end
88
97
  attr_accessor :active_scaffold_preload
89
98
  attr_accessor :active_scaffold_references
@@ -106,6 +115,10 @@ class ConstraintsTestObject
106
115
  @active_scaffold_habtm_joins = []
107
116
  @params = {}
108
117
  end
118
+
119
+ def params_hash?(v)
120
+ v.is_a? Hash
121
+ end
109
122
  end
110
123
 
111
124
  class ConstraintsTest < MiniTest::Test
@@ -116,60 +129,58 @@ class ConstraintsTest < MiniTest::Test
116
129
  def test_constraint_conditions_for_default_associations
117
130
  @test_object.active_scaffold_config = config_for('user')
118
131
  # has_one (vs belongs_to)
119
- assert_constraint_condition({:subscription => 5}, [{'subscriptions.id' => 5}], 'find the user with subscription #5')
132
+ assert_constraint_condition({:subscription => 5}, [{'subscriptions' => {'id' => 5}}], 'find the user with subscription #5')
120
133
  # habtm (vs habtm)
121
- assert_constraint_condition({:roles => 4}, [{'roles.id' => 4}], 'find all users with role #4')
134
+ assert_constraint_condition({:roles => 4}, [{'roles' => {'id' => 4}}], 'find all users with role #4')
122
135
  # has_one (vs polymorphic)
123
- assert_constraint_condition({:address => 11}, [{'addresses.id' => 11}], 'find the user with address #11')
136
+ assert_constraint_condition({:address => 11}, [{'addresses' => {'id' => 11}}], 'find the user with address #11')
124
137
  # reverse of a has_many :through
125
- assert_constraint_condition({:subscription => {:service => 5}}, [{'services.id' => 5}], 'find all users subscribed to service #5')
138
+ assert_constraint_condition({:subscription => {:service => 5}}, [{'services' => {'id' => 5}}], 'find all users subscribed to service #5')
126
139
  assert(@test_object.active_scaffold_references.include?(:subscription => :service), 'multi-level association include')
127
140
 
128
141
  @test_object.active_scaffold_config = config_for('subscription')
129
142
  # belongs_to (vs has_one)
130
- assert_constraint_condition({:user => 2}, [{'subscriptions.user_id' => 2}], 'find the subscription for user #2')
143
+ assert_constraint_condition({:user => 2}, [{'subscriptions' => {'user_id' => 2}}], 'find the subscription for user #2')
131
144
  # belongs_to (vs has_many)
132
- assert_constraint_condition({:service => 1}, [{'subscriptions.service_id' => 1}], 'find all subscriptions for service #1')
145
+ assert_constraint_condition({:service => 1}, [{'subscriptions' => {'service_id' => 1}}], 'find all subscriptions for service #1')
133
146
 
134
147
  @test_object.active_scaffold_config = config_for('service')
135
148
  # has_many (vs belongs_to)
136
- assert_constraint_condition({:subscriptions => 10}, [{'subscriptions.id' => 10}], 'find the service with subscription #10')
149
+ assert_constraint_condition({:subscriptions => 10}, [{'subscriptions' => {'id' => 10}}], 'find the service with subscription #10')
137
150
  # has_many :through (through has_many)
138
- assert_constraint_condition({:users => 7}, [{'users.id' => 7}], 'find the service with user #7')
151
+ assert_constraint_condition({:users => 7}, [{'users' => {'id' => 7}}], 'find the service with user #7')
139
152
 
140
153
  @test_object.active_scaffold_config = config_for('address')
141
154
  # belongs_to :polymorphic => true
142
- @test_object.params[:parent_model] = 'ModelStubs::User'
143
- assert_constraint_condition({:addressable => 14}, [{'addresses.addressable_id' => 14, 'addresses.addressable_type' => 'ModelStubs::User'}], 'find all addresses for user #14')
155
+ assert_constraint_condition({:addressable => ['ModelStubs::User', 14]}, [{'addresses' => {'addressable_id' => 14, 'addressable_type' => 'ModelStubs::User'}}], 'find all addresses for user #14')
144
156
  end
145
157
 
146
158
  def test_constraint_conditions_for_configured_associations
147
159
  @test_object.active_scaffold_config = config_for('other_user')
148
160
  # has_one (vs belongs_to)
149
- assert_constraint_condition({:other_subscription => 5}, [{'subscriptions.id' => 5}], 'find the user with subscription #5')
161
+ assert_constraint_condition({:other_subscription => 5}, [{'subscriptions' => {'id' => 5}}], 'find the user with subscription #5')
150
162
  # habtm (vs habtm)
151
- assert_constraint_condition({:other_roles => 4}, [{'roles.id' => 4}], 'find all users with role #4')
163
+ assert_constraint_condition({:other_roles => 4}, [{'roles' => {'id' => 4}}], 'find all users with role #4')
152
164
  # has_one (vs polymorphic)
153
- assert_constraint_condition({:other_address => 11}, [{'addresses.id' => 11}], 'find the user with address #11')
165
+ assert_constraint_condition({:other_address => 11}, [{'addresses' => {'id' => 11}}], 'find the user with address #11')
154
166
  # reverse of a has_many :through
155
- assert_constraint_condition({:other_subscription => {:other_service => 5}}, [{'services.id' => 5}], 'find all users subscribed to service #5')
167
+ assert_constraint_condition({:other_subscription => {:other_service => 5}}, [{'services' => {'id' => 5}}], 'find all users subscribed to service #5')
156
168
 
157
169
  @test_object.active_scaffold_config = config_for('other_subscription')
158
170
  # belongs_to (vs has_one)
159
- assert_constraint_condition({:other_user => 2}, [{'subscriptions.user_id' => 2}], 'find the subscription for user #2')
171
+ assert_constraint_condition({:other_user => 2}, [{'subscriptions' => {'user_id' => 2}}], 'find the subscription for user #2')
160
172
  # belongs_to (vs has_many)
161
- assert_constraint_condition({:other_service => 1}, [{'subscriptions.service_id' => 1}], 'find all subscriptions for service #1')
173
+ assert_constraint_condition({:other_service => 1}, [{'subscriptions' => {'service_id' => 1}}], 'find all subscriptions for service #1')
162
174
 
163
175
  @test_object.active_scaffold_config = config_for('other_service')
164
176
  # has_many (vs belongs_to)
165
- assert_constraint_condition({:other_subscriptions => 10}, [{'subscriptions.id' => 10}], 'find the service with subscription #10')
177
+ assert_constraint_condition({:other_subscriptions => 10}, [{'subscriptions' => {'id' => 10}}], 'find the service with subscription #10')
166
178
  # has_many :through (through has_many)
167
- assert_constraint_condition({:other_users => 7}, [{'users.id' => 7}], 'find the service with user #7')
179
+ assert_constraint_condition({:other_users => 7}, [{'users' => {'id' => 7}}], 'find the service with user #7')
168
180
 
169
181
  @test_object.active_scaffold_config = config_for('other_address')
170
182
  # belongs_to :polymorphic => true
171
- @test_object.params[:parent_model] = 'ModelStubs::OtherUser'
172
- assert_constraint_condition({:other_addressable => 14}, [{'addresses.other_addressable_id' => 14, 'addresses.other_addressable_type' => 'ModelStubs::OtherUser'}], 'find all addresses for user #14')
183
+ assert_constraint_condition({:other_addressable => ['ModelStubs::OtherUser', 14]}, [{'addresses' => {'other_addressable_id' => 14, 'other_addressable_type' => 'ModelStubs::OtherUser'}}], 'find all addresses for user #14')
173
184
  end
174
185
 
175
186
  def test_constraint_conditions_for_normal_attributes
@@ -181,7 +192,7 @@ class ConstraintsTest < MiniTest::Test
181
192
  @test_object.active_scaffold_config = config_for('primary_key_location')
182
193
  # user = ModelStubs::PrimaryKeyUser.new(:id => 1, :name => 'User Name')
183
194
  ModelStubs::PrimaryKeyUser.expects(:find).with(1).returns(stub(:id => 1, :name => 'User Name'))
184
- assert_constraint_condition({'user' => 1}, [{'primary_key_locations.username' => 'User Name'}], 'association with primary-key constraint')
195
+ assert_constraint_condition({'user' => 1}, [{'primary_key_locations' => {'username' => 'User Name'}}], 'association with primary-key constraint')
185
196
  end
186
197
 
187
198
  protected
@@ -1,20 +1,34 @@
1
1
  require 'test_helper'
2
+ require 'active_scaffold_config_mock'
2
3
 
3
4
  class NumberModel < ActiveRecord::Base
4
5
  include ActiveScaffold::ActiveRecordPermissions::ModelUserAccess::Model
5
6
  def self.columns
6
7
  @columns ||= [ColumnMock.new('id', '', 'int(11)'), ColumnMock.new('number', '', 'double(10,2)')]
7
8
  end
9
+
8
10
  def self.columns_hash
9
- @hash ||= Hash[@columns.map { |c| [c.name, c] }]
11
+ @columns_hash ||= Hash[columns.map { |c| [c.name, c] }]
12
+ end
13
+
14
+ def self.load_schema!
15
+ columns_hash.each do |name, column|
16
+ define_attribute(
17
+ name,
18
+ connection.lookup_cast_type_from_column(column),
19
+ default: column.default
20
+ )
21
+ end
10
22
  end
11
23
  end
12
24
 
13
25
  class ConvertNumbersFormatTest < MiniTest::Test
26
+ include ActiveScaffoldConfigMock
14
27
  include ActiveScaffold::AttributeParams
15
28
  include ActiveScaffold::Finder
16
29
 
17
30
  def setup
31
+ NumberModel.load_schema! if Rails.version >= '5.0'
18
32
  I18n.backend.store_translations :en, :number => {:format => {
19
33
  :delimiter => ',',
20
34
  :separator => '.'
@@ -46,7 +60,7 @@ class ConvertNumbersFormatTest < MiniTest::Test
46
60
  assert_equal 0.1, convert_number('0.1')
47
61
  assert_equal 0.345, convert_number('0.345')
48
62
  assert_equal 0.345, convert_number('+0.345')
49
- assert_equal -0.345, convert_number('-0.345')
63
+ assert_equal(-0.345, convert_number('-0.345'))
50
64
  assert_equal 9.345, convert_number('9.345')
51
65
  assert_equal 9.1, convert_number('9.1')
52
66
  assert_equal 90.1, convert_number('90.1')
@@ -56,7 +70,7 @@ class ConvertNumbersFormatTest < MiniTest::Test
56
70
  I18n.locale = :en
57
71
  assert_equal 1000, convert_number('1,000')
58
72
  assert_equal 1000, convert_number('+1,000')
59
- assert_equal -1000, convert_number('-1,000')
73
+ assert_equal(-1000, convert_number('-1,000'))
60
74
  assert_equal 1_000_000, convert_number('1,000,000')
61
75
  end
62
76
 
@@ -65,7 +79,7 @@ class ConvertNumbersFormatTest < MiniTest::Test
65
79
  assert_equal 1234.1, convert_number('1,234.1')
66
80
  assert_equal 1234.1, convert_number('1,234.100')
67
81
  assert_equal 1234.345, convert_number('+1,234.345')
68
- assert_equal -1234.345, convert_number('-1,234.345')
82
+ assert_equal(-1234.345, convert_number('-1,234.345'))
69
83
  assert_equal 1_234_000.1, convert_number('1,234,000.100')
70
84
  end
71
85
 
@@ -74,7 +88,7 @@ class ConvertNumbersFormatTest < MiniTest::Test
74
88
  assert_equal 0.1, convert_number('.1')
75
89
  assert_equal 0.1, convert_number('0.1')
76
90
  assert_equal 0.12, convert_number('+0.12')
77
- assert_equal -0.12, convert_number('-0.12')
91
+ assert_equal(-0.12, convert_number('-0.12'))
78
92
  assert_equal 9.1, convert_number('9.1')
79
93
  assert_equal 90.1, convert_number('90.1')
80
94
  end
@@ -86,7 +100,7 @@ class ConvertNumbersFormatTest < MiniTest::Test
86
100
  assert_equal 0.1, convert_number('0,1')
87
101
  assert_equal 0.345, convert_number('0,345')
88
102
  assert_equal 0.345, convert_number('+0,345')
89
- assert_equal -0.345, convert_number('-0,345')
103
+ assert_equal(-0.345, convert_number('-0,345'))
90
104
  assert_equal 9.1, convert_number('9,1')
91
105
  assert_equal 90.1, convert_number('90,1')
92
106
  assert_equal 9.1, convert_number('9,100')
@@ -96,7 +110,7 @@ class ConvertNumbersFormatTest < MiniTest::Test
96
110
  I18n.locale = :es
97
111
  assert_equal 1000, convert_number('1.000')
98
112
  assert_equal 1000, convert_number('+1.000')
99
- assert_equal -1000, convert_number('-1.000')
113
+ assert_equal(-1000, convert_number('-1.000'))
100
114
  assert_equal 1_000_000, convert_number('1.000.000')
101
115
  end
102
116
 
@@ -105,7 +119,7 @@ class ConvertNumbersFormatTest < MiniTest::Test
105
119
  assert_equal 1230.1, convert_number('1.230,1')
106
120
  assert_equal 1230.1, convert_number('1.230,100')
107
121
  assert_equal 1234.345, convert_number('+1.234,345')
108
- assert_equal -1234.345, convert_number('-1.234,345')
122
+ assert_equal(-1234.345, convert_number('-1.234,345'))
109
123
  assert_equal 1_234_000.1, convert_number('1.234.000,100')
110
124
  end
111
125
 
@@ -114,7 +128,7 @@ class ConvertNumbersFormatTest < MiniTest::Test
114
128
  assert_equal 0.1, convert_number('.1', :currency)
115
129
  assert_equal 0.1, convert_number('0.1', :currency)
116
130
  assert_equal 0.12, convert_number('+0.12', :currency)
117
- assert_equal -0.12, convert_number('-0.12', :currency)
131
+ assert_equal(-0.12, convert_number('-0.12', :currency))
118
132
  assert_equal 9.1, convert_number('9.1', :currency)
119
133
  assert_equal 90.1, convert_number('90.1', :currency)
120
134
  end
@@ -126,7 +140,7 @@ class ConvertNumbersFormatTest < MiniTest::Test
126
140
  assert_equal 0.1, convert_number('0,1', :currency)
127
141
  assert_equal 0.345, convert_number('0,345', :currency)
128
142
  assert_equal 0.345, convert_number('+0,345', :currency)
129
- assert_equal -0.345, convert_number('-0,345', :currency)
143
+ assert_equal(-0.345, convert_number('-0,345', :currency))
130
144
  assert_equal 9.1, convert_number('9,1', :currency)
131
145
  assert_equal 90.1, convert_number('90,1', :currency)
132
146
  assert_equal 9.1, convert_number('9,100', :currency)
@@ -146,4 +160,8 @@ class ConvertNumbersFormatTest < MiniTest::Test
146
160
  update_record_from_params(record, @config.create.columns, HashWithIndifferentAccess.new(:number => value))
147
161
  record.number
148
162
  end
163
+
164
+ def params_hash?(v)
165
+ v.is_a? Hash
166
+ end
149
167
  end
@@ -1,33 +1,10 @@
1
1
  require 'test_helper'
2
-
3
- class ClassWithFinder
4
- include ActiveScaffold::Finder
5
- def conditions_for_collection; end
6
-
7
- def conditions_from_params; end
8
-
9
- def conditions_from_constraints; end
10
-
11
- def joins_for_collection; end
12
-
13
- def custom_finder_options
14
- {}
15
- end
16
-
17
- def beginning_of_chain
18
- active_scaffold_config.model
19
- end
20
-
21
- def conditional_get_support?; end
22
-
23
- def params; {}; end
24
- end
2
+ require 'class_with_finder'
25
3
 
26
4
  class FinderTest < MiniTest::Test
27
5
  def setup
28
6
  @klass = ClassWithFinder.new
29
- @klass.stubs(:active_scaffold_config).returns(mock { stubs(:model).returns(ModelStub) })
30
- @klass.stubs(:active_scaffold_session_storage).returns({})
7
+ @klass.active_scaffold_config.stubs(model: ModelStub)
31
8
  end
32
9
 
33
10
  def test_create_conditions_for_columns
@@ -35,21 +12,21 @@ class FinderTest < MiniTest::Test
35
12
  ActiveScaffold::DataStructures::Column.new(:a, ModelStub),
36
13
  ActiveScaffold::DataStructures::Column.new(:b, ModelStub)
37
14
  ]
38
- tokens = %w(foo bar)
15
+ tokens = %w[foo bar]
39
16
 
40
17
  expected_conditions = [
41
18
  ['"model_stubs"."a" LIKE ? OR "model_stubs"."b" LIKE ?', '%foo%', '%foo%'],
42
19
  ['"model_stubs"."a" LIKE ? OR "model_stubs"."b" LIKE ?', '%bar%', '%bar%']
43
20
  ]
44
- assert_equal expected_conditions, ClassWithFinder.create_conditions_for_columns(tokens, columns)
21
+ assert_equal expected_conditions, ClassWithFinder.conditions_for_columns(tokens, columns)
45
22
 
46
23
  expected_conditions = [
47
24
  '"model_stubs"."a" LIKE ? OR "model_stubs"."b" LIKE ?',
48
25
  '%foo%', '%foo%'
49
26
  ]
50
- assert_equal [expected_conditions], ClassWithFinder.create_conditions_for_columns('foo', columns)
27
+ assert_equal [expected_conditions], ClassWithFinder.conditions_for_columns('foo', columns)
51
28
 
52
- assert_equal nil, ClassWithFinder.create_conditions_for_columns('foo', [])
29
+ assert_nil ClassWithFinder.conditions_for_columns('foo', [])
53
30
  end
54
31
 
55
32
  def test_method_sorting
@@ -0,0 +1,160 @@
1
+ require 'test_helper'
2
+ require 'active_scaffold_config_mock'
3
+
4
+ class DateTimeModel < ActiveRecord::Base
5
+ include ActiveScaffold::ActiveRecordPermissions::ModelUserAccess::Model
6
+ def self.columns
7
+ @columns ||= [ColumnMock.new('id', '', 'int(11)'), ColumnMock.new('run_at', '', 'datetime')]
8
+ end
9
+
10
+ def self.columns_hash
11
+ @columns_hash ||= Hash[columns.map { |c| [c.name, c] }]
12
+ end
13
+
14
+ def self.load_schema!
15
+ columns_hash.each do |name, column|
16
+ define_attribute(
17
+ name,
18
+ connection.lookup_cast_type_from_column(column),
19
+ default: column.default
20
+ )
21
+ end
22
+ end
23
+ end
24
+
25
+ class ParseDatetimeTest < MiniTest::Test
26
+ include ActiveScaffoldConfigMock
27
+ include ActiveScaffold::AttributeParams
28
+ include ActiveScaffold::Finder
29
+
30
+ def setup
31
+ DateTimeModel.load_schema! if Rails.version >= '5.0'
32
+ spanish = {
33
+ time: {
34
+ formats: {picker: '%a, %d %b %Y %H:%M:%S'}
35
+ },
36
+ date: {
37
+ day_names: %w[Domingo Lunes Martes Miércoles Jueves Viernes Sábado],
38
+ abbr_day_names: %w[Dom Lun Mar Mié Jue Vie Sáb],
39
+ month_names: [nil, 'Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'],
40
+ abbr_month_names: [nil, 'Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'],
41
+ formats: {default: '%Y-%m-%d', long: '%d de %B de %Y'}
42
+ }
43
+ }
44
+ I18n.backend.store_translations :es, spanish
45
+
46
+ @config = config_for('date_time_model')
47
+ @config.create.columns.set_columns @config.columns
48
+ end
49
+
50
+ def teardown
51
+ I18n.locale = :en
52
+ end
53
+
54
+ def test_translate_to_english
55
+ I18n.locale = :es
56
+ assert_equal 'Mon, 03 Apr 2017 16:30:26', translate_datetime('Lun, 03 Abr 2017 16:30:26')
57
+ assert_equal 'Fri, 24 Mar 2017 16:30:26', translate_datetime('Vie, 24 Mar 2017 16:30:26')
58
+ assert_equal 'Tue, 28 Mar 2017 16:30:26', translate_datetime('Mar, 28 Mar 2017 16:30:26')
59
+ end
60
+
61
+ def test_translate_to_english_with_different_order
62
+ I18n.locale = :es
63
+ format = '%d %b %Y, %a, %H:%M:%S'
64
+ assert_equal '03 Apr 2017, Mon, 16:30:26', translate_datetime('03 Abr 2017, Lun, 16:30:26', format)
65
+ assert_equal '24 Mar 2017, Fri, 16:30:26', translate_datetime('24 Mar 2017, Vie, 16:30:26', format)
66
+ assert_equal '28 Mar 2017, Tue, 16:30:26', translate_datetime('28 Mar 2017, Mar, 16:30:26', format)
67
+ end
68
+
69
+ def test_translate_to_english_with_words
70
+ I18n.locale = :es
71
+ format = '%A, %d de %B %Y, %H:%M:%S'
72
+ assert_equal 'Monday, 03 de April de 2017, 16:30:26', translate_datetime('Lunes, 03 de Abril de 2017, 16:30:26', format)
73
+ assert_equal 'Friday, 24 de March de 2017, 16:30:26', translate_datetime('Viernes, 24 de Marzo de 2017, 16:30:26', format)
74
+ assert_equal 'Tuesday, 28 de March de 2017, 16:30:26', translate_datetime('Martes, 28 de Marzo de 2017, 16:30:26', format)
75
+ end
76
+
77
+ def test_condition_for_spanish_datetime
78
+ with_js_framework :jquery do
79
+ I18n.locale = :es
80
+ assert_equal Time.zone.local(2017, 4, 3, 16, 30, 26), condition_value('Lun, 03 Abr 2017 16:30:26')
81
+ assert_equal Time.zone.local(2017, 3, 24, 16, 30, 26), condition_value('Vie, 24 Mar 2017 16:30:26')
82
+ assert_equal Time.zone.local(2017, 3, 28, 16, 30, 26), condition_value('Mar, 28 Mar 2017 16:30:26')
83
+ end
84
+ end
85
+
86
+ def test_condition_for_english_datetime
87
+ with_js_framework :jquery do
88
+ assert_equal Time.zone.local(2017, 4, 3, 16, 30, 26), condition_value('Mon, 03 Apr 2017 16:30:26')
89
+ assert_equal Time.zone.local(2017, 3, 24, 16, 30, 26), condition_value('Fri, 24 Mar 2017 16:30:26')
90
+ assert_equal Time.zone.local(2017, 3, 28, 16, 30, 26), condition_value('Tue, 28 Mar 2017 16:30:26')
91
+ end
92
+ end
93
+
94
+ def test_condition_for_english_datetime_without_time
95
+ with_js_framework :jquery do
96
+ assert_equal Time.zone.local(2017, 4, 3, 0, 0, 0), condition_value('Mon, 03 Apr 2017')
97
+ assert_equal Time.zone.local(2017, 3, 24, 0, 0, 0), condition_value('Fri, 24 Mar 2017')
98
+ assert_equal Time.zone.local(2017, 3, 28, 0, 0, 0), condition_value('Tue, 28 Mar 2017')
99
+ end
100
+ end
101
+
102
+ def test_condition_for_default_datetime_without_time
103
+ assert_equal Time.zone.local(2017, 4, 3, 0, 0, 0), condition_value('2017-04-03')
104
+ assert_equal Time.zone.local(2017, 3, 24, 0, 0, 0), condition_value('2017-03-24')
105
+ assert_equal Time.zone.local(2017, 3, 28, 0, 0, 0), condition_value('2017-03-28')
106
+ end
107
+
108
+ def test_condition_for_english_datetime_without_seconds
109
+ with_js_framework :jquery do
110
+ assert_equal Time.zone.local(2017, 4, 3, 16, 30), condition_value('Mon, 03 Apr 2017 16:30')
111
+ assert_equal Time.zone.local(2017, 3, 24, 16, 30), condition_value('Fri, 24 Mar 2017 16:30')
112
+ assert_equal Time.zone.local(2017, 3, 28, 16, 30), condition_value('Tue, 28 Mar 2017 16:30')
113
+ end
114
+ end
115
+
116
+ def test_condition_for_default_datetime_without_seconds
117
+ assert_equal Time.zone.local(2017, 4, 3, 16, 30, 0), condition_value('2017-04-03 16:30')
118
+ assert_equal Time.zone.local(2017, 3, 24, 16, 30, 0), condition_value('2017-03-24 16:30')
119
+ assert_equal Time.zone.local(2017, 3, 28, 16, 30, 0), condition_value('2017-03-28 16:30')
120
+ end
121
+
122
+ def test_condition_for_time
123
+ assert_equal Time.current.change(hour: 16, min: 30), condition_value('16:30')
124
+ assert_equal Time.current.change(hour: 16, min: 30, sec: 26), condition_value('16:30:26')
125
+ end
126
+
127
+ def test_condition_for_datetime_with_zone
128
+ assert_equal DateTime.new(2017, 4, 8, 16, 30, 0, '+0300'), condition_value('2017-04-08 16:30 +0300')
129
+ end
130
+
131
+ def test_condition_for_spanish_date
132
+ @config.columns[:run_at].options[:format] = :long
133
+ I18n.locale = :es
134
+ assert_equal Date.new(2017, 4, 3), condition_value('03 de Abril de 2017', :to_date)
135
+ assert_equal Date.new(2017, 3, 24), condition_value('24 de Marzo de 2017', :to_date)
136
+ assert_equal Date.new(2017, 3, 28), condition_value('28 de Marzo de 2017', :to_date)
137
+ end
138
+
139
+ def test_condition_for_english_date
140
+ @config.columns[:run_at].options[:format] = :long
141
+ assert_equal Date.new(2017, 4, 3), condition_value('April 03, 2017', :to_date)
142
+ assert_equal Date.new(2017, 3, 24), condition_value('March 24, 2017', :to_date)
143
+ assert_equal Date.new(2017, 3, 28), condition_value('March 28, 2017', :to_date)
144
+ end
145
+
146
+ private
147
+
148
+ def translate_datetime(value, format = nil)
149
+ format ||= I18n.t('time.formats.picker')
150
+ self.class.translate_days_and_months(value, format)
151
+ end
152
+
153
+ def condition_value(value, conversion = nil)
154
+ self.class.condition_value_for_datetime(@config.columns[:run_at], value, conversion || :to_time)
155
+ end
156
+
157
+ def params_hash?(v)
158
+ v.is_a? Hash
159
+ end
160
+ end