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.
- data/.gitignore +10 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +159 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +44 -0
- data/Rakefile +30 -0
- data/TODO +3 -0
- data/app/controllers/engine_room/content_controller.rb +117 -0
- data/app/controllers/engine_room/fields_controller.rb +119 -0
- data/app/controllers/engine_room/models_controller.rb +89 -0
- data/app/controllers/engine_room/pages_controller.rb +17 -0
- data/app/controllers/engine_room/sections_controller.rb +74 -0
- data/app/controllers/engine_room/users_controller.rb +84 -0
- data/app/controllers/er_devise/passwords_controller.rb +6 -0
- data/app/controllers/er_devise/registrations_controller.rb +8 -0
- data/app/controllers/er_devise/sessions_controller.rb +6 -0
- data/app/helpers/engine_room/content_helper.rb +103 -0
- data/app/helpers/engine_room/models_helper.rb +21 -0
- data/app/models/field.rb +89 -0
- data/app/models/section.rb +68 -0
- data/app/models/user.rb +31 -0
- data/app/views/engine_room/content/_form.html.erb +13 -0
- data/app/views/engine_room/content/_overview.html.erb +28 -0
- data/app/views/engine_room/content/_sidebar.html.erb +14 -0
- data/app/views/engine_room/content/edit.html.erb +38 -0
- data/app/views/engine_room/content/index.html.erb +1 -0
- data/app/views/engine_room/content/new.html.erb +1 -0
- data/app/views/engine_room/content/overview.html.erb +3 -0
- data/app/views/engine_room/fields/_form.html.erb +57 -0
- data/app/views/engine_room/fields/edit.html.erb +1 -0
- data/app/views/engine_room/fields/new.html.erb +1 -0
- data/app/views/engine_room/models/_form.html.erb +0 -0
- data/app/views/engine_room/models/edit.html.erb +14 -0
- data/app/views/engine_room/models/index.html.erb +16 -0
- data/app/views/engine_room/models/new.html.erb +14 -0
- data/app/views/engine_room/models/overview.html.erb +14 -0
- data/app/views/engine_room/pages/dashboard.html.erb +1 -0
- data/app/views/engine_room/pages/settings.html.erb +1 -0
- data/app/views/engine_room/sections/_form.html.erb +34 -0
- data/app/views/engine_room/sections/_sidebar.html.erb +11 -0
- data/app/views/engine_room/sections/edit.html.erb +81 -0
- data/app/views/engine_room/sections/index.html.erb +3 -0
- data/app/views/engine_room/sections/new.html.erb +1 -0
- data/app/views/engine_room/users/_form.html.erb +47 -0
- data/app/views/engine_room/users/edit.html.erb +11 -0
- data/app/views/engine_room/users/index.html.erb +24 -0
- data/app/views/engine_room/users/new.html.erb +1 -0
- data/app/views/er_devise/mailer/confirmation_instructions.html.erb +5 -0
- data/app/views/er_devise/mailer/reset_password_instructions.html.erb +8 -0
- data/app/views/er_devise/mailer/unlock_instructions.html.erb +7 -0
- data/app/views/er_devise/passwords/edit.html.erb +16 -0
- data/app/views/er_devise/passwords/new.html.erb +13 -0
- data/app/views/er_devise/registrations/edit.html.erb +42 -0
- data/app/views/er_devise/registrations/new.html.erb +21 -0
- data/app/views/er_devise/sessions/new.html.erb +23 -0
- data/app/views/er_devise/shared/_links.erb +19 -0
- data/app/views/layouts/engine_room.html.erb +103 -0
- data/app/views/layouts/login.html.erb +71 -0
- data/app/views/shared/_content_layout_selector.html.erb +45 -0
- data/app/views/shared/_error_messages.html.erb +17 -0
- data/config/initializers/devise.rb +146 -0
- data/config/initializers/locale.rb +5 -0
- data/config/locales/devise.de.yml +42 -0
- data/config/locales/devise.en.yml +39 -0
- data/config/locales/engine_room.de.yml +33 -0
- data/config/locales/engine_room.en.yml +42 -0
- data/config/routes.rb +62 -0
- data/engine_room.gemspec +35 -0
- data/lib/engine_room.rb +17 -0
- data/lib/engine_room/action_controller/controller_methods.rb +21 -0
- data/lib/engine_room/action_view/view_methods.rb +8 -0
- data/lib/engine_room/active_record/record_methods.rb +18 -0
- data/lib/engine_room/crummy/custom_renderer.rb +63 -0
- data/lib/engine_room/engine.rb +40 -0
- data/lib/engine_room/railties/tasks.rake +6 -0
- data/lib/engine_room/version.rb +3 -0
- data/lib/generators/engine_room/create_image_generator.rb +26 -0
- data/lib/generators/engine_room/setup_generator.rb +30 -0
- data/lib/generators/engine_room/templates/001_devise_create_users.rb +28 -0
- data/lib/generators/engine_room/templates/002_create_sections.rb +16 -0
- data/lib/generators/engine_room/templates/003_create_fields.rb +18 -0
- data/lib/generators/engine_room/templates/004_create_images.rb +19 -0
- data/lib/generators/engine_room/templates/image.rb +4 -0
- data/lib/tasks/dummy.rake +45 -0
- data/lib/tasks/templates/migrate/050_create_dogs.rb +18 -0
- data/lib/tasks/templates/models/dog.rb +3 -0
- data/public/images/er/accept.png +0 -0
- data/public/images/er/add.png +0 -0
- data/public/images/er/add_small.png +0 -0
- data/public/images/er/ajax-loader.gif +0 -0
- data/public/images/er/attach.png +0 -0
- data/public/images/er/back_disabled.jpg +0 -0
- data/public/images/er/back_enabled.jpg +0 -0
- data/public/images/er/bg/header_gradient_center.jpg +0 -0
- data/public/images/er/bg/header_gradient_left.jpg +0 -0
- data/public/images/er/bg/header_gradient_right.jpg +0 -0
- data/public/images/er/cancel.png +0 -0
- data/public/images/er/cog.png +0 -0
- data/public/images/er/database_add.png +0 -0
- data/public/images/er/delete.png +0 -0
- data/public/images/er/delete_small.png +0 -0
- data/public/images/er/down_arrow.gif +0 -0
- data/public/images/er/down_arrow.png +0 -0
- data/public/images/er/email.png +0 -0
- data/public/images/er/exclamation.png +0 -0
- data/public/images/er/forward_disabled.jpg +0 -0
- data/public/images/er/forward_enabled.jpg +0 -0
- data/public/images/er/help.png +0 -0
- data/public/images/er/image_add.png +0 -0
- data/public/images/er/information.png +0 -0
- data/public/images/er/link.png +0 -0
- data/public/images/er/loader.gif +0 -0
- data/public/images/er/telephone.png +0 -0
- data/public/images/er/up_arrow.gif +0 -0
- data/public/images/er/up_arrow.png +0 -0
- data/public/images/er/user.png +0 -0
- data/public/images/er/wrench.png +0 -0
- data/public/images/er/zoom.png +0 -0
- data/public/javascripts/er/dd_belatedpng.js +328 -0
- data/public/javascripts/er/fancybox/blank.gif +0 -0
- data/public/javascripts/er/fancybox/fancy_close.png +0 -0
- data/public/javascripts/er/fancybox/fancy_loading.png +0 -0
- data/public/javascripts/er/fancybox/fancy_nav_left.png +0 -0
- data/public/javascripts/er/fancybox/fancy_nav_right.png +0 -0
- data/public/javascripts/er/fancybox/fancy_shadow_e.png +0 -0
- data/public/javascripts/er/fancybox/fancy_shadow_n.png +0 -0
- data/public/javascripts/er/fancybox/fancy_shadow_ne.png +0 -0
- data/public/javascripts/er/fancybox/fancy_shadow_nw.png +0 -0
- data/public/javascripts/er/fancybox/fancy_shadow_s.png +0 -0
- data/public/javascripts/er/fancybox/fancy_shadow_se.png +0 -0
- data/public/javascripts/er/fancybox/fancy_shadow_sw.png +0 -0
- data/public/javascripts/er/fancybox/fancy_shadow_w.png +0 -0
- data/public/javascripts/er/fancybox/fancy_title_left.png +0 -0
- data/public/javascripts/er/fancybox/fancy_title_main.png +0 -0
- data/public/javascripts/er/fancybox/fancy_title_over.png +0 -0
- data/public/javascripts/er/fancybox/fancy_title_right.png +0 -0
- data/public/javascripts/er/fancybox/fancybox-x.png +0 -0
- data/public/javascripts/er/fancybox/fancybox-y.png +0 -0
- data/public/javascripts/er/fancybox/fancybox.png +0 -0
- data/public/javascripts/er/fancybox/jquery.fancybox-1.3.4.css +359 -0
- data/public/javascripts/er/fancybox/jquery.fancybox-1.3.4.pack.js +46 -0
- data/public/javascripts/er/jquery-1.4.4.min.js +167 -0
- data/public/javascripts/er/jquery-ui-1.8.6.custom.min.js +477 -0
- data/public/javascripts/er/modernizr-1.5.min.js +28 -0
- data/public/javascripts/er/plugins.js +48 -0
- data/public/javascripts/er/rails.js +156 -0
- data/public/javascripts/er/script.js +50 -0
- data/public/stylesheets/.gitkeep +0 -0
- data/public/stylesheets/admin.css +417 -0
- data/public/stylesheets/boilerplate.css +264 -0
- data/public/stylesheets/handheld.css +7 -0
- data/public/stylesheets/login.css +125 -0
- data/public/stylesheets/skin.css +2 -0
- data/public/stylesheets/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/public/stylesheets/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/public/stylesheets/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/public/stylesheets/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/public/stylesheets/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/public/stylesheets/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/public/stylesheets/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/public/stylesheets/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/public/stylesheets/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/public/stylesheets/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/public/stylesheets/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/public/stylesheets/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/public/stylesheets/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/public/stylesheets/smoothness/jquery-ui-1.8.6.custom.css +479 -0
- data/spec/controllers/content_controller_spec.rb +132 -0
- data/spec/controllers/fields_controller_spec.rb +103 -0
- data/spec/controllers/models_controller_spec.rb +65 -0
- data/spec/controllers/pages_controller_spec.rb +40 -0
- data/spec/controllers/sections_controller_spec.rb +124 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +45 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +22 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +26 -0
- data/spec/dummy/config/environments/production.rb +49 -0
- data/spec/dummy/config/environments/test.rb +35 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +58 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/javascripts/application.js +2 -0
- data/spec/dummy/public/javascripts/controls.js +965 -0
- data/spec/dummy/public/javascripts/dragdrop.js +974 -0
- data/spec/dummy/public/javascripts/effects.js +1123 -0
- data/spec/dummy/public/javascripts/prototype.js +6001 -0
- data/spec/dummy/public/javascripts/rails.js +175 -0
- data/spec/dummy/public/stylesheets/.gitkeep +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/engine_room_spec.rb +7 -0
- data/spec/factories.rb +32 -0
- data/spec/integration/navigation_spec.rb +9 -0
- data/spec/models/dog_spec.rb +14 -0
- data/spec/models/field_spec.rb +74 -0
- data/spec/models/section_spec.rb +70 -0
- data/spec/models/user_spec.rb +77 -0
- data/spec/routing/models_routing_spec.rb +66 -0
- data/spec/spec_helper.rb +39 -0
- data/spec/support/devise.rb +3 -0
- 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'
|
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,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
|