activeadmin 0.1.0

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 (89) hide show
  1. data/.document +5 -0
  2. data/.gitignore +25 -0
  3. data/Gemfile +16 -0
  4. data/LICENSE +20 -0
  5. data/README.rdoc +201 -0
  6. data/Rakefile +71 -0
  7. data/active_admin.gemspec +22 -0
  8. data/lib/active_admin.rb +229 -0
  9. data/lib/active_admin/action_builder.rb +60 -0
  10. data/lib/active_admin/action_items.rb +48 -0
  11. data/lib/active_admin/asset_registration.rb +34 -0
  12. data/lib/active_admin/breadcrumbs.rb +26 -0
  13. data/lib/active_admin/dashboards.rb +50 -0
  14. data/lib/active_admin/dashboards/dashboard_controller.rb +40 -0
  15. data/lib/active_admin/dashboards/renderer.rb +45 -0
  16. data/lib/active_admin/dashboards/section.rb +43 -0
  17. data/lib/active_admin/dashboards/section_renderer.rb +28 -0
  18. data/lib/active_admin/filters.rb +189 -0
  19. data/lib/active_admin/form_builder.rb +91 -0
  20. data/lib/active_admin/helpers/optional_display.rb +34 -0
  21. data/lib/active_admin/menu.rb +42 -0
  22. data/lib/active_admin/menu_item.rb +67 -0
  23. data/lib/active_admin/namespace.rb +111 -0
  24. data/lib/active_admin/page_config.rb +15 -0
  25. data/lib/active_admin/pages.rb +11 -0
  26. data/lib/active_admin/pages/base.rb +92 -0
  27. data/lib/active_admin/pages/edit.rb +21 -0
  28. data/lib/active_admin/pages/index.rb +58 -0
  29. data/lib/active_admin/pages/index/blog.rb +65 -0
  30. data/lib/active_admin/pages/index/table.rb +48 -0
  31. data/lib/active_admin/pages/index/thumbnails.rb +40 -0
  32. data/lib/active_admin/pages/new.rb +21 -0
  33. data/lib/active_admin/pages/show.rb +54 -0
  34. data/lib/active_admin/renderer.rb +72 -0
  35. data/lib/active_admin/resource.rb +96 -0
  36. data/lib/active_admin/resource_controller.rb +325 -0
  37. data/lib/active_admin/sidebar.rb +78 -0
  38. data/lib/active_admin/table_builder.rb +162 -0
  39. data/lib/active_admin/tabs_renderer.rb +39 -0
  40. data/lib/active_admin/version.rb +3 -0
  41. data/lib/active_admin/view_helpers.rb +106 -0
  42. data/lib/active_admin/views/active_admin_dashboard/index.html.erb +1 -0
  43. data/lib/active_admin/views/active_admin_default/edit.html.erb +1 -0
  44. data/lib/active_admin/views/active_admin_default/index.csv.erb +2 -0
  45. data/lib/active_admin/views/active_admin_default/index.html.erb +1 -0
  46. data/lib/active_admin/views/active_admin_default/new.html.erb +1 -0
  47. data/lib/active_admin/views/active_admin_default/show.html.erb +1 -0
  48. data/lib/active_admin/views/layouts/active_admin.html.erb +40 -0
  49. data/lib/activeadmin.rb +1 -0
  50. data/lib/generators/active_admin/install/install_generator.rb +31 -0
  51. data/lib/generators/active_admin/install/templates/active_admin.css +325 -0
  52. data/lib/generators/active_admin/install/templates/active_admin.js +10 -0
  53. data/lib/generators/active_admin/install/templates/active_admin.rb +47 -0
  54. data/lib/generators/active_admin/install/templates/active_admin_vendor.js +382 -0
  55. data/lib/generators/active_admin/install/templates/dashboards.rb +36 -0
  56. data/lib/generators/active_admin/install/templates/images/orderable.gif +0 -0
  57. data/lib/generators/active_admin/resource/resource_generator.rb +16 -0
  58. data/lib/generators/active_admin/resource/templates/admin.rb +3 -0
  59. data/spec/integration/dashboard_spec.rb +44 -0
  60. data/spec/integration/index_as_blog_spec.rb +65 -0
  61. data/spec/integration/index_as_csv_spec.rb +40 -0
  62. data/spec/integration/index_as_table_spec.rb +160 -0
  63. data/spec/integration/index_as_thumbnails_spec.rb +43 -0
  64. data/spec/integration/layout_spec.rb +82 -0
  65. data/spec/integration/new_view_spec.rb +52 -0
  66. data/spec/integration/show_view_spec.rb +91 -0
  67. data/spec/spec_helper.rb +104 -0
  68. data/spec/support/rails_template.rb +19 -0
  69. data/spec/unit/action_builder_spec.rb +76 -0
  70. data/spec/unit/action_items_spec.rb +41 -0
  71. data/spec/unit/active_admin_spec.rb +52 -0
  72. data/spec/unit/asset_registration_spec.rb +37 -0
  73. data/spec/unit/controller_filters_spec.rb +26 -0
  74. data/spec/unit/dashboard_section_spec.rb +63 -0
  75. data/spec/unit/dashboards_spec.rb +59 -0
  76. data/spec/unit/filter_form_builder_spec.rb +157 -0
  77. data/spec/unit/form_builder_spec.rb +238 -0
  78. data/spec/unit/menu_item_spec.rb +137 -0
  79. data/spec/unit/menu_spec.rb +53 -0
  80. data/spec/unit/namespace_spec.rb +107 -0
  81. data/spec/unit/registration_spec.rb +46 -0
  82. data/spec/unit/renderer_spec.rb +100 -0
  83. data/spec/unit/resource_controller_spec.rb +48 -0
  84. data/spec/unit/resource_spec.rb +197 -0
  85. data/spec/unit/routing_spec.rb +12 -0
  86. data/spec/unit/sidebar_spec.rb +96 -0
  87. data/spec/unit/table_builder_spec.rb +162 -0
  88. data/spec/unit/tabs_renderer_spec.rb +34 -0
  89. metadata +247 -0
