activeadmin 0.5.1 → 0.6.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 (196) hide show
  1. data/.travis.yml +8 -5
  2. data/CHANGELOG.md +151 -0
  3. data/Gemfile +16 -16
  4. data/LICENSE +1 -1
  5. data/activeadmin.gemspec +1 -0
  6. data/app/assets/images/active_admin/index_list_icons/block_icon.svg +10 -0
  7. data/app/assets/images/active_admin/index_list_icons/blog_icon.svg +4 -0
  8. data/app/assets/images/active_admin/index_list_icons/grid_icon.svg +13 -0
  9. data/app/assets/images/active_admin/index_list_icons/table_icon.svg +3 -0
  10. data/app/assets/javascripts/active_admin/components/jquery.aa.checkbox-toggler.js.coffee +17 -44
  11. data/app/assets/javascripts/active_admin/components/jquery.aa.dropdown-menu.js.coffee +2 -4
  12. data/app/assets/javascripts/active_admin/components/jquery.aa.popover.js.coffee +0 -3
  13. data/app/assets/javascripts/active_admin/components/jquery.aa.table-checkbox-toggler.js.coffee +10 -12
  14. data/app/assets/javascripts/active_admin/pages/application.js.coffee +13 -10
  15. data/app/assets/javascripts/active_admin/pages/batch_actions.js.coffee +3 -3
  16. data/app/assets/stylesheets/active_admin/_base.css.scss +1 -0
  17. data/app/assets/stylesheets/active_admin/_header.css.scss +5 -2
  18. data/app/assets/stylesheets/active_admin/components/_dropdown_menu.scss +2 -2
  19. data/app/assets/stylesheets/active_admin/components/_index_list.scss +12 -0
  20. data/app/assets/stylesheets/active_admin/components/_popovers.css.scss +2 -2
  21. data/app/assets/stylesheets/active_admin/components/_table_tools.css.scss +2 -2
  22. data/app/assets/stylesheets/active_admin/mixins/_buttons.css.scss +4 -4
  23. data/app/assets/stylesheets/active_admin/mixins/_gradients.css.scss +5 -4
  24. data/app/assets/stylesheets/active_admin/mixins/_sections.css.scss +1 -1
  25. data/app/assets/stylesheets/active_admin/pages/_logged_out.scss +1 -1
  26. data/app/assets/stylesheets/active_admin/print.css.scss +2 -2
  27. data/app/assets/stylesheets/active_admin/structure/_title_bar.scss +1 -1
  28. data/app/views/active_admin/devise/unlocks/new.html.erb +14 -12
  29. data/docs/1-general-configuration.md +13 -0
  30. data/docs/10-custom-pages.md +40 -28
  31. data/docs/11-decorators.md +6 -4
  32. data/docs/12-arbre-components.md +1 -1
  33. data/docs/13-authorization-adapter.md +206 -0
  34. data/docs/2-resource-customization.md +129 -14
  35. data/docs/3-index-pages.md +65 -0
  36. data/docs/3-index-pages/create-an-index.md +29 -0
  37. data/docs/3-index-pages/index-as-table.md +35 -11
  38. data/docs/5-forms.md +2 -2
  39. data/features/authorization.feature +64 -0
  40. data/features/authorization_cancan.feature +52 -0
  41. data/features/belongs_to.feature +41 -5
  42. data/features/index/batch_actions.feature +27 -3
  43. data/features/index/formats.feature +27 -0
  44. data/features/index/index_as_table.feature +74 -2
  45. data/features/index/index_parameters.feature +69 -0
  46. data/features/index/index_scopes.feature +7 -11
  47. data/features/index/page_title.feature +18 -0
  48. data/features/index/switch_index_view.feature +73 -0
  49. data/features/menu.feature +27 -0
  50. data/features/registering_pages.feature +21 -0
  51. data/features/step_definitions/additional_web_steps.rb +4 -0
  52. data/features/step_definitions/batch_action_steps.rb +16 -6
  53. data/features/step_definitions/index_scope_steps.rb +3 -3
  54. data/features/step_definitions/index_views_steps.rb +3 -0
  55. data/features/step_definitions/menu_steps.rb +4 -0
  56. data/features/support/env.rb +4 -0
  57. data/features/support/paths.rb +3 -0
  58. data/lib/active_admin.rb +4 -0
  59. data/lib/active_admin/application.rb +43 -76
  60. data/lib/active_admin/authorization_adapter.rb +128 -0
  61. data/lib/active_admin/base_controller.rb +18 -1
  62. data/lib/active_admin/base_controller/authorization.rb +153 -0
  63. data/lib/active_admin/base_controller/menu.rb +8 -3
  64. data/lib/active_admin/batch_actions/resource_extension.rb +8 -7
  65. data/lib/active_admin/batch_actions/views/batch_action_form.rb +1 -1
  66. data/lib/active_admin/cancan_adapter.rb +40 -0
  67. data/lib/active_admin/dashboards.rb +4 -5
  68. data/lib/active_admin/dashboards/dashboard_controller.rb +1 -1
  69. data/lib/active_admin/devise.rb +22 -7
  70. data/lib/active_admin/dsl.rb +18 -5
  71. data/lib/active_admin/engine.rb +1 -1
  72. data/lib/active_admin/filters/dsl.rb +1 -1
  73. data/lib/active_admin/filters/forms.rb +9 -7
  74. data/lib/active_admin/filters/resource_extension.rb +20 -15
  75. data/lib/active_admin/form_builder.rb +44 -49
  76. data/lib/active_admin/helpers/optional_display.rb +4 -8
  77. data/lib/active_admin/inputs/filter_boolean_input.rb +1 -1
  78. data/lib/active_admin/inputs/filter_string_input.rb +5 -1
  79. data/lib/active_admin/locales/bg.yml +1 -1
  80. data/lib/active_admin/locales/ca.yml +1 -1
  81. data/lib/active_admin/locales/cs.yml +26 -25
  82. data/lib/active_admin/locales/da.yml +1 -1
  83. data/lib/active_admin/locales/de.yml +1 -1
  84. data/lib/active_admin/locales/en.yml +11 -1
  85. data/lib/active_admin/locales/es.yml +16 -16
  86. data/lib/active_admin/locales/fr.yml +1 -1
  87. data/lib/active_admin/locales/he.yml +1 -1
  88. data/lib/active_admin/locales/hr.yml +1 -1
  89. data/lib/active_admin/locales/hu.yml +1 -1
  90. data/lib/active_admin/locales/it.yml +1 -1
  91. data/lib/active_admin/locales/ja.yml +4 -1
  92. data/lib/active_admin/locales/ko.yml +1 -1
  93. data/lib/active_admin/locales/lt.yml +1 -1
  94. data/lib/active_admin/locales/lv.yml +12 -1
  95. data/lib/active_admin/locales/nl.yml +2 -2
  96. data/lib/active_admin/locales/no-NB.yml +22 -1
  97. data/lib/active_admin/locales/pl.yml +1 -1
  98. data/lib/active_admin/locales/pt-BR.yml +1 -1
  99. data/lib/active_admin/locales/pt-PT.yml +81 -0
  100. data/lib/active_admin/locales/ro.yml +1 -1
  101. data/lib/active_admin/locales/ru.yml +1 -1
  102. data/lib/active_admin/locales/sv-SE.yml +1 -1
  103. data/lib/active_admin/locales/tr.yml +1 -1
  104. data/lib/active_admin/locales/vi.yml +1 -1
  105. data/lib/active_admin/locales/zh-CN.yml +1 -1
  106. data/lib/active_admin/locales/zh-TW.yml +1 -1
  107. data/lib/active_admin/menu.rb +76 -38
  108. data/lib/active_admin/menu_collection.rb +96 -0
  109. data/lib/active_admin/menu_item.rb +61 -71
  110. data/lib/active_admin/namespace.rb +67 -5
  111. data/lib/active_admin/page.rb +6 -0
  112. data/lib/active_admin/page_controller.rb +13 -3
  113. data/lib/active_admin/resource.rb +11 -20
  114. data/lib/active_admin/resource/action_items.rb +3 -3
  115. data/lib/active_admin/resource/controllers.rb +0 -17
  116. data/lib/active_admin/resource/menu.rb +52 -24
  117. data/lib/active_admin/resource/naming.rb +6 -10
  118. data/lib/active_admin/resource/page_presenters.rb +57 -3
  119. data/lib/active_admin/resource/routes.rb +46 -0
  120. data/lib/active_admin/resource_controller.rb +2 -17
  121. data/lib/active_admin/resource_controller/data_access.rb +299 -0
  122. data/lib/active_admin/resource_controller/decorators.rb +2 -1
  123. data/lib/active_admin/resource_dsl.rb +12 -14
  124. data/lib/active_admin/router.rb +61 -56
  125. data/lib/active_admin/scope.rb +28 -18
  126. data/lib/active_admin/version.rb +1 -1
  127. data/lib/active_admin/view_factory.rb +0 -1
  128. data/lib/active_admin/view_helpers/breadcrumb_helper.rb +13 -19
  129. data/lib/active_admin/view_helpers/fields_for.rb +2 -0
  130. data/lib/active_admin/view_helpers/form_helper.rb +1 -1
  131. data/lib/active_admin/view_helpers/method_or_proc_helper.rb +66 -11
  132. data/lib/active_admin/views/components/attributes_table.rb +7 -4
  133. data/lib/active_admin/views/components/index_list.rb +68 -0
  134. data/lib/active_admin/views/components/paginated_collection.rb +13 -9
  135. data/lib/active_admin/views/components/scopes.rb +2 -8
  136. data/lib/active_admin/views/components/table_for.rb +1 -1
  137. data/lib/active_admin/views/footer.rb +1 -1
  138. data/lib/active_admin/views/header.rb +3 -2
  139. data/lib/active_admin/views/index_as_block.rb +4 -0
  140. data/lib/active_admin/views/index_as_blog.rb +4 -0
  141. data/lib/active_admin/views/index_as_grid.rb +4 -0
  142. data/lib/active_admin/views/index_as_table.rb +49 -7
  143. data/lib/active_admin/views/pages/index.rb +19 -4
  144. data/lib/active_admin/views/tabbed_navigation.rb +10 -54
  145. data/lib/generators/active_admin/install/install_generator.rb +5 -1
  146. data/lib/generators/active_admin/install/templates/active_admin.rb.erb +58 -0
  147. data/spec/integration/{default_namespace.rb → default_namespace_spec.rb} +0 -16
  148. data/spec/spec_helper.rb +3 -0
  149. data/spec/support/detect_rails_version.rb +10 -3
  150. data/spec/support/rails_template.rb +1 -1
  151. data/spec/support/templates/post_decorator.rb +6 -6
  152. data/spec/unit/application_spec.rb +5 -5
  153. data/spec/unit/authorization/authorization_adapter_spec.rb +61 -0
  154. data/spec/unit/authorization/controller_authorization_spec.rb +47 -0
  155. data/spec/unit/base_controller_spec.rb +0 -2
  156. data/spec/unit/batch_actions/resource_spec.rb +1 -1
  157. data/spec/unit/breadcrumbs_spec.rb +3 -3
  158. data/spec/unit/cancan_adapter_spec.rb +35 -0
  159. data/spec/unit/config_shared_examples.rb +9 -30
  160. data/spec/unit/devise_spec.rb +29 -0
  161. data/spec/unit/dsl_spec.rb +61 -0
  162. data/spec/unit/filters/filter_form_builder_spec.rb +58 -4
  163. data/spec/unit/filters/resource_spec.rb +17 -5
  164. data/spec/unit/form_builder_spec.rb +15 -0
  165. data/spec/unit/menu_collection_spec.rb +62 -0
  166. data/spec/unit/menu_item_spec.rb +51 -37
  167. data/spec/unit/menu_spec.rb +33 -29
  168. data/spec/unit/namespace/authorization_spec.rb +31 -0
  169. data/spec/unit/namespace/register_page_spec.rb +6 -28
  170. data/spec/unit/namespace/register_resource_spec.rb +11 -34
  171. data/spec/unit/namespace_spec.rb +63 -2
  172. data/spec/unit/page_controller_spec.rb +0 -3
  173. data/spec/unit/reloader_spec.rb +5 -5
  174. data/spec/unit/resource/menu_spec.rb +1 -13
  175. data/spec/unit/resource/naming_spec.rb +20 -2
  176. data/spec/unit/resource/page_presenters_spec.rb +14 -2
  177. data/spec/unit/resource_controller/{collection_spec.rb → data_access_spec.rb} +31 -13
  178. data/spec/unit/resource_controller_spec.rb +4 -5
  179. data/spec/unit/resource_spec.rb +33 -11
  180. data/spec/unit/routing_spec.rb +43 -0
  181. data/spec/unit/scope_spec.rb +13 -0
  182. data/spec/unit/view_factory_spec.rb +0 -1
  183. data/spec/unit/view_helpers/fields_for_spec.rb +4 -0
  184. data/spec/unit/view_helpers/form_helper_spec.rb +6 -2
  185. data/spec/unit/view_helpers/method_or_proc_helper_spec.rb +97 -0
  186. data/spec/unit/views/components/attributes_table_spec.rb +11 -0
  187. data/spec/unit/views/components/index_list_spec.rb +32 -0
  188. data/spec/unit/views/tabbed_navigation_spec.rb +42 -40
  189. data/tasks/test.rake +1 -1
  190. metadata +127 -40
  191. data/lib/active_admin/menu_builder.rb +0 -65
  192. data/lib/active_admin/resource_controller/callbacks.rb +0 -59
  193. data/lib/active_admin/resource_controller/collection.rb +0 -158
  194. data/lib/active_admin/views/utility_nav.rb +0 -41
  195. data/spec/unit/base_controller_shared_examples.rb +0 -25
  196. data/spec/unit/dsl_include_spec.rb +0 -20
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActiveAdmin::AuthorizationAdapter do
4
+
5
+ let(:adapter) { ActiveAdmin::AuthorizationAdapter.new(stub, stub) }
6
+
7
+ describe "#authorized?" do
8
+
9
+ it "should always return true" do
10
+ adapter.authorized?(:read, "Resource").should == true
11
+ end
12
+
13
+ end
14
+
15
+ describe "#scope_collection" do
16
+
17
+ it "should return the collection unscoped" do
18
+ collection = stub
19
+ adapter.scope_collection(collection).should == collection
20
+ end
21
+
22
+ end
23
+
24
+ describe "using #normalized in a subclass" do
25
+
26
+ let(:auth_class) do
27
+ Class.new(ActiveAdmin::AuthorizationAdapter) do
28
+
29
+ def authorized?(action, subject = nil)
30
+ case subject
31
+ when normalized(String)
32
+ true
33
+ else
34
+ false
35
+ end
36
+ end
37
+
38
+ end
39
+ end
40
+
41
+ let(:adapter) { auth_class.new(stub, stub) }
42
+
43
+ it "should match agains a class" do
44
+ adapter.authorized?(:read, String).should == true
45
+ end
46
+
47
+ it 'should match against an instance' do
48
+ adapter.authorized?(:read, "String").should == true
49
+ end
50
+
51
+ it 'should not match a different class' do
52
+ adapter.authorized?(:read, Hash).should == false
53
+ end
54
+
55
+ it 'should not match a different instance' do
56
+ adapter.authorized?(:read, {}).should == false
57
+ end
58
+
59
+ end
60
+
61
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe Admin::PostsController, "Controller Authorization", :type => :controller do
4
+
5
+ let(:user) { AdminUser.create!(:email => "example@admin.com", :password => "password", :password_confirmation => "password") }
6
+ let(:app) { ActiveAdmin.application }
7
+ let(:authorization){ controller.send(:active_admin_authorization) }
8
+
9
+ before do
10
+ # TODO: Get these tests passing...
11
+ pending
12
+
13
+ load_defaults!
14
+ @request.env["devise.mapping"] = Devise.mappings[:admin]
15
+ @resource.namespace.current_user_method = :current_admin_user
16
+
17
+ sign_in(user)
18
+ end
19
+
20
+ it "should authorize the index action" do
21
+ authorization.should_receive(:authorized?).
22
+ with(ActiveAdmin::Authorization::READ, Post).
23
+ and_return(true)
24
+
25
+ get :index
26
+ end
27
+
28
+ it "should authorize the new action" do
29
+ authorization.should_receive(:authorized?).
30
+ with(ActiveAdmin::Authorization::CREATE, an_instance_of(Post)).
31
+ and_return(true)
32
+
33
+ get :new
34
+ end
35
+
36
+ it "should authorize the create action with the new resource" do
37
+ mock_post = mock("Post", :save => true, :errors => [])
38
+ Post.should_receive(:new).at_least(:once).and_return(mock_post)
39
+
40
+ authorization.should_receive(:authorized?).
41
+ with(ActiveAdmin::Authorization::CREATE, mock_post).
42
+ and_return(true)
43
+
44
+ post :create
45
+ end
46
+
47
+ end
@@ -1,8 +1,6 @@
1
1
  require 'spec_helper'
