imagine_cms 3.0.0.beta6 → 3.0.0.beta7

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 (278) hide show
  1. data/README.rdoc +1 -1
  2. data/app/assets/images/codepress/line-numbers.png +0 -0
  3. data/app/assets/images/cropper/marqueeHoriz.gif +0 -0
  4. data/app/assets/images/cropper/marqueeVert.gif +0 -0
  5. data/app/assets/images/management/btn_add.gif +0 -0
  6. data/app/assets/images/management/btn_archive.gif +0 -0
  7. data/app/assets/images/management/btn_delete.gif +0 -0
  8. data/app/assets/images/management/btn_duplicate.gif +0 -0
  9. data/app/assets/images/management/btn_edit.gif +0 -0
  10. data/app/assets/images/management/btn_help.gif +0 -0
  11. data/app/assets/images/management/btn_new_page.gif +0 -0
  12. data/app/assets/images/management/btn_preview.gif +0 -0
  13. data/app/assets/images/management/btn_properties.gif +0 -0
  14. data/app/assets/images/management/btn_restore.gif +0 -0
  15. data/app/assets/images/management/btn_top_delete.gif +0 -0
  16. data/app/assets/images/management/btn_top_duplicate.gif +0 -0
  17. data/app/assets/images/management/btn_top_edit.gif +0 -0
  18. data/app/assets/images/management/btn_top_new.gif +0 -0
  19. data/app/assets/images/management/btn_top_preview.gif +0 -0
  20. data/app/assets/images/management/btn_top_properties.gif +0 -0
  21. data/app/assets/{manage → images/management}/bullet.gif +0 -0
  22. data/app/assets/images/management/cvv2_graphic.gif +0 -0
  23. data/app/assets/images/management/error.gif +0 -0
  24. data/app/assets/images/management/gallery_index.gif +0 -0
  25. data/app/assets/images/management/gallery_preview_overlay.png +0 -0
  26. data/app/assets/images/management/gallery_small_drag_overlay.png +0 -0
  27. data/app/assets/images/management/gallery_small_overlay.png +0 -0
  28. data/app/assets/images/management/gallery_sort.gif +0 -0
  29. data/app/assets/images/management/icon_download.gif +0 -0
  30. data/app/assets/images/management/icon_locked.png +0 -0
  31. data/app/assets/images/management/icon_page.gif +0 -0
  32. data/app/assets/images/management/icon_time.gif +0 -0
  33. data/app/assets/images/management/icon_unlocked.png +0 -0
  34. data/app/assets/images/management/page_loading.gif +0 -0
  35. data/app/assets/{manage → images/management}/start.gif +0 -0
  36. data/app/assets/images/management/vcard.gif +0 -0
  37. data/app/assets/javascripts/builder.js +101 -0
  38. data/app/assets/javascripts/codepress/codepress.html +36 -0
  39. data/app/assets/javascripts/codepress/codepress.js +130 -0
  40. data/app/assets/javascripts/codepress/engines/gecko.js +240 -0
  41. data/{vendor/gems/acts_as_tree/test/abstract_unit.rb → app/assets/javascripts/codepress/engines/khtml.js} +0 -0
  42. data/app/assets/javascripts/codepress/engines/msie.js +263 -0
  43. data/{vendor/gems/acts_as_tree/test/database.yml → app/assets/javascripts/codepress/engines/older.js} +0 -0
  44. data/app/assets/javascripts/codepress/engines/opera.js +259 -0
  45. data/app/assets/javascripts/codepress/languages/css.js +23 -0
  46. data/app/assets/javascripts/codepress/languages/generic.js +25 -0
  47. data/app/assets/javascripts/codepress/languages/html.js +63 -0
  48. data/app/assets/javascripts/codepress/languages/java.js +24 -0
  49. data/app/assets/javascripts/codepress/languages/javascript.js +30 -0
  50. data/app/assets/javascripts/codepress/languages/perl.js +27 -0
  51. data/app/assets/javascripts/codepress/languages/php.js +60 -0
  52. data/app/assets/javascripts/codepress/languages/ruby.js +26 -0
  53. data/app/assets/javascripts/codepress/languages/sql.js +30 -0
  54. data/app/assets/javascripts/codepress/languages/text.js +9 -0
  55. data/app/assets/javascripts/cropper.js +568 -0
  56. data/app/assets/javascripts/dojo/dojo.js +14155 -0
  57. data/app/assets/javascripts/dojo/src/html/images/shadowB.png +0 -0
  58. data/app/assets/javascripts/dojo/src/html/images/shadowBL.png +0 -0
  59. data/app/assets/javascripts/dojo/src/html/images/shadowBR.png +0 -0
  60. data/app/assets/javascripts/dojo/src/html/images/shadowL.png +0 -0
  61. data/app/assets/javascripts/dojo/src/html/images/shadowR.png +0 -0
  62. data/app/assets/javascripts/dojo/src/html/images/shadowT.png +0 -0
  63. data/app/assets/javascripts/dojo/src/html/images/shadowTL.png +0 -0
  64. data/app/assets/javascripts/dojo/src/html/images/shadowTR.png +0 -0
  65. data/app/assets/javascripts/dojo/src/widget/templates/Editor2/showtableborder_gecko.css +19 -0
  66. data/app/assets/javascripts/dojo/src/widget/templates/HslColorPicker.svg +30 -0
  67. data/app/assets/javascripts/dojo/src/widget/templates/buttons/aggregate.gif +0 -0
  68. data/app/assets/javascripts/dojo/src/widget/templates/buttons/aggregate.psd +0 -0
  69. data/app/assets/javascripts/dojo/src/widget/templates/buttons/backcolor.gif +0 -0
  70. data/app/assets/javascripts/dojo/src/widget/templates/buttons/bg-fade.png +0 -0
  71. data/app/assets/javascripts/dojo/src/widget/templates/buttons/bold.gif +0 -0
  72. data/app/assets/javascripts/dojo/src/widget/templates/buttons/cancel.gif +0 -0
  73. data/app/assets/javascripts/dojo/src/widget/templates/buttons/copy.gif +0 -0
  74. data/app/assets/javascripts/dojo/src/widget/templates/buttons/createlink.gif +0 -0
  75. data/app/assets/javascripts/dojo/src/widget/templates/buttons/cut.gif +0 -0
  76. data/app/assets/javascripts/dojo/src/widget/templates/buttons/delete.gif +0 -0
  77. data/app/assets/javascripts/dojo/src/widget/templates/buttons/forecolor.gif +0 -0
  78. data/app/assets/javascripts/dojo/src/widget/templates/buttons/hilitecolor.gif +0 -0
  79. data/app/assets/javascripts/dojo/src/widget/templates/buttons/indent.gif +0 -0
  80. data/app/assets/javascripts/dojo/src/widget/templates/buttons/inserthorizontalrule.gif +0 -0
  81. data/app/assets/javascripts/dojo/src/widget/templates/buttons/insertimage.gif +0 -0
  82. data/app/assets/javascripts/dojo/src/widget/templates/buttons/insertorderedlist.gif +0 -0
  83. data/app/assets/javascripts/dojo/src/widget/templates/buttons/inserttable.gif +0 -0
  84. data/app/assets/javascripts/dojo/src/widget/templates/buttons/insertunorderedlist.gif +0 -0
  85. data/app/assets/javascripts/dojo/src/widget/templates/buttons/italic.gif +0 -0
  86. data/app/assets/javascripts/dojo/src/widget/templates/buttons/justifycenter.gif +0 -0
  87. data/app/assets/javascripts/dojo/src/widget/templates/buttons/justifyfull.gif +0 -0
  88. data/app/assets/javascripts/dojo/src/widget/templates/buttons/justifyleft.gif +0 -0
  89. data/app/assets/javascripts/dojo/src/widget/templates/buttons/justifyright.gif +0 -0
  90. data/app/assets/javascripts/dojo/src/widget/templates/buttons/left_to_right.gif +0 -0
  91. data/app/assets/javascripts/dojo/src/widget/templates/buttons/list_bullet_indent.gif +0 -0
  92. data/app/assets/javascripts/dojo/src/widget/templates/buttons/list_bullet_outdent.gif +0 -0
  93. data/app/assets/javascripts/dojo/src/widget/templates/buttons/list_num_indent.gif +0 -0
  94. data/app/assets/javascripts/dojo/src/widget/templates/buttons/list_num_outdent.gif +0 -0
  95. data/app/assets/javascripts/dojo/src/widget/templates/buttons/outdent.gif +0 -0
  96. data/app/assets/javascripts/dojo/src/widget/templates/buttons/paste.gif +0 -0
  97. data/app/assets/javascripts/dojo/src/widget/templates/buttons/redo.gif +0 -0
  98. data/app/assets/javascripts/dojo/src/widget/templates/buttons/removeformat.gif +0 -0
  99. data/app/assets/javascripts/dojo/src/widget/templates/buttons/right_to_left.gif +0 -0
  100. data/app/assets/javascripts/dojo/src/widget/templates/buttons/save.gif +0 -0
  101. data/app/assets/javascripts/dojo/src/widget/templates/buttons/sep.gif +0 -0
  102. data/app/assets/javascripts/dojo/src/widget/templates/buttons/space.gif +0 -0
  103. data/app/assets/javascripts/dojo/src/widget/templates/buttons/strikethrough.gif +0 -0
  104. data/app/assets/javascripts/dojo/src/widget/templates/buttons/subscript.gif +0 -0
  105. data/app/assets/javascripts/dojo/src/widget/templates/buttons/superscript.gif +0 -0
  106. data/app/assets/javascripts/dojo/src/widget/templates/buttons/underline.gif +0 -0
  107. data/app/assets/javascripts/dojo/src/widget/templates/buttons/undo.gif +0 -0
  108. data/app/assets/javascripts/dojo/src/widget/templates/buttons/wikiword.gif +0 -0
  109. data/app/assets/javascripts/dojo/src/widget/templates/check.gif +0 -0
  110. data/app/assets/javascripts/dojo/src/widget/templates/decrementMonth.gif +0 -0
  111. data/app/assets/javascripts/dojo/src/widget/templates/decrementWeek.gif +0 -0
  112. data/app/assets/javascripts/dojo/src/widget/templates/grabCorner.gif +0 -0
  113. data/app/assets/javascripts/dojo/src/widget/templates/images/floatingPaneClose.gif +0 -0
  114. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaAccordionOff.gif +0 -0
  115. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaAccordionSelected.gif +0 -0
  116. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaActive-c.gif +0 -0
  117. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaActive-l.gif +0 -0
  118. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaActive-r.gif +0 -0
  119. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaBarBg.gif +0 -0
  120. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaButton-c.gif +0 -0
  121. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaButton-l.gif +0 -0
  122. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaButton-r.gif +0 -0
  123. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaDisabled-c.gif +0 -0
  124. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaDisabled-l.gif +0 -0
  125. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaDisabled-r.gif +0 -0
  126. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaMenuBg.gif +0 -0
  127. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaPressed-c.gif +0 -0
  128. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaPressed-l.gif +0 -0
  129. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaPressed-r.gif +0 -0
  130. data/app/assets/javascripts/dojo/src/widget/templates/images/tab_close.gif +0 -0
  131. data/app/assets/javascripts/dojo/src/widget/templates/images/toolbar-bg.gif +0 -0
  132. data/app/assets/javascripts/dojo/src/widget/templates/incrementMonth.gif +0 -0
  133. data/app/assets/javascripts/dojo/src/widget/templates/incrementWeek.gif +0 -0
  134. data/app/assets/javascripts/dojo/src/widget/templates/richtextframe.html +24 -0
  135. data/app/assets/javascripts/imagine.js +1385 -0
  136. data/app/assets/javascripts/jquery_no_conflict.js +9405 -0
  137. data/app/assets/stylesheets/codepress/codepress.css +7 -0
  138. data/app/assets/stylesheets/codepress/languages/css.css +10 -0
  139. data/app/assets/stylesheets/codepress/languages/generic.css +9 -0
  140. data/app/assets/stylesheets/codepress/languages/html.css +18 -0
  141. data/app/assets/stylesheets/codepress/languages/java.css +7 -0
  142. data/app/assets/stylesheets/codepress/languages/javascript.css +8 -0
  143. data/app/assets/stylesheets/codepress/languages/perl.css +11 -0
  144. data/app/assets/stylesheets/codepress/languages/php.css +12 -0
  145. data/app/assets/stylesheets/codepress/languages/ruby.css +10 -0
  146. data/app/assets/stylesheets/codepress/languages/sql.css +10 -0
  147. data/app/assets/stylesheets/codepress/languages/text.css +5 -0
  148. data/app/assets/stylesheets/cropper.css +182 -0
  149. data/app/assets/stylesheets/management.css +96 -0
  150. data/app/assets/stylesheets/reset.css +58 -0
  151. data/app/controllers/cms/content_controller.rb +318 -2
  152. data/app/controllers/management/cms_controller.rb +1669 -0
  153. data/app/controllers/management/user_controller.rb +4 -4
  154. data/app/controllers/management/users_controller.rb +18 -4
  155. data/app/controllers/util_controller.rb +45 -0
  156. data/app/helpers/cms_application_helper.rb +662 -15
  157. data/app/models/cms_content_sweeper.rb +21 -0
  158. data/app/models/cms_page.rb +126 -0
  159. data/app/models/cms_page_object.rb +23 -0
  160. data/app/models/cms_page_tag.rb +5 -0
  161. data/app/models/cms_page_version.rb +3 -0
  162. data/app/models/cms_snippet.rb +16 -0
  163. data/app/models/cms_template.rb +29 -0
  164. data/app/models/user.rb +6 -3
  165. data/app/views/management/cms/_complete_gallery.html.erb +5 -0
  166. data/app/views/management/cms/_create_file_link.html.erb +21 -0
  167. data/app/views/management/cms/_crop_feature_image.html.erb +188 -0
  168. data/app/views/management/cms/_crop_image.html.erb +188 -0
  169. data/app/views/management/cms/_crop_results.html.erb +1 -0
  170. data/app/views/management/cms/_crop_results_feature_image.html.erb +1 -0
  171. data/app/views/management/cms/_crop_results_thumb.html.erb +1 -0
  172. data/app/views/management/cms/_crop_thumb.html.erb +188 -0
  173. data/app/views/management/cms/_dialogs.html.erb +39 -0
  174. data/app/views/management/cms/_edit_page.html.erb +176 -0
  175. data/app/views/management/cms/_gallery_index.html.erb +10 -0
  176. data/app/views/management/cms/_gallery_setup.html.erb +22 -0
  177. data/app/views/management/cms/_image.html.erb +3 -0
  178. data/app/views/management/cms/_image_details.html.erb +26 -0
  179. data/app/views/management/cms/_image_draggable.html.erb +4 -0
  180. data/app/views/management/cms/_list_page.html.erb +8 -0
  181. data/app/views/management/cms/_list_page_select.html.erb +8 -0
  182. data/app/views/management/cms/_list_pages.html.erb +1 -0
  183. data/app/views/management/cms/_list_pages_select.html.erb +1 -0
  184. data/app/views/management/cms/_page_attribute.html.erb +6 -0
  185. data/app/views/management/cms/_page_list.html.erb +171 -0
  186. data/app/views/management/cms/_page_list_source_folder.html.erb +20 -0
  187. data/app/views/management/cms/_page_list_source_tag.html.erb +18 -0
  188. data/app/views/management/cms/_select_gallery.html.erb +117 -0
  189. data/app/views/management/cms/_snippet.html.erb +3 -0
  190. data/app/views/management/cms/_sort_images.html.erb +15 -0
  191. data/app/views/management/cms/_temp.html.erb +3 -0
  192. data/app/views/management/cms/_template_options.html.erb +21 -0
  193. data/app/views/management/cms/_template_reference.html.erb +42 -0
  194. data/app/views/management/cms/_upload_feature_image.html.erb +35 -0
  195. data/app/views/management/cms/_upload_file.html.erb +31 -0
  196. data/app/views/management/cms/_upload_image.html.erb +74 -0
  197. data/app/views/management/cms/_upload_thumb.html.erb +35 -0
  198. data/app/views/management/cms/edit_master.html.erb +48 -0
  199. data/app/views/management/cms/edit_page_content.html.erb +4 -0
  200. data/app/views/management/cms/edit_snippet.html.erb +47 -0
  201. data/app/views/management/cms/edit_template.html.erb +48 -0
  202. data/app/views/management/cms/gallery_management.html.erb +108 -0
  203. data/app/views/management/cms/index.html.erb +20 -0
  204. data/app/views/management/cms/page_tags_for_lookup.html.erb +5 -0
  205. data/app/views/management/cms/pages.html.erb +99 -0
  206. data/app/views/management/cms/permission_denied.html.erb +1 -0
  207. data/app/views/management/cms/select_page.html.erb +57 -0
  208. data/app/views/management/cms/snippets.html.erb +14 -0
  209. data/app/views/management/cms/templates.html.erb +14 -0
  210. data/app/views/management/cms/toolbar_edit.html.erb +269 -0
  211. data/app/views/management/cms/toolbar_preview.html.erb +109 -0
  212. data/app/views/util/_calendar_days.html.erb +72 -0
  213. data/app/views/util/_calendar_month_year.html.erb +1 -0
  214. data/app/views/util/_date_picker.html.erb +56 -0
  215. data/app/views/util/_message.html.erb +1 -0
  216. data/app/views/util/_show_message.js.erb +6 -0
  217. data/app/views/util/_tab.html.erb +4 -0
  218. data/config/routes.rb +4 -1
  219. data/imagine_cms.gemspec +4 -0
  220. data/{vendor/gems → lib}/acts_as_versioned/.document +0 -0
  221. data/{vendor/gems → lib}/acts_as_versioned/.gitignore +2 -0
  222. data/{vendor/gems → lib}/acts_as_versioned/CHANGELOG +0 -0
  223. data/lib/acts_as_versioned/Gemfile +7 -0
  224. data/{vendor/gems → lib}/acts_as_versioned/MIT-LICENSE +0 -0
  225. data/{vendor/gems → lib}/acts_as_versioned/README +0 -0
  226. data/{vendor/gems → lib}/acts_as_versioned/RUNNING_UNIT_TESTS +0 -0
  227. data/{vendor/gems → lib}/acts_as_versioned/Rakefile +1 -1
  228. data/{vendor/gems → lib}/acts_as_versioned/acts_as_versioned.gemspec +4 -4
  229. data/{vendor/gems → lib}/acts_as_versioned/init.rb +0 -0
  230. data/{vendor/gems → lib}/acts_as_versioned/lib/acts_as_versioned.rb +109 -107
  231. data/{vendor/gems → lib}/acts_as_versioned/test/abstract_unit.rb +0 -0
  232. data/{vendor/gems → lib}/acts_as_versioned/test/database.yml +0 -0
  233. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/authors.yml +0 -0
  234. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/landmark.rb +0 -0
  235. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/landmark_versions.yml +0 -0
  236. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/landmarks.yml +0 -0
  237. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/locked_pages.yml +0 -0
  238. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/locked_pages_revisions.yml +0 -0
  239. data/{vendor/gems/acts_as_versioned/test/fixtures/migrations/1_add_versioned_tables.rb → lib/acts_as_versioned/test/fixtures/migrations/2_add_versioned_tables.rb} +0 -0
  240. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/page.rb +0 -0
  241. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/page_versions.yml +0 -0
  242. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/pages.yml +0 -0
  243. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/widget.rb +0 -0
  244. data/{vendor/gems → lib}/acts_as_versioned/test/migration_test.rb +0 -1
  245. data/{vendor/gems → lib}/acts_as_versioned/test/schema.rb +0 -0
  246. data/{vendor/gems → lib}/acts_as_versioned/test/versioned_test.rb +0 -0
  247. data/lib/extensions/action_controller.rb +154 -143
  248. data/lib/imagine_cms/engine.rb +33 -12
  249. data/lib/imagine_cms/version.rb +1 -1
  250. data/lib/imagine_cms.rb +30 -6
  251. data/lib/prototype_legacy_helper/README.markdown +13 -0
  252. data/lib/prototype_legacy_helper/init.rb +1 -0
  253. data/lib/prototype_legacy_helper/lib/prototype_legacy_helper.rb +430 -0
  254. data/lib/prototype_legacy_helper/test/test_prototype_helper.rb +297 -0
  255. data/lib/upload_progress/CHANGELOG +5 -0
  256. data/lib/upload_progress/MIT-LICENSE +20 -0
  257. data/lib/upload_progress/README +45 -0
  258. data/{vendor/gems/acts_as_tree → lib/upload_progress}/Rakefile +6 -5
  259. data/lib/upload_progress/init.rb +7 -0
  260. data/lib/upload_progress/lib/multipart_progress.rb +176 -0
  261. data/lib/upload_progress/lib/progress.rb +145 -0
  262. data/lib/upload_progress/lib/upload_progress.rb +303 -0
  263. data/lib/upload_progress/lib/upload_progress_helper.rb +425 -0
  264. data/lib/upload_progress/public/stylesheets/upload_progress.css +21 -0
  265. data/lib/upload_progress/test/multipart_progress_testx.rb +364 -0
  266. data/lib/upload_progress/test/upload_progress_helper_testx.rb +134 -0
  267. data/lib/upload_progress/test/upload_progress_testx.rb +88 -0
  268. metadata +305 -43
  269. data/app/assets/manage/btn_delete.gif +0 -0
  270. data/vendor/gems/.DS_Store +0 -0
  271. data/vendor/gems/acts_as_tree/README +0 -26
  272. data/vendor/gems/acts_as_tree/init.rb +0 -1
  273. data/vendor/gems/acts_as_tree/lib/active_record/acts/tree.rb +0 -96
  274. data/vendor/gems/acts_as_tree/test/acts_as_tree_test.rb +0 -219
  275. data/vendor/gems/acts_as_tree/test/fixtures/mixin.rb +0 -0
  276. data/vendor/gems/acts_as_tree/test/fixtures/mixins.yml +0 -0
  277. data/vendor/gems/acts_as_tree/test/schema.rb +0 -0
  278. data/vendor/gems/acts_as_versioned/Gemfile +0 -7
