tennpipes-su 3.6.6

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 (192) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +20 -0
  3. data/README.rdoc +70 -0
  4. data/Rakefile +22 -0
  5. data/lib/tennpipes-su.rb +35 -0
  6. data/lib/tennpipes-su/access_control.rb +191 -0
  7. data/lib/tennpipes-su/bootstrap-less/alerts.less +67 -0
  8. data/lib/tennpipes-su/bootstrap-less/badges.less +55 -0
  9. data/lib/tennpipes-su/bootstrap-less/bootstrap.less +49 -0
  10. data/lib/tennpipes-su/bootstrap-less/breadcrumbs.less +26 -0
  11. data/lib/tennpipes-su/bootstrap-less/button-groups.less +226 -0
  12. data/lib/tennpipes-su/bootstrap-less/buttons.less +155 -0
  13. data/lib/tennpipes-su/bootstrap-less/carousel.less +232 -0
  14. data/lib/tennpipes-su/bootstrap-less/close.less +33 -0
  15. data/lib/tennpipes-su/bootstrap-less/code.less +63 -0
  16. data/lib/tennpipes-su/bootstrap-less/component-animations.less +29 -0
  17. data/lib/tennpipes-su/bootstrap-less/dropdowns.less +213 -0
  18. data/lib/tennpipes-su/bootstrap-less/font-awesome/bordered-pulled.less +16 -0
  19. data/lib/tennpipes-su/bootstrap-less/font-awesome/core.less +12 -0
  20. data/lib/tennpipes-su/bootstrap-less/font-awesome/fixed-width.less +6 -0
  21. data/lib/tennpipes-su/bootstrap-less/font-awesome/font-awesome.less +17 -0
  22. data/lib/tennpipes-su/bootstrap-less/font-awesome/icons.less +412 -0
  23. data/lib/tennpipes-su/bootstrap-less/font-awesome/larger.less +13 -0
  24. data/lib/tennpipes-su/bootstrap-less/font-awesome/list.less +19 -0
  25. data/lib/tennpipes-su/bootstrap-less/font-awesome/mixins.less +20 -0
  26. data/lib/tennpipes-su/bootstrap-less/font-awesome/path.less +14 -0
  27. data/lib/tennpipes-su/bootstrap-less/font-awesome/rotated-flipped.less +9 -0
  28. data/lib/tennpipes-su/bootstrap-less/font-awesome/spinning.less +30 -0
  29. data/lib/tennpipes-su/bootstrap-less/font-awesome/stacked.less +20 -0
  30. data/lib/tennpipes-su/bootstrap-less/font-awesome/variables.less +381 -0
  31. data/lib/tennpipes-su/bootstrap-less/forms.less +419 -0
  32. data/lib/tennpipes-su/bootstrap-less/glyphicons.less +233 -0
  33. data/lib/tennpipes-su/bootstrap-less/grid.less +100 -0
  34. data/lib/tennpipes-su/bootstrap-less/input-groups.less +157 -0
  35. data/lib/tennpipes-su/bootstrap-less/jumbotron.less +44 -0
  36. data/lib/tennpipes-su/bootstrap-less/labels.less +64 -0
  37. data/lib/tennpipes-su/bootstrap-less/list-group.less +110 -0
  38. data/lib/tennpipes-su/bootstrap-less/media.less +56 -0
  39. data/lib/tennpipes-su/bootstrap-less/mixins.less +926 -0
  40. data/lib/tennpipes-su/bootstrap-less/modals.less +138 -0
  41. data/lib/tennpipes-su/bootstrap-less/navbar.less +616 -0
  42. data/lib/tennpipes-su/bootstrap-less/navs.less +242 -0
  43. data/lib/tennpipes-su/bootstrap-less/normalize.less +423 -0
  44. data/lib/tennpipes-su/bootstrap-less/pager.less +55 -0
  45. data/lib/tennpipes-su/bootstrap-less/pagination.less +88 -0
  46. data/lib/tennpipes-su/bootstrap-less/panels.less +230 -0
  47. data/lib/tennpipes-su/bootstrap-less/popovers.less +133 -0
  48. data/lib/tennpipes-su/bootstrap-less/print.less +101 -0
  49. data/lib/tennpipes-su/bootstrap-less/progress-bars.less +80 -0
  50. data/lib/tennpipes-su/bootstrap-less/responsive-utilities.less +93 -0
  51. data/lib/tennpipes-su/bootstrap-less/scaffolding.less +134 -0
  52. data/lib/tennpipes-su/bootstrap-less/tables.less +233 -0
  53. data/lib/tennpipes-su/bootstrap-less/tennpipes-su.less +18 -0
  54. data/lib/tennpipes-su/bootstrap-less/theme.less +247 -0
  55. data/lib/tennpipes-su/bootstrap-less/thumbnails.less +36 -0
  56. data/lib/tennpipes-su/bootstrap-less/tooltip.less +95 -0
  57. data/lib/tennpipes-su/bootstrap-less/type.less +296 -0
  58. data/lib/tennpipes-su/bootstrap-less/utilities.less +56 -0
  59. data/lib/tennpipes-su/bootstrap-less/variables.less +827 -0
  60. data/lib/tennpipes-su/bootstrap-less/wells.less +29 -0
  61. data/lib/tennpipes-su/generators/actions.rb +78 -0
  62. data/lib/tennpipes-su/generators/admin_app.rb +169 -0
  63. data/lib/tennpipes-su/generators/admin_page.rb +68 -0
  64. data/lib/tennpipes-su/generators/orm.rb +172 -0
  65. data/lib/tennpipes-su/generators/templates/account/activerecord.rb.tt +41 -0
  66. data/lib/tennpipes-su/generators/templates/account/couchrest.rb.tt +67 -0
  67. data/lib/tennpipes-su/generators/templates/account/datamapper.rb.tt +56 -0
  68. data/lib/tennpipes-su/generators/templates/account/dynamoid.rb.tt +55 -0
  69. data/lib/tennpipes-su/generators/templates/account/minirecord.rb.tt +44 -0
  70. data/lib/tennpipes-su/generators/templates/account/mongoid.rb.tt +54 -0
  71. data/lib/tennpipes-su/generators/templates/account/mongomapper.rb.tt +47 -0
  72. data/lib/tennpipes-su/generators/templates/account/ohm.rb.tt +70 -0
  73. data/lib/tennpipes-su/generators/templates/account/seeds.rb.tt +29 -0
  74. data/lib/tennpipes-su/generators/templates/account/sequel.rb.tt +53 -0
  75. data/lib/tennpipes-su/generators/templates/app.rb.tt +42 -0
  76. data/lib/tennpipes-su/generators/templates/app/controllers/base.rb.tt +5 -0
  77. data/lib/tennpipes-su/generators/templates/app/controllers/sessions.rb.tt +29 -0
  78. data/lib/tennpipes-su/generators/templates/assets/images/favicon.ico +0 -0
  79. data/lib/tennpipes-su/generators/templates/assets/images/font/FontAwesome.otf +0 -0
  80. data/lib/tennpipes-su/generators/templates/assets/images/font/fontawesome-webfont.eot +0 -0
  81. data/lib/tennpipes-su/generators/templates/assets/images/font/fontawesome-webfont.svg +414 -0
  82. data/lib/tennpipes-su/generators/templates/assets/images/font/fontawesome-webfont.ttf +0 -0
  83. data/lib/tennpipes-su/generators/templates/assets/images/font/fontawesome-webfont.woff +0 -0
  84. data/lib/tennpipes-su/generators/templates/assets/images/logo.png +0 -0
  85. data/lib/tennpipes-su/generators/templates/assets/javascripts/application.js +118 -0
  86. data/lib/tennpipes-su/generators/templates/assets/javascripts/bootstrap/affix.js +137 -0
  87. data/lib/tennpipes-su/generators/templates/assets/javascripts/bootstrap/alert.js +88 -0
  88. data/lib/tennpipes-su/generators/templates/assets/javascripts/bootstrap/bootstrap.min.js +6 -0
  89. data/lib/tennpipes-su/generators/templates/assets/javascripts/bootstrap/button.js +107 -0
  90. data/lib/tennpipes-su/generators/templates/assets/javascripts/bootstrap/carousel.js +205 -0
  91. data/lib/tennpipes-su/generators/templates/assets/javascripts/bootstrap/collapse.js +170 -0
  92. data/lib/tennpipes-su/generators/templates/assets/javascripts/bootstrap/dropdown.js +147 -0
  93. data/lib/tennpipes-su/generators/templates/assets/javascripts/bootstrap/modal.js +243 -0
  94. data/lib/tennpipes-su/generators/templates/assets/javascripts/bootstrap/popover.js +110 -0
  95. data/lib/tennpipes-su/generators/templates/assets/javascripts/bootstrap/scrollspy.js +153 -0
  96. data/lib/tennpipes-su/generators/templates/assets/javascripts/bootstrap/tab.js +125 -0
  97. data/lib/tennpipes-su/generators/templates/assets/javascripts/bootstrap/tooltip.js +399 -0
  98. data/lib/tennpipes-su/generators/templates/assets/javascripts/bootstrap/transition.js +48 -0
  99. data/lib/tennpipes-su/generators/templates/assets/javascripts/jquery-1.11.0.min.js +4 -0
  100. data/lib/tennpipes-su/generators/templates/assets/stylesheets/application.css +353 -0
  101. data/lib/tennpipes-su/generators/templates/assets/stylesheets/bootstrap.css +4 -0
  102. data/lib/tennpipes-su/generators/templates/assets/stylesheets/fonts/FontAwesome.otf +0 -0
  103. data/lib/tennpipes-su/generators/templates/assets/stylesheets/fonts/fontawesome-webfont.eot +0 -0
  104. data/lib/tennpipes-su/generators/templates/assets/stylesheets/fonts/fontawesome-webfont.svg +414 -0
  105. data/lib/tennpipes-su/generators/templates/assets/stylesheets/fonts/fontawesome-webfont.ttf +0 -0
  106. data/lib/tennpipes-su/generators/templates/assets/stylesheets/fonts/fontawesome-webfont.woff +0 -0
  107. data/lib/tennpipes-su/generators/templates/erb/app/base/index.erb.tt +15 -0
  108. data/lib/tennpipes-su/generators/templates/erb/app/errors/403.erb.tt +3 -0
  109. data/lib/tennpipes-su/generators/templates/erb/app/errors/404.erb.tt +3 -0
  110. data/lib/tennpipes-su/generators/templates/erb/app/errors/500.erb.tt +3 -0
  111. data/lib/tennpipes-su/generators/templates/erb/app/layouts/application.erb.tt +64 -0
  112. data/lib/tennpipes-su/generators/templates/erb/app/layouts/error.erb.tt +23 -0
  113. data/lib/tennpipes-su/generators/templates/erb/app/sessions/new.erb.tt +44 -0
  114. data/lib/tennpipes-su/generators/templates/erb/page/_form.erb.tt +18 -0
  115. data/lib/tennpipes-su/generators/templates/erb/page/edit.erb.tt +10 -0
  116. data/lib/tennpipes-su/generators/templates/erb/page/index.erb.tt +81 -0
  117. data/lib/tennpipes-su/generators/templates/erb/page/new.erb.tt +9 -0
  118. data/lib/tennpipes-su/generators/templates/haml/app/base/index.haml.tt +12 -0
  119. data/lib/tennpipes-su/generators/templates/haml/app/errors/403.haml.tt +3 -0
  120. data/lib/tennpipes-su/generators/templates/haml/app/errors/404.haml.tt +3 -0
  121. data/lib/tennpipes-su/generators/templates/haml/app/errors/500.haml.tt +3 -0
  122. data/lib/tennpipes-su/generators/templates/haml/app/layouts/application.haml.tt +49 -0
  123. data/lib/tennpipes-su/generators/templates/haml/app/layouts/error.haml.tt +18 -0
  124. data/lib/tennpipes-su/generators/templates/haml/app/sessions/new.haml.tt +38 -0
  125. data/lib/tennpipes-su/generators/templates/haml/page/_form.haml.tt +16 -0
  126. data/lib/tennpipes-su/generators/templates/haml/page/edit.haml.tt +8 -0
  127. data/lib/tennpipes-su/generators/templates/haml/page/index.haml.tt +58 -0
  128. data/lib/tennpipes-su/generators/templates/haml/page/new.haml.tt +7 -0
  129. data/lib/tennpipes-su/generators/templates/page/controller.rb.tt +92 -0
  130. data/lib/tennpipes-su/generators/templates/slim/app/base/index.slim.tt +12 -0
  131. data/lib/tennpipes-su/generators/templates/slim/app/errors/403.slim.tt +3 -0
  132. data/lib/tennpipes-su/generators/templates/slim/app/errors/404.slim.tt +3 -0
  133. data/lib/tennpipes-su/generators/templates/slim/app/errors/500.slim.tt +3 -0
  134. data/lib/tennpipes-su/generators/templates/slim/app/layouts/application.slim.tt +48 -0
  135. data/lib/tennpipes-su/generators/templates/slim/app/layouts/error.slim.tt +19 -0
  136. data/lib/tennpipes-su/generators/templates/slim/app/sessions/new.slim.tt +37 -0
  137. data/lib/tennpipes-su/generators/templates/slim/page/_form.slim.tt +16 -0
  138. data/lib/tennpipes-su/generators/templates/slim/page/edit.slim.tt +8 -0
  139. data/lib/tennpipes-su/generators/templates/slim/page/index.slim.tt +56 -0
  140. data/lib/tennpipes-su/generators/templates/slim/page/new.slim.tt +7 -0
  141. data/lib/tennpipes-su/helpers/authentication_helpers.rb +108 -0
  142. data/lib/tennpipes-su/helpers/view_helpers.rb +87 -0
  143. data/lib/tennpipes-su/locale/admin/cs.yml +56 -0
  144. data/lib/tennpipes-su/locale/admin/da.yml +56 -0
  145. data/lib/tennpipes-su/locale/admin/de.yml +56 -0
  146. data/lib/tennpipes-su/locale/admin/en.yml +56 -0
  147. data/lib/tennpipes-su/locale/admin/es.yml +56 -0
  148. data/lib/tennpipes-su/locale/admin/fr.yml +56 -0
  149. data/lib/tennpipes-su/locale/admin/hu.yml +56 -0
  150. data/lib/tennpipes-su/locale/admin/it.yml +56 -0
  151. data/lib/tennpipes-su/locale/admin/ja.yml +57 -0
  152. data/lib/tennpipes-su/locale/admin/lv.yml +56 -0
  153. data/lib/tennpipes-su/locale/admin/nl.yml +56 -0
  154. data/lib/tennpipes-su/locale/admin/no.yml +56 -0
  155. data/lib/tennpipes-su/locale/admin/pl.yml +56 -0
  156. data/lib/tennpipes-su/locale/admin/pt_br.yml +56 -0
  157. data/lib/tennpipes-su/locale/admin/ro.yml +56 -0
  158. data/lib/tennpipes-su/locale/admin/ru.yml +57 -0
  159. data/lib/tennpipes-su/locale/admin/sv.yml +56 -0
  160. data/lib/tennpipes-su/locale/admin/tr.yml +56 -0
  161. data/lib/tennpipes-su/locale/admin/uk.yml +56 -0
  162. data/lib/tennpipes-su/locale/admin/zh_cn.yml +56 -0
  163. data/lib/tennpipes-su/locale/admin/zh_tw.yml +56 -0
  164. data/lib/tennpipes-su/locale/orm/cs.yml +12 -0
  165. data/lib/tennpipes-su/locale/orm/da.yml +12 -0
  166. data/lib/tennpipes-su/locale/orm/de.yml +12 -0
  167. data/lib/tennpipes-su/locale/orm/en.yml +12 -0
  168. data/lib/tennpipes-su/locale/orm/es.yml +12 -0
  169. data/lib/tennpipes-su/locale/orm/fr.yml +12 -0
  170. data/lib/tennpipes-su/locale/orm/hu.yml +12 -0
  171. data/lib/tennpipes-su/locale/orm/it.yml +12 -0
  172. data/lib/tennpipes-su/locale/orm/ja.yml +12 -0
  173. data/lib/tennpipes-su/locale/orm/lv.yml +12 -0
  174. data/lib/tennpipes-su/locale/orm/nl.yml +12 -0
  175. data/lib/tennpipes-su/locale/orm/no.yml +12 -0
  176. data/lib/tennpipes-su/locale/orm/pl.yml +38 -0
  177. data/lib/tennpipes-su/locale/orm/pt_br.yml +12 -0
  178. data/lib/tennpipes-su/locale/orm/ro.yml +12 -0
  179. data/lib/tennpipes-su/locale/orm/ru.yml +12 -0
  180. data/lib/tennpipes-su/locale/orm/sv.yml +12 -0
  181. data/lib/tennpipes-su/locale/orm/tr.yml +12 -0
  182. data/lib/tennpipes-su/locale/orm/uk.yml +12 -0
  183. data/lib/tennpipes-su/locale/orm/zh_cn.yml +12 -0
  184. data/lib/tennpipes-su/locale/orm/zh_tw.yml +12 -0
  185. data/test/fixtures/sequel.rb +72 -0
  186. data/test/generators/test_account_model_generator.rb +108 -0
  187. data/test/generators/test_admin_app_generator.rb +218 -0
  188. data/test/generators/test_admin_page_generator.rb +140 -0
  189. data/test/helper.rb +47 -0
  190. data/test/test_admin_application.rb +271 -0
  191. data/test/test_locale.rb +25 -0
  192. metadata +298 -0