2
- require File.expand_path('base_controller_shared_examples', File.dirname(__FILE__))
3
2
 
4
3
  describe ActiveAdmin::BaseController do
5
4
  let(:controller) { ActiveAdmin::BaseController.new }
6
5
 
7
- it_should_behave_like "BaseController"
8
6
  end
@@ -54,7 +54,7 @@ describe ActiveAdmin::BatchActions::ResourceExtension do
54
54
  describe "#batch_action_path" do
55
55
 
56
56
  it "returns the path as a symbol" do
57
- resource.batch_action_path.should == :batch_action_admin_posts_path
57
+ resource.batch_action_path.should == "/admin/posts/batch_action"
58
58
  end
59
59
 
60
60
  end
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe "Breadcrumbs" do
4
4
 
@@ -73,7 +73,7 @@ describe "Breadcrumbs" do
73
73
 
74
74
  context "when Post.find(1) does exist" do
75
75
  before do
76
- Post.stub!(:find).and_return{ mock(:display_name => "Hello World") }
76
+ Post.stub!(:find_by_id).and_return{ mock(:display_name => "Hello World") }
77
77
  end
78
78
  it "should have a link to /admin/posts/1 using display name" do
79
79
  trail[2][:name].should == "Hello World"
@@ -106,7 +106,7 @@ describe "Breadcrumbs" do
106
106
 
