activeadmin 1.0.0.pre4 → 1.0.0.pre5

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activeadmin might be problematic. Click here for more details.

Files changed (277) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -3
  3. data/.travis.yml +48 -26
  4. data/Appraisals +103 -0
  5. data/CHANGELOG.md +12 -1
  6. data/CONTRIBUTING.md +85 -32
  7. data/Gemfile +13 -38
  8. data/README.md +10 -26
  9. data/Rakefile +41 -9
  10. data/activeadmin.gemspec +7 -4
  11. data/app/assets/javascripts/active_admin/initializers/filters.js.coffee +10 -3
  12. data/app/assets/javascripts/active_admin/jquery_ui.js.erb +11 -4
  13. data/app/assets/javascripts/active_admin/lib/checkbox-toggler.js.coffee +8 -0
  14. data/app/assets/javascripts/active_admin/lib/modal_dialog.js.coffee +1 -1
  15. data/app/assets/javascripts/active_admin/lib/per_page.js.coffee +14 -3
  16. data/app/assets/stylesheets/active_admin/_forms.scss +1 -0
  17. data/app/views/active_admin/devise/registrations/new.html.erb +1 -1
  18. data/codecov.yml +23 -0
  19. data/config/locales/es-MX.yml +1 -1
  20. data/config/locales/es.yml +1 -1
  21. data/config/locales/ru.yml +1 -0
  22. data/config/locales/sk.yml +110 -0
  23. data/docs/0-installation.md +3 -0
  24. data/docs/1-general-configuration.md +11 -0
  25. data/docs/10-custom-pages.md +25 -0
  26. data/docs/11-decorators.md +3 -0
  27. data/docs/12-arbre-components.md +3 -0
  28. data/docs/13-authorization-adapter.md +3 -0
  29. data/docs/14-gotchas.md +19 -0
  30. data/docs/2-resource-customization.md +21 -2
  31. data/docs/3-index-pages.md +21 -0
  32. data/docs/3-index-pages/custom-index.md +3 -0
  33. data/docs/3-index-pages/index-as-block.md +3 -0
  34. data/docs/3-index-pages/index-as-blog.md +3 -0
  35. data/docs/3-index-pages/index-as-grid.md +3 -0
  36. data/docs/3-index-pages/index-as-table.md +22 -0
  37. data/docs/4-csv-format.md +15 -0
  38. data/docs/5-forms.md +7 -3
  39. data/docs/6-show-pages.md +3 -0
  40. data/docs/7-sidebars.md +3 -0
  41. data/docs/8-custom-actions.md +3 -0
  42. data/docs/9-batch-actions.md +4 -1
  43. data/docs/CNAME +1 -0
  44. data/docs/Gemfile +2 -0
  45. data/docs/_config.yml +2 -0
  46. data/docs/_includes/footer.html +8 -0
  47. data/docs/_includes/google-analytics.html +16 -0
  48. data/docs/_includes/head.html +7 -0
  49. data/docs/_includes/toc.html +97 -0
  50. data/docs/_includes/top-menu.html +9 -0
  51. data/docs/_layouts/default.html +21 -0
  52. data/docs/documentation.md +62 -0
  53. data/docs/images/activeadmin.png +0 -0
  54. data/docs/images/code-header.png +0 -0
  55. data/docs/images/divider.png +0 -0
  56. data/docs/images/features.png +0 -0
  57. data/docs/index.html +130 -0
  58. data/docs/stylesheets/main.css +1199 -0
  59. data/features/action_item.feature +2 -2
  60. data/features/authorization_cancan.feature +3 -3
  61. data/features/belongs_to.feature +60 -2
  62. data/features/comments/commenting.feature +7 -7
  63. data/features/development_reloading.feature +1 -1
  64. data/features/edit_page.feature +9 -9
  65. data/features/footer.feature +28 -0
  66. data/features/i18n.feature +11 -0
  67. data/features/index/batch_actions.feature +28 -6
  68. data/features/index/filters.feature +31 -11
  69. data/features/index/format_as_csv.feature +13 -13
  70. data/features/index/formats.feature +4 -4
  71. data/features/index/index_as_block.feature +1 -1
  72. data/features/index/index_as_blog.feature +6 -6
  73. data/features/index/index_as_grid.feature +3 -3
  74. data/features/index/index_as_table.feature +11 -11
  75. data/features/index/index_blank_slate.feature +4 -4
  76. data/features/index/index_parameters.feature +10 -10
  77. data/features/index/index_scope_to.feature +3 -3
  78. data/features/index/index_scopes.feature +37 -18
  79. data/features/index/page_title.feature +3 -3
  80. data/features/index/pagination.feature +1 -1
  81. data/features/index/switch_index_view.feature +8 -8
  82. data/features/menu.feature +3 -3
  83. data/features/new_page.feature +8 -8
  84. data/features/registering_assets.feature +1 -1
  85. data/features/registering_pages.feature +73 -2
  86. data/features/registering_resources.feature +1 -1
  87. data/features/renamed_resource.feature +1 -1
  88. data/features/show/page_title.feature +3 -3
  89. data/features/sidebar_sections.feature +6 -6
  90. data/features/specifying_actions.feature +29 -4
  91. data/features/step_definitions/factory_steps.rb +1 -1
  92. data/features/step_definitions/footer_steps.rb +11 -0
  93. data/features/step_definitions/i18n_steps.rb +8 -0
  94. data/features/step_definitions/index_scope_steps.rb +4 -0
  95. data/features/step_definitions/sidebar_steps.rb +1 -3
  96. data/features/step_definitions/table_steps.rb +1 -5
  97. data/features/step_definitions/user_steps.rb +7 -0
  98. data/features/support/env.rb +6 -33
  99. data/features/support/paths.rb +5 -0
  100. data/features/users/logging_in.feature +2 -0
  101. data/gemfiles/rails_32.gemfile +54 -0
  102. data/gemfiles/rails_40.gemfile +53 -0
  103. data/gemfiles/rails_41.gemfile +53 -0
  104. data/gemfiles/rails_42.gemfile +53 -0
  105. data/gemfiles/rails_50.gemfile +46 -0
  106. data/lib/active_admin.rb +1 -0
  107. data/lib/active_admin/application.rb +11 -0
  108. data/lib/active_admin/batch_actions/resource_extension.rb +0 -8
  109. data/lib/active_admin/batch_actions/views/batch_action_form.rb +1 -1
  110. data/lib/active_admin/batch_actions/views/batch_action_selector.rb +1 -1
  111. data/lib/active_admin/dsl.rb +0 -6
  112. data/lib/active_admin/filters/active.rb +9 -1
  113. data/lib/active_admin/filters/formtastic_addons.rb +1 -1
  114. data/lib/active_admin/filters/humanized.rb +1 -1
  115. data/lib/active_admin/filters/resource_extension.rb +2 -4
  116. data/lib/active_admin/form_builder.rb +12 -6
  117. data/lib/active_admin/helpers/collection.rb +2 -0
  118. data/lib/active_admin/inputs.rb +1 -0
  119. data/lib/active_admin/inputs/filters/date_range_input.rb +9 -4
  120. data/lib/active_admin/inputs/filters/text_input.rb +26 -0
  121. data/lib/active_admin/localizers.rb +11 -0
  122. data/lib/active_admin/localizers/resource_localizer.rb +35 -0
  123. data/lib/active_admin/namespace.rb +1 -1
  124. data/lib/active_admin/order_clause.rb +29 -7
  125. data/lib/active_admin/page.rb +18 -4
  126. data/lib/active_admin/page_dsl.rb +4 -0
  127. data/lib/active_admin/resource.rb +16 -1
  128. data/lib/active_admin/resource/action_items.rb +7 -4
  129. data/lib/active_admin/resource/belongs_to.rb +4 -0
  130. data/lib/active_admin/resource/menu.rb +1 -1
  131. data/lib/active_admin/resource/ordering.rb +11 -0
  132. data/lib/active_admin/resource/routes.rb +34 -13
  133. data/lib/active_admin/resource/scopes.rb +1 -0
  134. data/lib/active_admin/resource_controller/data_access.rb +3 -10
  135. data/lib/active_admin/resource_dsl.rb +28 -1
  136. data/lib/active_admin/router.rb +5 -3
  137. data/lib/active_admin/scope.rb +3 -3
  138. data/lib/active_admin/version.rb +1 -1
  139. data/lib/active_admin/view_helpers/auto_link_helper.rb +2 -2
  140. data/lib/active_admin/view_helpers/display_helper.rb +8 -3
  141. data/lib/active_admin/view_helpers/method_or_proc_helper.rb +5 -1
  142. data/lib/active_admin/views/components/active_admin_form.rb +11 -10
  143. data/lib/active_admin/views/components/attributes_table.rb +1 -1
  144. data/lib/active_admin/views/components/columns.rb +3 -3
  145. data/lib/active_admin/views/components/dropdown_menu.rb +2 -2
  146. data/lib/active_admin/views/components/index_list.rb +4 -1
  147. data/lib/active_admin/views/components/paginated_collection.rb +1 -0
  148. data/lib/active_admin/views/components/scopes.rb +8 -1
  149. data/lib/active_admin/views/components/site_title.rb +2 -2
  150. data/lib/active_admin/views/components/table_for.rb +3 -3
  151. data/lib/active_admin/views/footer.rb +17 -3
  152. data/lib/active_admin/views/index_as_table.rb +3 -3
  153. data/lib/active_admin/views/pages/base.rb +4 -2
  154. data/lib/active_admin/views/pages/form.rb +2 -3
  155. data/lib/active_admin/views/pages/show.rb +2 -1
  156. data/lib/bug_report_templates/rails_5_master.rb +120 -0
  157. data/lib/generators/active_admin/devise/devise_generator.rb +6 -3
  158. data/lib/generators/active_admin/install/install_generator.rb +1 -1
  159. data/lib/generators/active_admin/install/templates/active_admin.rb.erb +15 -1
  160. data/lib/generators/active_admin/install/templates/migrations/{create_active_admin_comments.rb → create_active_admin_comments.rb.erb} +14 -1
  161. data/lib/ransack_ext.rb +2 -2
  162. data/spec/bug_report_templates_spec.rb +27 -0
  163. data/spec/javascripts/support/jasmine_runner.rb +4 -17
  164. data/spec/rails_helper.rb +20 -109
  165. data/spec/requests/default_namespace_spec.rb +16 -28
  166. data/spec/requests/javascript_spec.rb +1 -1
  167. data/spec/requests/memory_spec.rb +5 -1
  168. data/spec/requests/stylesheets_spec.rb +1 -1
  169. data/spec/spec_helper.rb +5 -10
  170. data/spec/support/active_admin_integration_spec_helper.rb +66 -0
  171. data/spec/support/active_admin_request_helpers.rb +12 -0
  172. data/spec/support/rails_template.rb +42 -15
  173. data/spec/support/rails_template_with_data.rb +24 -5
  174. data/spec/support/templates/manifest.js +3 -0
  175. data/spec/support/templates/policies/application_policy.rb +1 -1
  176. data/spec/unit/abstract_view_factory_spec.rb +1 -1
  177. data/spec/unit/action_builder_spec.rb +3 -12
  178. data/spec/unit/active_admin_spec.rb +1 -1
  179. data/spec/unit/application_spec.rb +5 -1
  180. data/spec/unit/asset_registration_spec.rb +1 -1
  181. data/spec/unit/authorization/authorization_adapter_spec.rb +1 -1
  182. data/spec/unit/authorization/controller_authorization_spec.rb +13 -9
  183. data/spec/unit/authorization/index_overriding_spec.rb +6 -6
  184. data/spec/unit/auto_link_spec.rb +48 -24
  185. data/spec/unit/batch_actions/resource_spec.rb +1 -14
  186. data/spec/unit/batch_actions/settings_spec.rb +1 -1
  187. data/spec/unit/belongs_to_spec.rb +9 -1
  188. data/spec/unit/cancan_adapter_spec.rb +1 -1
  189. data/spec/unit/comments_spec.rb +26 -19
  190. data/spec/unit/component_spec.rb +1 -1
  191. data/spec/unit/config_shared_examples.rb +1 -1
  192. data/spec/unit/controller_filters_spec.rb +1 -1
  193. data/spec/unit/csv_builder_spec.rb +5 -5
  194. data/spec/unit/dependency_spec.rb +1 -1
  195. data/spec/unit/devise_spec.rb +17 -3
  196. data/spec/unit/dsl_spec.rb +2 -2
  197. data/spec/unit/filters/active_spec.rb +21 -0
  198. data/spec/unit/filters/filter_form_builder_spec.rb +98 -31
  199. data/spec/unit/filters/humanized_spec.rb +9 -1
  200. data/spec/unit/filters/resource_spec.rb +5 -4
  201. data/spec/unit/form_builder_spec.rb +180 -33
  202. data/spec/unit/generators/install_spec.rb +12 -5
  203. data/spec/unit/helpers/collection_spec.rb +10 -7
  204. data/spec/unit/helpers/scope_chain_spec.rb +1 -1
  205. data/spec/unit/helpers/settings_spec.rb +1 -1
  206. data/spec/unit/i18n_spec.rb +1 -1
  207. data/spec/unit/localizers/resource_localizer_spec.rb +36 -0
  208. data/spec/unit/menu_collection_spec.rb +1 -1
  209. data/spec/unit/menu_item_spec.rb +1 -1
  210. data/spec/unit/menu_spec.rb +1 -1
  211. data/spec/unit/namespace/authorization_spec.rb +1 -1
  212. data/spec/unit/namespace/register_page_spec.rb +28 -2
  213. data/spec/unit/namespace/register_resource_spec.rb +3 -1
  214. data/spec/unit/namespace_spec.rb +23 -1
  215. data/spec/unit/order_clause_spec.rb +7 -7
  216. data/spec/unit/page_controller_spec.rb +1 -1
  217. data/spec/unit/page_spec.rb +55 -2
  218. data/spec/unit/pretty_format_spec.rb +8 -7
  219. data/spec/unit/pundit_adapter_spec.rb +1 -1
  220. data/spec/unit/resource/action_items_spec.rb +1 -1
  221. data/spec/unit/resource/includes_spec.rb +1 -1
  222. data/spec/unit/resource/menu_spec.rb +1 -1
  223. data/spec/unit/resource/naming_spec.rb +1 -1
  224. data/spec/unit/resource/ordering_spec.rb +38 -0
  225. data/spec/unit/resource/page_presenters_spec.rb +1 -1
  226. data/spec/unit/resource/pagination_spec.rb +1 -1
  227. data/spec/unit/resource/routes_spec.rb +101 -53
  228. data/spec/unit/resource/scopes_spec.rb +1 -1
  229. data/spec/unit/resource/sidebars_spec.rb +1 -1
  230. data/spec/unit/resource_collection_spec.rb +1 -1
  231. data/spec/unit/resource_controller/data_access_spec.rb +50 -1
  232. data/spec/unit/resource_controller/decorators_spec.rb +2 -2
  233. data/spec/unit/resource_controller/sidebars_spec.rb +16 -17
  234. data/spec/unit/resource_controller_spec.rb +50 -56
  235. data/spec/unit/resource_registration_spec.rb +9 -4
  236. data/spec/unit/resource_spec.rb +9 -1
  237. data/spec/unit/routing_spec.rb +30 -2
  238. data/spec/unit/scope_spec.rb +26 -2
  239. data/spec/unit/settings_spec.rb +2 -2
  240. data/spec/unit/view_factory_spec.rb +1 -1
  241. data/spec/unit/view_helpers/breadcrumbs_spec.rb +1 -1
  242. data/spec/unit/view_helpers/display_helper_spec.rb +18 -3
  243. data/spec/unit/view_helpers/download_format_links_helper_spec.rb +1 -1
  244. data/spec/unit/view_helpers/fields_for_spec.rb +1 -1
  245. data/spec/unit/view_helpers/flash_helper_spec.rb +1 -1
  246. data/spec/unit/view_helpers/form_helper_spec.rb +1 -1
  247. data/spec/unit/view_helpers/method_or_proc_helper_spec.rb +1 -1
  248. data/spec/unit/views/components/attributes_table_spec.rb +1 -1
  249. data/spec/unit/views/components/batch_action_selector_spec.rb +1 -1
  250. data/spec/unit/views/components/blank_slate_spec.rb +1 -1
  251. data/spec/unit/views/components/columns_spec.rb +1 -1
  252. data/spec/unit/views/components/index_list_spec.rb +18 -4
  253. data/spec/unit/views/components/index_table_for_spec.rb +1 -1
  254. data/spec/unit/views/components/paginated_collection_spec.rb +1 -1
  255. data/spec/unit/views/components/panel_spec.rb +1 -1
  256. data/spec/unit/views/components/sidebar_section_spec.rb +1 -1
  257. data/spec/unit/views/components/site_title_spec.rb +1 -1
  258. data/spec/unit/views/components/status_tag_spec.rb +1 -1
  259. data/spec/unit/views/components/table_for_spec.rb +9 -7
  260. data/spec/unit/views/components/tabs_spec.rb +1 -1
  261. data/spec/unit/views/components/unsupported_browser_spec.rb +3 -3
  262. data/spec/unit/views/index_as_blog_spec.rb +1 -1
  263. data/spec/unit/views/pages/form_spec.rb +1 -1
  264. data/spec/unit/views/pages/index_spec.rb +1 -1
  265. data/spec/unit/views/pages/layout_spec.rb +1 -1
  266. data/spec/unit/views/pages/show_spec.rb +1 -1
  267. data/spec/unit/views/tabbed_navigation_spec.rb +2 -2
  268. data/tasks/local.rake +25 -0
  269. data/tasks/parallel_tests.rake +4 -4
  270. data/tasks/test.rake +8 -53
  271. metadata +61 -18
  272. data/Guardfile +0 -8
  273. data/script/local +0 -53
  274. data/script/travis_cache +0 -107
  275. data/script/use_rails +0 -53
  276. data/spec/javascripts/support/jasmine_config.rb +0 -23
  277. data/spec/support/detect_rails_version.rb +0 -34
