alchemy_cms 2.1.12 → 2.2.rc1

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 (405) hide show
  1. data/.travis.yml +1 -1
  2. data/Gemfile +20 -16
  3. data/README.md +11 -7
  4. data/alchemy_cms.gemspec +31 -29
  5. data/app/assets/javascripts/alchemy/alchemy.base.js +234 -233
  6. data/app/assets/javascripts/alchemy/alchemy.buttons.js +26 -26
  7. data/app/assets/javascripts/alchemy/alchemy.datepicker.js +32 -32
  8. data/app/assets/javascripts/alchemy/alchemy.dirty.js +78 -78
  9. data/app/assets/javascripts/alchemy/alchemy.dragndrop.js +103 -103
  10. data/app/assets/javascripts/alchemy/alchemy.element_editor_selector.js +84 -84
  11. data/app/assets/javascripts/alchemy/alchemy.elements_window.js +88 -88
  12. data/app/assets/javascripts/alchemy/alchemy.file_progress.js +92 -0
  13. data/app/assets/javascripts/alchemy/alchemy.growler.js +23 -23
  14. data/app/assets/javascripts/alchemy/alchemy.html5.js +23 -0
  15. data/app/assets/javascripts/alchemy/alchemy.image_cropper.js +53 -52
  16. data/app/assets/javascripts/alchemy/alchemy.jquery_loader.js +33 -30
  17. data/app/assets/javascripts/alchemy/alchemy.js +2 -0
  18. data/app/assets/javascripts/alchemy/alchemy.js_extensions.js +14 -14
  19. data/app/assets/javascripts/alchemy/alchemy.link_overlay.js.coffee +181 -0
  20. data/app/assets/javascripts/alchemy/alchemy.menubar.js +48 -48
  21. data/app/assets/javascripts/alchemy/alchemy.page_sorter.js +39 -39
  22. data/app/assets/javascripts/alchemy/alchemy.preview.js +81 -83
  23. data/app/assets/javascripts/alchemy/alchemy.preview_window.js +86 -86
  24. data/app/assets/javascripts/alchemy/alchemy.routes.js.erb +23 -23
  25. data/app/assets/javascripts/alchemy/alchemy.swf_upload.js +208 -353
  26. data/app/assets/javascripts/alchemy/alchemy.uploader.js +279 -0
  27. data/app/assets/javascripts/alchemy/alchemy.windows.js +268 -268
  28. data/app/assets/javascripts/tiny_mce/plugins/alchemy_link/editor_plugin.js +42 -42
  29. data/app/assets/stylesheets/alchemy/_defaults.scss +89 -89
  30. data/app/assets/stylesheets/alchemy/base.css.scss +790 -804
  31. data/app/assets/stylesheets/alchemy/buttons.css.scss +263 -264
  32. data/app/assets/stylesheets/alchemy/dashboard.css.scss +66 -66
  33. data/app/assets/stylesheets/alchemy/elements.css.scss +575 -564
  34. data/app/assets/stylesheets/alchemy/flash.css.scss +45 -45
  35. data/app/assets/stylesheets/alchemy/frame.css.scss +262 -262
  36. data/app/assets/stylesheets/alchemy/icons.css.scss +86 -86
  37. data/app/assets/stylesheets/alchemy/jquery-ui.alchemy.css.scss +706 -707
  38. data/app/assets/stylesheets/alchemy/jquery.Jcrop.css.scss +46 -27
  39. data/app/assets/stylesheets/alchemy/jquery.sb.css.scss +107 -107
  40. data/app/assets/stylesheets/alchemy/login.css.scss +40 -38
  41. data/app/assets/stylesheets/alchemy/menubar.css.scss +84 -82
  42. data/app/assets/stylesheets/alchemy/modules.css.scss +9 -9
  43. data/app/assets/stylesheets/alchemy/pagination.css.scss +49 -49
  44. data/app/assets/stylesheets/alchemy/print.css +7 -7
  45. data/app/assets/stylesheets/alchemy/sitemap.css.scss +185 -154
  46. data/app/assets/stylesheets/alchemy/standard_set.css +205 -206
  47. data/app/assets/stylesheets/alchemy/tables.css.scss +94 -60
  48. data/app/assets/stylesheets/alchemy/tinymce_content.css.scss +34 -34
  49. data/app/assets/stylesheets/alchemy/tinymce_dialog.css.scss +177 -177
  50. data/app/assets/stylesheets/alchemy/upload.css.scss +68 -45
  51. data/app/assets/stylesheets/tiny_mce/plugins/inlinepopups/skins/alchemy/window.css.scss +222 -221
  52. data/app/controllers/alchemy/admin/attachments_controller.rb +100 -100
  53. data/app/controllers/alchemy/admin/base_controller.rb +116 -116
  54. data/app/controllers/alchemy/admin/clipboard_controller.rb +44 -44
  55. data/app/controllers/alchemy/admin/contents_controller.rb +55 -55
  56. data/app/controllers/alchemy/admin/dashboard_controller.rb +12 -11
  57. data/app/controllers/alchemy/admin/elements_controller.rb +109 -109
  58. data/app/controllers/alchemy/admin/essence_audios_controller.rb +8 -8
  59. data/app/controllers/alchemy/admin/essence_files_controller.rb +20 -20
  60. data/app/controllers/alchemy/admin/essence_flashes_controller.rb +8 -8
  61. data/app/controllers/alchemy/admin/essence_pictures_controller.rb +81 -81
  62. data/app/controllers/alchemy/admin/essence_videos_controller.rb +8 -8
  63. data/app/controllers/alchemy/admin/languages_controller.rb +16 -4
  64. data/app/controllers/alchemy/admin/layoutpages_controller.rb +9 -9
  65. data/app/controllers/alchemy/admin/pages_controller.rb +249 -248
  66. data/app/controllers/alchemy/admin/pictures_controller.rb +105 -105
  67. data/app/controllers/alchemy/admin/resources_controller.rb +111 -166
  68. data/app/controllers/alchemy/admin/trash_controller.rb +18 -18
  69. data/app/controllers/alchemy/admin/users_controller.rb +69 -69
  70. data/app/controllers/alchemy/attachments_controller.rb +27 -27
  71. data/app/controllers/alchemy/base_controller.rb +159 -155
  72. data/app/controllers/alchemy/elements_controller.rb +16 -16
  73. data/app/controllers/alchemy/messages_controller.rb +59 -59
  74. data/app/controllers/alchemy/pages_controller.rb +194 -198
  75. data/app/controllers/alchemy/pictures_controller.rb +57 -57
  76. data/app/controllers/alchemy/user_sessions_controller.rb +70 -70
  77. data/app/helpers/alchemy/admin/attachments_helper.rb +7 -7
  78. data/app/helpers/alchemy/admin/base_helper.rb +425 -425
  79. data/app/helpers/alchemy/admin/contents_helper.rb +72 -72
  80. data/app/helpers/alchemy/admin/elements_helper.rb +108 -107
  81. data/app/helpers/alchemy/admin/essences_helper.rb +108 -108
  82. data/app/helpers/alchemy/admin/pages_helper.rb +42 -42
  83. data/app/helpers/alchemy/admin/pictures_helper.rb +26 -26
  84. data/app/helpers/alchemy/base_helper.rb +90 -90
  85. data/app/helpers/alchemy/elements_helper.rb +167 -168
  86. data/app/helpers/alchemy/essences_helper.rb +133 -133
  87. data/app/helpers/alchemy/pages_helper.rb +515 -526
  88. data/app/helpers/alchemy/pictures_helper.rb +19 -0
  89. data/app/mailers/alchemy/messages.rb +13 -13
  90. data/app/mailers/alchemy/notifications.rb +19 -19
  91. data/app/models/alchemy.rb +3 -3
  92. data/app/models/alchemy/attachment.rb +52 -78
  93. data/app/models/alchemy/cell.rb +48 -48
  94. data/app/models/alchemy/content.rb +196 -196
  95. data/app/models/alchemy/element.rb +500 -490
  96. data/app/models/alchemy/essence_audio.rb +7 -7
  97. data/app/models/alchemy/essence_date.rb +10 -10
  98. data/app/models/alchemy/essence_file.rb +7 -7
  99. data/app/models/alchemy/essence_flash.rb +6 -6
  100. data/app/models/alchemy/essence_html.rb +9 -9
  101. data/app/models/alchemy/essence_picture.rb +17 -17
  102. data/app/models/alchemy/essence_richtext.rb +53 -53
  103. data/app/models/alchemy/essence_text.rb +21 -21
  104. data/app/models/alchemy/essence_video.rb +7 -7
  105. data/app/models/alchemy/folded_page.rb +3 -3
  106. data/app/models/alchemy/language.rb +91 -91
  107. data/app/models/alchemy/language/code.rb +14 -14
  108. data/app/models/alchemy/message.rb +48 -45
  109. data/app/models/alchemy/page.rb +555 -558
  110. data/app/models/alchemy/picture.rb +100 -99
  111. data/app/models/alchemy/user.rb +76 -74
  112. data/app/models/alchemy/user_session.rb +8 -8
  113. data/app/sweepers/alchemy/content_sweeper.rb +15 -15
  114. data/app/sweepers/alchemy/pages_sweeper.rb +50 -50
  115. data/app/sweepers/alchemy/pictures_sweeper.rb +14 -14
  116. data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +23 -23
  117. data/app/views/alchemy/admin/attachments/_attachment.html.erb +56 -56
  118. data/app/views/alchemy/admin/attachments/_file_to_assign.html.erb +15 -15
  119. data/app/views/alchemy/admin/attachments/_files_list.html.erb +16 -16
  120. data/app/views/alchemy/admin/attachments/create.js.erb +2 -2
  121. data/app/views/alchemy/admin/attachments/destroy.js.erb +3 -3
  122. data/app/views/alchemy/admin/attachments/edit.html.erb +10 -10
  123. data/app/views/alchemy/admin/attachments/index.html.erb +14 -14
  124. data/app/views/alchemy/admin/attachments/new.html.erb +9 -9
  125. data/app/views/alchemy/admin/clipboard/index.html.erb +21 -21
  126. data/app/views/alchemy/admin/clipboard/insert.js.erb +5 -5
  127. data/app/views/alchemy/admin/contents/_missing.html.erb +1 -1
  128. data/app/views/alchemy/admin/contents/create.js.erb +33 -33
  129. data/app/views/alchemy/admin/contents/destroy.js.erb +5 -5
  130. data/app/views/alchemy/admin/contents/new.html.erb +13 -13
  131. data/app/views/alchemy/admin/contents/order.js.erb +2 -2
  132. data/app/views/alchemy/admin/dashboard/index.html.erb +96 -92
  133. data/app/views/alchemy/admin/elements/_add_content.html.erb +12 -12
  134. data/app/views/alchemy/admin/elements/_element.html.erb +3 -3
  135. data/app/views/alchemy/admin/elements/_new_element_form.html.erb +28 -28
  136. data/app/views/alchemy/admin/elements/_picture_editor.html.erb +21 -21
  137. data/app/views/alchemy/admin/elements/create.js.erb +32 -32
  138. data/app/views/alchemy/admin/elements/index.html.erb +2 -2
  139. data/app/views/alchemy/admin/elements/new.html.erb +31 -31
  140. data/app/views/alchemy/admin/elements/order.js.erb +3 -3
  141. data/app/views/alchemy/admin/elements/trash.js.erb +13 -13
  142. data/app/views/alchemy/admin/elements/update.js.erb +6 -6
  143. data/app/views/alchemy/admin/essence_files/assign.js.erb +6 -6
  144. data/app/views/alchemy/admin/essence_pictures/crop.html.erb +32 -32
  145. data/app/views/alchemy/admin/essence_pictures/destroy.js.erb +1 -1
  146. data/app/views/alchemy/admin/essence_pictures/edit.html.erb +1 -1
  147. data/app/views/alchemy/admin/essence_pictures/update.js.erb +11 -11
  148. data/app/views/alchemy/admin/languages/_form.html.erb +51 -45
  149. data/app/views/alchemy/admin/languages/_language.html.erb +45 -45
  150. data/app/views/alchemy/admin/languages/_table.html.erb +25 -25
  151. data/app/views/alchemy/admin/layoutpages/index.html.erb +35 -35
  152. data/app/views/alchemy/admin/pages/_create_language_form.html.erb +42 -42
  153. data/app/views/alchemy/admin/pages/_external_link.html.erb +1 -1
  154. data/app/views/alchemy/admin/pages/_new_page_form.html.erb +27 -27
  155. data/app/views/alchemy/admin/pages/_page.html.erb +112 -112
  156. data/app/views/alchemy/admin/pages/_sitemap.html.erb +1 -1
  157. data/app/views/alchemy/admin/pages/configure.html.erb +71 -69
  158. data/app/views/alchemy/admin/pages/configure_external.html.erb +38 -38
  159. data/app/views/alchemy/admin/pages/destroy.js.erb +10 -10
  160. data/app/views/alchemy/admin/pages/edit.html.erb +165 -165
  161. data/app/views/alchemy/admin/pages/fold.js.erb +2 -2
  162. data/app/views/alchemy/admin/pages/index.html.erb +66 -66
  163. data/app/views/alchemy/admin/pages/locked.html.erb +1 -1
  164. data/app/views/alchemy/admin/pages/new.html.erb +40 -40
  165. data/app/views/alchemy/admin/pages/sort.js.erb +4 -4
  166. data/app/views/alchemy/admin/pages/unlock.js.erb +6 -6
  167. data/app/views/alchemy/admin/pages/update.js.erb +19 -19
  168. data/app/views/alchemy/admin/partials/_flash.html.erb +2 -2
  169. data/app/views/alchemy/admin/partials/_flash_notices.html.erb +1 -1
  170. data/app/views/alchemy/admin/partials/_flash_upload.html.erb +38 -0
  171. data/app/views/alchemy/admin/partials/_language_tree_select.html.erb +15 -15
  172. data/app/views/alchemy/admin/partials/_main_navigation_entry.html.erb +8 -8
  173. data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +35 -35
  174. data/app/views/alchemy/admin/partials/_search_form.html.erb +14 -14
  175. data/app/views/alchemy/admin/partials/_sub_navigation_tab.html.erb +6 -6
  176. data/app/views/alchemy/admin/partials/_upload_form.html.erb +56 -118
  177. data/app/views/alchemy/admin/pictures/_archive_overlay.html.erb +11 -11
  178. data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +71 -71
  179. data/app/views/alchemy/admin/pictures/_picture.html.erb +32 -32
  180. data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +26 -26
  181. data/app/views/alchemy/admin/pictures/_pictures_list.html.erb +6 -6
  182. data/app/views/alchemy/admin/pictures/create.js.erb +7 -7
  183. data/app/views/alchemy/admin/pictures/index.html.erb +67 -67
  184. data/app/views/alchemy/admin/pictures/show_in_window.html.erb +5 -4
  185. data/app/views/alchemy/admin/resources/_form.html.erb +25 -19
  186. data/app/views/alchemy/admin/resources/_resource.html.erb +37 -36
  187. data/app/views/alchemy/admin/resources/_table.html.erb +17 -17
  188. data/app/views/alchemy/admin/resources/destroy.js.erb +1 -1
  189. data/app/views/alchemy/admin/resources/index.html.erb +14 -14
  190. data/app/views/alchemy/admin/trash/index.html.erb +20 -20
  191. data/app/views/alchemy/admin/users/_table.html.erb +52 -52
  192. data/app/views/alchemy/admin/users/_user.html.erb +35 -36
  193. data/app/views/alchemy/admin/users/index.html.erb +26 -27
  194. data/app/views/alchemy/base/error_notice.html.erb +2 -2
  195. data/app/views/alchemy/base/update.js.erb +1 -1
  196. data/app/views/alchemy/elements/_contactform_view.html.erb +76 -76
  197. data/app/views/alchemy/elements/_download_view.html.erb +1 -1
  198. data/app/views/alchemy/elements/_editor_not_found.html.erb +3 -3
  199. data/app/views/alchemy/elements/_searchresult_view.html.erb +2 -2
  200. data/app/views/alchemy/elements/_sitemap_editor.html.erb +1 -1
  201. data/app/views/alchemy/essences/_essence_audio_view.html.erb +13 -13
  202. data/app/views/alchemy/essences/_essence_date_editor.html.erb +10 -10
  203. data/app/views/alchemy/essences/_essence_file_editor.html.erb +62 -62
  204. data/app/views/alchemy/essences/_essence_file_view.html.erb +8 -8
  205. data/app/views/alchemy/essences/_essence_flash_view.html.erb +19 -19
  206. data/app/views/alchemy/essences/_essence_html_editor.html.erb +6 -6
  207. data/app/views/alchemy/essences/_essence_picture_editor.html.erb +73 -73
  208. data/app/views/alchemy/essences/_essence_picture_view.html.erb +34 -34
  209. data/app/views/alchemy/essences/_essence_richtext_editor.html.erb +7 -7
  210. data/app/views/alchemy/essences/_essence_text_editor.html.erb +8 -8
  211. data/app/views/alchemy/navigation/_image_link.html.erb +12 -12
  212. data/app/views/alchemy/navigation/_link.html.erb +13 -13
  213. data/app/views/alchemy/navigation/_renderer.html.erb +17 -17
  214. data/app/views/alchemy/page_layouts/_layout_footer.html.erb +1 -1
  215. data/app/views/alchemy/page_layouts/_layout_header.html.erb +1 -1
  216. data/app/views/alchemy/pages/show.rss.builder +14 -14
  217. data/app/views/alchemy/search/_result.html.erb +7 -7
  218. data/app/views/alchemy/user_sessions/leave.html.erb +9 -9
  219. data/app/views/alchemy/user_sessions/login.html.erb +39 -39
  220. data/app/views/alchemy/user_sessions/logout.html.erb +1 -1
  221. data/app/views/layouts/alchemy/admin.html.erb +81 -81
  222. data/app/views/layouts/alchemy/login.html.erb +36 -36
  223. data/app/views/layouts/alchemy/pages.html.erb +48 -27
  224. data/bin/alchemy +136 -134
  225. data/config/alchemy/config.yml +13 -9
  226. data/config/locales/alchemy.de.yml +24 -30
  227. data/config/locales/alchemy.en.yml +11 -28
  228. data/config/routes.rb +146 -146
  229. data/db/migrate/20100607193638_create_essence_pictures.rb +3 -3
  230. data/db/migrate/20101109150312_alter_pages_visible_column_default.rb +1 -1
  231. data/db/migrate/20101109151812_create_languages.rb +3 -3
  232. data/db/migrate/20110115123343_remove_css_class_default_from_essence_pictures.rb +3 -3
  233. data/db/migrate/20110224105120_change_pages_visible_default.rb +3 -3
  234. data/db/migrate/20110228182659_remove_default_page_layout_from_pages.rb +2 -2
  235. data/db/migrate/20110414163140_remove_display_name_from_elements.rb +3 -3
  236. data/db/migrate/20110511100516_rename_essence_texts_title_to_link_title.rb +2 -2
  237. data/db/migrate/20110529130500_add_cell_id_to_elements.rb +3 -3
  238. data/db/migrate/20110530102804_change_pages_page_layout_column.rb +3 -3
  239. data/db/migrate/20110711142057_change_open_link_in_new_window_to_link_target.rb +1 -1
  240. data/db/migrate/20111116125112_namespace_alchemy_models.rb +21 -21
  241. data/lib/alchemy/auth_engine.rb +5 -5
  242. data/lib/alchemy/capistrano.rb +64 -64
  243. data/lib/alchemy/config.rb +47 -44
  244. data/lib/alchemy/engine.rb +41 -41
  245. data/lib/alchemy/essence.rb +50 -51
  246. data/lib/alchemy/i18n.rb +48 -48
  247. data/lib/alchemy/modules.rb +30 -30
  248. data/lib/alchemy/mount_point.rb +6 -6
  249. data/lib/alchemy/page_layout.rb +94 -93
  250. data/lib/alchemy/resource.rb +82 -0
  251. data/lib/alchemy/resources_helper.rb +56 -0
  252. data/lib/alchemy/scoped_pagination_url_helper.rb +8 -8
  253. data/lib/alchemy/seeder.rb +88 -88
  254. data/lib/alchemy/tinymce.rb +49 -49
  255. data/lib/alchemy/upgrader.rb +103 -103
  256. data/lib/alchemy/version.rb +1 -1
  257. data/lib/alchemy_cms.rb +26 -27
  258. data/lib/extensions/action_view.rb +1 -1
  259. data/lib/extensions/array.rb +3 -3
  260. data/lib/extensions/hash.rb +3 -3
  261. data/lib/middleware/flash_session_cookie.rb +1 -1
  262. data/lib/rails/generators/alchemy/deploy_script/deploy_script_generator.rb +24 -24
  263. data/lib/rails/generators/alchemy/elements/elements_generator.rb +7 -7
  264. data/lib/rails/generators/alchemy/elements/templates/view.html.erb +17 -17
  265. data/lib/rails/generators/alchemy/page_layouts/page_layouts_generator.rb +6 -6
  266. data/lib/rails/generators/alchemy/plugin/templates/authorization_rules.rb +8 -8
  267. data/lib/rails/generators/alchemy/scaffold/files/pages.html.erb +7 -7
  268. data/lib/rails/generators/alchemy/scaffold/scaffold_generator.rb +36 -36
  269. data/lib/rails/templates/alchemy.rb +1 -1
  270. data/lib/tasks/ferret.rake +2 -2
  271. data/lib/tasks/fleximage.rake +32 -32
  272. data/lib/tasks/install.rake +12 -12
  273. data/lib/tasks/upgrade.rake +4 -4
  274. data/spec/controllers/admin/clipboard_controller_spec.rb +43 -43
  275. data/spec/controllers/admin/contents_controller_spec.rb +22 -22
  276. data/spec/controllers/admin/elements_controller_spec.rb +13 -13
  277. data/spec/controllers/admin/languages_controller_spec.rb +31 -0
  278. data/spec/controllers/admin/pages_controller_spec.rb +10 -41
  279. data/spec/controllers/admin/resources_controller_spec.rb +19 -0
  280. data/spec/controllers/admin/trash_controller_spec.rb +11 -11
  281. data/spec/controllers/base_controller_spec.rb +46 -46
  282. data/spec/controllers/pages_controller_spec.rb +102 -92
  283. data/spec/dummy/app/controllers/admin/events_controller.rb +3 -0
  284. data/spec/dummy/app/controllers/errors_controller.rb +5 -0
  285. data/spec/dummy/app/models/event.rb +3 -0
  286. data/spec/dummy/config.ru +1 -1
  287. data/spec/dummy/config/application.rb +3 -0
  288. data/spec/dummy/config/authorization_rules.rb +7 -0
  289. data/spec/dummy/config/environments/development.rb +8 -1
  290. data/spec/dummy/config/environments/production.rb +1 -1
  291. data/spec/dummy/config/environments/test.rb +5 -2
  292. data/spec/dummy/config/routes.rb +9 -1
  293. data/spec/dummy/db/schema.rb +47 -35
  294. data/spec/dummy/public/404.html +19 -7
  295. data/spec/dummy/public/404.html.bak +26 -0
  296. data/spec/dummy/public/422.html +19 -7
  297. data/spec/dummy/public/500.html +19 -7
  298. data/spec/dummy/script/rails +2 -2
  299. data/spec/factories.rb +76 -76
  300. data/spec/helpers/admin/base_helper_spec.rb +21 -21
  301. data/spec/helpers/admin/contents_helper_spec.rb +14 -14
  302. data/spec/helpers/admin/elements_helper_spec.rb +40 -40
  303. data/spec/helpers/admin/essences_helper_spec.rb +7 -7
  304. data/spec/helpers/elements_helper_spec.rb +154 -154
  305. data/spec/helpers/essences_helper_spec.rb +10 -10
  306. data/spec/helpers/pages_helper_spec.rb +369 -372
  307. data/spec/helpers/pictures_helper_spec.rb +14 -0
  308. data/spec/helpers/url_helpers_spec.rb +29 -34
  309. data/spec/integration/admin/pages_controller_spec.rb +50 -50
  310. data/spec/integration/admin/resources_integration_spec.rb +100 -0
  311. data/spec/integration/navigation_spec.rb +1 -1
  312. data/spec/integration/pages_controller_spec.rb +205 -207
  313. data/spec/integration/security_spec.rb +47 -47
  314. data/spec/javascripts/alchemy/link_overlay_spec.js.coffee +42 -0
  315. data/spec/javascripts/alchemy_integration_spec.coffee +12 -0
  316. data/spec/javascripts/fixtures/select.html +3 -0
  317. data/spec/javascripts/helpers/.gitkeep +0 -0
  318. data/spec/javascripts/helpers/jasmine-jquery-1.3.1.js +289 -0
  319. data/spec/javascripts/helpers/mock-ajax.js +207 -0
  320. data/spec/javascripts/helpers/test_responses/test_responses.js +1 -0
  321. data/spec/javascripts/spec.css +3 -0
  322. data/spec/javascripts/spec.js +2 -0
  323. data/spec/libraries/resource_spec.rb +122 -0
  324. data/spec/libraries/resources_helper_spec.rb +105 -0
  325. data/spec/models/content_spec.rb +67 -67
  326. data/spec/models/element_spec.rb +133 -133
  327. data/spec/models/essence_picture_spec.rb +5 -5
  328. data/spec/models/essence_richtext_spec.rb +4 -4
  329. data/spec/models/language_spec.rb +89 -89
  330. data/spec/models/page_spec.rb +436 -506
  331. data/spec/models/picture_spec.rb +34 -34
  332. data/spec/models/user_spec.rb +2 -2
  333. data/spec/page_layout_spec.rb +24 -20
  334. data/spec/routing_spec.rb +253 -253
  335. data/spec/spec_helper.rb +51 -50
  336. data/spec/support/alchemy/controller_hacks.rb +25 -25
  337. data/spec/support/alchemy/specs_helpers.rb +25 -25
  338. data/spec/support/integration_spec_helper.rb +24 -0
  339. data/vendor/assets/javascripts/jquery_plugins/jquery.html5uploader.js +271 -0
  340. data/vendor/assets/javascripts/jquery_plugins/jquery.in-place-edit.js +86 -85
  341. data/vendor/assets/javascripts/jquery_plugins/jquery.ui.nestedSortable.js +380 -377
  342. data/vendor/assets/javascripts/jquery_plugins/jquery.ui.tabspaging.js +285 -279
  343. data/vendor/assets/javascripts/swfupload/SWFObject License.txt +3 -3
  344. data/vendor/assets/javascripts/swfupload/swfupload.cookies.js +47 -47
  345. data/vendor/assets/javascripts/swfupload/swfupload.js +612 -612
  346. data/vendor/assets/javascripts/swfupload/swfupload.queue.js +93 -93
  347. data/vendor/assets/javascripts/swfupload/swfupload.speed.js +337 -337
  348. data/vendor/assets/javascripts/swfupload/swfupload.swfobject.js +706 -102
  349. data/vendor/assets/javascripts/tiny_mce/license.txt +6 -6
  350. data/vendor/assets/javascripts/tiny_mce/plugins/fullscreen/fullscreen.htm +97 -97
  351. data/vendor/assets/javascripts/tiny_mce/plugins/inlinepopups/template.htm +386 -376
  352. data/vendor/assets/javascripts/tiny_mce/plugins/paste/js/pastetext.js +30 -30
  353. data/vendor/assets/javascripts/tiny_mce/plugins/paste/js/pasteword.js +45 -45
  354. data/vendor/assets/javascripts/tiny_mce/plugins/paste/pastetext.htm +20 -17
  355. data/vendor/assets/javascripts/tiny_mce/plugins/paste/pasteword.htm +12 -12
  356. data/vendor/assets/javascripts/tiny_mce/plugins/table/cell.htm +183 -173
  357. data/vendor/assets/javascripts/tiny_mce/plugins/table/css/cell.css +4 -4
  358. data/vendor/assets/javascripts/tiny_mce/plugins/table/css/row.css +7 -7
  359. data/vendor/assets/javascripts/tiny_mce/plugins/table/css/table.css +3 -3
  360. data/vendor/assets/javascripts/tiny_mce/plugins/table/js/cell.js +282 -280
  361. data/vendor/assets/javascripts/tiny_mce/plugins/table/js/merge_cells.js +15 -15
  362. data/vendor/assets/javascripts/tiny_mce/plugins/table/js/row.js +204 -204
  363. data/vendor/assets/javascripts/tiny_mce/plugins/table/js/table.js +435 -435
  364. data/vendor/assets/javascripts/tiny_mce/plugins/table/merge_cells.htm +24 -22
  365. data/vendor/assets/javascripts/tiny_mce/plugins/table/row.htm +144 -136
  366. data/vendor/assets/javascripts/tiny_mce/plugins/table/table.htm +184 -168
  367. data/vendor/assets/javascripts/tiny_mce/themes/advanced/about.htm +62 -46
  368. data/vendor/assets/javascripts/tiny_mce/themes/advanced/anchor.htm +17 -16
  369. data/vendor/assets/javascripts/tiny_mce/themes/advanced/charmap.htm +56 -47
  370. data/vendor/assets/javascripts/tiny_mce/themes/advanced/color_picker.htm +67 -54
  371. data/vendor/assets/javascripts/tiny_mce/themes/advanced/editor_template.js +852 -1
  372. data/vendor/assets/javascripts/tiny_mce/themes/advanced/image.htm +79 -69
  373. data/vendor/assets/javascripts/tiny_mce/themes/advanced/js/about.js +48 -48
  374. data/vendor/assets/javascripts/tiny_mce/themes/advanced/js/anchor.js +28 -28
  375. data/vendor/assets/javascripts/tiny_mce/themes/advanced/js/charmap.js +317 -317
  376. data/vendor/assets/javascripts/tiny_mce/themes/advanced/js/color_picker.js +248 -246
  377. data/vendor/assets/javascripts/tiny_mce/themes/advanced/js/image.js +246 -246
  378. data/vendor/assets/javascripts/tiny_mce/themes/advanced/js/link.js +146 -146
  379. data/vendor/assets/javascripts/tiny_mce/themes/advanced/js/source_editor.js +31 -31
  380. data/vendor/assets/javascripts/tiny_mce/themes/advanced/langs/de.js +1 -1
  381. data/vendor/assets/javascripts/tiny_mce/themes/advanced/langs/de_dlg.js +1 -1
  382. data/vendor/assets/javascripts/tiny_mce/themes/advanced/langs/en.js +1 -1
  383. data/vendor/assets/javascripts/tiny_mce/themes/advanced/langs/en_dlg.js +1 -1
  384. data/vendor/assets/javascripts/tiny_mce/themes/advanced/link.htm +53 -46
  385. data/vendor/assets/javascripts/tiny_mce/themes/advanced/shortcuts.htm +57 -45
  386. data/vendor/assets/javascripts/tiny_mce/themes/advanced/skins/default/content.css +182 -47
  387. data/vendor/assets/javascripts/tiny_mce/themes/advanced/skins/default/dialog.css +399 -92
  388. data/vendor/assets/javascripts/tiny_mce/themes/advanced/skins/default/ui.css +891 -187
  389. data/vendor/assets/javascripts/tiny_mce/themes/advanced/skins/highcontrast/content.css +102 -24
  390. data/vendor/assets/javascripts/tiny_mce/themes/advanced/skins/highcontrast/dialog.css +377 -78
  391. data/vendor/assets/javascripts/tiny_mce/themes/advanced/skins/highcontrast/ui.css +452 -77
  392. data/vendor/assets/javascripts/tiny_mce/themes/advanced/skins/o2k7/content.css +167 -45
  393. data/vendor/assets/javascripts/tiny_mce/themes/advanced/skins/o2k7/dialog.css +399 -92
  394. data/vendor/assets/javascripts/tiny_mce/themes/advanced/skins/o2k7/ui.css +890 -190
  395. data/vendor/assets/javascripts/tiny_mce/themes/advanced/skins/o2k7/ui_black.css +33 -7
  396. data/vendor/assets/javascripts/tiny_mce/themes/advanced/skins/o2k7/ui_silver.css +15 -4
  397. data/vendor/assets/javascripts/tiny_mce/themes/advanced/source_editor.htm +18 -15
  398. data/vendor/assets/javascripts/tiny_mce/utils/editable_selects.js +46 -46
  399. data/vendor/assets/javascripts/tiny_mce/utils/form_utils.js +124 -124
  400. data/vendor/assets/javascripts/tiny_mce/utils/mctabs.js +112 -112
  401. data/vendor/assets/javascripts/tiny_mce/utils/validate.js +213 -213
  402. metadata +102 -115
  403. data/app/assets/javascripts/alchemy/alchemy.link_overlay.js +0 -216
  404. data/lib/tasks/routes.rake +0 -29
  405. data/spec/integration/admin/resources_spec.rb +0 -19