@@ -0,0 +1,364 @@
1
+ require 'logger'
2
+ require 'test/unit'
3
+ require 'cgi'
4
+ require 'stringio'
5
+
6
+ DEBUG=false
7
+
8
+ def test_logger
9
+ if DEBUG then ActionController::Base.logger = Logger.new(STDERR)
10
+ else ActionController::Base.logger = Logger.new(StringIO.new)
11
+ end
12
+ end
13
+
14
+ # Provide a static version of the Controllers module instead of the auto-loading version.
15
+ # We don't want these tests to fail when dependencies are to blame.
16
+ module Controllers
17
+ class EmptyController < ActionController::Base
18
+ end
19
+ class ApplicationController < ActionController::Base
20
+ end
21
+
22
+ class MockController < ActionController::Base
23
+ def initialize
24
+ super
25
+ @session = {:uploads => {}}
26
+ @params = {}
27
+ end
28
+ end
29
+
30
+ class SingleUploadController < ActionController::Base
31
+ upload_status_for :one
32
+
33
+ def one; end
34
+ end
35
+
36
+ class DoubleUploadController < ActionController::Base
37
+ upload_status_for :one, :two
38
+
39
+ def one; end
40
+ def two; end
41
+ end
42
+
43
+ class DoubleStatusUploadController < ActionController::Base
44
+ upload_status_for :one, :two, :status => :custom_status
45
+
46
+ def one; end
47
+ def two; end
48
+ end
49
+
50
+ class DoubleSeperateController < ActionController::Base
51
+ upload_status_for :one
52
+ upload_status_for :two
53
+
54
+ def one; end
55
+ def two; end
56
+ end
57
+
58
+ class UploadController < ActionController::Base
59
+ upload_status_for :norendered, :rendered, :redirected, :finish_param_dict, :finish_param_string, :finish_param_number
60
+
61
+ def norendered
62
+ end
63
+
64
+ def rendered
65
+ render_text("rendered")
66
+ end
67
+
68
+ def redirected
69
+ redirect_to "/redirected/"
70
+ end
71
+
72
+ def finish_param_dict
73
+ finish_upload_status "{a: 'b'}"
74
+ end
75
+
76
+ def finish_param_string
77
+ finish_upload_status "'a string'"
78
+ end
79
+
80
+ def finish_param_number
81
+ finish_upload_status 123
82
+ end
83
+
84
+ def finish_param_number_redirect
85
+ redirect_to "/redirected/"
86
+ finish_upload_status 123
87
+ end
88
+ end
89
+ end
90
+
91
+ class MockIO < StringIO
92
+ def initialize(data='', &block)
93
+ test_logger.debug("MockIO inializing data: #{data[0..20]}")
94
+
95
+ @block = block
96
+ super(data)
97
+ end
98
+
99
+ def write(data)
100
+ test_logger.debug("MockIO write #{data.size} data: #{data[0..20]}")
101
+ super
102
+ end
103
+ def read(size)
104
+ test_logger.debug("MockIO getting data from super")
105
+ data = super
106
+
107
+ test_logger.debug("Calling read callback")
108
+ @block.call
109
+
110
+ test_logger.debug("Returning data: #{data.size}")
111
+ data
112
+ end
113
+ end
114
+
115
+ class MockCGI < CGI
116
+ BOUNDARY = '----------0xKhTmLbOuNdArY'
117
+ FILENAME = 'dummy.nul'
118
+
119
+ attr_reader :upload_id, :session_options, :session_id
120
+
121
+ def initialize(size=1000, url='/test', &block)
122
+ @url = url
123
+ @env = {}
124
+ @sio = MockIO.new('') { block.call(self) if block_given? }
125
+
126
+ @upload_id = '1'
127
+
128
+ add_param('param1', 'value1')
129
+ add_data(size)
130
+ add_param('param1', 'value2')
131
+ add_end_boundary
132
+ init_env
133
+ @sio.rewind
134
+ super()
135
+ end
136
+
137
+ #def stdinput_without_progress
138
+ # @sio
139
+ #end
140
+
141
+ def stdinput
142
+ @sio
143
+ end
144
+
145
+ def env_table
146
+ @env
147
+ end
148
+
149
+ private
150
+ def init_env
151
+ @env['HTTP_HOST'] = 'localhost'
152
+ @env['SERVER_PORT'] = '80'
153
+ @env['REQUEST_METHOD'] = "POST"
154
+ @env['QUERY_STRING'] = @url.split('?')[1] || "upload_id=#{upload_id}&query_param=query_value"
155
+ @env['REQUEST_URI'] = @url
156
+ @env['SCRIPT_NAME'] = @url.split('?').first.split('/').last
157
+ @env['PATH_INFO'] = @url.split('?').first
158
+ @env['CONTENT_TYPE'] = "multipart/form-data; boundary=#{BOUNDARY}"
159
+ @env['CONTENT_LENGTH'] = @sio.tell - EOL.size
160
+
161
+ @session_options = ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS.inject({}) { |options, pair|
162
+ options[pair.first.to_s] = pair.last; options
163
+ }
164
+ session = CGI::Session.new({}, @session_options.merge({'new_session' => true}))
165
+ @session_id = session.session_id
166
+ @env['COOKIE'] = "_session_id=#{session.session_id}"
167
+ session.close
168
+ end
169
+
170
+ def add_param(name, value)
171
+ add_boundary
172
+ @sio << "Content-Disposition: form-data; name=\"#{name}\"" << EOL << EOL
173
+ @sio << value.to_s << EOL
174
+ end
175
+
176
+ def add_data(size)
177
+ add_boundary
178
+ @sio << "Content-Disposition: form-data; name=\"file\"; filename=\"#{FILENAME}\"" << EOL
179
+ @sio << "Content-Type: application/octet-stream" << EOL << EOL
180
+ @sio << "." * size
181
+ @sio << EOL
182
+ end
183
+
184
+ def add_boundary
185
+ @sio << "--" << BOUNDARY << EOL
186
+ end
187
+
188
+ def add_end_boundary
189
+ @sio << "--" << BOUNDARY << "--" << EOL
190
+ end
191
+ end
192
+
193
+ class MultipartProgressTest < Test::Unit::TestCase
194
+
195
+ def test_domain_language_single
196
+ c = Controllers::SingleUploadController.new
197
+ assert_respond_to(c, :one)
198
+ assert_respond_to(c, :upload_status)
199
+ assert_respond_to(c, :finish_upload_status)
200
+ end
201
+
202
+ def test_domain_language_double
203
+ c = Controllers::DoubleUploadController.new
204
+ assert_respond_to(c, :one)
205
+ assert_respond_to(c, :two)
206
+ assert_respond_to(c, :upload_status)
207
+ assert_respond_to(c, :finish_upload_status)
208
+ end
209
+
210
+ def test_domain_language_double_status
211
+ c = Controllers::DoubleStatusUploadController.new
212
+ assert_respond_to(c, :one)
213
+ assert_respond_to(c, :two)
214
+ assert_respond_to(c, :custom_status)
215
+ assert_respond_to(c, :finish_upload_status)
216
+ end
217
+
218
+ def test_domain_language_double_seperate
219
+ c = Controllers::DoubleSeperateController.new
220
+ assert_respond_to(c, :one)
221
+ assert_respond_to(c, :two)
222
+ assert_respond_to(c, :upload_status)
223
+ assert_respond_to(c, :finish_upload_status)
224
+ end
225
+
226
+ def test_finish_status_norendered
227
+ # Fails to render the upload finish script because there is no view associated with this action
228
+ test_logger.debug('test_finish_status_norendered')
229
+
230
+ res = process(:action => 'norendered', :upload_id => 1)
231
+ assert_match(/ActionView::ActionViewError/s, res.body)
232
+
233
+ res = process(:action => :upload_status, :upload_id => 1)
234
+ assert_match(/Upload finished/s, res.body)
235
+
236
+ res = process(:action => :norendered)
237
+ assert_match(/ActionView::ActionViewError/s, res.body)
238
+ end
239
+
240
+ def test_finish_status_rendered
241
+ test_logger.debug('test_finish_status_rendered')
242
+
243
+ res = process(:action => :rendered, :upload_id => 1)
244
+ assert_match(/stop\(\)/s, res.body)
245
+ assert_no_match(/rendered/s, res.body)
246
+
247
+ res = process(:action => :upload_status, :upload_id => 1)
248
+ assert_match(/Upload finished/s, res.body)
249
+
250
+ res = process(:action => :rendered)
251
+ assert_no_match(/stop\(\)/s, res.body)
252
+ assert_match(/rendered/, res.body)
253
+ end
254
+
255
+ def test_finish_status_redirected
256
+ test_logger.debug('test_finish_status_redirected')
257
+
258
+ res = process(:action => :redirected, :upload_id => 1)
259
+ assert_match(/location\.replace/s, res.body)
260
+
261
+ res = process(:action => :redirected)
262
+ assert_no_match(/location\.replace/s, res.body)
263
+ assert_match(/\/redirected\//s, res.headers['location'])
264
+ assert_match(/302 .*$/, res.headers['Status'])
265
+
266
+ res = process(:action => :upload_status, :upload_id => 1)
267
+ assert_match(/Upload finished/s, res.body)
268
+ end
269
+
270
+ def test_finish_status_finish_param
271
+ test_logger.debug('test_finish_status_param')
272
+
273
+ res = process(:action => :finish_param_string, :upload_id => 1)
274
+ assert_match(/stop\('a string'\)/s, res.body)
275
+ assert_no_redirect res
276
+
277
+ res = process(:action => :finish_param_dict, :upload_id => 1)
278
+ assert_match(/stop\(\{a: 'b'\}\)/s, res.body)
279
+ assert_no_redirect res
280
+
281
+ res = process(:action => :finish_param_number, :upload_id => 1)
282
+ assert_match(/stop\(123\)/s, res.body)
283
+ assert_no_redirect res
284
+
285
+ res = process(:action => :finish_param_number_redirect, :upload_id => 1)
286
+ test_logger.debug('test_finish_status_param: ' + res.body)
287
+ assert_match(/stop\(123\)/s, res.body)
288
+ assert_match(/replace\('\http:\/\/localhost\/redirected\/'\).*?/s, res.body)
289
+ assert_no_redirect res
290
+ end
291
+
292
+ def test_basic_setup
293
+ test_logger.debug('test_basic_setup')
294
+
295
+ cgi, request, response = new_request(100000)
296
+ assert_not_nil(request.session)
297
+ assert_not_nil(request.session[:uploads], "uploads collection not set")
298
+ assert_not_nil(request.session[:uploads][cgi.upload_id], "upload id not set")
299
+ progress = request.session[:uploads][cgi.upload_id]
300
+ assert_equal(true, progress.finished?)
301
+ end
302
+
303
+ def test_params
304
+ test_logger.debug('test_params')
305
+
306
+ cgi, request, response = new_request(1000)
307
+ assert(!request.params.empty?)
308
+ assert(!request.params['param1'].empty?)
309
+ end
310
+
311
+ def test_share_session
312
+ cgi, request, response = new_request(100000) do |cgi, req|
313
+ if cgi.stdinput.tell > 50000
314
+ # force a save
315
+ cgi.stdinput.save_progress rescue flunk('Something else is wrong, our wrapper isnt setup, is ActionController::Base.logger set?')
316
+
317
+ other_session = CGI::Session.new(cgi, cgi.session_options.merge({'session_id' => cgi.session_id}))
318
+ assert_not_nil(other_session[:uploads])
319
+ assert_not_nil(other_session[:uploads][cgi.upload_id])
320
+ assert_in_delta(cgi.stdinput.session[:uploads][cgi.upload_id].bitrate, other_session[:uploads][cgi.upload_id].bitrate, 1000.0, "Seperate session does not share data from original session")
321
+
322
+ other_session.close
323
+ end
324
+ end
325
+ end
326
+
327
+ def test_upload_ids
328
+ c = Controllers::MockController.new
329
+ (1..222).each do |id|
330
+ c.params = {}
331
+
332
+ assert_equal((id-1).to_s, c.last_upload_id, "last_upload_id is out of sync")
333
+ assert_equal(id.to_s, c.next_upload_id, "next_upload_id is out of sync")
334
+ assert_equal(id.to_s, c.current_upload_id, "current_upload_id is out of sync")
335
+
336
+ c.params = {:upload_id => (id-1).to_s}
337
+ assert_equal((id-1).to_s, c.current_upload_id, "current_upload_id is out of sync")
338
+
339
+ c.session[:uploads][id] = {}
340
+ end
341
+ end
342
+
343
+ private
344
+ def new_request(size=1000, url='/test', &block)
345
+ test_logger.debug('Creating MockCGI')
346
+ cgi = MockCGI.new(size, url) do |cgi|
347
+ block.call(cgi) if block_given?
348
+ end
349
+
350
+ assert(cgi.private_methods.include?("read_multipart_with_progress"))
351
+ return [cgi, ActionController::CgiRequest.new(cgi), ActionController::CgiResponse.new(cgi)]
352
+ end
353
+
354
+ def process(options = {})
355
+ Controllers::UploadController.process(*(new_request(1000, '/upload?' + options.map {|k,v| "#{k}=#{v}"}.join('&'))[1..2]))
356
+ end
357
+
358
+ def assert_no_redirect(res)
359
+ assert_nil(res.redirected_to)
360
+ assert_nil(res.headers['location'])
361
+ assert_match(/200 .*$/, res.headers['Status'])
362
+ end
363
+
364
+ end
@@ -0,0 +1,134 @@
1
+ require File.dirname(__FILE__) + 'action_view/helpers/date_helper'
2
+ require File.dirname(__FILE__) + 'action_view/helpers/number_helper'
3
+ require File.dirname(__FILE__) + 'action_view/helpers/asset_tag_helper'
4
+ require File.dirname(__FILE__) + 'action_view/helpers/form_tag_helper'
5
+ require File.dirname(__FILE__) + 'action_view/helpers/tag_helper'
6
+ require File.dirname(__FILE__) + 'action_view/helpers/javascript_helper'
7
+ require File.dirname(__FILE__) + 'action_view/helpers/upload_progress_helper'
8
+ require File.dirname(__FILE__) + 'activesupport/lib/active_support/core_ext/hash' #for stringify keys
9
+
10
+ class MockProgress
11
+ def initialize(started, finished)
12
+ @started, @finished = [started, finished]
13
+ end
14
+
15
+ def started?
16
+ @started
17
+ end
18
+
19
+ def finished?
20
+ @finished
21
+ end
22
+
23
+ def message
24
+ "A message"
25
+ end
26
+
27
+ def method_missing(meth, *args)
28
+ # Just return some consitant number
29
+ meth.to_s.hash.to_i.abs + args.hash.to_i.abs
30
+ end
31
+ end
32
+
33
+ class UploadProgressHelperTest < Test::Unit::TestCase
34
+ include ActionView::Helpers::DateHelper
35
+ include ActionView::Helpers::NumberHelper
36
+ include ActionView::Helpers::AssetTagHelper
37
+ include ActionView::Helpers::FormTagHelper
38
+ include ActionView::Helpers::TagHelper
39
+ include ActionView::Helpers::UrlHelper
40
+ include ActionView::Helpers::JavaScriptHelper
41
+ include ActionView::Helpers::UploadProgressHelper
42
+
43
+ def next_upload_id; @upload_id = last_upload_id.succ; end
44
+ def last_upload_id; @upload_id ||= 0; end
45
+ def current_upload_id; last_upload_id; end
46
+ def upload_progress(upload_id = nil); @upload_progress ||= MockProgress.new(false, true); end
47
+
48
+ def setup
49
+ @controller = Class.new do
50
+ def url_for(options, *parameters_for_method_reference)
51
+ "http://www.example.com"
52
+ end
53
+ end
54
+ @controller = @controller.new
55
+ end
56
+
57
+ def test_upload_status_tag
58
+ assert_dom_equal(
59
+ '<div class="progressBar" id="UploadProgressBar0"><div class="border"><div class="background"><div class="foreground"></div></div></div></div><div class="uploadStatus" id="UploadStatus0"></div>',
60
+ upload_status_tag
61
+ )
62
+ end
63
+
64
+ def test_upload_status_text_tag
65
+ assert_dom_equal(
66
+ '<div class="my-upload" id="my-id">Starting</div>',
67
+ upload_status_text_tag('Starting', :class => 'my-upload', :id => 'my-id')
68
+ )
69
+ end
70
+
71
+
72
+ def test_upload_progress_text
73
+ @upload_progress = MockProgress.new(false, false)
74
+ assert_equal(
75
+ "Upload starting...",
76
+ upload_progress_text
77
+ )
78
+
79
+ @upload_progress = MockProgress.new(true, false)
80
+ assert_equal(
81
+ "828.7 MB of 456.2 MB at 990.1 MB/s; 10227 days remaining",
82
+ upload_progress_text
83
+ )
84
+
85
+ @upload_progress = MockProgress.new(true, true)
86
+ assert_equal(
87
+ "A message",
88
+ upload_progress_text
89
+ )
90
+ end
91
+
92
+ def test_upload_progress_update_bar_js
93
+ assert_equal(
94
+ "if($('UploadProgressBar0')){$('UploadProgressBar0').firstChild.firstChild.style.width='0%'}",
95
+ upload_progress_update_bar_js
96
+ )
97
+
98
+ assert_equal(
99
+ "if($('UploadProgressBar0')){$('UploadProgressBar0').firstChild.firstChild.style.width='50%'}",
100
+ upload_progress_update_bar_js(50)
101
+ )
102
+ end
103
+
104
+ def test_finish_upload_status
105
+ assert_dom_equal(
106
+ "<html><head><script language=\"javascript\" type=\"text/javascript\">function finish() { if (parent.document.uploadStatus0) { parent.document.uploadStatus0.stop();\n }\n }</script></head><body onload=\"finish()\"></body></html>",
107
+ finish_upload_status
108
+ )
109
+
110
+ assert_dom_equal(
111
+ "<html><head><script language=\"javascript\" type=\"text/javascript\">function finish() { if (parent.document.uploadStatus0) { parent.document.uploadStatus0.stop(123);\n }\n }</script></head><body onload=\"finish()\"></body></html>",
112
+ finish_upload_status(:client_js_argument => 123)
113
+ )
114
+
115
+ assert_dom_equal(
116
+ "<html><head><script language=\"javascript\" type=\"text/javascript\">function finish() { if (parent.document.uploadStatus0) { parent.document.uploadStatus0.stop();\nparent.location.replace('/redirected/');\n }\n }</script></head><body onload=\"finish()\"></body></html>",
117
+ finish_upload_status(:redirect_to => '/redirected/')
118
+ )
119
+ end
120
+
121
+ def test_form_tag_with_upload_progress
122
+ assert_dom_equal(
123
+ "<form action=\"http://www.example.com\" enctype=\"multipart/form-data\" method=\"post\" onsubmit=\"if (this.action.indexOf('upload_id') &lt; 0){ this.action += '?upload_id=1'; }this.target = 'UploadTarget1';$('UploadStatus1').innerHTML='Upload starting...'; if($('UploadProgressBar1')){$('UploadProgressBar1').firstChild.firstChild.style.width='0%'}; if (document.uploadStatus1) { document.uploadStatus1.stop(); }document.uploadStatus1 = new Ajax.PeriodicalUpdater('UploadStatus1','http://www.example.com', Object.extend({asynchronous:true, evalScripts:true, onComplete:function(request){$('UploadStatus1').innerHTML='A message';if($('UploadProgressBar1')){$('UploadProgressBar1').firstChild.firstChild.style.width='100%'};document.uploadStatus1 = null}},{decay:1.8,frequency:2.0})); return true\"><iframe id=\"UploadTarget1\" name=\"UploadTarget1\" src=\"\" style=\"width:0px;height:0px;border:0\"></iframe>",
124
+ form_tag_with_upload_progress
125
+ )
126
+ end
127
+
128
+ def test_form_tag_with_upload_progress_custom
129
+ assert_dom_equal(
130
+ "<form action=\"http://www.example.com\" enctype=\"multipart/form-data\" method=\"post\" onsubmit=\"if (this.action.indexOf('upload_id') &lt; 0){ this.action += '?upload_id=5'; }this.target = 'awindow';$('UploadStatus0').innerHTML='Upload starting...'; if($('UploadProgressBar0')){$('UploadProgressBar0').firstChild.firstChild.style.width='0%'}; alert('foo'); if (document.uploadStatus0) { document.uploadStatus0.stop(); }document.uploadStatus0 = new Ajax.PeriodicalUpdater('UploadStatus0','http://www.example.com', Object.extend({asynchronous:true, evalScripts:true, onComplete:function(request){$('UploadStatus0').innerHTML='A message';if($('UploadProgressBar0')){$('UploadProgressBar0').firstChild.firstChild.style.width='100%'};document.uploadStatus0 = null; alert('bar')}},{decay:7,frequency:6})); return true\" target=\"awindow\">",
131
+ form_tag_with_upload_progress({:upload_id => 5}, {:begin => "alert('foo')", :finish => "alert('bar')", :frequency => 6, :decay => 7, :target => 'awindow'})
132
+ )
133
+ end
134
+ end
@@ -0,0 +1,88 @@
1
+ require 'test/unit'
2
+ require 'cgi'
3
+ require 'stringio'
4
+
5
+ class UploadProgressTest < Test::Unit::TestCase
6
+ def test_remaining
7
+ progress = new_progress(20000)
8
+ assert_equal(0, progress.received_bytes)
9
+ assert_equal(20000, progress.remaining_bytes)
10
+ progress.update!(10000, 1.0)
11
+ assert_equal(10000, progress.remaining_bytes)
12
+ assert_equal(1.0, progress.remaining_seconds)
13
+ assert_equal(50, progress.completed_percent)
14
+ assert_equal(true, progress.started?)
15
+ assert_equal(false, progress.finished?)
16
+ assert_equal(false, progress.stalled?)
17
+ progress.update!(10000, 2.0)
18
+ assert_equal(true, progress.finished?)
19
+ assert_equal(0.0, progress.remaining_seconds)
20
+ end
21
+
22
+ def test_stalled
23
+ progress = new_progress(10000)
24
+ assert_equal(false, progress.stalled?)
25
+ progress.update!(100, 1.0)
26
+ assert_equal(false, progress.stalled?)
27
+ progress.update!(100, 20.0)
28
+ assert_equal(true, progress.stalled?)
29
+ assert_in_delta(0.0, progress.bitrate, 0.001)
30
+ progress.update!(100, 21.0)
31
+ assert_equal(false, progress.stalled?)
32
+ end
33
+
34
+ def test_elapsed
35
+ progress = new_progress(10000)
36
+ (1..5).each do |t|
37
+ progress.update!(1000, Float(t))
38
+ end
39
+ assert_in_delta(5.0, progress.elapsed_seconds, 0.001)
40
+ assert_equal(10000, progress.total_bytes)
41
+ assert_equal(5000, progress.received_bytes)
42
+ assert_equal(5000, progress.remaining_bytes)
43
+ end
44
+
45
+ def test_overflow
46
+ progress = new_progress(10000)
47
+ progress.update!(20000, 1.0)
48
+ assert_equal(10000, progress.received_bytes)
49
+ end
50
+
51
+ def test_zero
52
+ progress = new_progress(0)
53
+ assert_equal(0, progress.total_bytes)
54
+ assert_equal(0, progress.remaining_bytes)
55
+ assert_equal(false, progress.started?)
56
+ assert_equal(true, progress.finished?)
57
+ assert_equal(0, progress.bitrate)
58
+ assert_equal(0, progress.completed_percent)
59
+ assert_equal(0, progress.remaining_seconds)
60
+ end
61
+
62
+ def test_finished
63
+ progress = new_progress(10000)
64
+ (1..9).each do |t|
65
+ progress.update!(1000, Float(t))
66
+ assert_equal(false, progress.finished?)
67
+ assert_equal(1000.0, progress.bitrate)
68
+ assert_equal(false, progress.stalled?)
69
+ end
70
+ assert_equal(false, progress.finished?)
71
+ progress.update!(1000, 10.0)
72
+ assert_equal(true, progress.finished?)
73
+ end
74
+
75
+ def test_rapid_samples
76
+ progress = new_progress(10000)
77
+ (1..1000).each do |t|
78
+ progress.update!(10, t/100.0)
79
+ end
80
+ assert_in_delta(1000.0, progress.bitrate, 0.001)
81
+ assert_equal(true, progress.finished?)
82
+ end
83
+
84
+ private
85
+ def new_progress(total)
86
+ ActionController::UploadProgress::Progress.new(total)
87
+ end
88
+ end