spontaneous 0.2.0.alpha2 → 0.2.0.alpha3

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 (404) hide show
  1. data/Gemfile +3 -40
  2. data/Rakefile +29 -41
  3. data/Readme.markdown +21 -8
  4. data/application/css/add_alias_dialogue.css.scss +79 -0
  5. data/application/css/{v2.scss → core.css.scss} +537 -550
  6. data/application/css/{definitions.scss → definitions.css.scss} +121 -33
  7. data/application/css/dialogue.css.scss +409 -0
  8. data/application/css/{editing.scss → editing.css.scss} +25 -262
  9. data/application/css/font.css.scss +8 -0
  10. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  11. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  12. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_flat_10_000000_40x100.png +0 -0
  13. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  14. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  15. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  16. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  17. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  18. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  19. data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_222222_256x240.png +0 -0
  20. data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_228ef1_256x240.png +0 -0
  21. data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_ef8c08_256x240.png +0 -0
  22. data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_ffd27a_256x240.png +0 -0
  23. data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_ffffff_256x240.png +0 -0
  24. data/application/css/jquery-ui-1.8.21.custom/ui-lightness.css.scss +565 -0
  25. data/application/css/{login.scss → login.css.scss} +4 -4
  26. data/application/css/meta.css.scss +331 -0
  27. data/application/css/{popover.scss → popover.css.scss} +9 -8
  28. data/application/css/{schema_error.scss → schema_error.css.scss} +4 -4
  29. data/application/css/spontaneous.css +5 -0
  30. data/application/css/unsupported.css.scss +42 -0
  31. data/application/js/add_alias_dialogue.js +72 -10
  32. data/application/js/ajax.js +50 -16
  33. data/application/js/compatibility.js +19 -15
  34. data/application/js/content.js +39 -36
  35. data/application/js/content_area.js +53 -5
  36. data/application/js/dialogue.js +17 -0
  37. data/application/js/dom.js +1 -1
  38. data/application/js/edit_panel.js +23 -8
  39. data/application/js/extensions.js +7 -2
  40. data/application/js/field_preview.js +2 -1
  41. data/application/js/field_types/date_field.js +11 -8
  42. data/application/js/field_types/file_field.js +188 -9
  43. data/application/js/field_types/image_field.js +46 -29
  44. data/application/js/field_types/markdown_field.js +57 -14
  45. data/application/js/field_types/select_field.js +72 -0
  46. data/application/js/field_types/string_field.js +8 -0
  47. data/application/js/field_types/webvideo_field.js +8 -0
  48. data/application/js/init.js +1 -7
  49. data/application/js/location.js +41 -13
  50. data/application/js/login.js +3 -0
  51. data/application/js/meta_view/user_admin.js +543 -0
  52. data/application/js/meta_view.js +1 -0
  53. data/application/js/metadata.js +20 -0
  54. data/application/js/page.js +17 -3
  55. data/application/js/page_browser.js +40 -30
  56. data/application/js/page_entry.js +4 -0
  57. data/application/js/panel/root_menu.js +66 -0
  58. data/application/js/popover.js +2 -2
  59. data/application/js/preview.js +1 -1
  60. data/application/js/publish.js +138 -30
  61. data/application/js/services.js +43 -0
  62. data/application/js/sharded_upload.js +2 -2
  63. data/application/js/spontaneous.js +64 -5
  64. data/application/js/state.js +20 -9
  65. data/application/js/top_bar.js +273 -150
  66. data/application/js/types.js +20 -15
  67. data/application/js/upload.js +1 -2
  68. data/application/js/user.js +18 -4
  69. data/application/js/vendor/date.js +104 -0
  70. data/application/js/vendor/jquery-ui-1.8.18.custom.min.js +356 -0
  71. data/application/js/views/box_view.js +15 -8
  72. data/application/js/views/page_piece_view.js +11 -8
  73. data/application/js/views/page_view.js +21 -3
  74. data/application/js/views/piece_view.js +19 -10
  75. data/application/js/views.js +3 -0
  76. data/application/static/chromelogo-200x52-45c7cbc93be080bea342df5fcda2ef8b.png +0 -0
  77. data/application/static/dot-texture-9eea29e4ac7ad9a772285252078ec127.png +0 -0
  78. data/application/static/editing-textarea-resize-s-b5af62365eb7e19ea4beccf7242d508e.png +0 -0
  79. data/application/static/editing-texture-1-42b06a3439752490988f30f2a06d5e7c.png +0 -0
  80. data/application/static/font/fontawesome-webfont-5c5c21100a346972a82c34c5e96ffcfe.ttf +0 -0
  81. data/application/static/loop_alt1-white-7894b458528e92216196cae26b4c2c96.svg +12 -0
  82. data/application/static/spontaneous-states-e91ec89db525c62da0105b97cdd781ce.png +0 -0
  83. data/application/views/index.erb +2 -2
  84. data/application/views/login.erb +4 -8
  85. data/application/views/schema_modification_error.html.erb +1 -4
  86. data/application/views/unsupported.erb +9 -7
  87. data/bin/spot +1 -1
  88. data/db/migrations/20110209152710_users_and_groups.rb +10 -10
  89. data/db/migrations/20120305112647_site_modification_time.rb +11 -0
  90. data/db/migrations/20120418153903_add_ownership_of_content.rb +14 -0
  91. data/db/migrations/20120423175416_add_pending_modifications.rb +21 -0
  92. data/db/migrations/20120525164947_add_field_versions.rb +27 -0
  93. data/lib/sequel/plugins/scoped_table_name.rb +10 -1
  94. data/lib/spontaneous/asset/file.rb +25 -0
  95. data/lib/spontaneous/asset/source.rb +28 -0
  96. data/lib/spontaneous/asset.rb +75 -0
  97. data/lib/spontaneous/box.rb +6 -4
  98. data/lib/spontaneous/capistrano/deploy.rb +47 -0
  99. data/lib/spontaneous/capistrano/sync.rb +81 -0
  100. data/lib/spontaneous/capistrano.rb +13 -0
  101. data/lib/spontaneous/change.rb +60 -68
  102. data/lib/spontaneous/cli/assets.rb +29 -0
  103. data/lib/spontaneous/cli/base.rb +0 -48
  104. data/lib/spontaneous/cli/console.rb +1 -1
  105. data/lib/spontaneous/cli/server.rb +6 -4
  106. data/lib/spontaneous/cli/site.rb +28 -17
  107. data/lib/spontaneous/cli/user.rb +107 -0
  108. data/lib/spontaneous/cli.rb +100 -4
  109. data/lib/spontaneous/collections/entry_set.rb +2 -2
  110. data/lib/spontaneous/collections/field_set.rb +48 -22
  111. data/lib/spontaneous/collections/prototype_set.rb +20 -13
  112. data/lib/spontaneous/constants.rb +3 -0
  113. data/lib/spontaneous/content.rb +22 -5
  114. data/lib/spontaneous/errors.rb +3 -3
  115. data/lib/spontaneous/extensions/array.rb +12 -0
  116. data/lib/spontaneous/extensions/enumerable.rb +30 -0
  117. data/lib/spontaneous/extensions/nil.rb +3 -1
  118. data/lib/spontaneous/extensions/string.rb +16 -0
  119. data/lib/spontaneous/field_types/date_field.rb +45 -2
  120. data/lib/spontaneous/field_types/field.rb +42 -9
  121. data/lib/spontaneous/field_types/file_field.rb +68 -0
  122. data/lib/spontaneous/field_types/image_field.rb +63 -0
  123. data/lib/spontaneous/field_types/select_field.rb +109 -0
  124. data/lib/spontaneous/field_types/string_field.rb +6 -1
  125. data/lib/spontaneous/field_types/webvideo_field.rb +85 -27
  126. data/lib/spontaneous/field_types.rb +1 -1
  127. data/lib/spontaneous/field_version.rb +8 -0
  128. data/lib/spontaneous/generators/page.rb +1 -1
  129. data/lib/spontaneous/generators/site/Capfile.tt +1 -4
  130. data/lib/spontaneous/generators/site/Gemfile.tt +13 -6
  131. data/lib/spontaneous/generators/site/config/deploy.rb.tt +28 -0
  132. data/lib/spontaneous/generators/site/config/environments/production.rb.tt +7 -2
  133. data/lib/spontaneous/generators/site.rb +1 -0
  134. data/lib/spontaneous/json.rb +34 -11
  135. data/lib/spontaneous/layout.rb +22 -0
  136. data/lib/spontaneous/media/file.rb +4 -0
  137. data/lib/spontaneous/output/assets/compression.rb +58 -0
  138. data/lib/spontaneous/output/assets.rb +32 -0
  139. data/lib/spontaneous/output/context.rb +179 -0
  140. data/lib/spontaneous/output/format/html.rb +5 -0
  141. data/lib/spontaneous/output/format/plain.rb +5 -0
  142. data/lib/spontaneous/output/format.rb +180 -0
  143. data/lib/spontaneous/output/helpers/classes_helper.rb +18 -0
  144. data/lib/spontaneous/{render/helpers/html_helper.rb → output/helpers/conditional_comment_helper.rb} +3 -12
  145. data/lib/spontaneous/output/helpers/script_helper.rb +73 -0
  146. data/lib/spontaneous/output/helpers/stylesheet_helper.rb +61 -0
  147. data/lib/spontaneous/output/helpers.rb +28 -0
  148. data/lib/spontaneous/output/template/engine.rb +59 -0
  149. data/lib/spontaneous/output/template/renderer.rb +153 -0
  150. data/lib/spontaneous/output/template.rb +21 -0
  151. data/lib/spontaneous/output.rb +163 -0
  152. data/lib/spontaneous/page.rb +2 -1
  153. data/lib/spontaneous/paths.rb +6 -1
  154. data/lib/spontaneous/permissions/access_key.rb +5 -5
  155. data/lib/spontaneous/permissions/user.rb +81 -35
  156. data/lib/spontaneous/permissions/user_level.rb +26 -22
  157. data/lib/spontaneous/plugins/aliases.rb +76 -12
  158. data/lib/spontaneous/plugins/allowed_types.rb +60 -18
  159. data/lib/spontaneous/plugins/application/paths.rb +0 -28
  160. data/lib/spontaneous/plugins/application/system.rb +35 -0
  161. data/lib/spontaneous/plugins/boxes.rb +4 -0
  162. data/lib/spontaneous/plugins/content_groups.rb +16 -0
  163. data/lib/spontaneous/plugins/entries.rb +50 -30
  164. data/lib/spontaneous/plugins/fields.rb +15 -0
  165. data/lib/spontaneous/plugins/layouts.rb +8 -2
  166. data/lib/spontaneous/plugins/modifications.rb +228 -0
  167. data/lib/spontaneous/plugins/page/formats.rb +67 -42
  168. data/lib/spontaneous/plugins/page/request.rb +10 -0
  169. data/lib/spontaneous/plugins/page/site_timestamps.rb +28 -0
  170. data/lib/spontaneous/plugins/paths.rb +15 -3
  171. data/lib/spontaneous/plugins/publishing.rb +124 -45
  172. data/lib/spontaneous/plugins/render.rb +13 -8
  173. data/lib/spontaneous/plugins/schema_hierarchy.rb +18 -6
  174. data/lib/spontaneous/plugins/site/helpers.rb +53 -0
  175. data/lib/spontaneous/plugins/site/hooks.rb +50 -0
  176. data/lib/spontaneous/plugins/site/map.rb +1 -1
  177. data/lib/spontaneous/plugins/site/paths.rb +13 -0
  178. data/lib/spontaneous/plugins/site/publishing.rb +6 -2
  179. data/lib/spontaneous/plugins/site/{revisions.rb → state.rb} +5 -1
  180. data/lib/spontaneous/plugins/site/storage.rb +4 -0
  181. data/lib/spontaneous/plugins/site/url.rb +15 -0
  182. data/lib/spontaneous/plugins/site_map.rb +13 -3
  183. data/lib/spontaneous/plugins/styles.rb +5 -1
  184. data/lib/spontaneous/plugins/visibility.rb +39 -12
  185. data/lib/spontaneous/prototypes/box_prototype.rb +4 -0
  186. data/lib/spontaneous/prototypes/field_prototype.rb +15 -10
  187. data/lib/spontaneous/publishing/event_client.rb +46 -0
  188. data/lib/spontaneous/publishing/immediate.rb +81 -44
  189. data/lib/spontaneous/publishing/simultaneous.rb +23 -6
  190. data/lib/spontaneous/publishing.rb +4 -3
  191. data/lib/spontaneous/rack/around_back.rb +1 -5
  192. data/lib/spontaneous/rack/around_front.rb +4 -4
  193. data/lib/spontaneous/rack/around_preview.rb +4 -3
  194. data/lib/spontaneous/rack/assets.rb +81 -54
  195. data/lib/spontaneous/rack/authentication.rb +0 -1
  196. data/lib/spontaneous/rack/back.rb +160 -72
  197. data/lib/spontaneous/rack/cookie_authentication.rb +2 -2
  198. data/lib/spontaneous/rack/css.rb +18 -15
  199. data/lib/spontaneous/rack/event_source.rb +9 -21
  200. data/lib/spontaneous/rack/fiber_pool.rb +26 -0
  201. data/lib/spontaneous/rack/front.rb +12 -4
  202. data/lib/spontaneous/rack/helpers.rb +35 -13
  203. data/lib/spontaneous/rack/js.rb +41 -0
  204. data/lib/spontaneous/rack/public.rb +34 -44
  205. data/lib/spontaneous/rack/sse.rb +18 -0
  206. data/lib/spontaneous/rack/static.rb +3 -0
  207. data/lib/spontaneous/rack/user_admin.rb +100 -0
  208. data/lib/spontaneous/rack/user_helpers.rb +1 -1
  209. data/lib/spontaneous/rack.rb +6 -2
  210. data/lib/spontaneous/schema.rb +31 -4
  211. data/lib/spontaneous/search/index.rb +19 -3
  212. data/lib/spontaneous/search/results.rb +1 -1
  213. data/lib/spontaneous/sequel.rb +17 -0
  214. data/lib/spontaneous/site.rb +11 -4
  215. data/lib/spontaneous/state.rb +11 -0
  216. data/lib/spontaneous/storage/cloud.rb +4 -0
  217. data/lib/spontaneous/storage/local.rb +11 -0
  218. data/lib/spontaneous/style.rb +2 -2
  219. data/lib/spontaneous/tasks/database.rake +21 -22
  220. data/lib/spontaneous/utils/database/mysql_dumper.rb +4 -0
  221. data/lib/spontaneous/utils/database/postgres_dumper.rb +78 -0
  222. data/lib/spontaneous/utils/database.rb +6 -3
  223. data/lib/spontaneous/utils/smart_quotes.rb +499 -0
  224. data/lib/spontaneous/utils/smush_it.rb +66 -0
  225. data/lib/spontaneous/utils.rb +3 -1
  226. data/lib/spontaneous/version.rb +2 -2
  227. data/lib/spontaneous.rb +25 -29
  228. data/spontaneous.gemspec +186 -106
  229. data/test/experimental/test_features.rb +1 -1
  230. data/test/fixtures/asset_pipeline/application/css/basic.css.scss +4 -0
  231. data/test/fixtures/asset_pipeline/application/css/complex.css.scss.erb +6 -0
  232. data/test/fixtures/asset_pipeline/application/css/simple.css +3 -0
  233. data/test/fixtures/asset_pipeline/application/css/spontaneous.css +7 -0
  234. data/test/fixtures/asset_pipeline/application/css/subdir/complex.css.scss.erb +6 -0
  235. data/test/fixtures/asset_pipeline/application/css/subdir/library.css.scss +1 -0
  236. data/test/fixtures/asset_pipeline/application/css/subdir/simple.css +3 -0
  237. data/test/fixtures/asset_pipeline/application/js/basic.js.coffee +1 -0
  238. data/test/fixtures/asset_pipeline/application/js/complex.js.coffee.erb +1 -0
  239. data/test/fixtures/asset_pipeline/application/js/login.js +1 -0
  240. data/test/fixtures/asset_pipeline/application/js/require.js +1 -0
  241. data/test/fixtures/asset_pipeline/application/js/simple.js +1 -0
  242. data/test/fixtures/asset_pipeline/application/js/spontaneous.js +5 -0
  243. data/test/fixtures/asset_pipeline/application/js/subdir/complex.js.coffee.erb +1 -0
  244. data/test/fixtures/asset_pipeline/application/js/subdir/library.js.coffee +1 -0
  245. data/test/fixtures/asset_pipeline/application/js/subdir/simple.js +1 -0
  246. data/test/fixtures/asset_pipeline/application/js/vendor/jquery.js +1 -0
  247. data/test/fixtures/asset_pipeline/application/static/dot-texture.png +0 -0
  248. data/test/fixtures/asset_pipeline/application/static/subdir/px.gif +0 -0
  249. data/test/fixtures/assets/public1/css/a.scss +1 -0
  250. data/test/fixtures/assets/public1/js/a.js +1 -0
  251. data/test/fixtures/assets/public1/js/m.coffee +1 -0
  252. data/test/fixtures/assets/public2/css/b.scss +1 -0
  253. data/test/fixtures/assets/public2/css/c.css +1 -0
  254. data/test/fixtures/assets/public2/js/b.js +1 -0
  255. data/test/fixtures/assets/public2/js/c.js +1 -0
  256. data/test/fixtures/assets/public2/js/n.coffee +1 -0
  257. data/test/fixtures/back/config/user_levels.yml +3 -0
  258. data/test/fixtures/back/public/js/coffeescript.coffee +1 -0
  259. data/test/fixtures/back/templates/layouts/standard.css.cut +1 -0
  260. data/test/fixtures/back/templates/layouts/standard.js.cut +1 -0
  261. data/test/fixtures/example_application/config/database.yml +4 -4
  262. data/test/fixtures/helpers/templates/layouts/standard.html.cut +1 -0
  263. data/test/fixtures/helpers/templates/layouts/standard.mobile.cut +1 -0
  264. data/test/fixtures/images/vimlogo.pdf +0 -0
  265. data/test/fixtures/outputs/templates/layouts/standard.atom.cut +1 -0
  266. data/test/fixtures/permissions/config/user_levels.yml +6 -3
  267. data/test/fixtures/serialisation/class_hash.yaml.erb +1 -0
  268. data/test/fixtures/serialisation/root_hash.yaml.erb +2 -2
  269. data/test/fixtures/templates/extended/grandparent.html.cut +7 -7
  270. data/test/fixtures/templates/extended/main.html.cut +5 -5
  271. data/test/fixtures/templates/extended/parent.html.cut +8 -8
  272. data/test/fixtures/templates/extended/partial_with_locals.html.cut +1 -1
  273. data/test/fixtures/templates/extended/with_includes.html.cut +6 -6
  274. data/test/fixtures/templates/extended/with_includes_and_locals.html.cut +6 -7
  275. data/test/fixtures/templates/layouts/entries.html.cut +4 -4
  276. data/test/fixtures/templates/layouts/standard.html.cut +1 -0
  277. data/test/fixtures/templates/layouts/variables.html.cut +1 -1
  278. data/test/fixtures/templates/publishing/templates/layouts/static.html.cut +1 -1
  279. data/test/fixtures/templates/publishing/templates/layouts/static.rtf.cut +1 -0
  280. data/test/fixtures/templates/template_class/complex_template.html.cut +2 -2
  281. data/test/fixtures/templates/template_class/complex_template.pdf.cut +2 -2
  282. data/test/fixtures/templates/template_class/default_template_style.html.cut +1 -1
  283. data/test/fixtures/templates/template_class/images_with_template.html.cut +2 -2
  284. data/test/fixtures/templates/template_class/slots_template.html.cut +2 -2
  285. data/test/fixtures/templates/template_class/slots_template.pdf.cut +2 -2
  286. data/test/fixtures/user_manager/config/user_levels.yml +9 -0
  287. data/test/functional/test_application.rb +7 -7
  288. data/test/functional/test_back.rb +352 -97
  289. data/test/functional/test_front.rb +71 -20
  290. data/test/functional/test_user_manager.rb +284 -0
  291. data/test/javascript/env.js +13505 -0
  292. data/test/javascript/test_markdown.rb +43 -3
  293. data/test/support/custom_matchers.rb +3 -2
  294. data/test/test_helper.rb +50 -9
  295. data/test/test_javascript.rb +13 -13
  296. data/test/ui_helper.rb +1 -1
  297. data/test/unit/test_alias.rb +79 -8
  298. data/test/unit/test_asset_bundler.rb +220 -0
  299. data/test/unit/test_assets.rb +213 -0
  300. data/test/unit/test_async.rb +55 -0
  301. data/test/unit/test_authentication.rb +52 -39
  302. data/test/unit/test_boxes.rb +20 -15
  303. data/test/unit/test_changesets.rb +261 -0
  304. data/test/unit/test_content.rb +73 -33
  305. data/test/unit/test_content_inheritance.rb +18 -18
  306. data/test/unit/test_extensions.rb +26 -0
  307. data/test/unit/test_fields.rb +303 -16
  308. data/test/unit/test_formats.rb +267 -34
  309. data/test/unit/test_helpers.rb +79 -2
  310. data/test/unit/test_images.rb +10 -0
  311. data/test/unit/test_layouts.rb +21 -13
  312. data/test/unit/test_modifications.rb +648 -0
  313. data/test/unit/test_page.rb +6 -2
  314. data/test/unit/test_permissions.rb +101 -27
  315. data/test/unit/test_piece.rb +4 -4
  316. data/test/unit/test_plugins.rb +3 -2
  317. data/test/unit/test_publishing.rb +332 -0
  318. data/test/unit/test_render.rb +118 -67
  319. data/test/unit/test_revisions.rb +546 -0
  320. data/test/unit/test_schema.rb +83 -1
  321. data/test/unit/test_search.rb +59 -0
  322. data/test/unit/test_serialisation.rb +2 -47
  323. data/test/unit/test_site.rb +217 -108
  324. data/test/unit/test_storage.rb +26 -0
  325. data/test/unit/test_structure.rb +2 -2
  326. data/test/unit/test_styles.rb +90 -75
  327. data/test/unit/test_table_scoping.rb +21 -17
  328. data/test/unit/test_templates.rb +75 -69
  329. data/test/{slow → unit}/test_visibility.rb +78 -22
  330. metadata +528 -221
  331. data/application/css/add_alias_dialogue.scss +0 -27
  332. data/application/css/min/14c2a35812c443001b15d8b12a4780f88c678035.css +0 -1
  333. data/application/css/min/565d4c25e82148acb01c45c8d675b37a08676d77.css +0 -1
  334. data/application/css/min/84dbe894ea96eafd321c30823d630817bfc4b03b.css +0 -1
  335. data/application/css/spontaneous.scss +0 -111
  336. data/application/css/unsupported.scss +0 -16
  337. data/application/css/variables.scss +0 -80
  338. data/application/js/min/2a0c2962537a3181fedfff5c92596ba6d3122dc9.js +0 -3
  339. data/application/js/min/4cf1c493d3379ecba5287758c61238034c0893f9.js +0 -2
  340. data/application/js/min/78ac6b99d96750bb6b9f9aad4cb9cd91cd03f391.js +0 -3
  341. data/application/js/min/b8abf302a824c35385ff517b34111e1710ff3b37.js +0 -2
  342. data/application/js/min/c8efb9b9f7c3f6613fcebc6be60f605b6570a382.js +0 -90
  343. data/application/static/diagonal-texture.png +0 -0
  344. data/application/static/editing-0-noise.png +0 -0
  345. data/application/static/editing-1-noise.png +0 -0
  346. data/application/static/editing-texture-1.png +0 -0
  347. data/application/static/editing-texture.png +0 -0
  348. data/application/static/editing-toolbar-shadow-bottom.png +0 -0
  349. data/application/static/editing-toolbar-shadow-top.png +0 -0
  350. data/application/static/inner-glow.png +0 -0
  351. data/application/static/item-buttons-highlight.png +0 -0
  352. data/application/static/item-buttons.png +0 -0
  353. data/application/static/paper-texture-dark.png +0 -0
  354. data/application/static/plus_alt.svg +0 -8
  355. data/application/static/select-arrow-root.png +0 -0
  356. data/application/static/slot-up-arrow.png +0 -0
  357. data/application/static/spontaneous.png +0 -0
  358. data/lib/cutaneous/context_helper.rb +0 -187
  359. data/lib/cutaneous/preview_context.rb +0 -32
  360. data/lib/cutaneous/preview_renderer.rb +0 -10
  361. data/lib/cutaneous/publish_context.rb +0 -10
  362. data/lib/cutaneous/publish_renderer.rb +0 -14
  363. data/lib/cutaneous/publish_template.rb +0 -62
  364. data/lib/cutaneous/publish_token_parser.rb +0 -8
  365. data/lib/cutaneous/renderer.rb +0 -124
  366. data/lib/cutaneous/request_context.rb +0 -9
  367. data/lib/cutaneous/request_renderer.rb +0 -15
  368. data/lib/cutaneous/request_template.rb +0 -11
  369. data/lib/cutaneous/request_token_parser.rb +0 -9
  370. data/lib/cutaneous/token_parser.rb +0 -125
  371. data/lib/cutaneous.rb +0 -48
  372. data/lib/spontaneous/render/context_base.rb +0 -143
  373. data/lib/spontaneous/render/development_renderer.rb +0 -14
  374. data/lib/spontaneous/render/engine.rb +0 -19
  375. data/lib/spontaneous/render/format/html.rb +0 -5
  376. data/lib/spontaneous/render/format.rb +0 -75
  377. data/lib/spontaneous/render/helpers/script_helper.rb +0 -17
  378. data/lib/spontaneous/render/helpers/stylesheet_helper.rb +0 -16
  379. data/lib/spontaneous/render/helpers.rb +0 -14
  380. data/lib/spontaneous/render/preview_context.rb +0 -8
  381. data/lib/spontaneous/render/preview_renderer.rb +0 -24
  382. data/lib/spontaneous/render/publish_context.rb +0 -22
  383. data/lib/spontaneous/render/published_renderer.rb +0 -53
  384. data/lib/spontaneous/render/publishing_renderer.rb +0 -16
  385. data/lib/spontaneous/render/render_cache.rb +0 -26
  386. data/lib/spontaneous/render/renderer.rb +0 -50
  387. data/lib/spontaneous/render/request_context.rb +0 -8
  388. data/lib/spontaneous/render.rb +0 -214
  389. data/test/experimental/test_cutaneous.rb +0 -309
  390. data/test/fixtures/application/css/test.less +0 -5
  391. data/test/slow/test_publishing.rb +0 -1006
  392. /data/application/css/{developer.scss → developer.css.scss} +0 -0
  393. /data/application/js/vendor/{jquery-1.7.1.min.js → jquery.js} +0 -0
  394. /data/application/static/{location-arrow.png → location-arrow-c1c1d3ca472481c61a0a5f8cb289d743.png} +0 -0
  395. /data/application/static/{missing.png → missing-911ce6dbd9f4602e0f3fbcd7e78846a2.png} +0 -0
  396. /data/application/static/{orange-down-arrow.png → orange-down-arrow-395ae1929e8662b2ff0977daf12c35bb.png} +0 -0
  397. /data/application/static/{page-browser-next.png → page-browser-next-ce781a242c23b980b99b9db7abc20b05.png} +0 -0
  398. /data/application/static/{plus-box.png → plus-box-dcde74a1e496f68298c9b443caa1c5d5.png} +0 -0
  399. /data/application/static/{select-arrow.png → select-arrow-6e7dd3745b00e934b0d7a3250c46558b.png} +0 -0
  400. /data/application/static/{slot-down-arrow.png → slot-down-arrow-59ad5f5ee5b52a7ebd00bca4b3104194.png} +0 -0
  401. /data/application/static/{splash.png → splash-65b493a714df9b8b3ab170103401b53d.png} +0 -0
  402. /data/application/static/{spot.png → spot-71fab1d2f065034f5fc15e7bea2ad36c.png} +0 -0
  403. /data/application/static/{spot.svg → spot-8505041082d8d3bbe8d34c29dddb3b7d.svg} +0 -0
  404. /data/application/static/{texture.png → texture-03f7627e8264b1d607113ab32c593a58.png} +0 -0