107
107
  context "when Post.find(4e24d6249ccf967313000000) does exist" do
108
108
  before do
109
- Post.stub!(:find).with('4e24d6249ccf967313000000').and_return{ mock(:display_name => "Hello World") }
109
+ Post.stub!(:find_by_id).with('4e24d6249ccf967313000000').and_return{ mock(:display_name => "Hello World") }
110
110
  end
111
111
  it "should have a link to /admin/posts/4e24d6249ccf967313000000 using display name" do
112
112
  trail[2][:name].should == "Hello World"
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActiveAdmin::CanCanAdapter do
4
+
5
+ describe "full integration" do
6
+
7
+ let(:application){ ActiveAdmin::Application.new }
8
+ let(:namespace){ ActiveAdmin::Namespace.new(application, "Admin") }
9
+ let(:resource){ namespace.register(Post) }
10
+
11
+ let :mock_ability_class do
12
+ Class.new do
13
+ include CanCan::Ability
14
+
15
+ def initialize(user)
16
+ can :read, Post
17
+ cannot :update, Post
18
+ end
19
+
20
+ end
21
+ end
22
+
23
+ it "should initialize the ability stored in the namespace configuration" do
24
+ namespace.authorization_adapter = ActiveAdmin::CanCanAdapter
25
+ namespace.cancan_ability_class = mock_ability_class
26
+
27
+ auth = namespace.authorization_adapter.new(resource, mock)
28
+
29
+ auth.authorized?(:read, Post).should == true
30
+ auth.authorized?(:update, Post).should == false
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -31,22 +31,18 @@ shared_examples_for "ActiveAdmin::Config" do
31
31
  end