@@ -3,549 +3,479 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe Alchemy::Page do
6
-
7
- before(:each) do
8
- @rootpage = Alchemy::Page.root
9
- @language = Alchemy::Language.get_default
10
- @language_root = Factory(:language_root_page, :name => 'Default Language Root', :language => @language)
11
- end
12
-
13
- describe ".layout_description" do
14
-
15
- context "for a language root page" do
16
-
17
- it "should return the page layout description as hash" do
18
- @language_root.layout_description['name'].should == 'intro'
19
- end
20
-
21
- it "should return an empty hash for root page" do
22
- @rootpage.layout_description.should == {}
23
- end
24
-
25
- end
26
-
27
- it "should raise Exception if the page_layout could not be found in the definition file" do
28
- @page = mock(:page, :page_layout => 'foo')
29
- expect { @page.layout_description }.to raise_error
30
- end
31
-
32
- end
33
-
34
- it "should contain one rootpage" do
35
- Alchemy::Page.rootpage.should be_instance_of(Alchemy::Page)
36
- end
37
-
38
- it "should return all rss feed elements" do
39
- @page = Factory(:public_page, :page_layout => 'news', :parent_id => @language_root.id, :language => @language)
40
- @page.feed_elements.should == Alchemy::Element.find_all_by_name('news')
41
- end
42
-
43
- context "finding elements" do
44
-
45
- before(:each) do
46
- @page = Factory(:public_page)
47
- @non_public_elements = [
48
- Factory(:element, :public => false, :page => @page),
49
- Factory(:element, :public => false, :page => @page)
50
- ]
51
- end
52
-
53
- it "should return the collection of elements if passed an array into options[:collection]" do
54
- options = {:collection => @page.elements}
55
- @page.find_elements(options).all.should == @page.elements.all
56
- end
57
-
58
- context "with show_non_public argument TRUE" do
59
-
60
- it "should return all elements from empty options" do
61
- @page.find_elements({}, true).all.should == @page.elements.all
62
- end
63
-
64
- it "should only return the elements passed as options[:only]" do
65
- @page.find_elements({:only => ['article']}, true).all.should == @page.elements.named('article').all
66
- end
67
-
68
- it "should not return the elements passed as options[:except]" do
69
- @page.find_elements({:except => ['article']}, true).all.should == @page.elements - @page.elements.named('article').all
70
- end
71
-
72
- it "should return elements offsetted" do
73
- @page.find_elements({:offset => 2}, true).all.should == @page.elements.offset(2)
74
- end
75
-
76
- it "should return elements limitted in count" do
77
- @page.find_elements({:count => 1}, true).all.should == @page.elements.limit(1)
78
- end
79
-
80
- end
81
-
82
- context "with show_non_public argument FALSE" do
83
-
84
- it "should return all elements from empty arguments" do
85
- @page.find_elements().all.should == @page.elements.published.all
86
- end
87
-
88
- it "should only return the public elements passed as options[:only]" do
89
- @page.find_elements(:only => ['article']).all.should == @page.elements.published.named('article').all
90
- end
91
-
92
- it "should return all public elements except the ones passed as options[:except]" do
93
- @page.find_elements(:except => ['article']).all.should == @page.elements.published.all - @page.elements.published.named('article').all
94
- end
95
-
96
- it "should return elements offsetted" do
97
- @page.find_elements({:offset => 2}).all.should == @page.elements.published.offset(2)
98
- end
99
-
100
- it "should return elements limitted in count" do
101
- @page.find_elements({:count => 1}).all.should == @page.elements.published.limit(1)
102
- end
103
-
104
- end
105
-
106
- end
107
-
108
- describe "#contentpage" do
109
-
110
- it "should return false if its a systempage" do
111
- @page = Factory(:page, :language => @language, :parent_id => @language_root.id)
112
- @page.stub!(:systempage?).and_return(true)
113
- @page.stub!(:redirects_to_external?).and_return(false)
114
- @page.contentpage?.should be_false
115
- end
116
-
117
- it "should return false if it redirects to an external website" do
118
- @page = Factory(:page, :layoutpage => false, :language => @language, :parent_id => @language_root.id)
119
- @page.stub!(:systempage?).and_return(false)
120
- @page.stub!(:redirects_to_external?).and_return(true)
121
- @page.contentpage?.should be_false
122
- end
123
-
124
- it "should return false if its a layoutpage" do
125
- @page = Factory(:page, :layoutpage => true, :language => @language, :parent_id => @language_root.id)
126
- @page.stub!(:systempage?).and_return(false)
127
- @page.stub!(:redirects_to_external?).and_return(false)
128
- @page.contentpage?.should be_false
129
- end
130
-
131
- it "should return true if its not a layoutpage, does not redirect to an external website and its not a systempage" do
132
- @page = Factory(:page, :language => @language, :parent_id => @language_root.id)
133
- @page.stub!(:systempage?).and_return(false)
134
- @page.stub!(:redirects_to_external?).and_return(false)
135
- @page.contentpage?.should be_true
136
- end
137
-
138
- end
139
-
140
- describe '#create' do
141
-
142
- context "before/after filter" do
143
-
144
- it "should automatically set the title from its name" do
145
- page = Factory(:page, :name => 'My Testpage', :language => @language, :parent_id => @language_root.id)
146
- page.title.should == 'My Testpage'
147
- end
148
-
149
- it "should get a webfriendly urlname" do
150
- page = Factory(:page, :name => 'klingon$&stößel ', :language => @language, :parent_id => @language_root.id)
151
- page.urlname.should == 'klingon-stoessel'
152
- end
153
-
154
- it "should generate a three letter urlname from two letter name" do
155
- page = Factory(:page, :name => 'Au', :language => @language, :parent_id => @language_root.id)
156
- page.urlname.should == '-au'
157
- end
158
-
159
- it "should generate a three letter urlname from two letter name with umlaut" do
160
- page = Factory(:page, :name => 'Aü', :language => @language, :parent_id => @language_root.id)
161
- page.urlname.should == 'aue'
162
- end
163
-
164
- it "should generate a three letter urlname from one letter name" do
165
- page = Factory(:page, :name => 'A', :language => @language, :parent_id => @language_root.id)
166
- page.urlname.should == '--a'
167
- end
168
-
169
- context "with attribute :layoutpage set to true (global page)" do
170
-
171
- it "should not set the title from its name if its a global page" do
172
- page = Factory(:page, :layoutpage => true, :name => 'Page with no title', :language => @language, :parent_id => @language_root.id)
173
- page.title.should be_blank
174
- end
175
-
176
- it "should not set an urlname" do
177
- page = Factory(:page, :layoutpage => true, :name => 'Page with no urlname', :language => @language, :parent_id => @language_root.id)
178
- page.urlname.should be_blank
179
- end
180
-
181
- end
182
-
183
- end
184
-
185
- end
186
-
187
- describe '#update' do
188
-
189
- context "before/after filter" do
190
-
191
- it "should not set the title automatically if the name changed but title is not blank" do
192
- page = Factory(:page, :name => 'My Testpage', :language => @language, :parent_id => @language_root.id)
193
- page.name = "My Renaming Test"
194
- page.save; page.reload
195
- page.title.should == "My Testpage"
196
- end
197
-
198
- it "should not automatically set the title if it changed its value" do
199
- page = Factory(:page, :name => 'My Testpage', :language => @language, :parent_id => @language_root.id)
200
- page.title = "I like SEO"
201
- page.save; page.reload
202
- page.title.should == "I like SEO"
203
- end
204
-
205
- end
206
-
207
- end
208
-
209
- context "with children" do
210
-
211
- before(:each) do
212
- @first_child = Factory(:page, :name => "First child", :language => @language, :public => false, :parent_id => @language_root.id)
213
- @first_child.move_to_child_of(@language_root)
214
-
215
- @first_public_child = Factory(:page, :name => "First public child", :language => @language, :parent_id => @language_root.id, :public => true)
216
- @first_public_child.move_to_child_of(@language_root)
217
- end
218
-
219
- it "should return a page object (or nil if no public child exists) for first_public_child" do
220
- if @language_root.children.any?
221
- @language_root.first_public_child.should == @first_public_child
222
- else
223
- @language_root.first_public_child.should == nil
224
- end
225
- end
226
-
227
- end
228
-
229
- context ".contentpages" do
230
-
231
- before(:each) do
232
- @klingonian = Factory(:language)
233
- @layoutroot = Alchemy::Page.find_or_create_layout_root_for(@klingonian.id)
234
- @layoutpage = Factory(:public_page, :name => 'layoutpage', :layoutpage => true, :parent_id => @layoutroot.id, :language => @klingonian)
235
- @klingonian_lang_root = Factory(:language_root_page, :name => 'klingonian_lang_root', :layoutpage => nil, :language => @klingonian)
236
- @contentpage = Factory(:public_page, :name => 'contentpage', :parent_id => @language_root.id, :language => @language)
237
- end
238
-
239
- it "should return a collection of contentpages" do
240
- Alchemy::Page.contentpages.to_a.should == [@language_root, @klingonian_lang_root, @contentpage]
241
- end
242
-
243
- it "should not contain pages with attribute :layoutpage set to true" do
244
- Alchemy::Page.contentpages.to_a.select { |p| p.layoutpage == true }.should be_empty
245
- end
246
-
247
- it "should contain pages with attribute :layoutpage set to nil" do
248
- Alchemy::Page.contentpages.to_a.select { |p| p.layoutpage == nil }.should == [@klingonian_lang_root]
249
- end
250
-
251
- end
252
-
253
- context ".public" do
254
-
255
- it "should return pages that are public" do
256
- Factory(:public_page, :name => 'First Public Child', :parent_id => @language_root.id, :language => @language)
257
- Factory(:public_page, :name => 'Second Public Child', :parent_id => @language_root.id, :language => @language)
258
- Alchemy::Page.published.should have(3).pages
259
- end
260
-
261
- end
262
-
263
- context ".not_locked" do
264
-
265
- it "should return pages that are not blocked by a user at the moment" do
266
- Factory(:public_page, :locked => true, :name => 'First Public Child', :parent_id => @language_root.id, :language => @language)
267
- Factory(:public_page, :name => 'Second Public Child', :parent_id => @language_root.id, :language => @language)
268
- Alchemy::Page.not_locked.should have(3).pages
269
- end
270
- end
271
-
272
- context ".all_locked" do
273
- it "should return 1 page that is blocked by a user at the moment" do
274
- Factory(:public_page, :locked => true, :name => 'First Public Child', :parent_id => @language_root.id, :language => @language)
275
- Alchemy::Page.all_locked.should have(1).pages
276
- end
277
- end
278
-
279
- context ".language_roots" do
280
- it "should return 1 language_root" do
281
- Factory(:public_page, :name => 'First Public Child', :parent_id => @language_root.id, :language => @language)
282
- Alchemy::Page.language_roots.should have(1).pages
283
- end
284
- end
285
-
286
-
287
- context ".layoutpages" do
288
- it "should return 1 layoutpage" do
289
- Factory(:public_page, :layoutpage => true, :name => 'Layoutpage', :parent_id => @rootpage.id, :language => @language)
290
- Alchemy::Page.layoutpages.should have(1).pages
291
- end
292
- end
293
-
294
- context ".visible" do
295
- it "should return 1 visible page" do
296
- Factory(:public_page, :name => 'First Public Child', :visible => true, :parent_id => @language_root.id, :language => @language)
297
- Alchemy::Page.visible.should have(1).pages
298
- end
299
- end
300
-
301
- context ".accessable" do
302
- it "should return 2 accessable pages" do
303
- Factory(:public_page, :name => 'First Public Child', :restricted => true, :parent_id => @language_root.id, :language => @language)
304
- Alchemy::Page.accessable.should have(2).pages
305
- end
306
- end
307
-
308
- context ".restricted" do
309
- it "should return 1 restricted page" do
310
- Factory(:public_page, :name => 'First Public Child', :restricted => true, :parent_id => @language_root.id, :language => @language)
311
- Alchemy::Page.restricted.should have(1).pages
312
- end
313
- end
314
-
315
- context "#unlock" do
316
- it "should set the locked status to false" do
317
- @page = Factory(:public_page, :locked => true)
318
- @page.unlock
319
- @page.locked.should == false
320
- end
321
- end
322
-
323
- describe "#cell_definitions" do
324
-
325
- before(:each) do
326
- @page = Factory.build(:page, :page_layout => 'foo')
327
- @page.stub!(:layout_description).and_return({'name' => "foo", 'cells' => ["foo_cell"]})
328
- @cell_descriptions = [{'name' => "foo_cell", 'elements' => ["1", "2"]}]
329
- Alchemy::Cell.stub!(:definitions).and_return(@cell_descriptions)
330
- end
331
-
332
- it "should return all cell definitions for its page_layout" do
333
- @page.cell_definitions.should == @cell_descriptions
334
- end
335
-
336
- it "should return empty array if no cells defined in page layout" do
337
- @page.stub!(:layout_description).and_return({'name' => "foo"})
338
- @page.cell_definitions.should == []
339
- end
340
-
341
- end
342
-
343
- describe "#elements_grouped_by_cells" do
344
-
345
- context "with no elements defined that are not defined in a cell" do
346
- it "should not have a cell for 'other elements'" do
347
- @page = Factory.build(:page, :page_layout => 'foo')
348
- @page.stub!(:layout_description).and_return({'name' => "foo", 'cells' => ["foo_cell"], 'elements' => ["1", "2"]})
349
- @cell_descriptions = [{'name' => "foo_cell", 'elements' => ["1", "2"]}]
350
- Alchemy::Cell.stub!(:definitions).and_return(@cell_descriptions)
351
- @page.elements_grouped_by_cells.keys.collect(&:name).should_not include('for_other_elements')
352
- end
353
- end
354
-
355
- context "with elements defined that are not defined in a cell" do
356
- it "should have a cell for 'other elements'" do
357
- @page = Factory.build(:page, :page_layout => 'foo')
358
- @page.stub!(:layout_description).and_return({'name' => "foo", 'cells' => ["foo_cell"], 'elements' => ["1", "2", "3"]})
359
- @cell_descriptions = [{'name' => "foo_cell", 'elements' => ["1", "2"]}]
360
- Alchemy::Cell.stub!(:definitions).and_return(@cell_descriptions)
361
- @page.elements_grouped_by_cells.keys.collect(&:name).should include('for_other_elements')
362
- end
363
- end
364
-
365
- end
366
-
367
- describe '.all_from_clipboard_for_select' do
368
-
369
- context "with clipboard holding pages having non unique page layout" do
370
-
371
- it "should return the pages" do
372
- page_1 = Factory(:page, :language => @language)
373
- page_2 = Factory(:page, :language => @language, :name => 'Another Page')
374
- clipboard = [
375
- {:id => page_1.id, :action => "copy"},
376
- {:id => page_2.id, :action => "copy"}
377
- ]
378
- Alchemy::Page.all_from_clipboard_for_select(clipboard, @language.id).should == [page_1, page_2]
379
- end
380
-
381
- end
382
-
383
- context "with clipboard holding a page having unique page layout" do
384
-
385
- it "should not return any pages" do
386
- page_1 = Factory(:page, :language => @language, :page_layout => 'contact')
387
- clipboard = [
388
- {:id => page_1.id, :action => "copy"}
389
- ]
390
- Alchemy::Page.all_from_clipboard_for_select(clipboard, @language.id).should == []
391
- end
392
-
393
- end
394
-
395
- context "with clipboard holding two pages. One having a unique page layout." do
396
-
397
- it "should return one page" do
398
- page_1 = Factory(:page, :language => @language, :page_layout => 'standard')
399
- page_2 = Factory(:page, :name => 'Another Page', :language => @language, :page_layout => 'contact')
400
- clipboard = [
401
- {:id => page_1.id, :action => "copy"},
402
- {:id => page_2.id, :action => "copy"}
403
- ]
404
- Alchemy::Page.all_from_clipboard_for_select(clipboard, @language.id).should == [page_1]
405
- end
406
-
407
- end
408
-
409
- end
410
-
411
- describe "validations" do
412
-
413
- context "saving a normal content page" do
414
- it "should be possible to save when its urlname already exists in the scope of global pages" do
415
- @contentpage = Factory(:page, :urlname => "existing_twice")
416
- @global_with_same_urlname = Factory(:page, :urlname => "existing_twice", :layoutpage => true)
417
- @contentpage.title = "new Title"
418
- @contentpage.save.should == true
419
- end
420
- end
421
6
 