@@ -0,0 +1,197 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ module ActiveAdmin
4
+ describe Resource do
5
+
6
+ let(:namespace){ Namespace.new(:admin) }
7
+
8
+ def config(options = {})
9
+ @config ||= Resource.new(namespace, Category, options)
10
+ end
11
+
12
+ describe "underscored resource name" do
13
+ context "when class" do
14
+ it "should be the underscored singular resource name" do
15
+ config.underscored_resource_name.should == "category"
16
+ end
17
+ end
18
+ context "when a class in a module" do
19
+ it "should underscore the module and the class" do
20
+ module ::Mock; class Resource; end; end
21
+ Resource.new(namespace, Mock::Resource).underscored_resource_name.should == "mock_resource"
22
+ end
23
+ end
24
+ context "when you pass the 'as' option" do
25
+ it "should underscore the passed through string and singulralize" do
26
+ config(:as => "Blog Categories").underscored_resource_name.should == "blog_category"
27
+ end
28
+ end
29
+ end
30
+
31
+ describe "camelized resource name" do
32
+ it "should return a camelized version of the underscored resource name" do
33
+ config(:as => "Blog Categories").camelized_resource_name.should == "BlogCategory"
34
+ end
35
+ end
36
+
37
+ describe "resource name" do
38
+ it "should return a pretty name" do
39
+ config.resource_name.should == "Category"
40
+ end
41
+ it "should return the plural version" do
42
+ config.plural_resource_name.should == "Categories"
43
+ end
44
+ context "when the :as option is give" do
45
+ it "should return the custom name" do
46
+ config(:as => "My Category").resource_name.should == "My Category"
47
+ end
48
+ end
49
+ end
50
+
51
+ describe "namespace" do
52
+ it "should return the namespace" do
53
+ config.namespace.should == namespace
54
+ end
55
+ end
56
+
57
+ describe "controller name" do
58
+ it "should return a namespaced controller name" do
59
+ config.controller_name.should == "Admin::CategoriesController"
60
+ end
61
+ context "when non namespaced controller" do
62
+ let(:namespace){ ActiveAdmin::Namespace.new(:root) }
63
+ it "should return a non namespaced controller name" do
64
+ config.controller_name.should == "CategoriesController"
65
+ end
66
+ end
67
+ end
68
+
69
+ describe "parent menu item name" do
70
+ it "should be nil when not set" do
71
+ config.parent_menu_item_name.should == nil
72
+ end
73
+ it "should return the name if set" do
74
+ config.tap do |c|
75
+ c.menu :parent => "Blog"
76
+ end.parent_menu_item_name.should == "Blog"
77
+ end
78
+ end
79
+
80
+ describe "route names" do
81
+ let(:config){ ActiveAdmin.register Category }
82
+ it "should return the route prefix" do
83
+ config.route_prefix.should == "admin"
84
+ end
85
+ it "should return the route collection path" do
86
+ config.route_collection_path.should == :admin_categories_path
87
+ end
88
+ end
89
+
90
+ describe "page configs" do
91
+ context "when initialized" do
92
+ it "should be empty" do
93
+ config.page_configs.should == {}
94
+ end
95
+ end
96
+ it "should be set-able" do
97
+ config.page_configs[:index] = "hello world"
98
+ config.page_configs[:index].should == "hello world"
99
+ end
100
+ end
101
+
102
+ describe "scoping" do
103
+ let(:controller){ Admin::CategoriesController.new }
104
+ let(:begin_of_association_chain){ controller.send(:begin_of_association_chain) }
105
+
106
+ context "when using a block" do
107
+ before do
108
+ ActiveAdmin.register Category do
109
+ scope_to do
110
+ "scoped"
111
+ end
112
+ end
113
+ end
114
+ it "should call the proc for the begin of association chain" do
115
+ begin_of_association_chain.should == "scoped"
116
+ end
117
+ end
118
+
119
+ context "when using a symbol" do
120
+ before do
121
+ ActiveAdmin.register Category do
122
+ scope_to :current_user
123
+ end
124
+ end
125
+ it "should call the method for the begin of association chain" do
126
+ controller.should_receive(:current_user).and_return(true)
127
+ begin_of_association_chain.should == true
128
+ end
129
+ end
130
+
131
+ context "when not using a block or symbol" do
132
+ before do
133
+ ActiveAdmin.register Category do
134
+ scope_to "Some string"
135
+ end
136
+ end
137
+ it "should raise and exception" do
138
+ lambda {
139
+ begin_of_association_chain
140
+ }.should raise_error(ArgumentError)
141
+ end
142
+ end
143
+
144
+ describe "getting the method for the association chain" do
145
+ context "when a simple registration" do
146
+ before do
147
+ ActiveAdmin.register Category do
148
+ scope_to :current_user
149
+ end
150
+ end
151
+ it "should return the pluralized collection name" do
152
+ controller.send(:method_for_association_chain).should == :categories
153
+ end
154
+ end
155
+ context "when passing in the method as an option" do
156
+ before do
157
+ ActiveAdmin.register Category do
158
+ scope_to :current_user, :association_method => :blog_categories
159
+ end
160
+ end
161
+ it "should return the method from the option" do
162
+ controller.send(:method_for_association_chain).should == :blog_categories
163
+ end
164
+ end
165
+ end
166
+ end
167
+
168
+ describe "dashboard controller name" do
169
+ context "when namespaced" do
170
+ subject{ config.dashboard_controller_name }
171
+ it { should == "Admin::DashboardController" }
172
+ end
173
+ context "when not namespaced" do
174
+ let(:namespace){ ActiveAdmin::Namespace.new(:root) }
175
+ subject{ config.dashboard_controller_name }
176
+ it { should == "DashboardController" }
177
+ end
178
+ end
179
+
180
+ describe "sort order" do
181
+ subject { resource_config.sort_order }
182
+
183
+ context "by default" do
184
+ let(:resource_config) { config }
185
+
186
+ it { should == ActiveAdmin.default_sort_order }
187
+ end
188
+
189
+ context "when default_sort_order is set" do
190
+ let(:sort_order) { "name_desc" }
191
+ let(:resource_config) { config :sort_order => sort_order }
192
+
193
+ it { should == sort_order }
194
+ end
195
+ end
196
+ end
197
+ end
@@ -0,0 +1,12 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe ActiveAdmin, "Routing" do
4
+
5
+ subject { Admin::PostsController.new }
6
+
7
+ it { should respond_to(:admin_posts_path) }
8
+ it { should respond_to(:admin_post_path) }
9
+ it { should respond_to(:new_admin_post_path) }
10
+ it { should respond_to(:edit_admin_post_path) }
11
+
12
+ end
@@ -0,0 +1,96 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe_with_render ActiveAdmin::Sidebar do
4
+
5
+ before :all do
6
+ load_defaults!
7
+ reload_routes!
8
+ end
9
+
10
+ # Store the config and set it back after each spec so that we
11
+ # dont mess with other specs
12
+ before do
13
+ @config_before = Admin::PostsController.sidebar_sections
14
+ Admin::PostsController.clear_sidebar_sections!
15
+ end
16
+
17
+ after(:each) do
18
+ Admin::PostsController.sidebar_sections = @config_before
19
+ end
20
+
21
+ # Helper method to define a sidebar
22
+ def sidebar(name, options = {}, &block)
23
+ Admin::PostsController.class_eval do
24
+ sidebar(name, options, &block)
25
+ end
26
+ end
27
+
28
+ context "when setting with a block" do
29
+ before do
30
+ sidebar :my_filters do
31
+ link_to "My Filters", '#'
32
+ end
33
+ get :index
34
+ end
35
+ it "should add a new sidebar to @sidebar_sections" do
36
+ Admin::PostsController.sidebar_sections.size.should == 1
37
+ end
38
+ it "should render content in the context of the view" do
39
+ response.should have_tag("a", "My Filters")
40
+ end
41
+ it "should put a title for the section" do
42
+ response.should have_tag("h3", "My Filters")
43
+ end
44
+ end
45
+
46
+ context "when only adding to the index action" do
47
+ before do
48
+ sidebar(:filters, :only => :index){ }
49
+ end
50
+ it "should be available on index" do
51
+ Admin::PostsController.sidebar_sections_for(:index).size.should == 1
52
+ end
53
+ it "should not be available on edit" do
54
+ Admin::PostsController.sidebar_sections_for(:edit).size.should == 0
55
+ end
56
+ end
57
+
58
+ context "when adding to all except index action" do
59
+ before do
60
+ sidebar(:filters, :except => :index){ }
61
+ end
62
+ it "should not be availbale on index" do
63
+ Admin::PostsController.sidebar_sections_for(:index).size.should == 0
64
+ end
65
+ it "should be available on edit" do
66
+ Admin::PostsController.sidebar_sections_for(:edit).size.should == 1
67
+ end
68
+ end
69
+
70
+ context "when setting with a class"
71
+
72
+ describe "rendering partials" do
73
+ let(:sections){ [section] }
74
+ let(:renderer){ ActiveAdmin::Sidebar::Renderer.new(action_view) }
75
+ let(:render!){ renderer.to_html(sections) }
76
+
77
+ context "when a partial name is set" do
78
+ let(:section){ ActiveAdmin::Sidebar::Section.new(:filters, :partial => 'custom_partial') }
79
+
80
+ it "should render the partial" do
81
+ renderer.should_receive(:render).with('custom_partial').and_return("woot")
82
+ render!.should include("woot")
83
+ end
84
+ end
85
+
86
+ context "when no partial name is set" do
87
+ let(:section){ ActiveAdmin::Sidebar::Section.new(:filters) }
88
+
89
+ it "should render the partial based on the name of the sidebar section" do
90
+ renderer.should_receive(:render).with('filters_sidebar').and_return("woot")
91
+ render!.should include("woot")
92
+ end
93
+ end
94
+ end
95
+
96
+ end
@@ -0,0 +1,162 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ include ActiveAdmin
4
+
5
+ describe ActiveAdmin::TableBuilder do
6
+
7
+ describe "when creating a simple column" do
8
+ before(:each) do
9
+ @builder = TableBuilder.new do |t|
10
+ t.column :first_name
11
+ end
12
+ end
13
+
14
+ it "should set the column title" do
15
+ @builder.columns.first.title.should == 'First Name'
16
+ end
17
+
18
+ it "should set the column data" do
19
+ @builder.columns.first.data.should == :first_name
20
+ end
21
+ end
22
+
23
+ it "should generate multiple columns" do
24
+ builder = TableBuilder.new do |t|
25
+ t.column :username
26
+ t.column :last_name
27
+ end
28
+ builder.columns.size.should == 2
29
+ end
30
+
31
+ describe 'when creating a column with a title' do
32
+ before(:each) do
33
+ @builder = TableBuilder.new do |t|
34
+ t.column 'My Great Username', :username
35
+ end
36
+ end
37
+
38
+ it "should set the column title" do
39
+ @builder.columns.first.title.should == 'My Great Username'
40
+ end
41
+
42
+ it "should set the column data" do
43
+ @builder.columns.first.data.should == :username
44
+ end
45
+ end
46
+
47
+ describe 'when creating a column with a title and a block as the data' do
48
+ before(:each) do
49
+ @builder = TableBuilder.new do |t|
50
+ t.column('Username'){ |u| u.username }
51
+ end
52
+ end
53
+
54
+ it "should set the column title" do
55
+ @builder.columns.first.title.should == 'Username'
56
+ end
57
+
58
+ it "should set the column data" do
59
+ @builder.columns.first.data.should be_a(Proc)
60
+ end
61
+ end
62
+
63
+ describe "column sorting" do
64
+ before(:each) do
65
+ @builder = TableBuilder.new
66
+ end
67
+
68
+ it "should default to true" do
69
+ @builder.column :username
70
+ @builder.columns.first.should be_sortable
71
+ end
72
+
73
+ it "should be set with a symbol" do
74
+ @builder.column :username, :sortable => false
75
+ @builder.columns.first.should_not be_sortable
76
+ end
77
+
78
+ it "should be set with a string and a symbol" do
79
+ @builder.column "Username", :username, :sortable => false
80
+ @builder.columns.first.should_not be_sortable
81
+ end
82
+
83
+ it "should set the default sort key to the column symbol data" do
84
+ @builder.column :username
85
+ @builder.columns.first.sort_key.should == "username"
86
+ end
87
+
88
+ it "should not be sortable if a block given and no sort key" do
89
+ @builder.column('Username'){ @user.username }
90
+ @builder.columns.first.should_not be_sortable
91
+ end
92
+
93
+ it "should be sortable if a block given and a string to sortable" do
94
+ @builder.column('Username', :sortable => 'username'){ @user.pretty_username }
95
+ @builder.columns.first.should be_sortable
96
+ @builder.columns.first.sort_key.should == 'username'
97
+ end
98
+
99
+ it "should be sortable if a block given and a symbol to sortable" do
100
+ @builder.column('Username', :sortable => :username){ @user.pretty_username }
101
+ @builder.columns.first.should be_sortable
102
+ @builder.columns.first.sort_key.should == 'username'
103
+ end
104
+ end
105
+
106
+ describe "column conditionals" do
107
+ before(:each) do
108
+ @builder = TableBuilder.new
109
+ end
110
+ it "should default to true" do
111
+ @builder.column :username
112
+ @builder.columns.first.conditional_block.call.should be_true
113
+ end
114
+ it "should accept a lamdba" do
115
+ @builder.column :username, :if => proc{ false }
116
+ @builder.columns.first.conditional_block.call.should be_false
117
+ end
118
+ end
119
+
120
+
121
+ it "should generate many columns" do
122
+ builder = TableBuilder.new do |t|
123
+ t.columns :first, :second, :third
124
+ end
125
+ builder.columns.size.should == 3
126
+ builder.columns.first.data.should == :first
127
+ end
128
+
129
+ include ActiveAdminIntegrationSpecHelper
130
+
131
+ describe "rendering" do
132
+
133
+ let(:collection) { [ "Hello World", "Ruby Rocks", "Foo Bar" ] }
134
+ let(:table_builder) do
135
+ TableBuilder.new do |t|
136
+ t.column :to_s
137
+ t.column :size
138
+ t.column("Underscored"){|string| string.underscore }
139
+ end
140
+ end
141
+ let(:table) { TableBuilder::Renderer.new(action_view).to_html(table_builder,collection) }
142
+
143
+ context "when a table of objects" do
144
+ it "should have 3 rows and 1 header row" do
145
+ table.scan('<tr').size.should == 3
146
+ end
147
+ end
148
+
149
+ context "when unescaped html" do
150
+ let(:table_builder) do
151
+ TableBuilder.new do |t|
152
+ t.column(''){ "<h2>scary html</h2>" }
153
+ end
154
+ end
155
+ it "should escape the html" do
156
+ table.should_not include("<h2>scary html</h2>")
157
+ end
158
+ end
159
+
160
+ end
161
+
162
+ end