32
32
 
33
33
  describe "Menu" do
34
- describe "menu item" do
34
+ describe "#menu_item_options" do
35
35
 
36
- it "initializes a new menu item with defaults" do
37
- config.menu_item.label.should == config.plural_resource_label
38
- end
36
+ it "initializes a new menu item with defaults" do
37
+ config.menu_item_options[:label].call.should == config.plural_resource_label
38
+ end
39
39
 
40
- it "initialize a new menu item with custom options" do
41
- config.menu :label => "Hello"
42
- config.menu_item.label.should == "Hello"
43
- end
40
+ it "initialize a new menu item with custom options" do
41
+ config.menu_item_options = { :label => "Hello" }
42
+ config.menu_item_options[:label].should == "Hello"
43
+ end
44
44
 
45
- it "initialize a new menu item with label as Proc object" do
46
- config.menu :label => proc { "Hello" }
47
- config.menu_item.label.should == "Hello"
48
45
  end
49
- end
50
46
 
51
47
  describe "#include_in_menu?" do
52
48
  it "should be included in menu by default" do
@@ -54,27 +50,10 @@ shared_examples_for "ActiveAdmin::Config" do
54
50
  end
55
51
 
56
52
  it "should not be included in menu when menu set to false" do
57
- config.menu false
53
+ config.menu_item_options = false
58
54
  config.include_in_menu?.should == false