422
- context "creating a normal content page" do
7
+ before(:each) do
8
+ @rootpage = Alchemy::Page.root
9
+ @language = Alchemy::Language.get_default
10
+ @language_root = Factory(:language_root_page, :name => 'Default Language Root', :language => @language)
11
+ end
423
12
 
424
- before(:each) do
425
- @contentpage = Factory.build(:page, :parent_id => nil, :page_layout => nil)
426
- end
13
+ describe ".layout_description" do
427
14
 
428
- it "should validate the page_layout" do
429
- @contentpage.save
430
- @contentpage.should have(1).error_on(:page_layout)
431
- end
15
+ context "for a language root page" do
432
16
 
433
- it "should validate the parent_id" do
434
- @contentpage.save
435
- @contentpage.should have(1).error_on(:parent_id)
436
- end
17
+ it "should return the page layout description as hash" do
18
+ @language_root.layout_description['name'].should == 'intro'
19
+ end
437
20
 
438
- end
21
+ it "should return an empty hash for root page" do
22
+ @rootpage.layout_description.should == {}
23
+ end
439
24
 
440
- context "creating the rootpage without parent_id and page_layout" do
25
+ end
441
26
 
442
- before(:each) do
443
- Alchemy::Page.delete_all
444
- @rootpage = Factory.build(:page, :parent_id => nil, :page_layout => nil, :name => 'Rootpage')
445
- end
27
+ it "should raise Exception if the page_layout could not be found in the definition file" do
28
+ @page = mock(:page, :page_layout => 'foo')
29
+ expect { @page.layout_description }.to raise_error
30
+ end
446
31
 
