engine_room 0.5.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 (214) hide show
  1. data/.gitignore +10 -0
  2. data/Gemfile +4 -0
  3. data/Gemfile.lock +159 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.rdoc +44 -0
  6. data/Rakefile +30 -0
  7. data/TODO +3 -0
  8. data/app/controllers/engine_room/content_controller.rb +117 -0
  9. data/app/controllers/engine_room/fields_controller.rb +119 -0
  10. data/app/controllers/engine_room/models_controller.rb +89 -0
  11. data/app/controllers/engine_room/pages_controller.rb +17 -0
  12. data/app/controllers/engine_room/sections_controller.rb +74 -0
  13. data/app/controllers/engine_room/users_controller.rb +84 -0
  14. data/app/controllers/er_devise/passwords_controller.rb +6 -0
  15. data/app/controllers/er_devise/registrations_controller.rb +8 -0
  16. data/app/controllers/er_devise/sessions_controller.rb +6 -0
  17. data/app/helpers/engine_room/content_helper.rb +103 -0
  18. data/app/helpers/engine_room/models_helper.rb +21 -0
  19. data/app/models/field.rb +89 -0
  20. data/app/models/section.rb +68 -0
  21. data/app/models/user.rb +31 -0
  22. data/app/views/engine_room/content/_form.html.erb +13 -0
  23. data/app/views/engine_room/content/_overview.html.erb +28 -0
  24. data/app/views/engine_room/content/_sidebar.html.erb +14 -0
  25. data/app/views/engine_room/content/edit.html.erb +38 -0
  26. data/app/views/engine_room/content/index.html.erb +1 -0
  27. data/app/views/engine_room/content/new.html.erb +1 -0
  28. data/app/views/engine_room/content/overview.html.erb +3 -0
  29. data/app/views/engine_room/fields/_form.html.erb +57 -0
  30. data/app/views/engine_room/fields/edit.html.erb +1 -0
  31. data/app/views/engine_room/fields/new.html.erb +1 -0
  32. data/app/views/engine_room/models/_form.html.erb +0 -0
  33. data/app/views/engine_room/models/edit.html.erb +14 -0
  34. data/app/views/engine_room/models/index.html.erb +16 -0
  35. data/app/views/engine_room/models/new.html.erb +14 -0
  36. data/app/views/engine_room/models/overview.html.erb +14 -0
  37. data/app/views/engine_room/pages/dashboard.html.erb +1 -0
  38. data/app/views/engine_room/pages/settings.html.erb +1 -0
  39. data/app/views/engine_room/sections/_form.html.erb +34 -0
  40. data/app/views/engine_room/sections/_sidebar.html.erb +11 -0
  41. data/app/views/engine_room/sections/edit.html.erb +81 -0
  42. data/app/views/engine_room/sections/index.html.erb +3 -0
  43. data/app/views/engine_room/sections/new.html.erb +1 -0
  44. data/app/views/engine_room/users/_form.html.erb +47 -0
  45. data/app/views/engine_room/users/edit.html.erb +11 -0
  46. data/app/views/engine_room/users/index.html.erb +24 -0
  47. data/app/views/engine_room/users/new.html.erb +1 -0
  48. data/app/views/er_devise/mailer/confirmation_instructions.html.erb +5 -0
  49. data/app/views/er_devise/mailer/reset_password_instructions.html.erb +8 -0
  50. data/app/views/er_devise/mailer/unlock_instructions.html.erb +7 -0
  51. data/app/views/er_devise/passwords/edit.html.erb +16 -0
  52. data/app/views/er_devise/passwords/new.html.erb +13 -0
  53. data/app/views/er_devise/registrations/edit.html.erb +42 -0
  54. data/app/views/er_devise/registrations/new.html.erb +21 -0
  55. data/app/views/er_devise/sessions/new.html.erb +23 -0
  56. data/app/views/er_devise/shared/_links.erb +19 -0
  57. data/app/views/layouts/engine_room.html.erb +103 -0
  58. data/app/views/layouts/login.html.erb +71 -0
  59. data/app/views/shared/_content_layout_selector.html.erb +45 -0
  60. data/app/views/shared/_error_messages.html.erb +17 -0
  61. data/config/initializers/devise.rb +146 -0
  62. data/config/initializers/locale.rb +5 -0
  63. data/config/locales/devise.de.yml +42 -0
  64. data/config/locales/devise.en.yml +39 -0
  65. data/config/locales/engine_room.de.yml +33 -0
  66. data/config/locales/engine_room.en.yml +42 -0
  67. data/config/routes.rb +62 -0
  68. data/engine_room.gemspec +35 -0
  69. data/lib/engine_room.rb +17 -0
  70. data/lib/engine_room/action_controller/controller_methods.rb +21 -0
  71. data/lib/engine_room/action_view/view_methods.rb +8 -0
  72. data/lib/engine_room/active_record/record_methods.rb +18 -0
  73. data/lib/engine_room/crummy/custom_renderer.rb +63 -0
  74. data/lib/engine_room/engine.rb +40 -0
  75. data/lib/engine_room/railties/tasks.rake +6 -0
  76. data/lib/engine_room/version.rb +3 -0
  77. data/lib/generators/engine_room/create_image_generator.rb +26 -0
  78. data/lib/generators/engine_room/setup_generator.rb +30 -0
  79. data/lib/generators/engine_room/templates/001_devise_create_users.rb +28 -0
  80. data/lib/generators/engine_room/templates/002_create_sections.rb +16 -0
  81. data/lib/generators/engine_room/templates/003_create_fields.rb +18 -0
  82. data/lib/generators/engine_room/templates/004_create_images.rb +19 -0
  83. data/lib/generators/engine_room/templates/image.rb +4 -0
  84. data/lib/tasks/dummy.rake +45 -0
  85. data/lib/tasks/templates/migrate/050_create_dogs.rb +18 -0
  86. data/lib/tasks/templates/models/dog.rb +3 -0
  87. data/public/images/er/accept.png +0 -0
  88. data/public/images/er/add.png +0 -0
  89. data/public/images/er/add_small.png +0 -0
  90. data/public/images/er/ajax-loader.gif +0 -0
  91. data/public/images/er/attach.png +0 -0
  92. data/public/images/er/back_disabled.jpg +0 -0
  93. data/public/images/er/back_enabled.jpg +0 -0
  94. data/public/images/er/bg/header_gradient_center.jpg +0 -0
  95. data/public/images/er/bg/header_gradient_left.jpg +0 -0
  96. data/public/images/er/bg/header_gradient_right.jpg +0 -0
  97. data/public/images/er/cancel.png +0 -0
  98. data/public/images/er/cog.png +0 -0
  99. data/public/images/er/database_add.png +0 -0
  100. data/public/images/er/delete.png +0 -0
  101. data/public/images/er/delete_small.png +0 -0
  102. data/public/images/er/down_arrow.gif +0 -0
  103. data/public/images/er/down_arrow.png +0 -0
  104. data/public/images/er/email.png +0 -0
  105. data/public/images/er/exclamation.png +0 -0
  106. data/public/images/er/forward_disabled.jpg +0 -0
  107. data/public/images/er/forward_enabled.jpg +0 -0
  108. data/public/images/er/help.png +0 -0
  109. data/public/images/er/image_add.png +0 -0
  110. data/public/images/er/information.png +0 -0
  111. data/public/images/er/link.png +0 -0
  112. data/public/images/er/loader.gif +0 -0
  113. data/public/images/er/telephone.png +0 -0
  114. data/public/images/er/up_arrow.gif +0 -0
  115. data/public/images/er/up_arrow.png +0 -0
  116. data/public/images/er/user.png +0 -0
  117. data/public/images/er/wrench.png +0 -0
  118. data/public/images/er/zoom.png +0 -0
  119. data/public/javascripts/er/dd_belatedpng.js +328 -0
  120. data/public/javascripts/er/fancybox/blank.gif +0 -0
  121. data/public/javascripts/er/fancybox/fancy_close.png +0 -0
  122. data/public/javascripts/er/fancybox/fancy_loading.png +0 -0
  123. data/public/javascripts/er/fancybox/fancy_nav_left.png +0 -0
  124. data/public/javascripts/er/fancybox/fancy_nav_right.png +0 -0
  125. data/public/javascripts/er/fancybox/fancy_shadow_e.png +0 -0
  126. data/public/javascripts/er/fancybox/fancy_shadow_n.png +0 -0
  127. data/public/javascripts/er/fancybox/fancy_shadow_ne.png +0 -0
  128. data/public/javascripts/er/fancybox/fancy_shadow_nw.png +0 -0
  129. data/public/javascripts/er/fancybox/fancy_shadow_s.png +0 -0
  130. data/public/javascripts/er/fancybox/fancy_shadow_se.png +0 -0
  131. data/public/javascripts/er/fancybox/fancy_shadow_sw.png +0 -0
  132. data/public/javascripts/er/fancybox/fancy_shadow_w.png +0 -0
  133. data/public/javascripts/er/fancybox/fancy_title_left.png +0 -0
  134. data/public/javascripts/er/fancybox/fancy_title_main.png +0 -0
  135. data/public/javascripts/er/fancybox/fancy_title_over.png +0 -0
  136. data/public/javascripts/er/fancybox/fancy_title_right.png +0 -0
  137. data/public/javascripts/er/fancybox/fancybox-x.png +0 -0
  138. data/public/javascripts/er/fancybox/fancybox-y.png +0 -0
  139. data/public/javascripts/er/fancybox/fancybox.png +0 -0
  140. data/public/javascripts/er/fancybox/jquery.fancybox-1.3.4.css +359 -0
  141. data/public/javascripts/er/fancybox/jquery.fancybox-1.3.4.pack.js +46 -0
  142. data/public/javascripts/er/jquery-1.4.4.min.js +167 -0
  143. data/public/javascripts/er/jquery-ui-1.8.6.custom.min.js +477 -0
  144. data/public/javascripts/er/modernizr-1.5.min.js +28 -0
  145. data/public/javascripts/er/plugins.js +48 -0
  146. data/public/javascripts/er/rails.js +156 -0
  147. data/public/javascripts/er/script.js +50 -0
  148. data/public/stylesheets/.gitkeep +0 -0
  149. data/public/stylesheets/admin.css +417 -0
  150. data/public/stylesheets/boilerplate.css +264 -0
  151. data/public/stylesheets/handheld.css +7 -0
  152. data/public/stylesheets/login.css +125 -0
  153. data/public/stylesheets/skin.css +2 -0
  154. data/public/stylesheets/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  155. data/public/stylesheets/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  156. data/public/stylesheets/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  157. data/public/stylesheets/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  158. data/public/stylesheets/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  159. data/public/stylesheets/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  160. data/public/stylesheets/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  161. data/public/stylesheets/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  162. data/public/stylesheets/smoothness/images/ui-icons_222222_256x240.png +0 -0
  163. data/public/stylesheets/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  164. data/public/stylesheets/smoothness/images/ui-icons_454545_256x240.png +0 -0
  165. data/public/stylesheets/smoothness/images/ui-icons_888888_256x240.png +0 -0
  166. data/public/stylesheets/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  167. data/public/stylesheets/smoothness/jquery-ui-1.8.6.custom.css +479 -0
  168. data/spec/controllers/content_controller_spec.rb +132 -0
  169. data/spec/controllers/fields_controller_spec.rb +103 -0
  170. data/spec/controllers/models_controller_spec.rb +65 -0
  171. data/spec/controllers/pages_controller_spec.rb +40 -0
  172. data/spec/controllers/sections_controller_spec.rb +124 -0
  173. data/spec/dummy/Rakefile +7 -0
  174. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  175. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  176. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  177. data/spec/dummy/config.ru +4 -0
  178. data/spec/dummy/config/application.rb +45 -0
  179. data/spec/dummy/config/boot.rb +10 -0
  180. data/spec/dummy/config/database.yml +22 -0
  181. data/spec/dummy/config/environment.rb +5 -0
  182. data/spec/dummy/config/environments/development.rb +26 -0
  183. data/spec/dummy/config/environments/production.rb +49 -0
  184. data/spec/dummy/config/environments/test.rb +35 -0
  185. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  186. data/spec/dummy/config/initializers/inflections.rb +10 -0
  187. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  188. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  189. data/spec/dummy/config/initializers/session_store.rb +8 -0
  190. data/spec/dummy/config/locales/en.yml +5 -0
  191. data/spec/dummy/config/routes.rb +58 -0
  192. data/spec/dummy/public/404.html +26 -0
  193. data/spec/dummy/public/422.html +26 -0
  194. data/spec/dummy/public/500.html +26 -0
  195. data/spec/dummy/public/favicon.ico +0 -0
  196. data/spec/dummy/public/javascripts/application.js +2 -0
  197. data/spec/dummy/public/javascripts/controls.js +965 -0
  198. data/spec/dummy/public/javascripts/dragdrop.js +974 -0
  199. data/spec/dummy/public/javascripts/effects.js +1123 -0
  200. data/spec/dummy/public/javascripts/prototype.js +6001 -0
  201. data/spec/dummy/public/javascripts/rails.js +175 -0
  202. data/spec/dummy/public/stylesheets/.gitkeep +0 -0
  203. data/spec/dummy/script/rails +6 -0
  204. data/spec/engine_room_spec.rb +7 -0
  205. data/spec/factories.rb +32 -0
  206. data/spec/integration/navigation_spec.rb +9 -0
  207. data/spec/models/dog_spec.rb +14 -0
  208. data/spec/models/field_spec.rb +74 -0
  209. data/spec/models/section_spec.rb +70 -0
  210. data/spec/models/user_spec.rb +77 -0
  211. data/spec/routing/models_routing_spec.rb +66 -0
  212. data/spec/spec_helper.rb +39 -0
  213. data/spec/support/devise.rb +3 -0
  214. metadata +492 -0