59
55
  end
60
56
  end
61
57
 
62
- describe "parent menu item name" do
63
-
64
- it "should be nil when not set" do
65
- config.parent_menu_item_name.should == nil
66
- end
67
-
68
- it "should return the name if set" do
69
- config.menu :parent => "Blog"
70
- config.parent_menu_item_name.should == "Blog"
71
- end
72
-
73
- it "initialize a new parent menu item with label as Proc object" do
74
- config.menu :parent => proc{ "Blog" }
75
- config.parent_menu_item_name.should == "Blog"
76
- end
77
- end
78
-
79
58
  end
80
59
  end
@@ -42,6 +42,35 @@ describe ActiveAdmin::Devise::Controller do
42
42
  end
43
43
 
44
44
  end
45
+
46
+ context "within a scoped route" do
47
+
48
+ SCOPE = '/aa_scoped'
49
+
50
+ before do
51
+ # Remove existing routes
52
+ routes = Rails.application.routes
53
+ routes.clear!
54
+
55
+ # Add scoped routes
56
+ routes.draw do
57
+ scope :path => SCOPE do
58
+ ActiveAdmin.routes(self)
59
+ devise_for :admin_users, ActiveAdmin::Devise.config
60
+ end
61
+ end
62
+ end
63
+
64
+ after do
65
+ # Resume default routes
66
+ reload_routes!
67
+ end
68
+
69
+ it "should include scope path in root_path" do
70
+ controller.root_path.should == "#{SCOPE}/admin"
71
+ end
72
+
73
+ end
45
74
 