447
- it "should be valid" do
448
- @rootpage.save
449
- @rootpage.should be_valid
450
- end
32
+ end
451
33
 
452
- end
34
+ it "should contain one rootpage" do
35
+ Alchemy::Page.rootpage.should be_instance_of(Alchemy::Page)
36
+ end
453
37
 
454
- context "saving a systempage" do
38
+ it "should return all rss feed elements" do
39
+ @page = Factory(:public_page, :page_layout => 'news', :parent_id => @language_root.id, :language => @language)
40
+ @page.feed_elements.should == Alchemy::Element.find_all_by_name('news')
41
+ end
455
42
 
456
- before(:each) do
457
- @systempage = Factory.build(:systempage)
458
- end
43
+ context "finding elements" do
459
44
 
460
- it "should not validate the page_layout" do
461
- @systempage.save
462
- @systempage.should be_valid
463
- end
45
+ before(:each) do
46
+ @page = Factory(:public_page)
47
+ @non_public_elements = [
48
+ Factory(:element, :public => false, :page => @page),
49
+ Factory(:element, :public => false, :page => @page)
50
+ ]
51
+ end
464
52
 
465
- end
53
+ it "should return the collection of elements if passed an array into options[:collection]" do
54
+ options = {:collection => @page.elements}
55
+ @page.find_elements(options).all.should == @page.elements.all
56
+ end
466
57
 