@@ -9,7 +9,7 @@ class MarkdownEditorTest < MiniTest::Spec
9
9
 
10
10
  def setup
11
11
  @page = page
12
- @page.x(<<-JS)
12
+ @page.eval(<<-JS)
13
13
  var fake_input = function(start, end, value) {
14
14
  var array = [];
15
15
  array.value = value;
@@ -25,19 +25,25 @@ class MarkdownEditorTest < MiniTest::Spec
25
25
  if (new_value) { this.value = new_value; }
26
26
  return this.value;
27
27
  };
28
+ array.focus = function() {};
29
+ array.bind = function() { return array; };
28
30
  return array;
29
31
  }
30
32
  JS
31
33
  end
32
34
 
33
35
  def style(command, sel_start, sel_end, value)
34
- state = @page.x(<<-JS)
36
+ state = @page.eval(<<-JS)
35
37
  var input = fake_input(#{sel_start}, #{sel_end}, #{value.inspect})
36
38
  var command = new Spontaneous.FieldTypes.MarkdownField.#{command}(input)
37
39
  command.execute();
38
40
  Spontaneous.FieldTypes.MarkdownField.TextCommand.get_state(input)
39
41
  JS
40
- result = Hash[state.to_ary]
42
+ result = {
43
+ "before" => state["before"],
44
+ "middle" => state["middle"],
45
+ "after" => state["after"]
46
+ }
41
47
  result["value"] = result["before"] + result["middle"] + result["after"]
42
48
  result
43
49
  end
@@ -92,6 +98,40 @@ class MarkdownEditorTest < MiniTest::Spec
92
98
  end
93
99
  end
94
100
  end
101
+ context "for links" do
102
+ setup do
103
+ @page.eval("Spontaneous.Location.retrieve = function() {}")
104
+ @page.eval("Spontaneous.Popover.open = function() {}")
105
+ end
106
+ should "expand selection to full link if cursor inside a link text" do
107
+ state = style('Link', 8, 8, "Before [link](http://example.com/page?param1=a&param2=b) after")
108
+ state["middle"].should == "[link](http://example.com/page?param1=a&param2=b)"
109
+ end
110
+ should "expand selection to full link if cursor inside a link URL" do
111
+ state = style('Link', 14, 14, "Before [link](http://example.com/page?param1=a&param2=b) after")
112
+ state["middle"].should == "[link](http://example.com/page?param1=a&param2=b)"
113
+ end
114
+ should "expand selection to full link if cursor inside a link URL with brackets afterwards" do
115
+ state = style('Link', 14, 14, "Before [link](http://example.com/page?param1=a&param2=b) (after)")
116
+ state["middle"].should == "[link](http://example.com/page?param1=a&param2=b)"
117
+ end
118
+ should "expand selection to full link if cursor between link text & URL" do
119
+ state = style('Link', 13, 13, "Before [link](http://example.com/page?param1=a&param2=b) after")
120
+ state["middle"].should == "[link](http://example.com/page?param1=a&param2=b)"
121
+ end
122
+ should "not greedily expand forward to other brackets within text" do
123
+ state = style('Link', 7, 11, "Before link (after)")
124
+ state["middle"].should == "link"
125
+ end
126
+ should "not greedily expand to other brackets within text" do
127
+ state = style('Link', 9, 13, "(Before) link after")
128
+ state["middle"].should == "link"
129
+ end
130
+ should "properly extract link from surrounding brackets" do
131
+ state = style('Link', 9, 9, "Before ([link](http://example.com/page?param1=a&param2=b)) after")
132
+ state["middle"].should == "[link](http://example.com/page?param1=a&param2=b)"
133
+ end
134
+ end
95
135
  end
96
136
  end
97
137
  end
@@ -56,9 +56,10 @@ module CustomMatchers
56
56
  end
57
57
 
58
58
  custom_matcher :be_content_revision do |receiver, matcher, args|
59
+ ident = lambda { |ident| Spontaneous.database.dataset.quote_identifier(ident) }
59
60
  revision = args[0]
60
61
  types = args[1]
61
- table = "`#{Spontaneous::Content.revision_table(revision)}`"
62
+ table = "#{ident[Spontaneous::Content.revision_table(revision)]}"
62
63
  sql = "SELECT \\* FROM #{table}"
63
64
  if types
64
65
  if types.is_a?(Array)
@@ -66,7 +67,7 @@ module CustomMatchers
66
67
  else
67
68
  types = "'#{types}'"
68
69
  end
69
- sql << " WHERE \\(#{table}.`type_sid` IN \\(#{types}"
70
+ sql << " WHERE \\(#{table}.#{ident["type_sid"]} IN \\(#{types}"
70
71
  end
71
72
  regexp = %r{^#{sql}}
72
73
  matcher.positive_failure_message = "Expected #{receiver.sql} to =~ #{regexp}"
data/test/test_helper.rb CHANGED
@@ -18,17 +18,30 @@ $:.unshift(spot_path) if File.directory?(spot_path) && !$:.include?(spot_path)
18
18
 
19
19
  require 'rack'
20
20
  require 'logger'
21
+ require 'pg'
21
22
 
22
23
 
23
24
  Sequel.extension :migration
24
25
 
25
- DB = Sequel.connect('mysql2://root@localhost/spontaneous2_test') unless defined?(DB)
26
- # DB = Sequel.connect('postgres://postgres@localhost/spontaneous2_test') unless defined?(DB)
26
+ # for future integration with travis
27
+ ENV["SPOT_ADAPTER"] ||= "postgres"
28
+
29
+ connection_string = case ENV["SPOT_ADAPTER"]
30
+ when "postgres"
31
+ 'postgres:///spontaneous2_test'
32
+ when "mysql"
33
+ 'mysql2://root@localhost/spontaneous2_test'
34
+ end
35
+
36
+ p connection_string
37
+ DB = Sequel.connect(connection_string) unless defined?(DB)
27
38
  # DB.logger = Logger.new($stdout)
39
+
28
40
  Sequel::Migrator.apply(DB, 'db/migrations')
29
41
 
30
42
  require File.expand_path(File.dirname(__FILE__) + '/../lib/spontaneous')
31
- require File.expand_path(File.dirname(__FILE__) + '/../lib/cutaneous')
43
+ # require File.expand_path(File.dirname(__FILE__) + '/../lib/cutaneous')
44
+ require 'cutaneous'
32
45
 
33
46
  # require 'test/unit'
34
47
  require 'minitest/spec'
@@ -125,6 +138,32 @@ class MiniTest::Spec
125
138
  FileUtils.rm_r(Spontaneous.instance.root) rescue nil
126
139
  end
127
140
 
141
+ def self.stub_time(time)
142
+ Sequel.datetime_class.stubs(:now).returns(time)
143
+ Time.stubs(:now).returns(time)
144
+ end
145
+ def stub_time(time)
146
+ self.class.stub_time(time)
147
+ end
148
+
149
+ def assert_content_equal(result, compare)
150
+ serialised_columns = [:field_store, :entry_store]
151
+ columns = Content.columns - serialised_columns
152
+ columns.each do |col|
153
+ assert_equal(result[col], compare[col], "Column '#{col}' should be equal")
154
+ end
155
+ serialised_columns.each do |col|
156
+ result.send(col).should == compare.send(col)
157
+ end
158
+ end
159
+
160
+ def log_sql(&block)
161
+ logger = S::Content.db.logger
162
+ S::Content.db.logger = ::Logger.new($stdout)
163
+ yield
164
+ ensure
165
+ S::Content.db.logger = logger
166
+ end
128
167
  def setup_site(root = nil)
129
168
  self.class.setup_site(root)
130
169
  end
@@ -133,13 +172,8 @@ class MiniTest::Spec
133
172
  self.class.teardown_site
134
173
  end
135
174
 
136
- def template_root=(template_root)
137
- @template_root = template_root
138
- Spontaneous.stubs(:template_paths).returns([@template_root])
139
- end
140
-
141
175
  def assert_correct_template(content, expected_path, format = :html)
142
- assert_equal(template_root / expected_path, content.template(format))
176
+ assert_equal(expected_path, content.template(format))
143
177
  end
144
178
 
145
179
  def assert_file_exists(*path)
@@ -182,6 +216,13 @@ class MiniTest::Spec
182
216
  end
183
217
  end
184
218
 
219
+ def assert_login_page(path = nil, method = "GET")
220
+ assert last_response.status == 401, "#{method} #{path} should have status 401 but has #{last_response.status}"
221
+ last_response.body.should =~ %r{<form.+action="/@spontaneous/login"}
222
+ last_response.body.should =~ %r{<form.+method="post"}
223
+ last_response.body.should =~ %r{<input.+name="user\[login\]"}
224
+ last_response.body.should =~ %r{<input.+name="user\[password\]"}
225
+ end
185
226
 
186
227
  end
187
228
 
@@ -1,33 +1,33 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require 'harmony'
3
+ require 'v8'
4
+ require 'spontaneous/rack'
4
5
 
5
6
  module JavascriptTestBase
6
7
 
7
8
  def spontaneous_index
8
- Harmony::Page.new
9
+ V8::Context.new
9
10
  end
10
11
 
11
12
  def page
12
13
  config = mock()
13
14
  config.stubs(:reload_classes).returns(false)
14
15
  Spontaneous.stubs(:config).returns(config)
15
- page = Harmony::Page.new
16
- page.x("window.console = {'log': function(){ print.apply(window, arguments)}, 'dir': function() {}};")
17
- page.x("Spontaneous = {};")
18
- Spontaneous::Rack::Back::JAVASCRIPT_FILES.each do |script|
19
- # jquery 1.5.1 doesn't work with johnson
20
- script = script.gsub(/jquery-1\.5\.1/, 'jquery-1.4.2')
21
- # puts script
22
- page.load(javascript_dir / "#{script}.js")
16
+ page = V8::Context.new
17
+ page.load(File.expand_path('../javascript/env.js', __FILE__))
18
+ page.eval("window.console = {'log': function(){ print.apply(window, arguments)}, 'dir': function() {}};")
19
+ page.eval("Spontaneous = {};")
20
+ %w(JQUERY COMPATIBILITY EDITING_JS).each do |const|
21
+ Spontaneous::Rack::Assets::JavaScript.const_get(const).each do |script|
22
+ page.load(javascript_dir / "#{script}.js") unless ["load", "init"].include?(script)
23
+ end
23
24
  end
24
- page.x("jQuery.noConflict();")
25
- # page.load(javascript_dir / 'properties.js')
25
+ page.eval("jQuery.noConflict();")
26
26
  page
27
27
  end
28
28
 
29
29
  def javascript_dir
30
- "application/js"
30
+ File.expand_path("../../application/js", __FILE__)
31
31
  end
32
32
 
33
33
  end
data/test/ui_helper.rb CHANGED
@@ -25,7 +25,7 @@ module SeleniumTest
25
25
 
26
26
  def startup
27
27
  Spontaneous::Permissions::User.delete
28
- @user = Spontaneous::Permissions::User.create(:email => "root@example.com", :login => "root", :name => "root", :password => "rootpass", :password_confirmation => "rootpass")
28
+ @user = Spontaneous::Permissions::User.create(:email => "root@example.com", :login => "root", :name => "root", :password => "rootpass")
29
29
  @user.update(:level => Spontaneous::Permissions.root)
30
30
  @user.save
31
31
  launch_selenium
@@ -18,9 +18,12 @@ class AliasTest < MiniTest::Spec
18
18
  context "Aliases:" do
19
19
  setup do
20
20
  @site = setup_site
21
- Content.delete
21
+ @template_root = File.expand_path(File.join(File.dirname(__FILE__), "../fixtures/templates/aliases"))
22
+ @site.paths.add(:templates, @template_root)
23
+ @renderer = S::Output::Template::Renderer.new(false)
24
+ S::Output.renderer = @renderer
22
25
 
23
- self.template_root = File.expand_path(File.join(File.dirname(__FILE__), "../fixtures/templates/aliases"))
26
+ Content.delete
24
27
 
25
28
  class ::Page < Spontaneous::Page
26
29
  field :title
@@ -172,8 +175,8 @@ class AliasTest < MiniTest::Spec
172
175
  class ::XX < ::Piece
173
176
  alias_of :AA, :container => Proc.new { S::Site['#thepage'].box1 }
174
177
  end
175
- X.targets.should == @page.box1.select { |p| A === p }
176
- XX.targets.should == @page.box1.select { |p| AA === p }
178
+ Set.new(X.targets).should == Set.new(@page.box1.select { |p| A === p })
179
+ Set.new(XX.targets).should == Set.new(@page.box1.select { |p| AA === p })
177
180
  end
178
181
 
179
182
  should "allow for selecting only content from a range of boxes" do
@@ -219,10 +222,10 @@ class AliasTest < MiniTest::Spec
219
222
 
220
223
  should "allow for selecting content only from the content of the owner of the box" do
221
224
  class ::X < ::Piece
222
- alias_of proc { |owner| owner.box1.pieces }
225
+ alias_of proc { |owner| owner.box1.contents }
223
226
  end
224
227
  class ::XX < ::Piece
225
- alias_of proc { |owner, box| box.pieces }
228
+ alias_of proc { |owner, box| box.contents }
226
229
  end
227
230
  class ::XXX < ::Piece
228
231
  alias_of :A, :container => proc { |owner, box| box }
@@ -243,6 +246,36 @@ class AliasTest < MiniTest::Spec
243
246
  end
244
247
  assert_same_content pieces, X.targets
245
248
  end
249
+
250
+ should "allow for filtering instances according to current page content" do
251
+ @page.box1 << AAA.create
252
+ @page.box2 << AAA.create
253
+ @page.save.reload
254
+ allowable = AAA.all - @page.box1.contents
255
+ ::X = Class.new(::Piece) do
256
+ alias_of :AAA, :filter => proc { |choice, page, box| !box.include?(choice) }
257
+ end
258
+ assert_same_content allowable, X.targets(@page, @page.box1)
259
+ end
260
+
261
+ should "allow for ensuring the uniqueness of the entries" do
262
+ aaa = AAA.all
263
+ ::X = Class.new(::Piece) do
264
+ alias_of :AAA, :unique => true
265
+ end
266
+ @page.box1 << aaa.first
267
+ @page.save.reload
268
+ assert_same_content [aaa.last], X.targets(@page, @page.box1)
269
+ end
270
+
271
+ should "allow for returning an arbitrary list of results generated by a proc" do
272
+ results = [mock, mock, mock]
273
+ ::X = Class.new(::Piece) do
274
+ alias_of proc { results }
275
+ end
276
+ ::X.targets.should == results
277
+ end
278
+
246
279
  end
247
280
  end
248
281
 
@@ -257,6 +290,11 @@ class AliasTest < MiniTest::Spec
257
290
  @a_alias.field?(:a_alias_field1).should be_true
258
291
  end
259
292
 
293
+ should "provide access to their target" do
294
+ @a_alias.target.should == @a
295
+ end
296
+
297
+
260
298
  # TODO
261
299
  should "reference the aliases fields before the targets"
262
300
 
@@ -270,13 +308,13 @@ class AliasTest < MiniTest::Spec
270
308
  end
271
309
 
272
310
  should "have their own styles" do
273
- assert_correct_template(@a_alias, 'a_alias/a_alias_style')
311
+ assert_correct_template(@a_alias, @template_root / 'a_alias/a_alias_style')
274
312
  end
275
313
 
276
314
  should "present their target's styles as their own" do
277
315
  @a_alias.style = :a_style
278
316
 
279
- assert_correct_template(@a_alias, 'a/a_style')
317
+ assert_correct_template(@a_alias, @template_root / 'a/a_style')
280
318
  end
281
319
 
282
320
  # should "have an independent style setting"
@@ -297,11 +335,44 @@ class AliasTest < MiniTest::Spec
297
335
  @a_alias.export[:alias_title].should == @a.alias_title
298
336
  @a_alias.export[:alias_icon].should == @a.alias_icon_field.export
299
337
  end
338
+
300
339
  end
340
+ end
301
341
 
342
+ context "Aliases to custom models" do
343
+ setup do
344
+ @target_id = target_id = 9999
345
+ @target = target = mock()
346
+ @target.stubs(:id).returns(@target_id)
347
+ @target.stubs(:title).returns("custom object")
348
+
349
+ @custom_alias_class = Class.new(::Page) do
350
+ alias_of proc { [target] }, :lookup => lambda { |id|
351
+ return target if id == target_id
352
+ nil
353
+ }, :slug => lambda { |target| target.title.to_url }
354
+ end
355
+ end
356
+ should "be creatable using a custom initializer" do
357
+ a = @custom_alias_class.for_target(@target_id)
358
+
359
+ a.target_id.should == @target_id
360
+ a.target.should == @target
361
+ end
302
362
 
363
+ should "be able to provide a slug for pages" do
364
+ a = @custom_alias_class.for_target(@target_id)
365
+ a.target.should == @target
366
+ a.slug.should == "custom-object"
367
+ end
368
+
369
+ should "ignore styles if object doesn't provide them" do
370
+ a = @custom_alias_class.for_target(@target_id)
371
+ a.style.template.call.should == Page.new.style.template.call
372
+ end
303
373
  end
304
374
 
375
+
305
376
  context "Piece aliases" do
306
377
  should "be allowed to target pages" do
307
378
  a = BBAlias.create(:target => @bb)
@@ -0,0 +1,220 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path('../../test_helper', __FILE__)
4
+
5
+ class AssetBundler < MiniTest::Spec
6
+ include ::Rack::Test::Methods
7
+
8
+ def app
9
+ Spontaneous::Rack::Back.application
10
+ end
11
+
12
+ def fixture_dir
13
+ File.expand_path("../../fixtures/asset_pipeline", __FILE__)
14
+ end
15
+
16
+ def setup
17
+ @site = setup_site
18
+ end
19
+
20
+ def teardown
21
+ teardown_site
22
+ end
23
+
24
+ context "CMS asset bundler" do
25
+ should "compile Javascript into any destination directory ddd" do
26
+ compiler = Spontaneous::Asset::AppCompiler.new(fixture_dir, @site.root, :compress => false)
27
+ compiler.compile
28
+ compiled_js_path = Dir["#{@site.root}/public/@spontaneous/assets/spontaneous*.js"].first
29
+ js = File.read(compiled_js_path)
30
+ js.should =~ /var simple = "yes";/
31
+ js.should =~ /var basic/
32
+ js.should =~ /var complex/
33
+ js.should =~ /complex = "#{Date.today.day}"/
34
+ js.should =~ /var simple_subdir = "yes";/
35
+ js.should =~ /var complex_subdir;/
36
+ js.should =~ /complex_subdir = "subdir\/#{Date.today.day}";/
37
+ end
38
+
39
+ should "produce compressed Javascript on demand" do
40
+ compiler = Spontaneous::Asset::AppCompiler.new(fixture_dir, @site.root, :compress => true)
41
+ compiler.compile
42
+ compiled_js_path = Dir["#{@site.root}/public/@spontaneous/assets/spontaneous*.js"].first
43
+ js = File.read(compiled_js_path)
44
+ # hard to test because we don't know exactly what the uglifier is going to do
45
+ js.should =~ /var a;a="yes"/
46
+ js.should =~ /var a;a="#{Date.today.day}"/
47
+ js.should =~ /var a;a="subdir\/#{Date.today.day}"/
48
+ end
49
+
50
+ should "compile CSS into any destination directory" do
51
+ compiler = Spontaneous::Asset::AppCompiler.new(fixture_dir, @site.root, :compress => false)
52
+ compiler.compile
53
+ compiled_css_path = Dir["#{@site.root}/public/@spontaneous/assets/*.css"].first
54
+ css = File.read(compiled_css_path)
55
+ css.should =~ /\.simple \{\s+color: #aaa/
56
+ css.should =~ /\.basic \{\s+color: #aabbcc/
57
+ css.should =~ /\.complex \{\s+color: #ddeeff;\s*width: #{Date.today.day}px/
58
+ css.should =~ /\.subdir\.simple \{\s+color: #000;/
59
+ css.should =~ /\.subdir\.complex \{\s+color: #aaaaaa;\s+height: #{Date.today.day}px/
60
+ end
61
+
62
+ should "produce compressed CSS by default" do
63
+ compiler = Spontaneous::Asset::AppCompiler.new(fixture_dir, @site.root)
64
+ compiler.compile
65
+ compiled_css_path = Dir["#{@site.root}/public/@spontaneous/assets/spontaneous*.css"].first
66
+ css = File.read(compiled_css_path)
67
+ css.should =~ /\.simple\{color:#aaa\}/
68
+ css.should =~ /\.basic\{color:#aabbcc\}/
69
+ css.should =~ /\.complex\{color:#ddeeff;width:#{Date.today.day}px\}/
70
+ css.should =~ /\.subdir\.simple\{color:#000\}/
71
+ css.should =~ /\.subdir\.complex\{color:#aaaaaa;height:#{Date.today.day}px\}/
72
+ end
73
+ end
74
+
75
+ context "Development mode editing app" do
76
+ setup do
77
+ @page = ::S::Content.create
78
+ end
79
+
80
+ teardown do
81
+ Content.delete
82
+ end
83
+
84
+ context "unauthorised users" do
85
+ should "load a non-fingerprinted CSS file" do
86
+ get "/@spontaneous/#{@page.id}"
87
+ assert_login_page
88
+ last_response.body.should =~ %r{/@spontaneous/css/spontaneous\.css}
89
+ end
90
+ end
91
+
92
+ context "authorised users" do
93
+ setup do
94
+ @user = Spontaneous::Permissions::User.create(:email => "test@example.com", :login => "test", :name => "test name", :password => "testpass")
95
+ @site.config.auto_login @user.login
96
+
97
+ @key = "c5AMX3r5kMHX2z9a5ExLKjAmCcnT6PFf22YQxzb4Codj"
98
+ @key.stubs(:user).returns(@user)
99
+ @key.stubs(:key_id).returns(@key)
100
+ @user.stubs(:access_keys).returns([@key])
101
+
102
+ Spontaneous::Permissions::User.stubs(:[]).with(:login => 'test').returns(@user)
103
+ Spontaneous::Permissions::User.stubs(:[]).with(@user.id).returns(@user)
104
+ Spontaneous::Permissions::AccessKey.stubs(:authenticate).with(@key).returns(@key)
105
+ Spontaneous::Permissions::AccessKey.stubs(:valid?).with(@key, @user).returns(true)
106
+
107
+ end
108
+ teardown do
109
+ Content.delete
110
+ Spontaneous::Permissions::User.delete
111
+ end
112
+ end
113
+
114
+ should "be able to load spontaneous.css" do
115
+ get "/@spontaneous/css/spontaneous.css"
116
+ assert last_response.ok?, "Recieved a #{last_response.status} instead of 200"
117
+ last_response.body.should =~ /#content/
118
+ end
119
+ end
120
+
121
+ context "Production mode editing app xxxx" do
122
+ setup do
123
+ @compiler = Spontaneous::Asset::AppCompiler.new(fixture_dir, @site.root)
124
+ @compiler.compile
125
+ @page = ::S::Content.create
126
+ end
127
+
128
+ teardown do
129
+ Content.delete
130
+ end
131
+
132
+ should "be able to retrieve compiled assets" do
133
+ css_path = Dir["#{@site.root}/public/@spontaneous/assets/spontaneous*.css"].first
134
+ css_file = ::File.basename(css_path)
135
+ get "/@spontaneous/assets/#{css_file}"
136
+ assert last_response.ok?, "Recieved #{last_response.status} instead of 200 for /@spontaneous/assets/#{css_file}"
137
+ end
138
+
139
+ context "unauthorised users" do
140
+ should "load a fingerprinted CSS file" do
141
+ get "/@spontaneous/#{@page.id}"
142
+ assert_login_page
143
+ css_path = Dir["#{@site.root}/public/@spontaneous/assets/spontaneous*.css"].first
144
+ css_file = ::File.basename(css_path)
145
+ last_response.body.should =~ %r{/@spontaneous/assets/#{ css_file }}
146
+ end
147
+
148
+ should "load fingerpringed JS files" do
149
+ get "/@spontaneous/#{@page.id}"
150
+ assert_login_page
151
+
152
+ js_path = Dir["#{@site.root}/public/@spontaneous/assets/login*.js"].first
153
+ js_file = ::File.basename(js_path)
154
+ last_response.body.should =~ %r{/@spontaneous/assets/#{ js_file }}
155
+
156
+ js_path = Dir["#{@site.root}/public/@spontaneous/assets/vendor/jquery*.js"].first
157
+ js_file = ::File.basename(js_path)
158
+ last_response.body.should =~ %r{/@spontaneous/assets/vendor/#{ js_file }}
159
+ end
160
+ end
161
+
162
+ context "authorised users aaaa" do
163
+ setup do
164
+ Spontaneous.stubs(:reload!)
165
+ @user = Spontaneous::Permissions::User.create(:email => "test@example.com", :login => "test", :name => "test name", :password => "testpass")
166
+ @user.update(:level => Spontaneous::Permissions[:editor])
167
+ @user.save
168
+ config = mock()
169
+ config.stubs(:reload_classes).returns(false)
170
+ config.stubs(:auto_login).returns('test')
171
+ config.stubs(:default_charset).returns('utf-8')
172
+ config.stubs(:publishing_method).returns(:immediate)
173
+ config.stubs(:services).returns(nil)
174
+ config.stubs(:site_domain).returns('example.org')
175
+ config.stubs(:site_id).returns('example_org')
176
+ config.stubs(:site_id).returns('example_org')
177
+ @site.stubs(:config).returns(config)
178
+
179
+ @key = "c5AMX3r5kMHX2z9a5ExLKjAmCcnT6PFf22YQxzb4Codj"
180
+ @key.stubs(:user).returns(@user)
181
+ @key.stubs(:key_id).returns(@key)
182
+ @user.stubs(:access_keys).returns([@key])
183
+
184
+ Spontaneous::Permissions::User.stubs(:[]).with(:login => 'test').returns(@user)
185
+ Spontaneous::Permissions::User.stubs(:[]).with(@user.id).returns(@user)
186
+ Spontaneous::Permissions::AccessKey.stubs(:authenticate).with(@key).returns(@key)
187
+ Spontaneous::Permissions::AccessKey.stubs(:valid?).with(@key, @user).returns(true)
188
+ end
189
+
190
+ teardown do
191
+ Content.delete
192
+ Spontaneous::Permissions::User.delete
193
+ end
194
+
195
+ should "load fingerpringed JS files" do
196
+ get "/@spontaneous/"
197
+ assert last_response.ok?, "User should be authorised but recieving a #{last_response.status}"
198
+
199
+ js_path = Dir["#{@site.root}/public/@spontaneous/assets/spontaneous*.js"].first
200
+ js_file = ::File.basename(js_path)
201
+ js_size = ::File.size(js_path)
202
+ last_response.body.should =~ %r{\["/@spontaneous/assets/#{ js_file }", *#{js_size}\]}
203
+
204
+ js_path = Dir["#{@site.root}/public/@spontaneous/assets/require*.js"].first
205
+ js_file = ::File.basename(js_path)
206
+ last_response.body.should =~ %r{/@spontaneous/assets/#{ js_file }}
207
+
208
+ js_path = Dir["#{@site.root}/public/@spontaneous/assets/vendor/jquery*.js"].first
209
+ js_file = ::File.basename(js_path)
210
+ last_response.body.should =~ %r{/@spontaneous/assets/vendor/#{ js_file }}
211
+ end
212
+ end
213
+
214
+ should "be able to load spontaneous.css" do
215
+ get "/@spontaneous/css/spontaneous.css"
216
+ assert last_response.ok?, "Recieved a #{last_response.status} instead of 200"
217
+ last_response.body.should =~ /#content/
218
+ end
219
+ end
220
+ end