@@ -2,7 +2,7 @@ require 'rails_helper'
2
2
 
3
3
  class MockComponentClass < ActiveAdmin::Component; end
4
4
 
5
- describe ActiveAdmin::Component do
5
+ RSpec.describe ActiveAdmin::Component do
6
6
 
7
7
  let(:component_class){ MockComponentClass }
8
8
  let(:component){ component_class.new }
@@ -1,4 +1,4 @@
1
- shared_examples_for "ActiveAdmin::Resource" do
1
+ RSpec.shared_examples_for "ActiveAdmin::Resource" do
2
2
  describe "namespace" do
3
3
  it "should return the namespace" do
4
4
  expect(config.namespace).to eq(namespace)
@@ -1,6 +1,6 @@
1
1
  require 'rails_helper'
2
2
 
3
- describe ActiveAdmin::Application do
3
+ RSpec.describe ActiveAdmin::Application do
4
4
  let(:application){ ActiveAdmin::Application.new }
5
5
  let(:controllers){ application.controllers_for_filters }
6
6
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'rails_helper'
4
4
 
5
- describe ActiveAdmin::CSVBuilder do
5
+ RSpec.describe ActiveAdmin::CSVBuilder do
6
6
 
7
7
  describe '.default_for_resource using Post' do
8
8
  let(:csv_builder) { ActiveAdmin::CSVBuilder.default_for_resource(Post).tap(&:exec_columns) }