467
- end
58
+ context "with show_non_public argument TRUE" do
468
59
 
469
- describe 'before and after filters' do
60
+ it "should return all elements from empty options" do
61
+ @page.find_elements({}, true).all.should == @page.elements.all
62
+ end
470
63
 
471
- context "a normal page" do
64
+ it "should only return the elements passed as options[:only]" do
65
+ @page.find_elements({:only => ['article']}, true).all.should == @page.elements.named('article').all
66
+ end
472
67
 
473
- before(:each) do
474
- @page = Factory.build(:page, :language_code => nil, :language => Factory(:language))
475
- end
68
+ it "should not return the elements passed as options[:except]" do
69
+ @page.find_elements({:except => ['article']}, true).all.should == @page.elements - @page.elements.named('article').all
70
+ end
476
71
 
477
- it "should get the language code for language" do
478
- @page.save
479
- @page.language_code.should == "kl"
480
- end
72
+ it "should return elements offsetted" do
73
+ @page.find_elements({:offset => 2}, true).all.should == @page.elements.offset(2)
74
+ end
481
75
 
482
- it "should autogenerate the elements" do
483
- @page.save
484
- @page.elements.should_not be_empty
485
- end
76
+ it "should return elements limitted in count" do
77
+ @page.find_elements({:count => 1}, true).all.should == @page.elements.limit(1)
78
+ end
486
79
 