46
75
  describe "#config" do
47
76
  let(:config) { ActiveAdmin::Devise.config }
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ module MockModuleToInclude
5
+ def self.included(dsl)
6
+ end
7
+ end
8
+
9
+ describe ActiveAdmin::DSL do
10
+
11
+ let(:config){ mock }
12
+ let(:application) { ActiveAdmin::Application.new }
13
+ let(:namespace) { ActiveAdmin::Namespace.new application, :admin }
14
+ let(:resource_config) { ActiveAdmin::Resource.new namespace, Post }
15
+ let(:dsl){ ActiveAdmin::DSL.new(config) }
16
+
17
+ describe "#include" do
18
+
19
+ it "should call the included class method on the module that is included" do
20
+ MockModuleToInclude.should_receive(:included).with(dsl)
21
+ dsl.run_registration_block do
22
+ include MockModuleToInclude
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+ describe "#menu" do
29
+
30
+ it "should set the menu_item_options on the configuration" do
31
+ config.should_receive(:menu_item_options=).with({:parent => "Admin"})
32
+ dsl.run_registration_block do
33
+ menu :parent => "Admin"
34
+ end
35
+ end
36
+
37
+ end
38
+
39
+ describe "#navigation_menu" do
40
+
41
+ it "should set the navigation_menu_name on the configuration" do
42
+ config.should_receive(:navigation_menu_name=).with(:admin)
43
+ dsl.run_registration_block do
44
+ navigation_menu :admin
45
+ end
46
+ end
47
+
48
+ it "should accept a block" do
49
+
50
+ dsl = ActiveAdmin::DSL.new(resource_config)
51
+ dsl.run_registration_block do
52
+ navigation_menu { :dynamic_menu }
53
+ end
54
+
55
+ resource_config.navigation_menu_name.should == :dynamic_menu
56
+
57
+ end
58
+
59
+ end
60
+
61
+ end
@@ -22,16 +22,19 @@ describe ActiveAdmin::Filters::ViewHelper do
22
22
  view
23
23
  end
24
24
 
25
- def render_filter(search, name, options = {})
26
- render_arbre_component({:filter_args => [search, [options.merge(:attribute => name)]]}, helpers) do
25
+ def render_filter(search, filters)
26
+ render_arbre_component({:filter_args => [search, filters]}, helpers) do
27
27
  text_node active_admin_filters_form_for(*assigns[:filter_args])
28
28
  end
