sinatra-admin 0.1.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 (61) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +176 -0
  6. data/Rakefile +2 -0
  7. data/dummy/config.ru +12 -0
  8. data/dummy/config/mongoid.yml +6 -0
  9. data/dummy/dummy.rb +19 -0
  10. data/dummy/models/admin.rb +6 -0
  11. data/dummy/models/comment.rb +5 -0
  12. data/dummy/models/user.rb +11 -0
  13. data/dummy/views/admin/customs/index.haml +4 -0
  14. data/dummy/views/admin/users/custom.haml +2 -0
  15. data/features/admin_login.feature +36 -0
  16. data/features/admin_logout.feature +14 -0
  17. data/features/creating_users.feature +44 -0
  18. data/features/custom_pages.feature +34 -0
  19. data/features/default_root.feature +43 -0
  20. data/features/editing_users.feature +46 -0
  21. data/features/listing_users.feature +46 -0
  22. data/features/main_menu_resources.feature +41 -0
  23. data/features/removing_users.feature +34 -0
  24. data/features/step_definitions/common_steps.rb +59 -0
  25. data/features/step_definitions/web_steps.rb +212 -0
  26. data/features/support/database_cleaner.rb +17 -0
  27. data/features/support/env.rb +18 -0
  28. data/features/support/paths.rb +30 -0
  29. data/features/support/sinatra_admin.rb +3 -0
  30. data/features/support/warden.rb +9 -0
  31. data/features/user_details.feature +31 -0
  32. data/lib/sinatra-admin.rb +42 -0
  33. data/lib/sinatra-admin/app.rb +74 -0
  34. data/lib/sinatra-admin/config.rb +45 -0
  35. data/lib/sinatra-admin/helpers/session.rb +24 -0
  36. data/lib/sinatra-admin/helpers/template_lookup.rb +7 -0
  37. data/lib/sinatra-admin/models/admin.rb +40 -0
  38. data/lib/sinatra-admin/register.rb +8 -0
  39. data/lib/sinatra-admin/register/base.rb +29 -0
  40. data/lib/sinatra-admin/register/custom.rb +10 -0
  41. data/lib/sinatra-admin/register/model.rb +75 -0
  42. data/lib/sinatra-admin/version.rb +3 -0
  43. data/lib/sinatra-admin/views/auth/login.haml +16 -0
  44. data/lib/sinatra-admin/views/edit.haml +21 -0
  45. data/lib/sinatra-admin/views/index.haml +34 -0
  46. data/lib/sinatra-admin/views/layout.haml +19 -0
  47. data/lib/sinatra-admin/views/new.haml +19 -0
  48. data/lib/sinatra-admin/views/show.haml +16 -0
  49. data/lib/sinatra-admin/warden_strategies/sinatra_admin.rb +27 -0
  50. data/sinatra-admin.gemspec +36 -0
  51. data/spec/sinatra-admin/app_spec.rb +15 -0
  52. data/spec/sinatra-admin/config_spec.rb +111 -0
  53. data/spec/sinatra-admin/models/admin_spec.rb +33 -0
  54. data/spec/sinatra-admin/register/base_spec.rb +13 -0
  55. data/spec/sinatra-admin/register/custom_spec.rb +40 -0
  56. data/spec/sinatra-admin/register/model_spec.rb +26 -0
  57. data/spec/sinatra-admin/register_spec.rb +15 -0
  58. data/spec/sinatra-admin/version_spec.rb +5 -0
  59. data/spec/sinatra-admin_spec.rb +73 -0
  60. data/spec/spec_helper.rb +81 -0
  61. metadata +343 -0