@@ -0,0 +1,175 @@
1
+ (function() {
2
+ // Technique from Juriy Zaytsev
3
+ // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
4
+ function isEventSupported(eventName) {
5
+ var el = document.createElement('div');
6
+ eventName = 'on' + eventName;
7
+ var isSupported = (eventName in el);
8
+ if (!isSupported) {
9
+ el.setAttribute(eventName, 'return;');
10
+ isSupported = typeof el[eventName] == 'function';
11
+ }
12
+ el = null;
13
+ return isSupported;
14
+ }
15
+
16
+ function isForm(element) {
17
+ return Object.isElement(element) && element.nodeName.toUpperCase() == 'FORM'
18
+ }
19
+
20
+ function isInput(element) {
21
+ if (Object.isElement(element)) {
22
+ var name = element.nodeName.toUpperCase()
23
+ return name == 'INPUT' || name == 'SELECT' || name == 'TEXTAREA'
24
+ }
25
+ else return false
26
+ }
27
+
28
+ var submitBubbles = isEventSupported('submit'),
29
+ changeBubbles = isEventSupported('change')
30
+
31
+ if (!submitBubbles || !changeBubbles) {
32
+ // augment the Event.Handler class to observe custom events when needed
33
+ Event.Handler.prototype.initialize = Event.Handler.prototype.initialize.wrap(
34
+ function(init, element, eventName, selector, callback) {
35
+ init(element, eventName, selector, callback)
36
+ // is the handler being attached to an element that doesn't support this event?
37
+ if ( (!submitBubbles && this.eventName == 'submit' && !isForm(this.element)) ||
38
+ (!changeBubbles && this.eventName == 'change' && !isInput(this.element)) ) {
39
+ // "submit" => "emulated:submit"
40
+ this.eventName = 'emulated:' + this.eventName
41
+ }
42
+ }
43
+ )
44
+ }
45
+
46
+ if (!submitBubbles) {
47
+ // discover forms on the page by observing focus events which always bubble
48
+ document.on('focusin', 'form', function(focusEvent, form) {
49
+ // special handler for the real "submit" event (one-time operation)
50
+ if (!form.retrieve('emulated:submit')) {
51
+ form.on('submit', function(submitEvent) {
52
+ var emulated = form.fire('emulated:submit', submitEvent, true)
53
+ // if custom event received preventDefault, cancel the real one too
54
+ if (emulated.returnValue === false) submitEvent.preventDefault()
55
+ })
56
+ form.store('emulated:submit', true)
57
+ }
58
+ })
59
+ }
60
+
61
+ if (!changeBubbles) {
62
+ // discover form inputs on the page
63
+ document.on('focusin', 'input, select, texarea', function(focusEvent, input) {
64
+ // special handler for real "change" events
65
+ if (!input.retrieve('emulated:change')) {
66
+ input.on('change', function(changeEvent) {
67
+ input.fire('emulated:change', changeEvent, true)
68
+ })
69
+ input.store('emulated:change', true)
70
+ }
71
+ })
72
+ }
73
+
74
+ function handleRemote(element) {
75
+ var method, url, params;
76
+
77
+ var event = element.fire("ajax:before");
78
+ if (event.stopped) return false;
79
+
80
+ if (element.tagName.toLowerCase() === 'form') {
81
+ method = element.readAttribute('method') || 'post';
82
+ url = element.readAttribute('action');
83
+ params = element.serialize();
84
+ } else {
85
+ method = element.readAttribute('data-method') || 'get';
86
+ url = element.readAttribute('href');
87
+ params = {};
88
+ }
89
+
90
+ new Ajax.Request(url, {
91
+ method: method,
92
+ parameters: params,
93
+ evalScripts: true,
94
+
95
+ onComplete: function(request) { element.fire("ajax:complete", request); },
96
+ onSuccess: function(request) { element.fire("ajax:success", request); },
97
+ onFailure: function(request) { element.fire("ajax:failure", request); }
98
+ });
99
+
100
+ element.fire("ajax:after");
101
+ }
102
+
103
+ function handleMethod(element) {
104
+ var method = element.readAttribute('data-method'),
105
+ url = element.readAttribute('href'),
106
+ csrf_param = $$('meta[name=csrf-param]')[0],
107
+ csrf_token = $$('meta[name=csrf-token]')[0];
108
+
109
+ var form = new Element('form', { method: "POST", action: url, style: "display: none;" });
110
+ element.parentNode.insert(form);
111
+
112
+ if (method !== 'post') {
113
+ var field = new Element('input', { type: 'hidden', name: '_method', value: method });
114
+ form.insert(field);
115
+ }
116
+
117
+ if (csrf_param) {
118
+ var param = csrf_param.readAttribute('content'),
119
+ token = csrf_token.readAttribute('content'),
120
+ field = new Element('input', { type: 'hidden', name: param, value: token });
121
+ form.insert(field);
122
+ }
123
+
124
+ form.submit();
125
+ }
126
+
127
+
128
+ document.on("click", "*[data-confirm]", function(event, element) {
129
+ var message = element.readAttribute('data-confirm');
130
+ if (!confirm(message)) event.stop();
131
+ });
132
+
133
+ document.on("click", "a[data-remote]", function(event, element) {
134
+ if (event.stopped) return;
135
+ handleRemote(element);
136
+ event.stop();
137
+ });
138
+
139
+ document.on("click", "a[data-method]", function(event, element) {
140
+ if (event.stopped) return;
141
+ handleMethod(element);
142
+ event.stop();
143
+ });
144
+
145
+ document.on("submit", function(event) {
146
+ var element = event.findElement(),
147
+ message = element.readAttribute('data-confirm');
148
+ if (message && !confirm(message)) {
149
+ event.stop();
150
+ return false;
151
+ }
152
+
153
+ var inputs = element.select("input[type=submit][data-disable-with]");
154
+ inputs.each(function(input) {
155
+ input.disabled = true;
156
+ input.writeAttribute('data-original-value', input.value);
157
+ input.value = input.readAttribute('data-disable-with');
158
+ });
159
+
160
+ var element = event.findElement("form[data-remote]");
161
+ if (element) {
162
+ handleRemote(element);
163
+ event.stop();
164
+ }
165
+ });
166
+
167
+ document.on("ajax:after", "form", function(event, element) {
168
+ var inputs = element.select("input[type=submit][disabled=true][data-disable-with]");
169
+ inputs.each(function(input) {
170
+ input.value = input.readAttribute('data-original-value');
171
+ input.removeAttribute('data-original-value');
172
+ input.disabled = false;
173
+ });
174
+ });
175
+ })();
File without changes
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
5
+ require File.expand_path('../../config/boot', __FILE__)
6
+ require 'rails/commands'
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe EngineRoom do
4
+ it "should be valid" do
5
+ EngineRoom.should be_a(Module)
6
+ end
7
+ end
data/spec/factories.rb ADDED
@@ -0,0 +1,32 @@
1
+ require 'factory_girl'
2
+
3
+ # By using the symbol ':user', we get Facory Firl to simulate the User model.
4
+ Factory.define :user do |user|
5
+ user.username "jdoe"
6
+ user.email "jdoe@test.com"
7
+ user.password "foobar123"
8
+ user.password_confirmation "foobar123"
9
+ user.is_admin 1
10
+ end
11
+
12
+ Factory.define :section do |section|
13
+ section.name "Dogs"
14
+ section.model_name "dog"
15
+ section.sort_order 1
16
+ end
17
+
18
+ Factory.define :field do |field|
19
+ field.column "name"
20
+ field.field_type "text_field"
21
+ field.sort_order 1
22
+ field.display_type "detail"
23
+ field.help "please fill in field."
24
+ field.association :section
25
+ end
26
+
27
+ Factory.define :dog do |dog|
28
+ dog.name "Sigmund"
29
+ dog.color "golden"
30
+ dog.description "awesome"
31
+ dog.fleas 13
32
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Navigation" do
4
+ include Capybara
5
+
6
+ it "should be a valid app" do
7
+ ::Rails.application.should be_a(Dummy::Application)
8
+ end
9
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dog do
4
+
5
+ it "should create new instance given valid attributes" do
6
+ @attr = {
7
+ :name => "Sigmund",
8
+ :color => "golden",
9
+ :description => "awesome",
10
+ :fleas => 1
11
+ }
12
+ dog = Dog.create!(@attr)
13
+ end
14
+ end
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+ require 'factories'
3
+
4
+ describe Field do
5
+
6
+ before(:each) do
7
+ @section = Factory(:section)
8
+ @attr = {
9
+ :column => "name",
10
+ :field_type => "text_field",
11
+ :display_type => "detail"
12
+ }
13
+ end
14
+
15
+ it "should create a new instance given valid attributes" do
16
+ @section.fields.create!(@attr)
17
+ end
18
+
19
+ describe "section associations" do
20
+
21
+ before(:each) do
22
+ @field = @section.fields.create(@attr)
23
+ end
24
+
25
+ it "should have a section attribute" do
26
+ @field.should respond_to(:section)
27
+ end
28
+
29
+ it "should have the right associated section" do
30
+ @field.section_id.should == @section.id
31
+ @field.section.should == @section
32
+ end
33
+ end
34
+
35
+ describe "validations" do
36
+
37
+ it "should require a section id" do
38
+ Field.new(@attr).should_not be_valid
39
+ end
40
+
41
+ it "should require nonblank column" do
42
+ @section.fields.build(@attr.merge(:column => " ")).should_not be_valid
43
+ end
44
+
45
+ it "should require nonblank field_type" do
46
+ @section.fields.build(@attr.merge(:field_type => " ")).should_not be_valid
47
+ end
48
+
49
+ it "should reject invalid field_types" do
50
+ @section.fields.build(@attr.merge(:field_type => "foo")).should_not be_valid
51
+ end
52
+
53
+ it "should accept valid field_types" do
54
+ @section.fields.build(@attr.merge(:field_type => "boolean")).should be_valid
55
+ end
56
+ end
57
+
58
+ describe "options hash" do
59
+
60
+ before(:each) do
61
+ @field = @section.fields.create!(@attr)
62
+ end
63
+
64
+ it "should respond to is_overview_link" do
65
+ @field.should respond_to(:overview_link)
66
+ end
67
+
68
+ it "should set and retrieve value through is_overview_link" do
69
+ @field.overview_link = true
70
+ @field.save
71
+ @field.overview_link.should be_true
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+ require 'factories'
3
+
4
+ describe Section do
5
+
6
+ before(:each) do
7
+ @attr = {
8
+ :name => "Section Name",
9
+ :model_name => "dog"
10
+ }
11
+ end
12
+
13
+ it "should create a new instance given valid attributes" do
14
+ Section.create!(@attr)
15
+ end
16
+
17
+ it "should require a name" do
18
+ no_name_section = Section.new(@attr.merge(:name => ""))
19
+ no_name_section.should_not be_valid
20
+ end
21
+
22
+ it "should require a model_name" do
23
+ no_email_section = Section.new(@attr.merge(:model_name => ""))
24
+ no_email_section.should_not be_valid
25
+ end
26
+
27
+ it "should reject invalid model_names" do
28
+ section = Section.new(@attr.merge(:model_name => "foobar"))
29
+ section.should_not be_valid
30
+ end
31
+
32
+ it "should accept 'dog' as valid model name" do
33
+ # dog is dummy model
34
+ Section.model_names.include?("dog").should be_true
35
+ end
36
+
37
+ it "should return model from model_name" do
38
+ section = Factory(:section)
39
+ section.model.name.should == section.model_name.camelize
40
+ end
41
+
42
+ it "should return valid column names" do
43
+ section = Factory(:section)
44
+ section.column_names.should == ["id","name","color","description","fleas","created_at","updated_at"]
45
+ end
46
+
47
+ describe "field associations" do
48
+
49
+ before(:each) do
50
+ @section = Section.create(@attr)
51
+ @field1 = Factory(:field, :section => @section, :sort_order => 5)
52
+ @field2 = Factory(:field, :section => @section, :sort_order => 2)
53
+ end
54
+
55
+ it "should have a fields attribute" do
56
+ @section.should respond_to(:fields)
57
+ end
58
+
59
+ it "should have the right fields in the right order" do
60
+ @section.fields.should == [@field2, @field1]
61
+ end
62
+
63
+ it "should destroy associated fields" do
64
+ @section.destroy
65
+ [@field1, @field2].each do |field|
66
+ Field.find_by_id(field.id).should be_nil
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+
3
+ describe User do
4
+
5
+ before(:each) do
6
+ @attr = {
7
+ :username => "Example User",
8
+ :email => "user@example.com",
9
+ :password => "foobar",
10
+ :password_confirmation => "foobar"
11
+ }
12
+ end
13
+
14
+ it "should create new instance given valid attributes" do
15
+ user = User.new(@attr)
16
+ user.should be_valid
17
+ user.save.should be_true
18
+ end
19
+
20
+ it "should require an email address" do
21
+ no_email_user = User.new(@attr.merge(:email => ""))
22
+ no_email_user.should_not be_valid
23
+ end
24
+
25
+ it "should accept valid email addresses" do
26
+ addresses = %w[user@foo.com THE_USER@foo.bar.com first.last@foo.jp]
27
+ addresses.each do |address|
28
+ valid_email_user = User.new(@attr.merge(:email => address))
29
+ valid_email_user.should be_valid
30
+ end
31
+ end
32
+
33
+ it "should reject invalid email address" do
34
+ addresses = %w[user@foo,com user_at_foo.org example.user@foo.]
35
+ addresses.each do |address|
36
+ invalid_email_user = User.new(@attr.merge(:email => address))
37
+ invalid_email_user.should_not be_valid
38
+ end
39
+ end
40
+
41
+ it "should reject duplicate email addresses" do
42
+ # Put a user with given email address into the database
43
+ User.create!(@attr)
44
+ user_with_duplicate_email = User.new(@attr)
45
+ user_with_duplicate_email.should_not be_valid
46
+ end
47
+
48
+ it "should reject email addresses identical up to case" do
49
+ upcased_email = @attr[:email].upcase
50
+ User.create!(@attr.merge(:email => upcased_email))
51
+ user_with_duplicate_email = User.new(@attr)
52
+ user_with_duplicate_email.should_not be_valid
53
+ end
54
+
55
+ describe "password validations" do
56
+
57
+ it "should require a password" do
58
+ User.new(@attr.merge(:password => "", :password_confirmation => "")).should_not be_valid
59
+ end
60
+
61
+ it "should require a matching password confirmation" do
62
+ User.new(@attr.merge(:password_confirmation => "invalid")).should_not be_valid
63
+ end
64
+
65
+ it "should reject short passwords" do
66
+ short = "a" * 5
67
+ hash = @attr.merge(:password => short, :password_confirmation => short)
68
+ User.new(hash).should_not be_valid
69
+ end
70
+
71
+ it "should reject long passwords" do
72
+ long = "a" * 41
73
+ hash = @attr.merge(:password => long, :password_confirmation => long)
74
+ User.new(hash).should_not be_valid
75
+ end
76
+ end
77
+ end