487
- context "with children getting restricted set to true" do
80
+ end
488
81
 
489
- before(:each) do
490
- @page.save
491
- @child1 = Factory(:page, :name => 'Child 1', :parent_id => @page.id)
492
- @page.reload
493
- @page.restricted = true
494
- @page.save
495
- end
82
+ context "with show_non_public argument FALSE" do
496
83
 
497
- it "should restrict all its children" do
498
- @child1.reload
499
- @child1.restricted?.should be_true
500
- end
84
+ it "should return all elements from empty arguments" do
85
+ @page.find_elements().all.should == @page.elements.published.all
86
+ end
501
87
 
502
- end
88
+ it "should only return the public elements passed as options[:only]" do
89
+ @page.find_elements(:only => ['article']).all.should == @page.elements.published.named('article').all
90
+ end
503
91
 
504
- context "with restricted parent gets created" do
92
+ it "should return all public elements except the ones passed as options[:except]" do
93
+ @page.find_elements(:except => ['article']).all.should == @page.elements.published.all - @page.elements.published.named('article').all
94
+ end
505
95
 
506
- before(:each) do
507
- @page.save
508
- @page.parent.update_attributes(:restricted => true)
509
- @new_page = Factory(:page, :name => 'New Page', :parent_id => @page.id)
510
- end
96
+ it "should return elements offsetted" do
97
+ @page.find_elements({:offset => 2}).all.should == @page.elements.published.offset(2)
98
+ end
511
99
 