@@ -0,0 +1,140 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../helper')
2
+
3
+ class Person
4
+ def self.properties
5
+ [:id, :name, :age, :email].map { |c| OpenStruct.new(:name => c) }
6
+ end
7
+ end
8
+
9
+ class Page
10
+ def self.properties
11
+ [:id, :name, :body].map { |c| OpenStruct.new(:name => c) }
12
+ end
13
+ end
14
+
15
+ describe "AdminPageGenerator" do
16
+ before do
17
+ @apptmp = "#{Dir.tmpdir}/tennpipes-tests/#{SecureRandom.hex}"
18
+ `mkdir -p #{@apptmp}`
19
+ end
20
+
21
+ after do
22
+ `rm -rf #{@apptmp}`
23
+ end
24
+
25
+ describe 'the admin page generator' do
26
+ it 'should fail outside app root' do
27
+ out, err = capture_io { generate(:admin_page, 'foo', "-r=#{@apptmp}/sample_project") }
28
+ assert_match(/not at the root/, out)
29
+ assert_no_file_exists("#{@apptmp}/admin")
30
+ end
31
+
32
+ it 'should fail without an existent model' do
33
+ capture_io { generate(:project, 'sample_project', '-e=slim', "--root=#{@apptmp}", '-d=activerecord') }
34
+ capture_io { generate(:admin_app, "--root=#{@apptmp}/sample_project") }
35
+ assert_raises(Tennpipes::Admin::Generators::OrmError) { generate(:admin_page, 'foo', "-r=#{@apptmp}/sample_project") }
36
+ end
37
+
38
+ it 'should correctly generate a new page' do
39
+ capture_io { generate(:project, 'sample_project', '-e=slim', "--root=#{@apptmp}", '-d=datamapper','-e=haml') }
40
+ capture_io { generate(:admin_app, "--root=#{@apptmp}/sample_project") }
41
+ capture_io { generate(:model, 'person', "name:string", "age:integer", "email:string", "--root=#{@apptmp}/sample_project") }
42
+ capture_io { generate(:admin_page, 'person', "--root=#{@apptmp}/sample_project") }
43
+ assert_file_exists "#{@apptmp}/sample_project/admin/controllers/people.rb"
44
+ assert_match_in_file "SampleProject::Admin.controllers :people do", "#{@apptmp}/sample_project/admin/controllers/people.rb"
45
+ assert_match_in_file "role.project_module :people, '/people'", "#{@apptmp}/sample_project/admin/app.rb"
46
+ assert_match_in_file "elsif Tennpipes.env == :development && params[:bypass]", "#{@apptmp}/sample_project/admin/controllers/sessions.rb"
47
+ end
48
+
49
+ # users can override certain templates from a generators/templates folder in the destination_root
50
+ it "should use custom generator templates from the project root, if they exist" do
51
+ capture_io { generate(:project, 'sample_project', '-e=slim', "--root=#{@apptmp}", '-d=datamapper','-e=haml') }
52
+ custom_template_path = "#{@apptmp}/sample_project/generators/templates/haml/page/"
53
+ `mkdir -p #{custom_template_path} && echo "%h1= 'Hello, custom generator' " > #{custom_template_path}index.haml.tt`
54
+ capture_io { generate(:admin_app, "--root=#{@apptmp}/sample_project") }
55
+ capture_io { generate(:model, 'person', "name:string", "age:integer", "email:string", "--root=#{@apptmp}/sample_project") }
56
+ capture_io { generate(:admin_page, 'person', "--root=#{@apptmp}/sample_project") }
57
+ assert_match_in_file(/Hello, custom generator/, "#{@apptmp}/sample_project/admin/views/people/index.haml")
58
+ end
59
+
60
+ describe "renderers" do
61
+ it 'should correctly generate a new page with haml' do
62
+ capture_io { generate(:project, 'sample_project', '-e=slim', "--root=#{@apptmp}", '-d=datamapper','-e=haml') }
63
+ capture_io { generate(:admin_app, "--root=#{@apptmp}/sample_project") }
64
+ capture_io { generate(:model, 'person', "name:string", "age:integer", "email:string", "--root=#{@apptmp}/sample_project") }
65
+ capture_io { generate(:admin_page, 'person', "--root=#{@apptmp}/sample_project") }
66
+ assert_file_exists "#{@apptmp}/sample_project/admin/views/people/_form.haml"
67
+ assert_file_exists "#{@apptmp}/sample_project/admin/views/people/edit.haml"
68
+ assert_file_exists "#{@apptmp}/sample_project/admin/views/people/index.haml"
69
+ assert_file_exists "#{@apptmp}/sample_project/admin/views/people/new.haml"
70
+ %w(name age email).each do |field|
71
+ assert_match_in_file "label :#{field}", "#{@apptmp}/sample_project/admin/views/people/_form.haml"
72
+ assert_match_in_file "text_field :#{field}", "#{@apptmp}/sample_project/admin/views/people/_form.haml"
73
+ end
74
+ assert_match_in_file "check_box_tag :bypass", "#{@apptmp}/sample_project/admin/views/sessions/new.haml"
75
+ end
76
+
77
+ it 'should correctly generate a new page with erb' do
78
+ capture_io { generate(:project, 'sample_project', '-e=slim', "--root=#{@apptmp}", '-d=datamapper','-e=erb') }
79
+ capture_io { generate(:admin_app, "--root=#{@apptmp}/sample_project") }
80
+ capture_io { generate(:model, 'person', "name:string", "age:integer", "email:string", "--root=#{@apptmp}/sample_project") }
81
+ capture_io { generate(:admin_page, 'person', "--root=#{@apptmp}/sample_project") }
82
+ assert_file_exists "#{@apptmp}/sample_project/admin/views/people/_form.erb"
83
+ assert_file_exists "#{@apptmp}/sample_project/admin/views/people/edit.erb"
84
+ assert_file_exists "#{@apptmp}/sample_project/admin/views/people/index.erb"
85
+ assert_file_exists "#{@apptmp}/sample_project/admin/views/people/new.erb"
86
+ %w(name age email).each do |field|
87
+ assert_match_in_file "label :#{field}", "#{@apptmp}/sample_project/admin/views/people/_form.erb"
88
+ assert_match_in_file "text_field :#{field}", "#{@apptmp}/sample_project/admin/views/people/_form.erb"
89
+ end
90
+ assert_match_in_file "check_box_tag :bypass", "#{@apptmp}/sample_project/admin/views/sessions/new.erb"
91
+ end
92
+
93
+ it 'should correctly generate a new page with slim' do
94
+ capture_io { generate(:project, 'sample_project', '-e=slim', "--root=#{@apptmp}", '-d=datamapper','-e=slim') }
95
+ capture_io { generate(:admin_app, "--root=#{@apptmp}/sample_project") }
96
+ capture_io { generate(:model, 'person', "name:string", "age:integer", "email:string", "--root=#{@apptmp}/sample_project") }
97
+ capture_io { generate(:admin_page, 'person', "--root=#{@apptmp}/sample_project") }
98
+ assert_file_exists "#{@apptmp}/sample_project/admin/views/people/_form.slim"
99
+ assert_file_exists "#{@apptmp}/sample_project/admin/views/people/edit.slim"
100
+ assert_file_exists "#{@apptmp}/sample_project/admin/views/people/index.slim"
101
+ assert_file_exists "#{@apptmp}/sample_project/admin/views/people/new.slim"
102
+ %w(name age email).each do |field|
103
+ assert_match_in_file "label :#{field}", "#{@apptmp}/sample_project/admin/views/people/_form.slim"
104
+ assert_match_in_file "text_field :#{field}", "#{@apptmp}/sample_project/admin/views/people/_form.slim"
105
+ end
106
+ assert_match_in_file "check_box_tag :bypass", "#{@apptmp}/sample_project/admin/views/sessions/new.slim"
107
+ end
108
+ end
109
+
110
+ it 'should correctly generate a new tennpipes admin application with multiple models at the same time' do
111
+ capture_io { generate(:project, 'sample_project', '-e=slim', "--root=#{@apptmp}", '-d=datamapper','-e=haml') }
112
+ capture_io { generate(:admin_app, "--root=#{@apptmp}/sample_project") }
113
+ capture_io { generate(:model, 'person', "name:string", "age:integer", "email:string", "-root=#{@apptmp}/sample_project") }
114
+ capture_io { generate(:model, 'page', "name:string", "body:string", "-root=#{@apptmp}/sample_project") }
115
+ capture_io { generate(:admin_page, 'person', 'page', "--root=#{@apptmp}/sample_project") }
116
+ # For Person
117
+ assert_file_exists "#{@apptmp}/sample_project/admin/controllers/people.rb"
118
+ assert_file_exists "#{@apptmp}/sample_project/admin/views/people/_form.haml"
119
+ assert_file_exists "#{@apptmp}/sample_project/admin/views/people/edit.haml"
120
+ assert_file_exists "#{@apptmp}/sample_project/admin/views/people/index.haml"
121
+ assert_file_exists "#{@apptmp}/sample_project/admin/views/people/new.haml"
122
+ %w(name age email).each do |field|
123
+ assert_match_in_file "label :#{field}", "#{@apptmp}/sample_project/admin/views/people/_form.haml"
124
+ assert_match_in_file "text_field :#{field}", "#{@apptmp}/sample_project/admin/views/people/_form.haml"
125
+ end
126
+ assert_match_in_file "role.project_module :people, '/people'", "#{@apptmp}/sample_project/admin/app.rb"
127
+ # For Page
128
+ assert_file_exists "#{@apptmp}/sample_project/admin/controllers/pages.rb"
129
+ assert_file_exists "#{@apptmp}/sample_project/admin/views/pages/_form.haml"
130
+ assert_file_exists "#{@apptmp}/sample_project/admin/views/pages/edit.haml"
131
+ assert_file_exists "#{@apptmp}/sample_project/admin/views/pages/index.haml"
132
+ assert_file_exists "#{@apptmp}/sample_project/admin/views/pages/new.haml"
133
+ %w(name body).each do |field|
134
+ assert_match_in_file "label :#{field}", "#{@apptmp}/sample_project/admin/views/pages/_form.haml"
135
+ assert_match_in_file "text_field :#{field}", "#{@apptmp}/sample_project/admin/views/pages/_form.haml"
136
+ end
137
+ assert_match_in_file "role.project_module :pages, '/pages'", "#{@apptmp}/sample_project/admin/app.rb"
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,47 @@
1
+ ENV['RACK_ENV'] = 'test'
2
+ TENNPIPES_ROOT = File.dirname(__FILE__) unless defined? TENNPIPES_ROOT
3
+
4
+ require 'minitest/autorun'
5
+ require 'minitest/pride'
6
+ require 'mocha/setup'
7
+ require 'rack/test'
8
+ require 'thor/group'
9
+ require 'dm-core'
10
+ require 'tennpipes-su'
11
+
12
+ require 'ext/minitest-spec'
13
+ require 'ext/rack-test-methods'
14
+
15
+ Tennpipes::Generators.load_components!
16
+
17
+ module Kernel
18
+ def load_fixture(file)
19
+ Object.send(:remove_const, :Account) if defined?(Account)
20
+ Object.send(:remove_const, :Category) if defined?(Category)
21
+ file += ".rb" if file !~ /.rb$/
22
+ capture_io { load File.join(File.dirname(__FILE__), "fixtures", file) }
23
+ end
24
+ end
25
+
26
+ class MiniTest::Spec
27
+ include Rack::Test::Methods
28
+
29
+ # Sets up a Sinatra::Base subclass defined with the block
30
+ # given. Used in setup or individual spec methods to establish
31
+ # the application.
32
+ def mock_app(base=Tennpipes::Application, &block)
33
+ @app = Sinatra.new base do
34
+ register Tennpipes::Helpers
35
+ instance_eval &block
36
+ end
37
+ end
38
+
39
+ def app
40
+ Rack::Lint.new(@app)
41
+ end
42
+
43
+ # generate(:admin_app, "-r=#{@apptmp}/sample_project")
44
+ def generate(name, *params)
45
+ "Tennpipes::Generators::#{name.to_s.camelize}".constantize.start(params)
46
+ end
47
+ end
@@ -0,0 +1,271 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/helper')
2
+
3
+ describe "AdminApplication" do
4
+
5
+ def setup
6
+ load_fixture 'sequel'
7
+ end
8
+
9
+ describe "session id setting" do
10
+ it "should provide it if it doesn't exist" do
11
+ mock_app do
12
+ register Tennpipes::Admin::AccessControl
13
+ end
14
+
15
+ assert_equal @app.session_id, "_tennpipes_#{File.basename(Tennpipes.root)}_#{@app.app_name}".to_sym
16
+ end
17
+
18
+ # it "should preserve it if it already existed" do
19
+ # Tennpipes.configure_apps { enable :sessions; set :session_id, "foo" }
20
+
21
+ # mock_app do
22
+ # register Tennpipes::Admin::AccessControl
23
+ # end
24
+
25
+ # assert_equal @app.session_id, "foo"
26
+ # end
27
+ end
28
+
29
+ it 'should require correctly login' do
30
+ mock_app do
31
+ register Tennpipes::Admin::AccessControl
32
+ enable :sessions
33
+
34
+ # Do a simple mapping
35
+ access_control.roles_for :any do |role|
36
+ role.protect "/foo"
37
+ end
38
+
39
+ get "/foo", :provides => [:html, :js] do
40
+ "foo"
41
+ end
42
+
43
+ get "/unauthenticated" do
44
+ "unauthenticated"
45
+ end
46
+
47
+ end
48
+
49
+ get "/foo"
50
+ assert_equal "You don't have permission for this resource", body
51
+
52
+ get "/unauthenticated"
53
+ assert_equal "unauthenticated", body
54
+ end
55
+
56
+ it 'should set basic roles with store location and login page' do
57
+ mock_app do
58
+ set :app_name, :basic_app
59
+ register Tennpipes::Admin::AccessControl
60
+ enable :store_location
61
+ enable :sessions
62
+ set :login_page, "/login"
63
+
64
+ access_control.roles_for :any do |role|
65
+ role.protect "/foo"
66
+ end
67
+
68
+ # Prepare a basic page
69
+ get "/login" do
70
+ redirect_back_or_default("/foo") if logged_in?
71
+ set_current_account(Account.admin)
72
+ "login page"
73
+ end
74
+
75
+ get "/foo" do
76
+ "foo"
77
+ end
78
+ end
79
+
80
+ get "/foo"
81
+ follow_redirect!
82
+ assert_equal "login page", body
83
+
84
+ get "/foo"
85
+ assert_equal "foo", body
86
+
87
+ get "/login"
88
+ follow_redirect!
89
+ assert_equal "foo", body
90
+ end
91
+
92
+ it 'should set advanced roles with store location and login page' do
93
+ mock_app do
94
+ register Tennpipes::Admin::AccessControl
95
+ enable :sessions
96
+
97
+ access_control.roles_for :any do |role|
98
+ role.protect "/"
99
+ role.allow "/login"
100
+ role.allow "/any"
101
+ end
102
+
103
+ access_control.roles_for :admin do |role|
104
+ role.project_module :settings, "/settings"
105
+ end
106
+
107
+ access_control.roles_for :editor do |role|
108
+ role.project_module :posts, "/posts"
109
+ end
110
+
111
+ # Prepare a basic page
112
+ get "/login(/:role)?" do
113
+ set_current_account(Account.send(params[:role])) if params[:role]
114
+ "logged as #{params[:role] || "any"}"
115
+ end
116
+
117
+ get "/any" do; "any"; end
118
+ get "/settings" do; "settings"; end
119
+ get "/posts" do; "posts"; end
120
+ end
121
+
122
+ assert @app.access_control.allowed?(Account.admin, "/login")
123
+ assert @app.access_control.allowed?(Account.admin, "/any")
124
+ assert @app.access_control.allowed?(Account.admin, "/settings")
125
+ assert ! @app.access_control.allowed?(Account.admin, "/posts")
126
+
127
+ assert @app.access_control.allowed?(Account.editor, "/login")
128
+ assert @app.access_control.allowed?(Account.editor, "/any")
129
+ assert ! @app.access_control.allowed?(Account.editor, "/settings")
130
+ assert @app.access_control.allowed?(Account.editor, "/posts")
131
+
132
+ get "/login"
133
+ assert_equal "logged as any", body
134
+
135
+ get "/any"
136
+ assert_equal "any", body
137
+
138
+ get "/settings"
139
+ assert_equal "You don't have permission for this resource", body
140
+
141
+ get "/posts"
142
+ assert_equal "You don't have permission for this resource", body
143
+
144
+ get "/login/admin"
145
+ assert_equal "logged as admin", body
146
+
147
+ get "/any"
148
+ assert_equal "any", body
149
+
150
+ get "/settings"
151
+ assert_equal "settings", body
152
+
153
+ get "/posts"
154
+ assert_equal "You don't have permission for this resource", body
155
+
156
+ get "/login/editor"
157
+ assert_equal "logged as editor", body
158
+
159
+ get "/any"
160
+ assert_equal "any", body
161
+
162
+ get "/settings"
163
+ assert_equal "You don't have permission for this resource", body
164
+
165
+ get "/posts"
166
+ assert_equal "posts", body
167
+ end
168
+
169
+ it 'should emulate an ecommerce app' do
170
+ mock_app do
171
+ register Tennpipes::Admin::AccessControl
172
+ enable :sessions
173
+
174
+ access_control.roles_for :any do |role|
175
+ role.protect "/cart"
176
+ role.allow "/cart/add"
177
+ role.allow "/cart/empty"
178
+ end
179
+
180
+ get "/login" do
181
+ set_current_account(Account.admin)
182
+ "Logged in"
183
+ end
184
+
185
+ get "/cart/checkout" do
186
+ "Checkout"
187
+ end
188
+
189
+ get "/cart/add" do
190
+ "Product Added"
191
+ end
192
+
193
+ get "/cart/empty" do
194
+ "Cart Empty"
195
+ end
196
+ end
197
+
198
+ get "/cart/checkout"
199
+ assert_equal "You don't have permission for this resource", body
200
+
201
+ get "/cart/add"
202
+ assert_equal "Product Added", body
203
+
204
+ get "/cart/empty"
205
+ assert_equal "Cart Empty", body
206
+
207
+ get "/login"
208
+ assert_equal "Logged in", body
209
+
210
+ get "/cart/checkout"
211
+ assert_equal "Checkout", body
212
+
213
+ get "/cart/add"
214
+ assert_equal "Product Added", body
215
+
216
+ get "/cart/empty"
217
+ assert_equal "Cart Empty", body
218
+ end
219
+
220
+ it 'should check access control helper' do
221
+ mock_app do
222
+ register Tennpipes::Admin::AccessControl
223
+ enable :sessions
224
+
225
+ access_control.roles_for :any do |role|
226
+ role.project_module :foo, "/foo"
227
+ role.project_module :bar, "/bar"
228
+ end
229
+
230
+ access_control.roles_for :admin do |role|
231
+ role.project_module :admin, "/admin"
232
+ end
233
+
234
+ access_control.roles_for :editor do |role|
235
+ role.project_module :editor, "/editor"
236
+ end
237
+
238
+ get "/login" do
239
+ set_current_account(Account.admin)
240
+ "Logged in"
241
+ end
242
+
243
+ get "/roles" do
244
+ access_control.roles.join(", ")
245
+ end
246
+
247
+ get "/modules" do
248
+ project_modules.map { |pm| "#{pm.name} => #{pm.path}" }.join(", ")
249
+ end
250
+
251
+ get "/modules-prefixed" do
252
+ project_modules.map { |pm| "#{pm.name} => #{pm.path("/admin")}" }.join(", ")
253
+ end
254
+ end
255
+
256
+ get "/roles"
257
+ assert_equal "admin, editor", body
258
+
259
+ get "/modules"
260
+ assert_equal "foo => /foo, bar => /bar", body
261
+
262
+ get "/modules-prefixed"
263
+ assert_equal "foo => /admin/foo, bar => /admin/bar", body
264
+
265
+ get "/login"
266
+ assert_equal "Logged in", body
267
+
268
+ get "/modules"
269
+ assert_equal "admin => /admin", body
270
+ end
271
+ end