@@ -189,8 +189,8 @@ describe ActiveAdmin::CSVBuilder do
189
189
 
190
190
  context "build csv using the supplied order" do
191
191
  before do
192
- @post1 = Post.create!(title: "Hello1", published_at: Date.today - 2.day )
193
- @post2 = Post.create!(title: "Hello2", published_at: Date.today - 1.day )
192
+ @post1 = Post.create!(title: "Hello1", published_date: Date.today - 2.day )
193
+ @post2 = Post.create!(title: "Hello2", published_date: Date.today - 1.day )
194
194
  end
195
195
  let(:dummy_controller) {
196
196
  class DummyController
@@ -199,7 +199,7 @@ describe ActiveAdmin::CSVBuilder do
199
199
  end
200
200
 
201
201
  def collection
202
- Post.order('published_at DESC')
202
+ Post.order('published_date DESC')
203
203
  end
204
204
 
205
205
  def apply_decorator(resource)
@@ -215,7 +215,7 @@ describe ActiveAdmin::CSVBuilder do
215
215
  ActiveAdmin::CSVBuilder.new do
216
216
  column "id"
217
217
  column "title"
218
- column "published_at"
218
+ column "published_date"
219
219
  end
220
220
  end
221
221
 
@@ -1,6 +1,6 @@
1
1
  require 'rails_helper'
2
2
 
3
- describe ActiveAdmin::Dependency do
3
+ RSpec.describe ActiveAdmin::Dependency do
4
4
 
5
5
  k = ActiveAdmin::Dependency
6
6
 
@@ -1,6 +1,6 @@
1
1
  require 'rails_helper'
2
2
 
3
- describe ActiveAdmin::Devise::Controller do
3
+ RSpec.describe ActiveAdmin::Devise::Controller do
4
4
 
5
5
  let(:controller_class) do
6
6
  klass = Class.new do
@@ -12,10 +12,22 @@ describe ActiveAdmin::Devise::Controller do
12
12
  end
13
13
 
14
14
  let(:controller) { controller_class.new }
15
+ let(:action_controller_config) { Rails.configuration.action_controller }
16
+
17
+ def with_temp_relative_url_root(relative_url_root)
18
+ previous_relative_url_root = action_controller_config[:relative_url_root]
19
+ action_controller_config[:relative_url_root] = relative_url_root
20
+
21
+ yield
22
+ ensure
23
+ action_controller_config[:relative_url_root] = previous_relative_url_root
24
+ end
15
25
 
16
26
  context 'with a RAILS_RELATIVE_URL_ROOT set' do
17
27
 
18
- before { Rails.configuration.action_controller[:relative_url_root] = '/foo' }
28
+ around do |example|
29
+ with_temp_relative_url_root('/foo') { example.call }
30
+ end
19
31
 
20
32
  it "should set the root path to the default namespace" do
21
33
  expect(controller.root_path).to eq "/foo/admin"
@@ -30,7 +42,9 @@ describe ActiveAdmin::Devise::Controller do
30
42
 
31
43
  context 'without a RAILS_RELATIVE_URL_ROOT set' do
32
44
 
33
- before { Rails.configuration.action_controller[:relative_url_root] = nil }
45
+ around do |example|
46
+ with_temp_relative_url_root(nil) { example.call }
47
+ end
34
48
 
35
49
  it "should set the root path to the default namespace" do
36
50
  expect(controller.root_path).to eq "/admin"
@@ -6,11 +6,11 @@ module MockModuleToInclude
6
6
  end
7
7
  end
8
8
 
9
- describe ActiveAdmin::DSL do
9
+ RSpec.describe ActiveAdmin::DSL do
10
10
 
11
11
  let(:application) { ActiveAdmin::Application.new }
12
12
  let(:namespace) { ActiveAdmin::Namespace.new application, :admin }
13
- let(:resource_config) { ActiveAdmin::Resource.new namespace, Post }
13
+ let(:resource_config) { namespace.register Post }
14
14
  let(:dsl){ ActiveAdmin::DSL.new(resource_config) }
15
15
 
16
16
  describe "#include" do
@@ -0,0 +1,21 @@
1
+ require 'rails_helper'
2
+
3
+ RSpec.describe ActiveAdmin::Filters::Active do
4
+ subject { described_class.new(Post, params) }
5
+ let(:params_klass) do
6
+ if defined? ::ActionController::Parameters
7
+ ::ActionController::Parameters
8
+ else
9
+ HashWithIndifferentAccess #remove this when drop rails 3 support
10
+ end
11
+ end
12
+
13
+ let(:params) do
14
+ params_klass.new(q: {author_id_eq: 1})
15
+ end
16
+
17
+ it 'should have filters' do
18
+ expect(subject.filters.size).to eq(1)
19
+ end
20
+
21
+ end
@@ -1,12 +1,6 @@
1
1
  require 'rails_helper'
2
2
 
3
- class Post
4
- ransacker :custom_searcher do
5
- # nothing to see here
6
- end
7
- end
8
-
9
- describe ActiveAdmin::Filters::ViewHelper do
3
+ RSpec.describe ActiveAdmin::Filters::ViewHelper do
10
4
 
11
5
  # Setup an ActionView::Base object which can be used for
12
6
  # generating the form for.
@@ -102,6 +96,19 @@ describe ActiveAdmin::Filters::ViewHelper do
102
96
  expect(body).to have_selector("option[value=title_starts_with][selected=selected]", text: "Starts with")
103
97
  end
104
98
 
99
+ context "with filters options" do
100
+ let(:body) { Capybara.string(filter :title, filters: [:contains, :starts_with]) }
101
+
102
+ it "should generate provided options for filter select" do
103
+ expect(body).to have_selector("option[value=title_contains]", text: "Contains")
104
+ expect(body).to have_selector("option[value=title_starts_with]", text: "Starts with")
105
+ end
106
+
107
+ it "should not generate a select option for ends with" do
108
+ expect(body).not_to have_selector("option[value=title_ends_with]")
109
+ end
110
+ end
111
+
105
112
  context "with predicate" do
106
113
  %w[eq equals cont contains start starts_with end ends_with].each do |predicate|
107
114
  describe "'#{predicate}'" do
@@ -153,39 +160,68 @@ describe ActiveAdmin::Filters::ViewHelper do
153
160
  end
154
161
  end
155
162
 
156
- describe "datetime attribute" do
157
- let(:body) { Capybara.string(filter :created_at) }
163
+ describe "date attribute" do
164
+ let(:body) { Capybara.string(filter :published_date) }
158
165
 
159
166
  it "should generate a date greater than" do
160
- expect(body).to have_selector("input.datepicker[name='q[created_at_gteq_date]']")
167
+ expect(body).to have_selector("input.datepicker[name='q[published_date_gteq]']")
161
168
  end
162
169
  it "should generate a seperator" do
163
170
  expect(body).to have_selector("span.seperator")
164
171
  end
165
172
  it "should generate a date less than" do
166
- expect(body).to have_selector("input.datepicker[name='q[created_at_lteq_date]']")
173
+ expect(body).to have_selector("input.datepicker[name='q[published_date_lteq]']")
167
174
  end
168
175
  end
169
176
 
170
- describe "integer attribute" do
171
- let(:body) { Capybara.string(filter :id) }
177
+ describe "datetime attribute" do
178
+ let(:body) { Capybara.string(filter :created_at) }
172
179
 
173
- it "should generate a select option for equal to" do
174
- expect(body).to have_selector("option[value=id_equals]", text: "Equals")
180
+ it "should generate a date greater than" do
181
+ expect(body).to have_selector("input.datepicker[name='q[created_at_gteq_datetime]']")
175
182
  end
176
- it "should generate a select option for greater than" do
177
- expect(body).to have_selector("option", text: "Greater than")
183
+ it "should generate a seperator" do
184
+ expect(body).to have_selector("span.seperator")
178
185
  end
179
- it "should generate a select option for less than" do
180
- expect(body).to have_selector("option", text: "Less than")
186
+ it "should generate a date less than" do
187
+ expect(body).to have_selector("input.datepicker[name='q[created_at_lteq_datetime]']")
181
188
  end
182
- it "should generate a text field for input" do
183
- expect(body).to have_selector("input[name='q[id_equals]']")
189
+ end
190
+
191
+ describe "integer attribute" do
192
+ context "without options" do
193
+ let(:body) { Capybara.string(filter :id) }
194
+
195
+ it "should generate a select option for equal to" do
196
+ expect(body).to have_selector("option[value=id_equals]", text: "Equals")
197
+ end
198
+ it "should generate a select option for greater than" do
199
+ expect(body).to have_selector("option[value=id_greater_than]", text: "Greater than")
200
+ end
201
+ it "should generate a select option for less than" do
202
+ expect(body).to have_selector("option[value=id_less_than]", text: "Less than")
203
+ end
204
+ it "should generate a text field for input" do
205
+ expect(body).to have_selector("input[name='q[id_equals]']")
206
+ end
207
+ it "should select the option which is currently being filtered" do
208
+ scope = Post.search id_greater_than: 1
209
+ body = Capybara.string(render_filter scope, id: {})
210
+ expect(body).to have_selector("option[value=id_greater_than][selected=selected]", text: "Greater than")
211
+ end
184
212
  end
185
- it "should select the option which is currently being filtered" do
186
- scope = Post.search id_greater_than: 1
187
- body = Capybara.string(render_filter scope, id: {})
188
- expect(body).to have_selector("option[value=id_greater_than][selected=selected]", text: "Greater than")
213
+
214
+ context "with filters options" do
215
+ let(:body) { Capybara.string(filter :id, filters: [:equals, :greater_than]) }
216
+
217
+ it "should generate provided options for filter select" do
218
+ expect(body).to have_selector("option[value=id_equals]", text: "Equals")
219
+ expect(body).to have_selector("option[value=id_greater_than]", text: "Greater than")
220
+ end
221
+
222
+ it "should not generate a select option for less than" do
223
+ expect(body).not_to have_selector("option[value=id_less_than]")
224
+ end
189
225
  end
190
226
  end
191
227
 
@@ -389,21 +425,52 @@ describe ActiveAdmin::Filters::ViewHelper do
389
425
 
390
426
  describe "custom search methods" do
391
427
 
428
+ it "should use the default type of the ransacker" do
429
+ body = Capybara.string(filter :custom_searcher_numeric)
430
+ expect(body).to have_selector("option[value=custom_searcher_numeric_equals]")
431
+ expect(body).to have_selector("option[value=custom_searcher_numeric_greater_than]")
432
+ expect(body).to have_selector("option[value=custom_searcher_numeric_less_than]")
433
+ end
434
+
392
435
  it "should work as select" do
393
- body = Capybara.string(filter :custom_searcher, as: :select, collection: ['foo'])
394
- expect(body).to have_selector("select[name='q[custom_searcher]']")
436
+ body = Capybara.string(filter :custom_title_searcher, as: :select, collection: ['foo'])
437
+ expect(body).to have_selector("select[name='q[custom_title_searcher_eq]']")
395
438
  end
396
439
 
397
440
  it "should work as string" do
398
- body = Capybara.string(filter :custom_searcher, as: :string)
399
- expect(body).to have_selector("input[name='q[custom_searcher]']")
441
+ body = Capybara.string(filter :custom_title_searcher, as: :string)
442
+ expect(body).to have_selector("option[value=custom_title_searcher_contains]")
443
+ expect(body).to have_selector("option[value=custom_title_searcher_starts_with]")
444
+ end
445
+
446
+ describe "custom date range search" do
447
+ let(:qteq) { "2010-10-01" }
448
+ let(:lteq) { "2010-10-02" }
449
+ let(:scope){ Post.search custom_created_at_searcher_gteq_datetime: qteq, custom_created_at_searcher_lteq_datetime: lteq }
450
+ let(:body) { Capybara.string(render_filter scope, custom_created_at_searcher: {as: :date_range}) }
451
+
452
+ it "should work as date_range" do
453
+ expect(body).to have_selector("input[name='q[custom_created_at_searcher_gteq_datetime]'][value='2010-10-01']")
454
+ expect(body).to have_selector("input[name='q[custom_created_at_searcher_lteq_datetime]'][value='2010-10-02']")
455
+ end
456
+
457
+ context "filter value can't be casted to date" do
458
+ let(:qteq) { "Ooops" }
459
+ let(:lteq) { "Ooops" }
460
+
461
+ it "should work display empty filter values" do
462
+ expect(body).to have_selector("input[name='q[custom_created_at_searcher_gteq_datetime]'][value='']")
463
+ expect(body).to have_selector("input[name='q[custom_created_at_searcher_lteq_datetime]'][value='']")
464
+ end
465
+ end
466
+
400
467
  end
401
468
  end
402
469
 
403
470
  describe "does not support some filter inputs" do
404
471
  it "should fallback to use formtastic inputs" do
405
- body = Capybara.string(filter :custom_searcher, as: :text)
406
- expect(body).to have_selector("textarea[name='q[custom_searcher]']")
472
+ body = Capybara.string(filter :custom_title_searcher, as: :text)
473
+ expect(body).to have_selector("textarea[name='q[custom_title_searcher]']")
407
474
  end
408
475
  end
409
476
 
@@ -1,6 +1,6 @@
1
1
  require 'rails_helper'
2
2
 
3
- describe ActiveAdmin::Filters::Humanized do
3
+ RSpec.describe ActiveAdmin::Filters::Humanized do
4
4
  describe '#value' do
5
5
  it 'should equal query string parameter if not an Array' do
6
6
  param = ['category_id_eq', '1']
@@ -52,5 +52,13 @@ describe ActiveAdmin::Filters::Humanized do
52
52
  expect(humanizer.body).to eq("Name Predicate Does Not Exist")
53
53
  end
54
54
  end
55
+
56
+ context 'when column name similar to predicate' do
57
+ it 'parses correct predicate' do
58
+ param = ['time_start_gteq', 'test']
59
+ humanizer = ActiveAdmin::Filters::Humanized.new(param)
60
+ expect(humanizer.body).to eq('Time Start greater than or equal to')
61
+ end
62
+ end
55
63
  end
56
64
  end
@@ -1,6 +1,6 @@
1
1
  require 'rails_helper'
2
2
 
3
- describe ActiveAdmin::Filters::ResourceExtension do
3
+ RSpec.describe ActiveAdmin::Filters::ResourceExtension do
4
4
 
5
5
  let(:resource) do
6
6
  namespace = ActiveAdmin::Namespace.new(ActiveAdmin::Application.new, :admin)
@@ -13,7 +13,7 @@ describe ActiveAdmin::Filters::ResourceExtension do
13
13
 
14
14
  it "should return the defaults if no filters are set" do
15
15
  expect(resource.filters.keys).to match_array([
16
- :author, :body, :category, :created_at, :custom_searcher, :position, :published_at, :starred, :taggings, :title, :updated_at
16
+ :author, :body, :category, :created_at, :custom_created_at_searcher, :custom_title_searcher, :custom_searcher_numeric, :position, :published_date, :starred, :taggings, :title, :updated_at
17
17
  ])
18
18
  end
19
19
 
@@ -35,7 +35,7 @@ describe ActiveAdmin::Filters::ResourceExtension do
35
35
  it "should return the defaults without associations if default association filters are disabled on the namespace" do
36
36
  resource.namespace.include_default_association_filters = false
37
37
  expect(resource.filters.keys).to match_array([
38
- :body, :created_at, :custom_searcher, :position, :published_at, :starred, :title, :updated_at
38
+ :body, :created_at, :custom_created_at_searcher, :custom_title_searcher, :custom_searcher_numeric, :position, :published_date, :starred, :title, :updated_at
39
39
  ])
40
40
  end
41
41
 
@@ -104,7 +104,8 @@ describe ActiveAdmin::Filters::ResourceExtension do
104
104
  resource.add_filter :count, as: :string
105
105
 
106
106
  expect(resource.filters.keys).to match_array([
107
- :author, :body, :category, :count, :created_at, :custom_searcher, :position, :published_at, :starred, :taggings, :title, :updated_at
107
+ :author, :body, :category, :count, :created_at, :custom_created_at_searcher, :custom_title_searcher, :custom_searcher_numeric, :position, :published_date, :starred, :taggings, :title, :updated_at
108
+
108
109
  ])
109
110
  end
110
111
 
@@ -1,8 +1,7 @@
1
1
  require 'rails_helper'
2
2
  require "rspec/mocks/standalone"
3
3
 
4
- describe ActiveAdmin::FormBuilder do
5
-
4
+ RSpec.describe ActiveAdmin::FormBuilder do
6
5
  # Setup an ActionView::Base object which can be used for
7
6
  # generating the form for.
8
7
  let(:helpers) do
@@ -63,7 +62,7 @@ describe ActiveAdmin::FormBuilder do
63
62
  context "it with custom settings" do
64
63
  let :body do
65
64
  build_form do |f|
66
- f.inputs class: "custom_class" do
65
+ f.inputs class: "custom_class", name: 'custom_name', custom_attr: 'custom_attr' do
67
66
  f.input :title
68
67
  f.input :body
69
68
  end
@@ -71,7 +70,15 @@ describe ActiveAdmin::FormBuilder do
71
70
  end
72
71
 
73
72
  it "should generate a fieldset with a inputs and custom class" do
74
- expect(body).to have_selector("fieldset.inputs.custom_class")
73
+ expect(body).to have_selector("fieldset.custom_class")
74
+ end
75
+
76
+ it "should generate a fieldset with a custom legend" do
77
+ expect(body).to have_css("legend", text: 'custom_name')
78
+ end
79
+
80
+ it "should generate a fieldset with a custom attributes" do
81
+ expect(body).to have_selector("fieldset[custom_attr='custom_attr']")
75
82
  end
76
83
  end
77
84
  end
@@ -277,6 +284,36 @@ describe ActiveAdmin::FormBuilder do
277
284
 
278
285
  end
279
286
 
287
+ context "with inputs component inside has_many" do
288
+
289
+ def user
290
+ u = User.new
291
+ u.profile = Profile.new(bio: 'bio')
292
+ u
293
+ end
294
+
295
+ let :body do
296
+ author = user()
297
+ build_form do |f|
298
+ f.form_builder.instance_eval do
299
+ @object.author = author
300
+ end
301
+ f.inputs name: 'Author', for: :author do |author|
302
+ author.has_many :profile, allow_destroy: true do |profile|
303
+ profile.inputs "inputs for profile #{profile.object.bio}" do
304
+ profile.input :bio
305
+ end
306
+ end
307
+ end
308
+ end
309
+ end
310
+
311
+ it "should see the profile fields for an existing profile" do
312
+ expect(body).to have_selector("[id='post_author_attributes_profile_attributes_bio']", count: 1)
313
+ expect(body).to have_selector("textarea[name='post[author_attributes][profile_attributes][bio]']")
314
+ end
315
+ end
316
+
280
317
  context "with a has_one relation on an author's profile" do
281
318
  let :body do
282
319
  author = user()
@@ -402,7 +439,7 @@ describe ActiveAdmin::FormBuilder do
402
439
  end
403
440
  f.inputs do
404
441
  f.input :author
405
- f.input :published_at
442
+ f.input :created_at
406
443
  end
407
444
  end
408
445
  end
@@ -410,10 +447,10 @@ describe ActiveAdmin::FormBuilder do
410
447
  expect(body).to have_selector("input[name='post[title]']", count: 1)
411
448
  expect(body).to have_selector("textarea[name='post[body]']", count: 1)
412
449
  expect(body).to have_selector("select[name='post[author_id]']", count: 1)
413
- expect(body).to have_selector("select[name='post[published_at(1i)]']", count: 1)
414
- expect(body).to have_selector("select[name='post[published_at(2i)]']", count: 1)
415
- expect(body).to have_selector("select[name='post[published_at(3i)]']", count: 1)
416
- expect(body).to have_selector("select[name='post[published_at(4i)]']", count: 1)
450
+ expect(body).to have_selector("select[name='post[created_at(1i)]']", count: 1)
451
+ expect(body).to have_selector("select[name='post[created_at(2i)]']", count: 1)
452
+ expect(body).to have_selector("select[name='post[created_at(3i)]']", count: 1)
453
+ expect(body).to have_selector("select[name='post[created_at(4i)]']", count: 1)
417
454
  end
418
455
  end
419
456
 
@@ -502,7 +539,6 @@ describe ActiveAdmin::FormBuilder do
502
539
  it "should add a custom header" do
503
540
  expect(body).to have_selector("h3", text: "Post")
504
541
  end
505
-
506
542
  end
507
543
 
508
544
  describe "without heading and new record link" do
@@ -539,9 +575,8 @@ describe ActiveAdmin::FormBuilder do
539
575
  end
540
576
 
541
577
  it "should add a custom header" do
542
- expect(body).to have_selector("h3", "Test heading")
578
+ expect(body).to have_selector("h3", text: "Test heading")
543
579
  end
544
-
545
580
  end
546
581
 
547
582
  describe "with custom new record link" do
@@ -557,29 +592,20 @@ describe ActiveAdmin::FormBuilder do
557
592
  it "should add a custom new record link" do
558
593
  expect(body).to have_selector("a", text: "My Custom New Post")
559
594
  end
560
-
561
595
  end
562
596
 
563
597
  describe "with allow destroy" do
564
- context "with an existing post" do
565
- let :body do
566
- s = self
567
- build_form({url: '/categories'}, Category.new) do |f|
568
- s.instance_exec do
569
- allow(f.object.posts.build).to receive(:new_record?).and_return(false)
570
- end
571
- f.has_many :posts, allow_destroy: true do |p|
572
- p.input :title
573
- end
574
- end
598
+ shared_examples_for "has many with allow_destroy = true" do |child_num|
599
+ it "should render the nested form" do
600
+ expect(body).to have_selector("input[name='category[posts_attributes][#{child_num}][title]']")
575
601
  end
576
602
 
577
603
  it "should include a boolean field for _destroy" do
578
- expect(body).to have_selector("input[name='category[posts_attributes][0][_destroy]']")
604
+ expect(body).to have_selector("input[name='category[posts_attributes][#{child_num}][_destroy]']")
579
605
  end
580
606
 
581
607
  it "should have a check box with 'Remove' as its label" do
582
- expect(body).to have_selector("label[for=category_posts_attributes_0__destroy]", text: "Delete")
608
+ expect(body).to have_selector("label[for=category_posts_attributes_#{child_num}__destroy]", text: "Delete")
583
609
  end
584
610
 
585
611
  it "should wrap the destroy field in an li with class 'has_many_delete'" do
@@ -587,22 +613,143 @@ describe ActiveAdmin::FormBuilder do
587
613
  end
588
614
  end
589
615
 
590
- context "with a new post" do
616
+ shared_examples_for "has many with allow_destroy = false" do |child_num|
617
+ it "should render the nested form" do
618
+ expect(body).to have_selector("input[name='category[posts_attributes][#{child_num}][title]']")
619
+ end
620
+
621
+ it "should not have a boolean field for _destroy" do
622
+ expect(body).not_to have_selector("input[name='category[posts_attributes][#{child_num}][_destroy]']")
623
+ end
624
+
625
+ it "should not have a check box with 'Remove' as its label" do
626
+ expect(body).not_to have_selector("label[for=category_posts_attributes_#{child_num}__destroy]", text: "Remove")
627
+ end
628
+ end
629
+
630
+ shared_examples_for "has many with allow_destroy as String, Symbol or Proc" do |allow_destroy_option|
591
631
  let :body do
632
+ s = self
592
633
  build_form({url: '/categories'}, Category.new) do |f|
593
- f.object.posts.build
594
- f.has_many :posts, allow_destroy: true do |p|
634
+ s.instance_exec do
635
+ allow(f.object.posts.build).to receive(:foo?).and_return(true)
636
+ allow(f.object.posts.build).to receive(:foo?).and_return(false)
637
+
638
+ f.object.posts.each do |post|
639
+ allow(post).to receive(:new_record?).and_return(false)
640
+ end
641
+ end
642
+ f.has_many :posts, allow_destroy: allow_destroy_option do |p|
595
643
  p.input :title
596
644
  end
597
645
  end
598
646
  end
599
647
 
600
- it "should not have a boolean field for _destroy" do
601
- expect(body).not_to have_selector("input[name='category[posts_attributes][0][_destroy]']")
648
+ context 'for the child that responds with true' do
649
+ it_behaves_like "has many with allow_destroy = true", 0
602
650
  end
603
651
 
604
- it "should not have a check box with 'Remove' as its label" do
605
- expect(body).not_to have_selector("label[for=category_posts_attributes_0__destroy]", text: "Remove")
652
+ context 'for the child that responds with false' do
653
+ it_behaves_like "has many with allow_destroy = false", 1
654
+ end
655
+ end
656
+
657
+ context "with an existing post" do
658
+ context "with allow_destroy = true" do
659
+ let :body do
660
+ s = self
661
+ build_form({url: '/categories'}, Category.new) do |f|
662
+ s.instance_exec do
663
+ allow(f.object.posts.build).to receive(:new_record?).and_return(false)
664
+ end
665
+ f.has_many :posts, allow_destroy: true do |p|
666
+ p.input :title
667
+ end
668
+ end
669
+ end
670
+
671
+ it_behaves_like "has many with allow_destroy = true", 0
672
+ end
673
+
674
+ context "with allow_destroy = false" do
675
+ let :body do
676
+ s = self
677
+ build_form({url: '/categories'}, Category.new) do |f|
678
+ s.instance_exec do
679
+ allow(f.object.posts.build).to receive(:new_record?).and_return(false)
680
+ end
681
+ f.has_many :posts, allow_destroy: false do |p|
682
+ p.input :title
683
+ end
684
+ end
685
+ end
686
+
687
+ it_behaves_like "has many with allow_destroy = false", 0
688
+ end
689
+
690
+ context "with allow_destroy = nil" do
691
+ let :body do
692
+ s = self
693
+ build_form({url: '/categories'}, Category.new) do |f|
694
+ s.instance_exec do
695
+ allow(f.object.posts.build).to receive(:new_record?).and_return(false)
696
+ end
697
+ f.has_many :posts, allow_destroy: nil do |p|
698
+ p.input :title
699
+ end
700
+ end
701
+ end
702
+
703
+ it_behaves_like "has many with allow_destroy = false", 0
704
+ end
705
+
706
+ context "with allow_destroy as Symbol" do
707
+ it_behaves_like("has many with allow_destroy as String, Symbol or Proc", :foo?)
708
+ end
709
+
710
+ context "with allow_destroy as String" do
711
+ it_behaves_like("has many with allow_destroy as String, Symbol or Proc", "foo?")
712
+ end
713
+
714
+ context "with allow_destroy as proc" do
715
+ it_behaves_like("has many with allow_destroy as String, Symbol or Proc",
716
+ Proc.new { |child| child.foo? })
717
+ end
718
+
719
+ context "with allow_destroy as lambda" do
720
+ it_behaves_like("has many with allow_destroy as String, Symbol or Proc",
721
+ lambda { |child| child.foo? })
722
+ end
723
+
724
+ context "with allow_destroy as any other expression that evaluates to true" do
725
+ let :body do
726
+ s = self
727
+ build_form({url: '/categories'}, Category.new) do |f|
728
+ s.instance_exec do
729
+ allow(f.object.posts.build).to receive(:new_record?).and_return(false)
730
+ end
731
+ f.has_many :posts, allow_destroy: Object.new do |p|
732
+ p.input :title
733
+ end
734
+ end
735
+ end
736
+
737
+ it_behaves_like "has many with allow_destroy = true", 0
738
+ end
739
+ end
740
+
741
+ context "with a new post" do
742
+ context "with allow_destroy = true" do
743
+ let :body do
744
+ build_form({url: '/categories'}, Category.new) do |f|
745
+ f.object.posts.build
746
+ f.has_many :posts, allow_destroy: true do |p|
747
+ p.input :title
748
+ end
749
+ end
750
+ end
751
+
752
+ it_behaves_like "has many with allow_destroy = false", 0
606
753
  end
607
754
  end
608
755
  end