512
- it "should also be restricted" do
513
- @new_page.restricted?.should be_true
514
- end
100
+ it "should return elements limitted in count" do
101
+ @page.find_elements({:count => 1}).all.should == @page.elements.published.limit(1)
102
+ end
515
103
 
516
- end
104
+ end
517
105
 
518
- context "with do_not_autogenerate set to true" do
106
+ end
519
107
 
520
- before(:each) do
521
- @page.do_not_autogenerate = true
522
- end
108
+ describe '#create' do
523
109
 
524
- it "should not autogenerate the elements" do
525
- @page.save
526
- @page.elements.should be_empty
527
- end
110
+ context "before/after filter" do
528
111
 
529
- end
112
+ it "should automatically set the title from its name" do
113
+ page = Factory(:page, :name => 'My Testpage', :language => @language, :parent_id => @language_root.id)
114
+ page.title.should == 'My Testpage'
115
+ end
530
116
 
531
- end
117
+ it "should get a webfriendly urlname" do
118
+ page = Factory(:page, :name => 'klingon$&stößel ', :language => @language, :parent_id => @language_root.id)
119
+ page.urlname.should == 'klingon-stoessel'
120
+ end
532
121
 
533
- context "a systempage" do
122
+ it "should generate a three letter urlname from two letter name" do
123
+ page = Factory(:page, :name => 'Au', :language => @language, :parent_id => @language_root.id)
124
+ page.urlname.should == '-au'
125
+ end
534
126
 
535
- before(:each) do
536
- @page = Factory(:systempage)
537
- end
127
+ it "should generate a three letter urlname from two letter name with umlaut" do
128
+ page = Factory(:page, :name => 'Aü', :language => @language, :parent_id => @language_root.id)
129
+ page.urlname.should == 'aue'
130
+ end
538
131
 
539
- it "should not get the language code for language" do
540
- @page.language_code.should be_nil
541
- end
132
+ it "should generate a three letter urlname from one letter name" do
133
+ page = Factory(:page, :name => 'A', :language => @language, :parent_id => @language_root.id)
134
+ page.urlname.should == '--a'
135
+ end
542
136
 
543
- it "should not autogenerate the elements" do
544
- @page.elements.should be_empty
545
- end
137
+ end
546
138
 
547
- end
139
+ end
548
140
 