@@ -0,0 +1,43 @@
1
+ Feature: Default root
2
+ In order to use SinatraAdmin
3
+ As an Admin
4
+ I want to either define a root resource or allow SinatraAdmin to use the first registered
5
+
6
+ Scenario: Admin tries to visit root without login
7
+ Given I add SinatraAdmin as middleware
8
+ And I register "User" resource
9
+ And I register "Comment" resource
10
+ And I am an Admin
11
+ And I define "User" as root resource
12
+ When I go to the home page
13
+ Then I should see "Login - SinatraAdmin"
14
+ And I should see "You must log in"
15
+
16
+ Scenario: Admin is redirected to defined root resource when it's defined
17
+ Given I add SinatraAdmin as middleware
18
+ And I register "User" resource
19
+ And I register "Comment" resource
20
+ And I am an Admin
21
+ And I am logged in as admin
22
+ And I define "User" as root resource
23
+ When I go to the home page
24
+ Then I should see "Users - Index"
25
+ And I should see "_id"
26
+ And I should see "first_name"
27
+ And I should see "last_name"
28
+ And I should see "email"
29
+ And I should see "There are not records in the database"
30
+
31
+ Scenario: Admin is redirected to first registered route when root resource is not defined
32
+ Given I add SinatraAdmin as middleware
33
+ And I register "Comment" resource
34
+ And I register "User" resource
35
+ And I am an Admin
36
+ And I am logged in as admin
37
+ When I go to the home page
38
+ Then I should see "Users - Index"
39
+ And I should see "_id"
40
+ And I should see "first_name"
41
+ And I should see "last_name"
42
+ And I should see "email"
43
+ And I should see "There are not records in the database"
@@ -0,0 +1,46 @@
1
+ Feature: Users edit
2
+ In order to use SinatraAdmin
3
+ As an Admin
4
+ I want to edit users records when I register the "User" resource
5
+
6
+ Scenario: Admin tries to edit a record without login
7
+ Given I add SinatraAdmin as middleware
8
+ And I register "User" resource
9
+ And I am an Admin
10
+ And There are users
11
+ When I go to users listing
12
+ Then I should see "Login - SinatraAdmin"
13
+ And I should see "You must log in"
14
+
15
+ Scenario: Admin edits a record without errors
16
+ Given I add SinatraAdmin as middleware
17
+ And I register "User" resource
18
+ And I am an Admin
19
+ And I am logged in as admin
20
+ And There are users
21
+ And I am on users listing
22
+ And I click on Carlo id
23
+ When I follow "Edit"
24
+ And I fill in "email" with "carlo.edit@herbalife.com"
25
+ And I press "Update"
26
+ Then I should see "User - Show"
27
+ And I should see "_id"
28
+ And I should see "first_name"
29
+ And I should see "last_name"
30
+ And I should see "email"
31
+ And I should see "Carlo"
32
+ And I should see "Cajucom"
33
+ And I should see "carlo.edit@herbalife.com"
34
+
35
+ Scenario: Admin edits a record with errors
36
+ Given I add SinatraAdmin as middleware
37
+ And I register "User" resource
38
+ And I am an Admin
39
+ And I am logged in as admin
40
+ And There are users
41
+ And I am on users listing
42
+ And I click on Carlo id
43
+ When I follow "Edit"
44
+ And I fill in "email" with ""
45
+ And I press "Update"
46
+ Then I should see "email ["can't be blank"]"
@@ -0,0 +1,46 @@
1
+ Feature: Users listing
2
+ In order to use SinatraAdmin
3
+ As an Admin
4
+ I want to see the all users when I register the "User" resource
5
+
6
+ Scenario: Admin tries to see user listing without login
7
+ Given I add SinatraAdmin as middleware
8
+ And I register "User" resource
9
+ And I am an Admin
10
+ And There are users
11
+ When I go to users listing
12
+ Then I should see "Login - SinatraAdmin"
13
+ And I should see "You must log in"
14
+
15
+ Scenario: Admin sees user listing when there are records
16
+ Given I add SinatraAdmin as middleware
17
+ And I register "User" resource
18
+ And I am an Admin
19
+ And I am logged in as admin
20
+ And There are users
21
+ When I go to users listing
22
+ Then I should see "Users - Index"
23
+ And I should see "_id"
24
+ And I should see "first_name"
25
+ And I should see "last_name"
26
+ And I should see "email"
27
+ And I should see "Carlo"
28
+ And I should see "Cajucom"
29
+ And I should see "carlo@herbalife.com"
30
+ And I should see "Francisco"
31
+ And I should see "Delgado"
32
+ And I should see "francisco@herbalife.com"
33
+
34
+ Scenario: Admin sees "No records" message when there are not users
35
+ Given I add SinatraAdmin as middleware
36
+ And I register "User" resource
37
+ And I am an Admin
38
+ And I am logged in as admin
39
+ And There are not users
40
+ When I go to users listing
41
+ Then I should see "Users - Index"
42
+ And I should see "_id"
43
+ And I should see "first_name"
44
+ And I should see "last_name"
45
+ And I should see "email"
46
+ And I should see "There are not records in the database"
@@ -0,0 +1,41 @@
1
+ Feature: Main Menu resources
2
+ In order to use SinatraAdmin
3
+ As an Admin
4
+ I want to see all registered routes links in the main menu
5
+
6
+ Scenario: Admin does not see main menu when he/she is not logged in
7
+ Given I add SinatraAdmin as middleware
8
+ And I register "User" resource
9
+ And I register "Comment" resource
10
+ And I am an Admin
11
+ When I go to the login page
12
+ Then I should not see "Users"
13
+ Then I should not see "Comments"
14
+
15
+ Scenario: Admin sees main menu when he/she is logged in
16
+ Given I add SinatraAdmin as middleware
17
+ And I register "User" resource
18
+ And I register "Comment" resource
19
+ And I am an Admin
20
+ And I am logged in as admin
21
+ When I go to the home page
22
+ Then I should see "Users"
23
+ Then I should see "Comments"
24
+
25
+ Scenario: Admin navigates through main menu when he/she is logged in
26
+ Given I add SinatraAdmin as middleware
27
+ And I register "User" resource
28
+ And I am an Admin
29
+ And I am logged in as admin
30
+ When I go to the home page
31
+ And I follow "Users"
32
+ Then I should see "Users - Index"
33
+
34
+ Scenario: Admin navigates through main menu when he/she is logged in
35
+ Given I add SinatraAdmin as middleware
36
+ And I register "Comment" resource
37
+ And I am an Admin
38
+ And I am logged in as admin
39
+ When I go to the home page
40
+ And I follow "Comments"
41
+ Then I should see "Comments - Index"
@@ -0,0 +1,34 @@
1
+ Feature: User show
2
+ In order to use SinatraAdmin
3
+ As an Admin
4
+ I want to remove user records when I register the "User" resource
5
+ And I click on remove button
6
+
7
+ Scenario: Admin tries to remove a user without login
8
+ Given I add SinatraAdmin as middleware
9
+ And I register "User" resource
10
+ And I am an Admin
11
+ And There are users
12
+ When I go to users listing
13
+ Then I should see "Login - SinatraAdmin"
14
+ And I should see "You must log in"
15
+
16
+ Scenario: Admin removes user from list
17
+ Given I add SinatraAdmin as middleware
18
+ And I register "User" resource
19
+ And I am an Admin
20
+ And I am logged in as admin
21
+ And There are users
22
+ And I am on users listing
23
+ When I click on Carlo remove button
24
+ Then I should see "Users - Index"
25
+ And I should see "_id"
26
+ And I should see "first_name"
27
+ And I should see "last_name"
28
+ And I should see "email"
29
+ And I should see "Francisco"
30
+ And I should see "Delgado"
31
+ And I should see "francisco@herbalife.com"
32
+ And I should not see "Carlo"
33
+ And I should not see "Cajucom"
34
+ And I should not see "carlo@herbalife.com"
@@ -0,0 +1,59 @@
1
+ Given /^I am an Admin$/ do
2
+ @admin = SinatraAdmin.config.admin_model.create(email: "admin@mail.com", password: "admin")
3
+ end
4
+
5
+ Given /^I am logged in as admin$/ do
6
+ login_as @admin, scope: :sinatra_admin
7
+ end
8
+
9
+ Given /^There are users$/ do
10
+ @carlo = User.create(first_name: "Carlo", last_name: "Cajucom", email: "carlo@herbalife.com")
11
+ @fco = User.create(first_name: "Francisco", last_name: "Delgado", email: "francisco@herbalife.com")
12
+ end
13
+
14
+ Given /^There are not users$/ do
15
+ User.destroy_all
16
+ end
17
+
18
+ Given /^I add SinatraAdmin as middleware$/ do
19
+ Dummy::Admin.use SinatraAdmin::App
20
+ end
21
+
22
+ Given /^I register "(\w+)" resource$/ do |resource|
23
+ SinatraAdmin.register resource
24
+ end
25
+
26
+ Given /^I register "(\w+)" resource with custom route$/ do |resource|
27
+ SinatraAdmin.register resource do
28
+ get '/custom/?' do
29
+ @message = "Welcome to Resource model custom page"
30
+ haml "users/custom".to_sym
31
+ end
32
+ end
33
+ end
34
+
35
+ Given /^I register my custom page$/ do
36
+ SinatraAdmin.register 'Custom' do
37
+ get '/?' do
38
+ @welcome_msg = 'Welcome to SinatraAdmin custom pages!'
39
+ @admin_count = SinatraAdmin::Admin.count
40
+ haml 'customs/index'.to_sym
41
+ end
42
+ end
43
+ end
44
+
45
+ Given /^I add main app views to SinatraAdmin views$/ do
46
+ SinatraAdmin.extend_views_from(Dummy::API)
47
+ end
48
+
49
+ Given /^I define "(\w+)" as root resource$/ do |resource|
50
+ SinatraAdmin.root resource
51
+ end
52
+
53
+ When /^I click on Carlo id$/ do
54
+ click_link(@carlo.id.to_s)
55
+ end
56
+
57
+ When /^I click on Carlo remove button$/ do
58
+ click_button("delete_#{@carlo.id.to_s}")
59
+ end
@@ -0,0 +1,212 @@
1
+ require 'uri'
2
+ require 'cgi'
3
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
4
+
5
+ module WithinHelpers
6
+ def with_scope(locator)
7
+ locator ? within(locator) { yield } : yield
8
+ end
9
+ end
10
+ World(WithinHelpers)
11
+
12
+ Given /^(?:|I )am on (.+)$/ do |page_name|
13
+ visit path_to(page_name)
14
+ end
15
+
16
+ When /^(?:|I )go to (.+)$/ do |page_name|
17
+ visit path_to(page_name)
18
+ end
19
+
20
+ When /^(?:|I )press "([^\"]*)"(?: within "([^\"]*)")?$/ do |button, selector|
21
+ with_scope(selector) do
22
+ click_button(button)
23
+ end
24
+ end
25
+
26
+ When /^(?:|I )follow "([^\"]*)"(?: within "([^\"]*)")?$/ do |link, selector|
27
+ with_scope(selector) do
28
+ click_link(link)
29
+ end
30
+ end
31
+
32
+ When /^(?:|I )fill in "([^\"]*)" with "([^\"]*)"(?: within "([^\"]*)")?$/ do |field, value, selector|
33
+ with_scope(selector) do
34
+ fill_in(field, :with => value)
35
+ end
36
+ end
37
+
38
+ When /^(?:|I )fill in "([^\"]*)" for "([^\"]*)"(?: within "([^\"]*)")?$/ do |value, field, selector|
39
+ with_scope(selector) do
40
+ fill_in(field, :with => value)
41
+ end
42
+ end
43
+
44
+ # Use this to fill in an entire form with data from a table. Example:
45
+ #
46
+ # When I fill in the following:
47
+ # | Account Number | 5002 |
48
+ # | Expiry date | 2009-11-01 |
49
+ # | Note | Nice guy |
50
+ # | Wants Email? | |
51
+ #
52
+ # TODO: Add support for checkbox, select og option
53
+ # based on naming conventions.
54
+ #
55
+ When /^(?:|I )fill in the following(?: within "([^\"]*)")?:$/ do |selector, fields|
56
+ with_scope(selector) do
57
+ fields.rows_hash.each do |name, value|
58
+ When %{I fill in "#{name}" with "#{value}"}
59
+ end
60
+ end
61
+ end
62
+
63
+ When /^(?:|I )select "([^\"]*)" from "([^\"]*)"(?: within "([^\"]*)")?$/ do |value, field, selector|
64
+ with_scope(selector) do
65
+ select(value, :from => field)
66
+ end
67
+ end
68
+
69
+ When /^(?:|I )check "([^\"]*)"(?: within "([^\"]*)")?$/ do |field, selector|
70
+ with_scope(selector) do
71
+ check(field)
72
+ end
73
+ end
74
+
75
+ When /^(?:|I )uncheck "([^\"]*)"(?: within "([^\"]*)")?$/ do |field, selector|
76
+ with_scope(selector) do
77
+ uncheck(field)
78
+ end
79
+ end
80
+
81
+ When /^(?:|I )choose "([^\"]*)"(?: within "([^\"]*)")?$/ do |field, selector|
82
+ with_scope(selector) do
83
+ choose(field)
84
+ end
85
+ end
86
+
87
+ When /^(?:|I )attach the file "([^\"]*)" to "([^\"]*)"(?: within "([^\"]*)")?$/ do |path, field, selector|
88
+ with_scope(selector) do
89
+ attach_file(field, path)
90
+ end
91
+ end
92
+
93
+ Then /^(?:|I )should see JSON:$/ do |expected_json|
94
+ require 'json'
95
+ expected = JSON.pretty_generate(JSON.parse(expected_json))
96
+ actual = JSON.pretty_generate(JSON.parse(response.body))
97
+ expected.should == actual
98
+ end
99
+
100
+ Then /^(?:|I )should see "(.*)"(?: within "([^\"]*)")?$/ do |text, selector|
101
+ with_scope(selector) do
102
+ if page.respond_to? :should
103
+ page.should have_content(text)
104
+ else
105
+ assert page.has_content?(text)
106
+ end
107
+ end
108
+ end
109
+
110
+ Then /^(?:|I )should see \/([^\/]*)\/(?: within "([^\"]*)")?$/ do |regexp, selector|
111
+ regexp = Regexp.new(regexp)
112
+ with_scope(selector) do
113
+ if page.respond_to? :should
114
+ page.should have_xpath('//*', :text => regexp)
115
+ else
116
+ assert page.has_xpath?('//*', :text => regexp)
117
+ end
118
+ end
119
+ end
120
+
121
+ Then /^(?:|I )should not see "([^\"]*)"(?: within "([^\"]*)")?$/ do |text, selector|
122
+ with_scope(selector) do
123
+ if page.respond_to? :should
124
+ page.should have_no_content(text)
125
+ else
126
+ assert page.has_no_content?(text)
127
+ end
128
+ end
129
+ end
130
+
131
+ Then /^(?:|I )should not see \/([^\/]*)\/(?: within "([^\"]*)")?$/ do |regexp, selector|
132
+ regexp = Regexp.new(regexp)
133
+ with_scope(selector) do
134
+ if page.respond_to? :should
135
+ page.should have_no_xpath('//*', :text => regexp)
136
+ else
137
+ assert page.has_no_xpath?('//*', :text => regexp)
138
+ end
139
+ end
140
+ end
141
+
142
+ Then /^the "([^\"]*)" field(?: within "([^\"]*)")? should contain "([^\"]*)"$/ do |field, selector, value|
143
+ with_scope(selector) do
144
+ field = find_field(field)
145
+ field_value = (field.tag_name == 'textarea') ? field.text : field.value
146
+ if field_value.respond_to? :should
147
+ field_value.should =~ /#{value}/
148
+ else
149
+ assert_match(/#{value}/, field_value)
150
+ end
151
+ end
152
+ end
153
+
154
+ Then /^the "([^\"]*)" field(?: within "([^\"]*)")? should not contain "([^\"]*)"$/ do |field, selector, value|
155
+ with_scope(selector) do
156
+ field = find_field(field)
157
+ field_value = (field.tag_name == 'textarea') ? field.text : field.value
158
+ if field_value.respond_to? :should_not
159
+ field_value.should_not =~ /#{value}/
160
+ else
161
+ assert_no_match(/#{value}/, field_value)
162
+ end
163
+ end
164
+ end
165
+
166
+ Then /^the "([^\"]*)" checkbox(?: within "([^\"]*)")? should be checked$/ do |label, selector|
167
+ with_scope(selector) do
168
+ field_checked = find_field(label)['checked']
169
+ if field_checked.respond_to? :should
170
+ field_checked.should == 'checked'
171
+ else
172
+ assert_equal 'checked', field_checked
173
+ end
174
+ end
175
+ end
176
+
177
+ Then /^the "([^\"]*)" checkbox(?: within "([^\"]*)")? should not be checked$/ do |label, selector|
178
+ with_scope(selector) do
179
+ field_checked = find_field(label)['checked']
180
+ if field_checked.respond_to? :should_not
181
+ field_checked.should_not == 'checked'
182
+ else
183
+ assert_not_equal 'checked', field_checked
184
+ end
185
+ end
186
+ end
187
+
188
+ Then /^(?:|I )should be on (.+)$/ do |page_name|
189
+ current_path = URI.parse(current_url).path
190
+ if current_path.respond_to? :should
191
+ current_path.should == path_to(page_name)
192
+ else
193
+ assert_equal path_to(page_name), current_path
194
+ end
195
+ end
196
+
197
+ Then /^(?:|I )should have the following query string:$/ do |expected_pairs|
198
+ query = URI.parse(current_url).query
199
+ actual_params = query ? CGI.parse(query) : {}
200
+ expected_params = {}
201
+ expected_pairs.rows_hash.each_pair{|k,v| expected_params[k] = v.split(',')}
202
+
203
+ if actual_params.respond_to? :should
204
+ actual_params.should == expected_params
205
+ else
206
+ assert_equal expected_params, actual_params
207
+ end
208
+ end
209
+
210
+ Then /^show me the page$/ do
211
+ save_and_open_page
212
+ end