29
29
  end
30
30
 
31
31
  def filter(name, options = {})
32
- render_filter Post.search, name, options
32
+ render_filter Post.search, @filters.push(options.merge(:attribute => name))
33
33
  end
34
34
 
35
+ before(:each) { @filters = [] }
36
+
37
+
35
38
  describe "the form in general" do
36
39
  let(:body) { filter :title }
37
40
 
@@ -72,6 +75,22 @@ describe ActiveAdmin::Filters::ViewHelper do
72
75
  I18n.backend.reload!
73
76
  end
74
77
  end
78
+
79
+ context "using starts_with and as" do
80
+ let(:body) { filter :title_starts_with, :as => :string }
81
+
82
+ it "should generate a search field for a string attribute with query starts_with" do
83
+ body.should have_tag("input", :attributes => { :name => "q[title_starts_with]" })
84
+ end
85
+ end
86
+
87
+ context "using ends_with and as" do
88
+ let(:body) { filter :title_ends_with, :as => :string }
89
+
90
+ it "should generate a search field for a string attribute with query starts_with" do
91
+ body.should have_tag("input", :attributes => { :name => "q[title_ends_with]" })
92
+ end
93
+ end
75
94
  end
76
95
 
77
96
  describe "text attribute" do
@@ -217,11 +236,46 @@ describe ActiveAdmin::Filters::ViewHelper do
217
236
  context "when polymorphic relationship" do
218
237
  let(:body) do
219
238
  search = ActiveAdmin::Comment.search
220
- render_filter(search, :resource)
239
+ render_filter(search, [{:attribute => :resource}])
221
240
  end
222
241
  it "should not generate any field" do
223
242
  body.should have_tag("form", :attributes => { :method => 'get' })
224
243
  end
225
244
  end
226
245
  end # belongs to
246
+
247
+
248
+ describe "conditional display" do
249
+
250
+ context "with :if block" do
251
+ let(:body) do
252
+ filter :body, :if => proc{true}
253
+ filter :author, :if => proc{false}
254
+ end
255
+
256
+ it "should be displayed if true" do
257
+ body.should have_tag("input", :attributes => { :name => "q[body_contains]"})
258
+ end
259
+
260
+ it "should NOT be displayed if false" do
261
+ body.should_not have_tag("input", :attributes => { :name => "q[author_id_eq]"})
262
+ end
263
+ end
264
+
265
+ context "with :unless block" do
266
+ let(:body) do
267
+ filter :created_at, :unless => proc{false}
268
+ filter :updated_at, :unless => proc{true}
269
+ end
270
+
271
+ it "should be displayed if false" do
272
+ body.should have_tag("input", :attributes => { :name => "q[created_at_gte]"})
273
+ end
274
+
275
+ it "should NOT be displayed if true" do
276
+ body.should_not have_tag("input", :attributes => { :name => "q[updated_at_gte]"})
277
+ end
278
+ end
279
+ end
280
+
227
281
  end
@@ -28,12 +28,25 @@ describe ActiveAdmin::Filters::ResourceExtension do
28
28
  resource.filters.should be_empty
29
29
  end
30
30
 
31
- it "should remove a filter" do
32
- resource.filters.should include({:attribute => :author})
33
- resource.remove_filter :author
34
- resource.filters.should_not include({:attribute => :author})
31
+ context "filter removal" do
32
+ it "should work" do
33
+ resource.filters.should include :attribute => :author
34
+ resource.remove_filter :author
35
+ resource.filters.should_not include :attribute => :author
36
+ end
37
+
38
+ it "should be lazy" do
39
+ resource.should_not_receive :default_filters # this hits the DB
40
+ resource.remove_filter :author
41
+ end
42
+
43
+ it "should not prevent the default filters from being added" do
44
+ resource.remove_filter :author
45
+ resource.filters.should_not be_empty
46
+ end
35
47
  end
36
48
 
49
+ # TODO: wrap the below in a context like "filter removal" was above
37
50
  it "should add a filter" do
38
51
  resource.add_filter :title
39
52
  resource.filters.should == [{:attribute => :title}]
@@ -70,5 +83,4 @@ describe ActiveAdmin::Filters::ResourceExtension do
70
83
  resource.sidebar_sections.first.name.should == :filters
71
84
  end
72
85
 
73
-
74
86
  end