549
- end
141
+ describe '#update' do
142
+
143
+ context "before/after filter" do
144
+
145
+ it "should not set the title automatically if the name changed but title is not blank" do
146
+ page = Factory(:page, :name => 'My Testpage', :language => @language, :parent_id => @language_root.id)
147
+ page.name = "My Renaming Test"
148
+ page.save; page.reload
149
+ page.title.should == "My Testpage"
150
+ end
151
+
152
+ it "should not automatically set the title if it changed its value" do
153
+ page = Factory(:page, :name => 'My Testpage', :language => @language, :parent_id => @language_root.id)
154
+ page.title = "I like SEO"
155
+ page.save; page.reload
156
+ page.title.should == "I like SEO"
157
+ end
158
+
159
+ end
160
+
161
+ end
162
+
163
+ context "with children" do
164
+
165
+ before(:each) do
166
+ @first_child = Factory(:page, :name => "First child", :language => @language, :public => false, :parent_id => @language_root.id)
167
+ @first_child.move_to_child_of(@language_root)
168
+
169
+ @first_public_child = Factory(:page, :name => "First public child", :language => @language, :parent_id => @language_root.id, :public => true)
170
+ @first_public_child.move_to_child_of(@language_root)
171
+ end
172
+
173
+ it "should return a page object (or nil if no public child exists) for first_public_child" do
174
+ if @language_root.children.any?
175
+ @language_root.first_public_child.should == @first_public_child
176
+ else
177
+ @language_root.first_public_child.should == nil
178
+ end
179
+ end
180
+
181
+ end
182
+
183
+ context ".public" do
184
+
185
+ it "should return pages that are public" do
186
+ Factory(:public_page, :name => 'First Public Child', :parent_id => @language_root.id, :language => @language)
187
+ Factory(:public_page, :name => 'Second Public Child', :parent_id => @language_root.id, :language => @language)
188
+ Alchemy::Page.published.should have(3).pages
189
+ end
190
+
191
+ end
192
+
193
+ context ".not_locked" do
194
+
195
+ it "should return pages that are not blocked by a user at the moment" do
196
+ Factory(:public_page, :locked => true, :name => 'First Public Child', :parent_id => @language_root.id, :language => @language)
197
+ Factory(:public_page, :name => 'Second Public Child', :parent_id => @language_root.id, :language => @language)
198
+ Alchemy::Page.not_locked.should have(3).pages
199
+ end
200
+ end
201
+
202
+ context ".all_locked" do
203
+ it "should return 1 page that is blocked by a user at the moment" do
204
+ Factory(:public_page, :locked => true, :name => 'First Public Child', :parent_id => @language_root.id, :language => @language)
205
+ Alchemy::Page.all_locked.should have(1).pages
206
+ end
207
+ end
208
+
209
+ context ".language_roots" do
210
+ it "should return 1 language_root" do
211
+ Factory(:public_page, :name => 'First Public Child', :parent_id => @language_root.id, :language => @language)
212
+ Alchemy::Page.language_roots.should have(1).pages
213
+ end
214
+ end
215
+
216
+
217
+ context ".layoutpages" do
218
+ it "should return 1 layoutpage" do
219
+ Factory(:public_page, :layoutpage => true, :name => 'Layoutpage', :parent_id => @rootpage.id, :language => @language)
220
+ Alchemy::Page.layoutpages.should have(1).pages
221
+ end
222
+ end
223
+
224
+ context ".visible" do
225
+ it "should return 1 visible page" do
226
+ Factory(:public_page, :name => 'First Public Child', :visible => true, :parent_id => @language_root.id, :language => @language)
227
+ Alchemy::Page.visible.should have(1).pages
228
+ end
229
+ end
230
+
231
+ context ".accessable" do
232
+ it "should return 2 accessable pages" do
233
+ Factory(:public_page, :name => 'First Public Child', :restricted => true, :parent_id => @language_root.id, :language => @language)
234
+ Alchemy::Page.accessable.should have(2).pages
235
+ end
236
+ end
237
+
238
+ context ".restricted" do
239
+ it "should return 1 restricted page" do
240
+ Factory(:public_page, :name => 'First Public Child', :restricted => true, :parent_id => @language_root.id, :language => @language)
241
+ Alchemy::Page.restricted.should have(1).pages
242
+ end
243
+ end
244
+
245
+ context "#unlock" do
246
+ it "should set the locked status to false" do
247
+ @page = Factory(:public_page, :locked => true)
248
+ @page.unlock
249
+ @page.locked.should == false
250
+ end
251
+ end
252
+
253
+ describe "#cell_definitions" do
254
+
255
+ before(:each) do
256
+ @page = Factory.build(:page, :page_layout => 'foo')
257
+ @page.stub!(:layout_description).and_return({'name' => "foo", 'cells' => ["foo_cell"]})
258
+ @cell_descriptions = [{'name' => "foo_cell", 'elements' => ["1", "2"]}]
259
+ Alchemy::Cell.stub!(:definitions).and_return(@cell_descriptions)
260
+ end
261
+
262
+ it "should return all cell definitions for its page_layout" do
263
+ @page.cell_definitions.should == @cell_descriptions
264
+ end
265
+
266
+ it "should return empty array if no cells defined in page layout" do
267
+ @page.stub!(:layout_description).and_return({'name' => "foo"})
268
+ @page.cell_definitions.should == []
269
+ end
270
+
271
+ end
272
+
273
+ describe "#elements_grouped_by_cells" do
274
+
275
+ context "with no elements defined that are not defined in a cell" do
276
+ it "should not have a cell for 'other elements'" do
277
+ @page = Factory.build(:page, :page_layout => 'foo')
278
+ @page.stub!(:layout_description).and_return({'name' => "foo", 'cells' => ["foo_cell"], 'elements' => ["1", "2"]})
279
+ @cell_descriptions = [{'name' => "foo_cell", 'elements' => ["1", "2"]}]
280
+ Alchemy::Cell.stub!(:definitions).and_return(@cell_descriptions)
281
+ @page.elements_grouped_by_cells.keys.collect(&:name).should_not include('for_other_elements')
282
+ end
283
+ end
284
+
285
+ context "with elements defined that are not defined in a cell" do
286
+ it "should have a cell for 'other elements'" do
287
+ @page = Factory.build(:page, :page_layout => 'foo')
288
+ @page.stub!(:layout_description).and_return({'name' => "foo", 'cells' => ["foo_cell"], 'elements' => ["1", "2", "3"]})
289
+ @cell_descriptions = [{'name' => "foo_cell", 'elements' => ["1", "2"]}]
290
+ Alchemy::Cell.stub!(:definitions).and_return(@cell_descriptions)
291
+ @page.elements_grouped_by_cells.keys.collect(&:name).should include('for_other_elements')
292
+ end
293
+ end
294
+
295
+ end
296
+
297
+ describe '.all_from_clipboard_for_select' do
298
+
299
+ context "with clipboard holding pages having non unique page layout" do
300
+
301
+ it "should return the pages" do
302
+ page_1 = Factory(:page, :language => @language)
303
+ page_2 = Factory(:page, :language => @language)
304
+ clipboard = [
305
+ {:id => page_1.id, :action => "copy"},
306
+ {:id => page_2.id, :action => "copy"}
307
+ ]
308
+ Alchemy::Page.all_from_clipboard_for_select(clipboard, @language.id).should == [page_1, page_2]
309
+ end
310
+
311
+ end
312
+
313
+ context "with clipboard holding a page having unique page layout" do
314
+
315
+ it "should not return any pages" do
316
+ page_1 = Factory(:page, :language => @language, :page_layout => 'contact')
317
+ clipboard = [
318
+ {:id => page_1.id, :action => "copy"}
319
+ ]
320
+ Alchemy::Page.all_from_clipboard_for_select(clipboard, @language.id).should == []
321
+ end
322
+
323
+ end
324
+
325
+ context "with clipboard holding two pages. One having a unique page layout." do
326
+
327
+ it "should return one page" do
328
+ page_1 = Factory(:page, :language => @language, :page_layout => 'standard')
329
+ page_2 = Factory(:page, :language => @language, :page_layout => 'contact')
330
+ clipboard = [
331
+ {:id => page_1.id, :action => "copy"},
332
+ {:id => page_2.id, :action => "copy"}
333
+ ]
334
+ Alchemy::Page.all_from_clipboard_for_select(clipboard, @language.id).should == [page_1]
335
+ end
336
+
337
+ end
338
+
339
+ end
340
+
341
+ describe "validations" do
342
+
343
+ context "saving a normal content page" do
344
+ it "should be possible to save when its urlname already exists in the scope of global pages" do
345
+ @contentpage = Factory(:page, :urlname => "existing_twice")
346
+ @global_with_same_urlname = Factory(:page, :urlname => "existing_twice", :layoutpage => true)
347
+ @contentpage.title = "new Title"
348
+ @contentpage.save.should == true
349
+ end
350
+ end
351
+
352
+ context "creating a normal content page" do
353
+
354
+ before(:each) do
355
+ @contentpage = Factory.build(:page, :parent_id => nil, :page_layout => nil)
356
+ end
357
+
358
+ it "should validate the page_layout" do
359
+ @contentpage.save
360
+ @contentpage.should have(1).error_on(:page_layout)
361
+ end
362
+
363
+ it "should validate the parent_id" do
364
+ @contentpage.save
365
+ @contentpage.should have(1).error_on(:parent_id)
366
+ end
367
+
368
+ end
369
+
370
+ context "creating the rootpage without parent_id and page_layout" do
371
+
372
+ before(:each) do
373
+ Alchemy::Page.delete_all
374
+ @rootpage = Factory.build(:page, :parent_id => nil, :page_layout => nil, :name => 'Rootpage')
375
+ end
376
+
377
+ it "should be valid" do
378
+ @rootpage.save
379
+ @rootpage.should be_valid
380
+ end
381
+
382
+ end
383
+
384
+ context "saving a systempage" do
385
+
386
+ before(:each) do
387
+ @systempage = Factory.build(:systempage)
388
+ end
389
+
390
+ it "should not validate the page_layout" do
391
+ @systempage.save
392
+ @systempage.should be_valid
393
+ end
394
+
395
+ end
396
+
397
+ end
398
+
399
+ describe 'before and after filters' do
400
+
401
+ context "a normal page" do
402
+
403
+ before(:each) do
404
+ @page = Factory.build(:page, :language_code => nil, :language => Factory(:language))
405
+ end
406
+
407
+ it "should get the language code for language" do
408
+ @page.save
409
+ @page.language_code.should == "kl"
410
+ end
411
+
412
+ it "should autogenerate the elements" do
413
+ @page.save
414
+ @page.elements.should_not be_empty
415
+ end
416
+
417
+ context "with children getting restricted set to true" do
418
+
419
+ before(:each) do
420
+ @page.save
421
+ @child1 = Factory(:page, :name => 'Child 1', :parent_id => @page.id)
422
+ @page.reload
423
+ @page.restricted = true
424
+ @page.save
425
+ end
426
+
427
+ it "should restrict all its children" do
428
+ @child1.reload
429
+ @child1.restricted?.should be_true
430
+ end
431
+
432
+ end
433
+
434
+ context "with restricted parent gets created" do
435
+
436
+ before(:each) do
437
+ @page.save
438
+ @page.parent.update_attributes(:restricted => true)
439
+ @new_page = Factory(:page, :name => 'New Page', :parent_id => @page.id)
440
+ end
441
+
442
+ it "should also be restricted" do
443
+ @new_page.restricted?.should be_true
444
+ end
445
+
446
+ end
447
+
448
+ context "with do_not_autogenerate set to true" do
449
+
450
+ before(:each) do
451
+ @page.do_not_autogenerate = true
452
+ end
453
+
454
+ it "should not autogenerate the elements" do
455
+ @page.save
456
+ @page.elements.should be_empty
457
+ end
458
+
459
+ end
460
+
461
+ end
462
+
463
+ context "a systempage" do
464
+
465
+ before(:each) do
466
+ @page = Factory(:systempage)
467
+ end
468
+
469
+ it "should not get the language code for language" do
470
+ @page.language_code.should be_nil
471
+ end
472
+
473
+ it "should not autogenerate the elements" do
474
+ @page.elements.should be_empty
475
+ end
476
+
477
+ end
478
+
479
+ end
550
480
 
551
481
  end