card 1.19.0 → 1.19.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (424) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/card.gemspec +3 -3
  4. data/config/initializers/{02_extensions → 02_patches}/kaminari.rb +16 -5
  5. data/config/initializers/patches.rb +7 -0
  6. data/config/locales/en.yml +15 -6
  7. data/db/migrate_core_cards/20150724123438_update_file_and_image_cards.rb +11 -11
  8. data/db/migrate_core_cards/data/themes/bootstrap_default/_variables.scss +2 -1
  9. data/db/seed/new/card_actions.yml +915 -443
  10. data/db/seed/new/card_acts.yml +348 -186
  11. data/db/seed/new/card_changes.yml +4409 -3329
  12. data/db/seed/new/card_references.yml +220 -3
  13. data/db/seed/new/cards.yml +6687 -3445
  14. data/db/seed/test/fixtures/card_actions.yml +1953 -1513
  15. data/db/seed/test/fixtures/card_acts.yml +615 -453
  16. data/db/seed/test/fixtures/card_changes.yml +7596 -6516
  17. data/db/seed/test/fixtures/card_references.yml +892 -675
  18. data/db/seed/test/fixtures/cards.yml +8803 -5561
  19. data/db/seeds.rb +8 -0
  20. data/lib/card.rb +10 -0
  21. data/lib/card/auth/setup.rb +6 -6
  22. data/lib/card/mod/dirs.rb +13 -3
  23. data/lib/card/set/advanced_api.rb +5 -4
  24. data/lib/cardio.rb +7 -3
  25. data/mod/Modfile +2 -2
  26. data/mod/admin/set/self/admin.rb +47 -30
  27. data/mod/admin/set/self/admin_info.rb +11 -11
  28. data/mod/basic_formats/set/self/head.rb +1 -1
  29. data/mod/{basic_types → basic_formats}/spec/set/all/all_css_spec.rb +0 -0
  30. data/mod/{basic_types → basic_formats}/spec/set/all/all_csv_spec.rb +0 -0
  31. data/mod/{basic_types → basic_formats}/spec/set/all/base_spec.rb +0 -0
  32. data/mod/{basic_types → basic_formats}/spec/set/all/file_spec.rb +0 -0
  33. data/mod/{basic_types → basic_formats}/spec/set/all/json_spec.rb +0 -0
  34. data/mod/{basic_types → basic_formats}/spec/set/all/rss_spec.rb +0 -0
  35. data/mod/{basic_types → basic_formats}/spec/set/all/text_spec.rb +0 -0
  36. data/mod/bootstrap/lib/stylesheets/bootstrap/_variables.scss +1 -1
  37. data/mod/bootstrap/set/all/bootstrap/table.rb +1 -1
  38. data/mod/bootstrap/set/self/bootswatch_shared.rb +1 -1
  39. data/mod/carrierwave/Gemfile +4 -0
  40. data/mod/carrierwave/lib/carrier_wave/cardmount.rb +24 -13
  41. data/mod/carrierwave/lib/carrier_wave/file_card_uploader.rb +189 -57
  42. data/mod/carrierwave/lib/carrier_wave/image_card_uploader.rb +5 -0
  43. data/mod/carrierwave/set/abstract/attachment.rb +26 -190
  44. data/mod/carrierwave/set/abstract/attachment/paths.rb +50 -0
  45. data/mod/carrierwave/set/abstract/attachment/storage_type.rb +319 -0
  46. data/mod/carrierwave/set/abstract/attachment/upload_cache.rb +77 -0
  47. data/mod/carrierwave/set/all/file_utils.rb +28 -0
  48. data/mod/carrierwave/set/self/admin.rb +23 -0
  49. data/mod/carrierwave/set/type/file.rb +26 -23
  50. data/mod/carrierwave/set/type/image.rb +1 -0
  51. data/mod/carrierwave/spec/lib/carrier_wave/file_card_uploader_spec.rb +67 -0
  52. data/mod/carrierwave/spec/set/type/file_spec.rb +557 -0
  53. data/mod/{standard → carrierwave}/spec/set/type/image_spec.rb +22 -4
  54. data/mod/core/set/abstract/code_file.rb +3 -3
  55. data/mod/core/set/all/debug.rb +23 -0
  56. data/mod/core/set/all/name.rb +1 -1
  57. data/mod/core/set/all/permissions.rb +22 -12
  58. data/mod/core/set/all/tracked_attributes.rb +0 -76
  59. data/mod/core/set/all/trash.rb +50 -0
  60. data/mod/core/set/all/update_read_rules.rb +84 -0
  61. data/mod/core/set/all/utils.rb +1 -75
  62. data/mod/email/set/type_plus_right/user/follow.rb +4 -8
  63. data/mod/history/lib/card/act.rb +3 -1
  64. data/mod/history/lib/card/action.rb +3 -1
  65. data/mod/history/lib/card/action/differ.rb +12 -1
  66. data/mod/history/set/all/history.rb +2 -1
  67. data/mod/machines/file/all_script_machine_output/file.js +211 -0
  68. data/mod/machines/file/all_style_machine_output/file.css +19 -0
  69. data/mod/machines/set/abstract/machine.rb +270 -0
  70. data/mod/machines/set/abstract/machine_input.rb +76 -0
  71. data/mod/machines/set/right/machine_output.rb +9 -1
  72. data/mod/machines/set/type/coffee_script.rb +2 -6
  73. data/mod/machines/set/type/css.rb +2 -2
  74. data/mod/machines/set/type/java_script.rb +2 -2
  75. data/mod/machines/set/type/skin.rb +2 -2
  76. data/mod/machines/spec/set/abstract/machine_spec.rb +10 -0
  77. data/mod/{basic_types → pointer}/spec/set/type/pointer_spec.rb +10 -26
  78. data/mod/settings/set/right/script.rb +1 -1
  79. data/mod/settings/set/right/style.rb +1 -1
  80. data/mod/solid_cache/set/all/solid_cache.rb +1 -1
  81. data/mod/standard/file/credit_image/image-icon.png +0 -0
  82. data/mod/standard/file/credit_image/image-large.png +0 -0
  83. data/mod/standard/file/credit_image/image-medium.png +0 -0
  84. data/mod/standard/file/credit_image/image-small.png +0 -0
  85. data/mod/standard/file/favicon/image-icon.png +0 -0
  86. data/mod/standard/file/favicon/image-large.png +0 -0
  87. data/mod/standard/file/favicon/image-medium.png +0 -0
  88. data/mod/standard/file/favicon/image-small.png +0 -0
  89. data/mod/standard/file/logo/image-icon.png +0 -0
  90. data/mod/standard/file/logo/image-large.png +0 -0
  91. data/mod/standard/file/logo/image-medium.png +0 -0
  92. data/mod/standard/file/logo/image-small.png +0 -0
  93. data/mod/standard/set/all/links.rb +2 -2
  94. data/spec/spec_helper.rb +15 -3
  95. data/tmpsets/set/{mod014-admin → mod001-admin}/self/admin.rb +47 -30
  96. data/tmpsets/set/{mod014-admin → mod001-admin}/self/admin_info.rb +11 -11
  97. data/tmpsets/set/{mod014-admin → mod001-admin}/self/version.rb +0 -0
  98. data/tmpsets/set/{mod001-core → mod002-core}/abstract/code_file.rb +0 -0
  99. data/tmpsets/set/{mod001-core → mod002-core}/all/actify.rb +6 -5
  100. data/tmpsets/set/{mod001-core → mod002-core}/all/active_card.rb +0 -0
  101. data/tmpsets/set/{mod001-core → mod002-core}/all/collection.rb +0 -0
  102. data/tmpsets/set/{mod001-core → mod002-core}/all/content.rb +0 -0
  103. data/tmpsets/set/mod002-core/all/debug.rb +30 -0
  104. data/tmpsets/set/{mod001-core → mod002-core}/all/erb.rb +0 -0
  105. data/tmpsets/set/{mod001-core → mod002-core}/all/event.rb +0 -0
  106. data/tmpsets/set/{mod001-core → mod002-core}/all/export.rb +0 -0
  107. data/tmpsets/set/{mod001-core → mod002-core}/all/fetch.rb +0 -0
  108. data/tmpsets/set/{mod001-core → mod002-core}/all/haml.rb +0 -0
  109. data/tmpsets/set/{mod001-core → mod002-core}/all/initialize.rb +0 -0
  110. data/tmpsets/set/{mod001-core → mod002-core}/all/location_history.rb +0 -0
  111. data/tmpsets/set/{mod001-core → mod002-core}/all/name.rb +1 -1
  112. data/tmpsets/set/{mod001-core → mod002-core}/all/name_validations.rb +0 -0
  113. data/tmpsets/set/{mod001-core → mod002-core}/all/pattern.rb +0 -0
  114. data/tmpsets/set/{mod001-core → mod002-core}/all/permissions.rb +22 -12
  115. data/tmpsets/set/{mod001-core → mod002-core}/all/phases.rb +0 -0
  116. data/tmpsets/set/{mod001-core → mod002-core}/all/references.rb +0 -0
  117. data/tmpsets/set/{mod001-core → mod002-core}/all/rules.rb +0 -0
  118. data/tmpsets/set/{mod001-core → mod002-core}/all/stages.rb +0 -0
  119. data/tmpsets/set/{mod001-core → mod002-core}/all/states.rb +0 -0
  120. data/tmpsets/set/{mod001-core → mod002-core}/all/subcards.rb +0 -0
  121. data/tmpsets/set/{mod001-core → mod002-core}/all/templating.rb +0 -0
  122. data/tmpsets/set/mod002-core/all/tracked_attributes.rb +78 -0
  123. data/tmpsets/set/{mod001-core → mod002-core}/all/trash.rb +50 -0
  124. data/tmpsets/set/{mod001-core → mod002-core}/all/type.rb +0 -0
  125. data/tmpsets/set/mod002-core/all/update_read_rules.rb +91 -0
  126. data/tmpsets/set/mod002-core/all/utils.rb +62 -0
  127. data/tmpsets/set/{mod001-core → mod002-core}/all/view_cache.rb +0 -0
  128. data/tmpsets/set/{mod002-history → mod003-history}/all/actions.rb +0 -0
  129. data/tmpsets/set/{mod002-history → mod003-history}/all/content_history.rb +0 -0
  130. data/tmpsets/set/{mod002-history → mod003-history}/all/history.rb +2 -1
  131. data/tmpsets/set/{mod003-basic_formats → mod004-basic_formats}/all/all_css.rb +0 -0
  132. data/tmpsets/set/{mod003-basic_formats → mod004-basic_formats}/all/all_csv.rb +0 -0
  133. data/tmpsets/set/{mod003-basic_formats → mod004-basic_formats}/all/all_js.rb +0 -0
  134. data/tmpsets/set/{mod003-basic_formats → mod004-basic_formats}/all/base.rb +0 -0
  135. data/tmpsets/set/{mod003-basic_formats → mod004-basic_formats}/all/file.rb +0 -0
  136. data/tmpsets/set/{mod003-basic_formats → mod004-basic_formats}/all/json.rb +0 -0
  137. data/tmpsets/set/{mod003-basic_formats → mod004-basic_formats}/all/rss.rb +0 -0
  138. data/tmpsets/set/{mod003-basic_formats → mod004-basic_formats}/all/text.rb +0 -0
  139. data/tmpsets/set/{mod003-basic_formats → mod004-basic_formats}/self/01_head/javascript.rb +0 -0
  140. data/tmpsets/set/{mod003-basic_formats → mod004-basic_formats}/self/head.rb +1 -1
  141. data/tmpsets/set/{mod004-pointer → mod005-pointer}/abstract/01_pointer.rb +0 -0
  142. data/tmpsets/set/{mod004-pointer → mod005-pointer}/abstract/01_pointer/edit.rb +0 -0
  143. data/tmpsets/set/{mod004-pointer → mod005-pointer}/abstract/code_pointer.rb +0 -0
  144. data/tmpsets/set/{mod004-pointer → mod005-pointer}/self/script_editors.rb +0 -0
  145. data/tmpsets/set/{mod004-pointer → mod005-pointer}/self/script_mods.rb +0 -0
  146. data/tmpsets/set/{mod004-pointer → mod005-pointer}/self/script_pointer_config.rb +0 -0
  147. data/tmpsets/set/{mod004-pointer → mod005-pointer}/type/pointer.rb +0 -0
  148. data/tmpsets/set/{mod005-ace_editor → mod006-ace_editor}/abstract/ace_editor.rb +0 -0
  149. data/tmpsets/set/{mod005-ace_editor → mod006-ace_editor}/self/script_ace.rb +0 -0
  150. data/tmpsets/set/{mod005-ace_editor → mod006-ace_editor}/self/script_ace_config.rb +0 -0
  151. data/tmpsets/set/{mod006-prosemirror_editor → mod007-prosemirror_editor}/abstract/prosemirror_editor.rb +0 -0
  152. data/tmpsets/set/{mod006-prosemirror_editor → mod007-prosemirror_editor}/self/script_prosemirror.rb +0 -0
  153. data/tmpsets/set/{mod006-prosemirror_editor → mod007-prosemirror_editor}/self/script_prosemirror_config.rb +0 -0
  154. data/tmpsets/set/{mod008-solid_cache → mod009-solid_cache}/abstract/solid_cache.rb +0 -0
  155. data/tmpsets/set/{mod008-solid_cache → mod009-solid_cache}/all/solid_cache.rb +0 -0
  156. data/tmpsets/set/{mod008-solid_cache → mod009-solid_cache}/right/solid_cache.rb +0 -0
  157. data/tmpsets/set/{mod009-basic_types → mod010-basic_types}/type/html.rb +0 -0
  158. data/tmpsets/set/{mod009-basic_types → mod010-basic_types}/type/plain_text.rb +0 -0
  159. data/tmpsets/set/mod011-machines/abstract/machine.rb +277 -0
  160. data/tmpsets/set/mod011-machines/abstract/machine_input.rb +83 -0
  161. data/tmpsets/set/{mod010-machines → mod011-machines}/abstract/script.rb +0 -0
  162. data/tmpsets/set/{mod010-machines → mod011-machines}/all/reset_machines.rb +0 -0
  163. data/tmpsets/set/{mod010-machines → mod011-machines}/right/machine_cache.rb +0 -0
  164. data/tmpsets/set/{mod010-machines → mod011-machines}/right/machine_input.rb +0 -0
  165. data/tmpsets/set/{mod010-machines → mod011-machines}/right/machine_output.rb +9 -1
  166. data/tmpsets/set/{mod010-machines → mod011-machines}/self/script_card_menu.rb +0 -0
  167. data/tmpsets/set/{mod010-machines → mod011-machines}/self/script_html5shiv_printshiv.rb +0 -0
  168. data/tmpsets/set/{mod010-machines → mod011-machines}/self/script_jquery.rb +0 -0
  169. data/tmpsets/set/{mod010-machines → mod011-machines}/self/script_jquery_helper.rb +0 -0
  170. data/tmpsets/set/{mod010-machines → mod011-machines}/self/script_slot.rb +0 -0
  171. data/tmpsets/set/{mod010-machines → mod011-machines}/self/style_bootstrap_compatible.rb +0 -0
  172. data/tmpsets/set/{mod010-machines → mod011-machines}/self/style_cards.rb +0 -0
  173. data/tmpsets/set/{mod010-machines → mod011-machines}/self/style_jquery_ui_smoothness.rb +0 -0
  174. data/tmpsets/set/{mod010-machines → mod011-machines}/type/coffee_script.rb +2 -6
  175. data/tmpsets/set/{mod010-machines → mod011-machines}/type/css.rb +2 -2
  176. data/tmpsets/set/{mod010-machines → mod011-machines}/type/java_script.rb +2 -2
  177. data/tmpsets/set/{mod010-machines → mod011-machines}/type/scss.rb +0 -0
  178. data/tmpsets/set/{mod010-machines → mod011-machines}/type/skin.rb +2 -2
  179. data/tmpsets/set/{mod011-settings → mod012-settings}/abstract/permission.rb +0 -0
  180. data/tmpsets/set/{mod011-settings → mod012-settings}/right/add_help.rb +0 -0
  181. data/tmpsets/set/{mod011-settings → mod012-settings}/right/comment.rb +0 -0
  182. data/tmpsets/set/{mod011-settings → mod012-settings}/right/create.rb +0 -0
  183. data/tmpsets/set/{mod011-settings → mod012-settings}/right/default.rb +0 -0
  184. data/tmpsets/set/{mod011-settings → mod012-settings}/right/delete.rb +0 -0
  185. data/tmpsets/set/{mod011-settings → mod012-settings}/right/help.rb +0 -0
  186. data/tmpsets/set/{mod011-settings → mod012-settings}/right/read.rb +0 -0
  187. data/tmpsets/set/{mod011-settings → mod012-settings}/right/script.rb +1 -1
  188. data/tmpsets/set/{mod011-settings → mod012-settings}/right/structure.rb +0 -0
  189. data/tmpsets/set/{mod011-settings → mod012-settings}/right/style.rb +1 -1
  190. data/tmpsets/set/{mod011-settings → mod012-settings}/right/update.rb +0 -0
  191. data/tmpsets/set/{mod011-settings → mod012-settings}/self/accountable.rb +0 -0
  192. data/tmpsets/set/{mod011-settings → mod012-settings}/self/add_help.rb +0 -0
  193. data/tmpsets/set/{mod011-settings → mod012-settings}/self/autoname.rb +0 -0
  194. data/tmpsets/set/{mod011-settings → mod012-settings}/self/captcha.rb +0 -0
  195. data/tmpsets/set/{mod011-settings → mod012-settings}/self/create.rb +0 -0
  196. data/tmpsets/set/{mod011-settings → mod012-settings}/self/default.rb +0 -0
  197. data/tmpsets/set/{mod011-settings → mod012-settings}/self/default_html_view.rb +0 -0
  198. data/tmpsets/set/{mod011-settings → mod012-settings}/self/delete.rb +0 -0
  199. data/tmpsets/set/{mod011-settings → mod012-settings}/self/follow_fields.rb +0 -0
  200. data/tmpsets/set/{mod011-settings → mod012-settings}/self/help.rb +0 -0
  201. data/tmpsets/set/{mod011-settings → mod012-settings}/self/input.rb +0 -0
  202. data/tmpsets/set/{mod011-settings → mod012-settings}/self/layout.rb +0 -0
  203. data/tmpsets/set/{mod011-settings → mod012-settings}/self/on_create.rb +0 -0
  204. data/tmpsets/set/{mod011-settings → mod012-settings}/self/on_delete.rb +0 -0
  205. data/tmpsets/set/{mod011-settings → mod012-settings}/self/on_update.rb +0 -0
  206. data/tmpsets/set/{mod011-settings → mod012-settings}/self/options.rb +0 -0
  207. data/tmpsets/set/{mod011-settings → mod012-settings}/self/options_label.rb +0 -0
  208. data/tmpsets/set/{mod011-settings → mod012-settings}/self/read.rb +0 -0
  209. data/tmpsets/set/{mod011-settings → mod012-settings}/self/recent_settings.rb +0 -0
  210. data/tmpsets/set/{mod011-settings → mod012-settings}/self/script.rb +0 -0
  211. data/tmpsets/set/{mod011-settings → mod012-settings}/self/structure.rb +0 -0
  212. data/tmpsets/set/{mod011-settings → mod012-settings}/self/style.rb +0 -0
  213. data/tmpsets/set/{mod011-settings → mod012-settings}/self/table_of_contents.rb +0 -0
  214. data/tmpsets/set/{mod011-settings → mod012-settings}/self/thanks.rb +0 -0
  215. data/tmpsets/set/{mod011-settings → mod012-settings}/self/update.rb +0 -0
  216. data/tmpsets/set/{mod011-settings → mod012-settings}/type/setting.rb +0 -0
  217. data/tmpsets/set/{mod012-email → mod013-email}/all/email_html.rb +0 -0
  218. data/tmpsets/set/{mod012-email → mod013-email}/all/email_text.rb +0 -0
  219. data/tmpsets/set/{mod012-email → mod013-email}/all/follow.rb +0 -0
  220. data/tmpsets/set/{mod012-email → mod013-email}/all/notify.rb +0 -0
  221. data/tmpsets/set/{mod012-email → mod013-email}/all/observer.rb +0 -0
  222. data/tmpsets/set/{mod012-email → mod013-email}/right/bcc.rb +0 -0
  223. data/tmpsets/set/{mod012-email → mod013-email}/right/cc.rb +0 -0
  224. data/tmpsets/set/{mod012-email → mod013-email}/right/follow.rb +0 -0
  225. data/tmpsets/set/{mod012-email → mod013-email}/right/follow_fields.rb +0 -0
  226. data/tmpsets/set/{mod012-email → mod013-email}/right/followers.rb +0 -0
  227. data/tmpsets/set/{mod012-email → mod013-email}/right/following.rb +0 -0
  228. data/tmpsets/set/{mod012-email → mod013-email}/right/from.rb +0 -0
  229. data/tmpsets/set/{mod012-email → mod013-email}/right/html_message.rb +0 -0
  230. data/tmpsets/set/{mod012-email → mod013-email}/right/to.rb +0 -0
  231. data/tmpsets/set/{mod012-email → mod013-email}/self/always.rb +0 -0
  232. data/tmpsets/set/{mod012-email → mod013-email}/self/created.rb +0 -0
  233. data/tmpsets/set/{mod012-email → mod013-email}/self/edited.rb +0 -0
  234. data/tmpsets/set/{mod012-email → mod013-email}/self/follow.rb +0 -0
  235. data/tmpsets/set/{mod012-email → mod013-email}/self/follow_defaults.rb +0 -0
  236. data/tmpsets/set/{mod012-email → mod013-email}/self/never.rb +0 -0
  237. data/tmpsets/set/{mod012-email → mod013-email}/type/email_template.rb +0 -0
  238. data/tmpsets/set/{mod012-email → mod013-email}/type_plus_right/user/follow.rb +4 -8
  239. data/tmpsets/set/{mod015-developer → mod014-developer}/all/event_viz.rb +0 -0
  240. data/tmpsets/set/{mod015-developer → mod014-developer}/all/view_viz.rb +0 -0
  241. data/tmpsets/set/{mod015-developer → mod014-developer}/right/debug.rb +0 -0
  242. data/tmpsets/set/mod015-carrierwave/abstract/attachment.rb +118 -0
  243. data/tmpsets/set/mod015-carrierwave/abstract/attachment/paths.rb +57 -0
  244. data/tmpsets/set/mod015-carrierwave/abstract/attachment/storage_type.rb +326 -0
  245. data/tmpsets/set/mod015-carrierwave/abstract/attachment/upload_cache.rb +84 -0
  246. data/tmpsets/set/mod015-carrierwave/all/file_utils.rb +35 -0
  247. data/tmpsets/set/mod015-carrierwave/self/admin.rb +30 -0
  248. data/tmpsets/set/{mod013-carrierwave → mod015-carrierwave}/type/file.rb +27 -24
  249. data/tmpsets/set/{mod013-carrierwave → mod015-carrierwave}/type/image.rb +1 -0
  250. data/tmpsets/set/mod016-standard/all/links.rb +2 -2
  251. data/tmpsets/set/mod018-bootstrap/all/bootstrap/table.rb +1 -1
  252. data/tmpsets/set/mod018-bootstrap/self/bootswatch_shared.rb +1 -1
  253. data/vendor/carrierwave/.gitignore +19 -0
  254. data/vendor/carrierwave/.rubocop.yml +262 -0
  255. data/vendor/carrierwave/.travis.yml +58 -0
  256. data/vendor/carrierwave/CHANGELOG.md +81 -0
  257. data/vendor/carrierwave/CONTRIBUTING.md +37 -0
  258. data/vendor/carrierwave/Gemfile +5 -0
  259. data/vendor/carrierwave/README.md +995 -0
  260. data/vendor/carrierwave/Rakefile +26 -0
  261. data/vendor/carrierwave/carrierwave.gemspec +45 -0
  262. data/vendor/carrierwave/cucumber.yml +2 -0
  263. data/vendor/carrierwave/features/caching.feature +28 -0
  264. data/vendor/carrierwave/features/download.feature +20 -0
  265. data/vendor/carrierwave/features/file_storage.feature +37 -0
  266. data/vendor/carrierwave/features/file_storage_overridden_filename.feature +38 -0
  267. data/vendor/carrierwave/features/file_storage_overridden_store_dir.feature +38 -0
  268. data/vendor/carrierwave/features/file_storage_reversing_processor.feature +43 -0
  269. data/vendor/carrierwave/features/fixtures/bork.txt +1 -0
  270. data/vendor/carrierwave/features/fixtures/monkey.txt +1 -0
  271. data/vendor/carrierwave/features/fixtures/upcased_bork.txt +1 -0
  272. data/vendor/carrierwave/features/mount_activerecord.feature +46 -0
  273. data/vendor/carrierwave/features/step_definitions/activerecord_steps.rb +20 -0
  274. data/vendor/carrierwave/features/step_definitions/caching_steps.rb +12 -0
  275. data/vendor/carrierwave/features/step_definitions/datamapper_steps.rb +27 -0
  276. data/vendor/carrierwave/features/step_definitions/download_steps.rb +8 -0
  277. data/vendor/carrierwave/features/step_definitions/file_steps.rb +51 -0
  278. data/vendor/carrierwave/features/step_definitions/general_steps.rb +102 -0
  279. data/vendor/carrierwave/features/step_definitions/mount_steps.rb +17 -0
  280. data/vendor/carrierwave/features/step_definitions/store_steps.rb +16 -0
  281. data/vendor/carrierwave/features/support/activerecord.rb +18 -0
  282. data/vendor/carrierwave/features/support/env.rb +19 -0
  283. data/vendor/carrierwave/features/versions_basics.feature +50 -0
  284. data/vendor/carrierwave/features/versions_caching_from_versions.feature +32 -0
  285. data/vendor/carrierwave/features/versions_nested_versions.feature +70 -0
  286. data/vendor/carrierwave/features/versions_overridden_filename.feature +51 -0
  287. data/vendor/carrierwave/features/versions_overriden_store_dir.feature +41 -0
  288. data/vendor/carrierwave/gemfiles/rails-4-0-stable.gemfile +5 -0
  289. data/vendor/carrierwave/gemfiles/rails-4-1-stable.gemfile +5 -0
  290. data/vendor/carrierwave/gemfiles/rails-4-2-stable.gemfile +5 -0
  291. data/vendor/carrierwave/gemfiles/rails-master.gemfile +11 -0
  292. data/vendor/carrierwave/lib/carrierwave.rb +93 -0
  293. data/vendor/carrierwave/lib/carrierwave/compatibility/paperclip.rb +103 -0
  294. data/vendor/carrierwave/lib/carrierwave/error.rb +8 -0
  295. data/vendor/carrierwave/lib/carrierwave/locale/cs.yml +14 -0
  296. data/vendor/carrierwave/lib/carrierwave/locale/de.yml +14 -0
  297. data/vendor/carrierwave/lib/carrierwave/locale/el.yml +14 -0
  298. data/vendor/carrierwave/lib/carrierwave/locale/en.yml +14 -0
  299. data/vendor/carrierwave/lib/carrierwave/locale/es.yml +14 -0
  300. data/vendor/carrierwave/lib/carrierwave/locale/fr-CA.yml +14 -0
  301. data/vendor/carrierwave/lib/carrierwave/locale/fr.yml +14 -0
  302. data/vendor/carrierwave/lib/carrierwave/locale/id.yml +14 -0
  303. data/vendor/carrierwave/lib/carrierwave/locale/ja.yml +14 -0
  304. data/vendor/carrierwave/lib/carrierwave/locale/nb.yml +14 -0
  305. data/vendor/carrierwave/lib/carrierwave/locale/nl.yml +14 -0
  306. data/vendor/carrierwave/lib/carrierwave/locale/pl.yml +14 -0
  307. data/vendor/carrierwave/lib/carrierwave/locale/pt-BR.yml +14 -0
  308. data/vendor/carrierwave/lib/carrierwave/locale/pt-PT.yml +14 -0
  309. data/vendor/carrierwave/lib/carrierwave/locale/ru.yml +14 -0
  310. data/vendor/carrierwave/lib/carrierwave/locale/sk.yml +14 -0
  311. data/vendor/carrierwave/lib/carrierwave/locale/tr.yml +14 -0
  312. data/vendor/carrierwave/lib/carrierwave/locale/zh-CN.yml +14 -0
  313. data/vendor/carrierwave/lib/carrierwave/locale/zh-TW.yml +14 -0
  314. data/vendor/carrierwave/lib/carrierwave/mount.rb +444 -0
  315. data/vendor/carrierwave/lib/carrierwave/mounter.rb +163 -0
  316. data/vendor/carrierwave/lib/carrierwave/orm/activerecord.rb +103 -0
  317. data/vendor/carrierwave/lib/carrierwave/processing.rb +2 -0
  318. data/vendor/carrierwave/lib/carrierwave/processing/mini_magick.rb +328 -0
  319. data/vendor/carrierwave/lib/carrierwave/processing/rmagick.rb +379 -0
  320. data/vendor/carrierwave/lib/carrierwave/sanitized_file.rb +348 -0
  321. data/vendor/carrierwave/lib/carrierwave/storage.rb +2 -0
  322. data/vendor/carrierwave/lib/carrierwave/storage/abstract.rb +43 -0
  323. data/vendor/carrierwave/lib/carrierwave/storage/file.rb +118 -0
  324. data/vendor/carrierwave/lib/carrierwave/storage/fog.rb +462 -0
  325. data/vendor/carrierwave/lib/carrierwave/test/matchers.rb +394 -0
  326. data/vendor/carrierwave/lib/carrierwave/uploader.rb +67 -0
  327. data/vendor/carrierwave/lib/carrierwave/uploader/cache.rb +207 -0
  328. data/vendor/carrierwave/lib/carrierwave/uploader/callbacks.rb +33 -0
  329. data/vendor/carrierwave/lib/carrierwave/uploader/configuration.rb +203 -0
  330. data/vendor/carrierwave/lib/carrierwave/uploader/content_type_blacklist.rb +48 -0
  331. data/vendor/carrierwave/lib/carrierwave/uploader/content_type_whitelist.rb +48 -0
  332. data/vendor/carrierwave/lib/carrierwave/uploader/default_url.rb +17 -0
  333. data/vendor/carrierwave/lib/carrierwave/uploader/download.rb +92 -0
  334. data/vendor/carrierwave/lib/carrierwave/uploader/extension_blacklist.rb +51 -0
  335. data/vendor/carrierwave/lib/carrierwave/uploader/extension_whitelist.rb +51 -0
  336. data/vendor/carrierwave/lib/carrierwave/uploader/file_size.rb +41 -0
  337. data/vendor/carrierwave/lib/carrierwave/uploader/magic_mime_blacklist.rb +94 -0
  338. data/vendor/carrierwave/lib/carrierwave/uploader/magic_mime_whitelist.rb +94 -0
  339. data/vendor/carrierwave/lib/carrierwave/uploader/mountable.rb +38 -0
  340. data/vendor/carrierwave/lib/carrierwave/uploader/processing.rb +88 -0
  341. data/vendor/carrierwave/lib/carrierwave/uploader/proxy.rb +86 -0
  342. data/vendor/carrierwave/lib/carrierwave/uploader/remove.rb +21 -0
  343. data/vendor/carrierwave/lib/carrierwave/uploader/serialization.rb +28 -0
  344. data/vendor/carrierwave/lib/carrierwave/uploader/store.rb +93 -0
  345. data/vendor/carrierwave/lib/carrierwave/uploader/url.rb +41 -0
  346. data/vendor/carrierwave/lib/carrierwave/uploader/versions.rb +295 -0
  347. data/vendor/carrierwave/lib/carrierwave/utilities.rb +6 -0
  348. data/vendor/carrierwave/lib/carrierwave/utilities/uri.rb +21 -0
  349. data/vendor/carrierwave/lib/carrierwave/validations/active_model.rb +78 -0
  350. data/vendor/carrierwave/lib/carrierwave/version.rb +3 -0
  351. data/vendor/carrierwave/lib/generators/templates/uploader.rb +49 -0
  352. data/vendor/carrierwave/lib/generators/uploader_generator.rb +7 -0
  353. data/vendor/carrierwave/script/console +10 -0
  354. data/vendor/carrierwave/script/destroy +14 -0
  355. data/vendor/carrierwave/script/generate +14 -0
  356. data/vendor/carrierwave/spec/compatibility/paperclip_spec.rb +138 -0
  357. data/vendor/carrierwave/spec/fixtures/Uppercase.jpg +1 -0
  358. data/vendor/carrierwave/spec/fixtures/bork.ttxt +1 -0
  359. data/vendor/carrierwave/spec/fixtures/bork.txt +1 -0
  360. data/vendor/carrierwave/spec/fixtures/bork.txtt +1 -0
  361. data/vendor/carrierwave/spec/fixtures/case.JPG +1 -0
  362. data/vendor/carrierwave/spec/fixtures/landscape.jpg +0 -0
  363. data/vendor/carrierwave/spec/fixtures/multi_page.pdf +0 -0
  364. data/vendor/carrierwave/spec/fixtures/new.jpeg +1 -0
  365. data/vendor/carrierwave/spec/fixtures/new.txt +1 -0
  366. data/vendor/carrierwave/spec/fixtures/old.jpeg +1 -0
  367. data/vendor/carrierwave/spec/fixtures/old.txt +1 -0
  368. data/vendor/carrierwave/spec/fixtures/portrait.jpg +0 -0
  369. data/vendor/carrierwave/spec/fixtures/ruby.gif +0 -0
  370. data/vendor/carrierwave/spec/fixtures/sponsored.doc +1 -0
  371. data/vendor/carrierwave/spec/fixtures/test+.jpg +1 -0
  372. data/vendor/carrierwave/spec/fixtures/test.jpeg +1 -0
  373. data/vendor/carrierwave/spec/fixtures/test.jpg +1 -0
  374. data/vendor/carrierwave/spec/generators/uploader_generator_spec.rb +19 -0
  375. data/vendor/carrierwave/spec/mount_multiple_spec.rb +913 -0
  376. data/vendor/carrierwave/spec/mount_single_spec.rb +793 -0
  377. data/vendor/carrierwave/spec/orm/activerecord_spec.rb +1556 -0
  378. data/vendor/carrierwave/spec/processing/mini_magick_spec.rb +210 -0
  379. data/vendor/carrierwave/spec/processing/rmagick_spec.rb +250 -0
  380. data/vendor/carrierwave/spec/sanitized_file_spec.rb +805 -0
  381. data/vendor/carrierwave/spec/spec_helper.rb +105 -0
  382. data/vendor/carrierwave/spec/storage/file_spec.rb +82 -0
  383. data/vendor/carrierwave/spec/storage/fog_credentials.rb +46 -0
  384. data/vendor/carrierwave/spec/storage/fog_helper.rb +428 -0
  385. data/vendor/carrierwave/spec/storage/fog_spec.rb +48 -0
  386. data/vendor/carrierwave/spec/support/activerecord.rb +31 -0
  387. data/vendor/carrierwave/spec/support/file_utils_helper.rb +15 -0
  388. data/vendor/carrierwave/spec/uploader/cache_spec.rb +324 -0
  389. data/vendor/carrierwave/spec/uploader/callback_spec.rb +30 -0
  390. data/vendor/carrierwave/spec/uploader/configuration_spec.rb +133 -0
  391. data/vendor/carrierwave/spec/uploader/content_type_blacklist_spec.rb +61 -0
  392. data/vendor/carrierwave/spec/uploader/content_type_whitelist_spec.rb +63 -0
  393. data/vendor/carrierwave/spec/uploader/default_url_spec.rb +77 -0
  394. data/vendor/carrierwave/spec/uploader/download_spec.rb +204 -0
  395. data/vendor/carrierwave/spec/uploader/extension_blacklist_spec.rb +112 -0
  396. data/vendor/carrierwave/spec/uploader/extension_whitelist_spec.rb +102 -0
  397. data/vendor/carrierwave/spec/uploader/file_size_spec.rb +52 -0
  398. data/vendor/carrierwave/spec/uploader/mountable_spec.rb +26 -0
  399. data/vendor/carrierwave/spec/uploader/overrides_spec.rb +71 -0
  400. data/vendor/carrierwave/spec/uploader/paths_spec.rb +18 -0
  401. data/vendor/carrierwave/spec/uploader/processing_spec.rb +159 -0
  402. data/vendor/carrierwave/spec/uploader/proxy_spec.rb +79 -0
  403. data/vendor/carrierwave/spec/uploader/remove_spec.rb +71 -0
  404. data/vendor/carrierwave/spec/uploader/store_spec.rb +400 -0
  405. data/vendor/carrierwave/spec/uploader/url_spec.rb +273 -0
  406. data/vendor/carrierwave/spec/uploader/versions_spec.rb +633 -0
  407. metadata +339 -187
  408. data/config/initializers/extensions.rb +0 -3
  409. data/mod/05_standard/file/favicon/image-icon.png +0 -0
  410. data/mod/05_standard/file/favicon/image-large.png +0 -0
  411. data/mod/05_standard/file/favicon/image-medium.png +0 -0
  412. data/mod/05_standard/file/favicon/image-original.png +0 -0
  413. data/mod/05_standard/file/favicon/image-small.png +0 -0
  414. data/mod/machines/lib/card/machine.rb +0 -261
  415. data/mod/machines/lib/card/machine_input.rb +0 -80
  416. data/mod/standard/file/credit/icon-image.png +0 -0
  417. data/mod/standard/file/credit/large-image.png +0 -0
  418. data/mod/standard/file/credit/medium-image.png +0 -0
  419. data/mod/standard/file/credit/original-image.png +0 -0
  420. data/mod/standard/file/credit/small-image.png +0 -0
  421. data/mod/standard/spec/set/type/file_spec.rb +0 -99
  422. data/tmpsets/set/mod001-core/all/tracked_attributes.rb +0 -154
  423. data/tmpsets/set/mod001-core/all/utils.rb +0 -132
  424. data/tmpsets/set/mod013-carrierwave/abstract/attachment.rb +0 -282
@@ -0,0 +1,1556 @@
1
+ require 'spec_helper'
2
+ require 'support/activerecord'
3
+
4
+ def create_table(name)
5
+ ActiveRecord::Base.connection.create_table(name, force: true) do |t|
6
+ t.column :image, :string
7
+ t.column :images, :json
8
+ t.column :textfile, :string
9
+ t.column :textfiles, :json
10
+ t.column :foo, :string
11
+ end
12
+ end
13
+
14
+ def drop_table(name)
15
+ ActiveRecord::Base.connection.drop_table(name)
16
+ end
17
+
18
+ def reset_class(class_name)
19
+ Object.send(:remove_const, class_name) rescue nil
20
+ Object.const_set(class_name, Class.new(ActiveRecord::Base))
21
+ end
22
+
23
+ describe CarrierWave::ActiveRecord do
24
+ before(:all) { create_table("events") }
25
+ after(:all) { drop_table("events") }
26
+
27
+ before do
28
+ @uploader = Class.new(CarrierWave::Uploader::Base)
29
+ reset_class("Event")
30
+ @event = Event.new
31
+ end
32
+
33
+ after do
34
+ Event.delete_all
35
+ end
36
+
37
+ describe '#mount_uploader' do
38
+ before do
39
+ Event.mount_uploader(:image, @uploader)
40
+ end
41
+
42
+ describe '#image' do
43
+
44
+ it "should return blank uploader when nothing has been assigned" do
45
+ expect(@event.image).to be_blank
46
+ end
47
+
48
+ it "should return blank uploader when an empty string has been assigned" do
49
+ @event[:image] = ''
50
+ @event.save!
51
+ @event.reload
52
+ expect(@event.image).to be_blank
53
+ end
54
+
55
+ it "should retrieve a file from the storage if a value is stored in the database" do
56
+ @event[:image] = 'test.jpeg'
57
+ @event.save!
58
+ @event.reload
59
+ expect(@event.image).to be_an_instance_of(@uploader)
60
+ end
61
+
62
+ it "should set the path to the store dir" do
63
+ @event[:image] = 'test.jpeg'
64
+ @event.save!
65
+ @event.reload
66
+ expect(@event.image.current_path).to eq public_path('uploads/test.jpeg')
67
+ end
68
+
69
+ it "should return valid JSON when to_json is called when image is nil" do
70
+ expect(@event[:image]).to be_nil
71
+ hash = JSON.parse(@event.to_json)
72
+ expect(hash.keys).to include("image")
73
+ expect(hash["image"].keys).to include("url")
74
+ expect(hash["image"]["url"]).to be_nil
75
+ end
76
+
77
+ it "should return valid JSON when to_json is called when image is present" do
78
+ @event[:image] = 'test.jpeg'
79
+ @event.save!
80
+ @event.reload
81
+
82
+ expect(JSON.parse(@event.to_json)["image"]).to eq({"url" => "/uploads/test.jpeg"})
83
+ end
84
+
85
+ it "should return valid JSON when to_json is called on a collection containing uploader from a model" do
86
+ @event[:image] = 'test.jpeg'
87
+ @event.save!
88
+ @event.reload
89
+
90
+ expect(JSON.parse({:data => @event.image}.to_json)).to eq({"data"=>{"url"=>"/uploads/test.jpeg"}})
91
+ end
92
+
93
+ it "should return valid XML when to_xml is called when image is nil" do
94
+ hash = Hash.from_xml(@event.to_xml)["event"]
95
+
96
+ expect(@event[:image]).to be_nil
97
+ expect(hash.keys).to include("image")
98
+ expect(hash["image"].keys).to include("url")
99
+ expect(hash["image"]["url"]).to be_nil
100
+ end
101
+
102
+ it "should return valid XML when to_xml is called when image is present" do
103
+ @event[:image] = 'test.jpeg'
104
+ @event.save!
105
+ @event.reload
106
+
107
+ expect(Hash.from_xml(@event.to_xml)["event"]["image"]).to eq({"url" => "/uploads/test.jpeg"})
108
+ end
109
+
110
+ it "should respect options[:only] when passed to as_json for the serializable hash" do
111
+ @event[:image] = 'test.jpeg'
112
+ @event.save!
113
+ @event.reload
114
+
115
+ expect(@event.as_json(:only => [:foo])).to eq({"foo" => nil})
116
+ end
117
+
118
+ it "should respect options[:except] when passed to as_json for the serializable hash" do
119
+ @event[:image] = 'test.jpeg'
120
+ @event.save!
121
+ @event.reload
122
+
123
+ expect(@event.as_json(:except => [:id, :image, :images, :textfiles, :foo])).to eq({"textfile" => nil})
124
+ end
125
+ it "should respect both options[:only] and options[:except] when passed to as_json for the serializable hash" do
126
+ @event[:image] = 'test.jpeg'
127
+ @event.save!
128
+ @event.reload
129
+
130
+ expect(@event.as_json(:only => [:foo], :except => [:id])).to eq({"foo" => nil})
131
+ end
132
+
133
+ it "should respect options[:only] when passed to to_xml for the serializable hash" do
134
+ @event[:image] = 'test.jpeg'
135
+ @event.save!
136
+ @event.reload
137
+
138
+ expect(Hash.from_xml(@event.to_xml(only: [:foo]))["event"]["image"]).to be_nil
139
+ end
140
+
141
+ it "should respect options[:except] when passed to to_xml for the serializable hash" do
142
+ @event[:image] = 'test.jpeg'
143
+ @event.save!
144
+ @event.reload
145
+
146
+ expect(Hash.from_xml(@event.to_xml(except: [:image]))["event"]["image"]).to be_nil
147
+ end
148
+
149
+ it "should respect both options[:only] and options[:except] when passed to to_xml for the serializable hash" do
150
+ @event[:image] = 'test.jpeg'
151
+ @event.save!
152
+ @event.reload
153
+
154
+ expect(Hash.from_xml(@event.to_xml(only: [:foo], except: [:id]))["event"]["image"]).to be_nil
155
+ end
156
+
157
+ it "resets cached value on record reload" do
158
+ @event.image = CarrierWave::SanitizedFile.new(stub_file('new.jpeg', 'image/jpeg'))
159
+ @event.save!
160
+
161
+ expect(@event.reload.image).to be_present
162
+
163
+ Event.find(@event.id).update_column(:image, nil)
164
+
165
+ expect(@event.reload.image).to be_blank
166
+ end
167
+ end
168
+
169
+ describe '#image=' do
170
+
171
+ it "should cache a file" do
172
+ @event.image = stub_file('test.jpeg')
173
+ expect(@event.image).to be_an_instance_of(@uploader)
174
+ end
175
+
176
+ it "should write nothing to the database, to prevent overriden filenames to fail because of unassigned attributes" do
177
+ expect(@event[:image]).to be_nil
178
+ end
179
+
180
+ it "should copy a file into the cache directory" do
181
+ @event.image = stub_file('test.jpeg')
182
+ expect(@event.image.current_path).to match(%r(^#{public_path('uploads/tmp')}))
183
+ end
184
+
185
+ context "when empty string is assigned" do
186
+ it "does nothing when" do
187
+ @event.image = ''
188
+ expect(@event.image).to be_blank
189
+ end
190
+
191
+ context "and the previous value was an empty string" do
192
+ before do
193
+ @event.image = ""
194
+ @event.save
195
+ end
196
+
197
+ it "does not write to dirty changes" do
198
+ @event.image = ''
199
+ expect(@event.changes.keys).not_to include("image")
200
+ end
201
+ end
202
+
203
+ end
204
+
205
+ context "when nil is assigned" do
206
+ it "does nothing" do
207
+ @event.image = nil
208
+ expect(@event.image).to be_blank
209
+ end
210
+
211
+ context "and the previous value was nil" do
212
+ before do
213
+ @event.image = nil
214
+ @event.save
215
+ end
216
+
217
+ it "does not write to dirty changes" do
218
+ @event.image = nil
219
+ expect(@event.changes.keys).not_to include("image")
220
+ end
221
+ end
222
+ end
223
+
224
+
225
+ context 'when validating white list integrity' do
226
+ before do
227
+ @uploader.class_eval do
228
+ def extension_whitelist
229
+ %w(txt)
230
+ end
231
+ end
232
+ end
233
+
234
+ it "should use I18n for integrity error messages" do
235
+ # Localize the error message to Dutch
236
+ change_locale_and_store_translations(:nl, :errors => {
237
+ :messages => {
238
+ :extension_whitelist_error => "Het opladen van %{extension} bestanden is niet toe gestaan. Geaccepteerde types: %{allowed_types}"
239
+ }
240
+ }) do
241
+ # Assigning image triggers check_whitelist! and thus should be inside change_locale_and_store_translations
242
+ @event.image = stub_file('test.jpg')
243
+ expect(@event).to_not be_valid
244
+ @event.valid?
245
+ expect(@event.errors[:image]).to eq (['Het opladen van "jpg" bestanden is niet toe gestaan. Geaccepteerde types: txt'])
246
+ end
247
+ end
248
+ end
249
+
250
+ context 'when validating black list integrity' do
251
+ before do
252
+ @uploader.class_eval do
253
+ def extension_blacklist
254
+ %w(jpg)
255
+ end
256
+ end
257
+ end
258
+
259
+ it "should use I18n for integrity error messages" do
260
+ # Localize the error message to Dutch
261
+ change_locale_and_store_translations(:nl, :errors => {
262
+ :messages => {
263
+ :extension_blacklist_error => "You are not allowed to upload %{extension} files, prohibited types: %{prohibited_types}"
264
+ }
265
+ }) do
266
+ # Assigning image triggers check_blacklist! and thus should be inside change_locale_and_store_translations
267
+ @event.image = stub_file('test.jpg')
268
+ expect(@event).to_not be_valid
269
+ @event.valid?
270
+ expect(@event.errors[:image]).to eq(['You are not allowed to upload "jpg" files, prohibited types: jpg'])
271
+ end
272
+ end
273
+ end
274
+
275
+
276
+ context 'when validating processing' do
277
+ before do
278
+ @uploader.class_eval do
279
+ process :monkey
280
+ def monkey
281
+ raise CarrierWave::ProcessingError
282
+ end
283
+ end
284
+ @event.image = stub_file('test.jpg')
285
+ end
286
+
287
+ it "should make the record invalid when a processing error occurs" do
288
+ expect(@event).to_not be_valid
289
+ end
290
+
291
+ it "should use I18n for processing errors without messages" do
292
+ @event.valid?
293
+ expect(@event.errors[:image]).to eq(['failed to be processed'])
294
+
295
+ change_locale_and_store_translations(:pt, :activerecord => {
296
+ :errors => {
297
+ :messages => {
298
+ :carrierwave_processing_error => 'falha ao processar imagem.'
299
+ }
300
+ }
301
+ }) do
302
+ expect(@event).to_not be_valid
303
+ expect(@event.errors[:image]).to eq(['falha ao processar imagem.'])
304
+ end
305
+ end
306
+ end
307
+
308
+ context 'when validating processing' do
309
+ before do
310
+ @uploader.class_eval do
311
+ process :monkey
312
+ def monkey
313
+ raise CarrierWave::ProcessingError, "Ohh noez!"
314
+ end
315
+ end
316
+ @event.image = stub_file('test.jpg')
317
+ end
318
+
319
+ it "should make the record invalid when a processing error occurs" do
320
+ expect(@event).to_not be_valid
321
+ end
322
+
323
+ it "should use the error's messages for processing errors with messages" do
324
+ @event.valid?
325
+ expect(@event.errors[:image]).to eq(['Ohh noez!'])
326
+
327
+ change_locale_and_store_translations(:pt, :activerecord => {
328
+ :errors => {
329
+ :messages => {
330
+ :carrierwave_processing_error => 'falha ao processar imagem.'
331
+ }
332
+ }
333
+ }) do
334
+ expect(@event).to_not be_valid
335
+ expect(@event.errors[:image]).to eq(['Ohh noez!'])
336
+ end
337
+ end
338
+ end
339
+ end
340
+
341
+ describe '#save' do
342
+
343
+ it "should do nothing when no file has been assigned" do
344
+ expect(@event.save).to be_truthy
345
+ expect(@event.image).to be_blank
346
+ end
347
+
348
+ it "should copy the file to the upload directory when a file has been assigned" do
349
+ @event.image = stub_file('test.jpeg')
350
+ expect(@event.save).to be_truthy
351
+ expect(@event.image).to be_an_instance_of(@uploader)
352
+ expect(@event.image.current_path).to eq public_path('uploads/test.jpeg')
353
+ end
354
+
355
+ it "should do nothing when a validation fails" do
356
+ Event.validate { |r| r.errors.add :textfile, "FAIL!" }
357
+ @event.image = stub_file('test.jpeg')
358
+
359
+ expect(@event.save).to be_falsey
360
+ expect(@event.image).to be_an_instance_of(@uploader)
361
+ expect(@event.image.current_path).to match(/^#{public_path('uploads/tmp')}/)
362
+ end
363
+
364
+ it "should assign the filename to the database" do
365
+ @event.image = stub_file('test.jpeg')
366
+ expect(@event.save).to be_truthy
367
+ @event.reload
368
+ expect(@event[:image]).to eq('test.jpeg')
369
+ expect(@event.image_identifier).to eq('test.jpeg')
370
+ end
371
+
372
+ it "should preserve the image when nothing is assigned" do
373
+ @event.image = stub_file('test.jpeg')
374
+ expect(@event.save).to be_truthy
375
+
376
+ @event = Event.find(@event.id)
377
+ @event.foo = "bar"
378
+
379
+ expect(@event.save).to be_truthy
380
+ expect(@event[:image]).to eq('test.jpeg')
381
+ expect(@event.image_identifier).to eq('test.jpeg')
382
+ end
383
+
384
+ it "should remove the image if remove_image? returns true" do
385
+ @event.image = stub_file('test.jpeg')
386
+ @event.save!
387
+ @event.remove_image = true
388
+ @event.save!
389
+ @event.reload
390
+ expect(@event.image).to be_blank
391
+ expect(@event[:image]).to eq(nil)
392
+ expect(@event.image_identifier).to eq(nil)
393
+ end
394
+
395
+ it "should mark image as changed when saving a new image" do
396
+ expect(@event.image_changed?).to be_falsey
397
+ @event.image = stub_file("test.jpeg")
398
+ expect(@event.image_changed?).to be_truthy
399
+ @event.save
400
+ @event.reload
401
+ expect(@event.image_changed?).to be_falsey
402
+ @event.image = stub_file("test.jpg")
403
+ expect(@event.image_changed?).to be_truthy
404
+ expect(@event.changed_for_autosave?).to be_truthy
405
+ end
406
+ end
407
+
408
+ describe "image?" do
409
+ it "returns true when the file is cached" do
410
+ @event.image = stub_file('test.jpg')
411
+
412
+ expect(@event.image?).to be_truthy
413
+ end
414
+
415
+ it "returns false when the file is removed" do
416
+ @event.remove_image!
417
+ @event.save!
418
+
419
+ expect(@event.image?).to be_falsey
420
+ end
421
+
422
+ it "returns true when the file is stored" do
423
+ @event.image = stub_file('test.jpg')
424
+ @event.save!
425
+
426
+ expect(@event.image?).to be_truthy
427
+ end
428
+
429
+ it "returns true when a file is removed and stored again" do
430
+ @event.image = stub_file('test.jpeg')
431
+ @event.save!
432
+ @event.remove_image!
433
+ @event.save!
434
+ @event.image = stub_file('test.jpeg')
435
+ @event.save!
436
+
437
+ expect(@event.image?).to be_truthy
438
+ end
439
+ end
440
+
441
+ describe "remove_image!" do
442
+ before do
443
+ @event.image = stub_file('test.jpeg')
444
+ @event.save!
445
+ end
446
+
447
+ it "should clear the serialization column" do
448
+ @event.remove_image!
449
+
450
+ expect(@event.attributes['image']).to be_blank
451
+ end
452
+
453
+ it "resets remove_image? to false" do
454
+ @event.remove_image = true
455
+
456
+ expect {
457
+ @event.remove_image!
458
+ }.to change {
459
+ @event.remove_image?
460
+ }.from(true).to(false)
461
+ end
462
+ end
463
+
464
+ describe "remove_image=" do
465
+ it "should mark the image as changed if changed" do
466
+ expect(@event.image_changed?).to be_falsey
467
+ expect(@event.remove_image).to be_nil
468
+ @event.remove_image = "1"
469
+ expect(@event.image_changed?).to be_truthy
470
+ end
471
+ end
472
+
473
+ describe "#remote_image_url=" do
474
+ before do
475
+ stub_request(:get, "www.example.com/test.jpg").to_return(body: File.read(file_path("test.jpg")))
476
+ end
477
+
478
+ # FIXME ideally image_changed? and remote_image_url_changed? would return true
479
+ it "should mark image as changed when setting remote_image_url" do
480
+ expect(@event.image_changed?).to be_falsey
481
+ @event.remote_image_url = 'http://www.example.com/test.jpg'
482
+ expect(@event.image_changed?).to be_truthy
483
+ @event.save!
484
+ @event.reload
485
+ expect(@event.image_changed?).to be_falsey
486
+ end
487
+
488
+ context 'when validating download' do
489
+ before do
490
+ @uploader.class_eval do
491
+ def download! file
492
+ raise CarrierWave::DownloadError
493
+ end
494
+ end
495
+ @event.remote_image_url = 'http://www.example.com/missing.jpg'
496
+ end
497
+
498
+ it "should make the record invalid when a download error occurs" do
499
+ expect(@event).to_not be_valid
500
+ end
501
+
502
+ it "should use I18n for download errors without messages" do
503
+ @event.valid?
504
+ expect(@event.errors[:image]).to eq(['could not be downloaded'])
505
+
506
+ change_locale_and_store_translations(:pt, :activerecord => {
507
+ :errors => {
508
+ :messages => {
509
+ :carrierwave_download_error => 'não pode ser descarregado'
510
+ }
511
+ }
512
+ }) do
513
+ expect(@event).to_not be_valid
514
+ expect(@event.errors[:image]).to eq(['não pode ser descarregado'])
515
+ end
516
+ end
517
+ end
518
+
519
+ end
520
+
521
+ describe '#destroy' do
522
+
523
+ it "should not raise an error with a custom filename" do
524
+ @uploader.class_eval do
525
+ def filename
526
+ "page.jpeg"
527
+ end
528
+ end
529
+
530
+ @event.image = stub_file('test.jpeg')
531
+ expect(@event.save).to be_truthy
532
+ expect {
533
+ @event.destroy
534
+ }.to_not raise_error
535
+ end
536
+
537
+ it "should do nothing when no file has been assigned" do
538
+ expect(@event.save).to be_truthy
539
+ @event.destroy
540
+ end
541
+
542
+ it "should remove the file from the filesystem" do
543
+ @event.image = stub_file('test.jpeg')
544
+ expect(@event.save).to be_truthy
545
+ expect(@event.image).to be_an_instance_of(@uploader)
546
+ expect(@event.image.current_path).to eq public_path('uploads/test.jpeg')
547
+ @event.destroy
548
+ expect(File.exist?(public_path('uploads/test.jpeg'))).to be_falsey
549
+ end
550
+
551
+ end
552
+
553
+ describe 'with overriddent filename' do
554
+
555
+ describe '#save' do
556
+
557
+ before do
558
+ @uploader.class_eval do
559
+ def filename
560
+ model.name + File.extname(super)
561
+ end
562
+ end
563
+ allow(@event).to receive(:name).and_return('jonas')
564
+ end
565
+
566
+ it "should copy the file to the upload directory when a file has been assigned" do
567
+ @event.image = stub_file('test.jpeg')
568
+ expect(@event.save).to be_truthy
569
+ expect(@event.image).to be_an_instance_of(@uploader)
570
+ expect(@event.image.current_path).to eq(public_path('uploads/jonas.jpeg'))
571
+ end
572
+
573
+ it "should assign an overridden filename to the database" do
574
+ @event.image = stub_file('test.jpeg')
575
+ expect(@event.save).to be_truthy
576
+ @event.reload
577
+ expect(@event[:image]).to eq('jonas.jpeg')
578
+ end
579
+
580
+ end
581
+
582
+ end
583
+
584
+ describe 'with validates_presence_of' do
585
+
586
+ before do
587
+ Event.validates_presence_of :image
588
+ allow(@event).to receive(:name).and_return('jonas')
589
+ end
590
+
591
+ it "should be valid if a file has been cached" do
592
+ @event.image = stub_file('test.jpeg')
593
+ expect(@event).to be_valid
594
+ end
595
+
596
+ it "should not be valid if a file has not been cached" do
597
+ expect(@event).to_not be_valid
598
+ end
599
+
600
+ end
601
+
602
+ describe 'with validates_size_of' do
603
+
604
+ before do
605
+ Event.validates_size_of :image, maximum: 40
606
+ allow(@event).to receive(:name).and_return('jonas')
607
+ end
608
+
609
+ it "should be valid if a file has been cached that matches the size criteria" do
610
+ @event.image = stub_file('test.jpeg')
611
+ expect(@event).to be_valid
612
+ end
613
+
614
+ it "should not be valid if a file has been cached that does not match the size criteria" do
615
+ @event.image = stub_file('bork.txt')
616
+ expect(@event).to_not be_valid
617
+ end
618
+
619
+ end
620
+ end
621
+
622
+ describe '#mount_uploader with mount_on' do
623
+ describe '#avatar=' do
624
+ it "should cache a file" do
625
+ reset_class("Event")
626
+ Event.mount_uploader(:avatar, @uploader, mount_on: :image)
627
+ @event = Event.new
628
+ @event.avatar = stub_file('test.jpeg')
629
+ @event.save
630
+ @event.reload
631
+
632
+ expect(@event.avatar).to be_an_instance_of(@uploader)
633
+ expect(@event.image).to eq('test.jpeg')
634
+ end
635
+
636
+ end
637
+ end
638
+
639
+ describe '#mount_uploader removing old files' do
640
+ before do
641
+ reset_class("Event")
642
+ Event.mount_uploader(:image, @uploader)
643
+ @event = Event.new
644
+ @event.image = stub_file('old.jpeg')
645
+
646
+ expect(@event.save).to be_truthy
647
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_truthy
648
+ end
649
+
650
+ after do
651
+ FileUtils.rm_rf(file_path("uploads"))
652
+ end
653
+
654
+ describe 'normally' do
655
+ it "should remove old file if old file had a different path" do
656
+ @event.image = stub_file('new.jpeg')
657
+ expect(@event.save).to be_truthy
658
+ expect(File.exist?(public_path('uploads/new.jpeg'))).to be_truthy
659
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_falsey
660
+ end
661
+
662
+ it "should not remove old file if old file had a different path but config is false" do
663
+ @uploader.remove_previously_stored_files_after_update = false
664
+ @event.image = stub_file('new.jpeg')
665
+ expect(@event.save).to be_truthy
666
+ expect(File.exist?(public_path('uploads/new.jpeg'))).to be_truthy
667
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_truthy
668
+ end
669
+
670
+ it "should not remove file if old file had the same path" do
671
+ @event.image = stub_file('old.jpeg')
672
+ expect(@event.save).to be_truthy
673
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_truthy
674
+ end
675
+
676
+ it "should not remove file if validations fail on save" do
677
+ Event.validate { |r| r.errors.add :textfile, "FAIL!" }
678
+ @event.image = stub_file('new.jpeg')
679
+
680
+ expect(@event.save).to be_falsey
681
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_truthy
682
+ end
683
+
684
+ pending do
685
+ it "should only delete the file once when the file is removed" do
686
+ @event.remove_image = true
687
+ expect_any_instance_of(CarrierWave::SanitizedFile).to receive(:delete).exactly(1).times
688
+ expect(@event.save).to be_truthy
689
+ end
690
+ end
691
+ end
692
+
693
+ describe 'with an overriden filename' do
694
+ before do
695
+ @uploader.class_eval do
696
+ def filename
697
+ model.foo + File.extname(super)
698
+ end
699
+ end
700
+
701
+ @event.image = stub_file('old.jpeg')
702
+ @event.foo = 'test'
703
+ expect(@event.save).to be_truthy
704
+ expect(File.exist?(public_path('uploads/test.jpeg'))).to be_truthy
705
+ expect(@event.image.read).to eq('this is stuff')
706
+ end
707
+
708
+ it "should not remove file if old file had the same dynamic path" do
709
+ @event.image = stub_file('test.jpeg')
710
+ expect(@event.save).to be_truthy
711
+ expect(File.exist?(public_path('uploads/test.jpeg'))).to be_truthy
712
+ end
713
+
714
+ it "should remove old file if old file had a different dynamic path" do
715
+ @event.foo = "new"
716
+ @event.image = stub_file('test.jpeg')
717
+ expect(@event.save).to be_truthy
718
+ expect(File.exist?(public_path('uploads/new.jpeg'))).to be_truthy
719
+ expect(File.exist?(public_path('uploads/test.jpeg'))).to be_falsey
720
+ end
721
+ end
722
+ end
723
+
724
+ describe '#mount_uploader removing old files with versions' do
725
+ before do
726
+ @uploader.version :thumb
727
+ reset_class("Event")
728
+ Event.mount_uploader(:image, @uploader)
729
+ @event = Event.new
730
+ @event.image = stub_file('old.jpeg')
731
+
732
+ expect(@event.save).to be_truthy
733
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_truthy
734
+ expect(File.exist?(public_path('uploads/thumb_old.jpeg'))).to be_truthy
735
+ end
736
+
737
+ after do
738
+ FileUtils.rm_rf(file_path("uploads"))
739
+ end
740
+
741
+ it "should remove old file if old file had a different path" do
742
+ @event.image = stub_file('new.jpeg')
743
+ expect(@event.save).to be_truthy
744
+ expect(File.exist?(public_path('uploads/new.jpeg'))).to be_truthy
745
+ expect(File.exist?(public_path('uploads/thumb_new.jpeg'))).to be_truthy
746
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_falsey
747
+ expect(File.exist?(public_path('uploads/thumb_old.jpeg'))).to be_falsey
748
+ end
749
+
750
+ it "should not remove file if old file had the same path" do
751
+ @event.image = stub_file('old.jpeg')
752
+ expect(@event.save).to be_truthy
753
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_truthy
754
+ expect(File.exist?(public_path('uploads/thumb_old.jpeg'))).to be_truthy
755
+ end
756
+
757
+ it 'should not remove old file if transaction is rollback' do
758
+ Event.transaction do
759
+ @event.image = stub_file('new.jpeg')
760
+ @event.save
761
+ expect(File.exist?(public_path('uploads/new.jpeg'))).to be_truthy
762
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_truthy
763
+ raise ActiveRecord::Rollback
764
+ end
765
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_truthy
766
+ end
767
+ end
768
+
769
+ describe '#mount_uploader removing old files with multiple uploaders' do
770
+ before do
771
+ @uploader = Class.new(CarrierWave::Uploader::Base)
772
+ @uploader1 = Class.new(CarrierWave::Uploader::Base)
773
+ reset_class("Event")
774
+ Event.mount_uploader(:image, @uploader)
775
+ Event.mount_uploader(:textfile, @uploader1)
776
+ @event = Event.new
777
+ @event.image = stub_file('old.jpeg')
778
+ @event.textfile = stub_file('old.txt')
779
+
780
+ expect(@event.save).to be_truthy
781
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_truthy
782
+ expect(File.exist?(public_path('uploads/old.txt'))).to be_truthy
783
+ end
784
+
785
+ after do
786
+ FileUtils.rm_rf(file_path("uploads"))
787
+ end
788
+
789
+ it "should remove old file1 and file2 if old file1 and file2 had a different paths" do
790
+ @event.image = stub_file('new.jpeg')
791
+ @event.textfile = stub_file('new.txt')
792
+ expect(@event.save).to be_truthy
793
+ expect(File.exist?(public_path('uploads/new.jpeg'))).to be_truthy
794
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_falsey
795
+ expect(File.exist?(public_path('uploads/new.txt'))).to be_truthy
796
+ expect(File.exist?(public_path('uploads/old.txt'))).to be_falsey
797
+ end
798
+
799
+ it "should remove old file1 but not file2 if old file1 had a different path but old file2 has the same path" do
800
+ @event.image = stub_file('new.jpeg')
801
+ @event.textfile = stub_file('old.txt')
802
+ expect(@event.save).to be_truthy
803
+ expect(File.exist?(public_path('uploads/new.jpeg'))).to be_truthy
804
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_falsey
805
+ expect(File.exist?(public_path('uploads/old.txt'))).to be_truthy
806
+ end
807
+
808
+ it "should not remove file1 or file2 if file1 and file2 have the same paths" do
809
+ @event.image = stub_file('old.jpeg')
810
+ @event.textfile = stub_file('old.txt')
811
+ expect(@event.save).to be_truthy
812
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_truthy
813
+ expect(File.exist?(public_path('uploads/old.txt'))).to be_truthy
814
+ end
815
+ end
816
+
817
+ describe '#mount_uploader removing old files with with mount_on' do
818
+ before do
819
+ reset_class("Event")
820
+ Event.mount_uploader(:avatar, @uploader, mount_on: :image)
821
+ @event = Event.new
822
+ @event.avatar = stub_file('old.jpeg')
823
+
824
+ expect(@event.save).to be_truthy
825
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_truthy
826
+ end
827
+
828
+ after do
829
+ FileUtils.rm_rf(file_path("uploads"))
830
+ end
831
+
832
+ it "should remove old file if old file had a different path" do
833
+ @event.avatar = stub_file('new.jpeg')
834
+ expect(@event.save).to be_truthy
835
+ expect(File.exist?(public_path('uploads/new.jpeg'))).to be_truthy
836
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_falsey
837
+ end
838
+
839
+ it "should not remove file if old file had the same path" do
840
+ @event.avatar = stub_file('old.jpeg')
841
+ expect(@event.save).to be_truthy
842
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_truthy
843
+ end
844
+ end
845
+
846
+ describe '#mount_uploaders' do
847
+ before do
848
+ Event.mount_uploaders(:images, @uploader)
849
+ end
850
+
851
+ describe '#images' do
852
+
853
+ it "should return blank uploader when nothing has been assigned" do
854
+ expect(@event.images).to be_empty
855
+ end
856
+
857
+ it "should retrieve a file from the storage if a value is stored in the database" do
858
+ @event[:images] = ['test.jpeg']
859
+ @event.save!
860
+ @event.reload
861
+ expect(@event.images[0]).to be_an_instance_of(@uploader)
862
+ end
863
+
864
+ it "should set the path to the store dir" do
865
+ @event[:images] = ['test.jpeg']
866
+ @event.save!
867
+ @event.reload
868
+ expect(@event.images[0].current_path).to eq public_path('uploads/test.jpeg')
869
+ end
870
+
871
+ it "should return valid JSON when to_json is called when images is nil" do
872
+ expect(@event[:images]).to be_nil
873
+ hash = JSON.parse(@event.to_json)
874
+ expect(hash.keys).to include("images")
875
+ expect(hash["images"]).to be_empty
876
+ end
877
+
878
+ it "should return valid JSON when to_json is called when images is present" do
879
+ @event[:images] = ['test.jpeg', 'old.jpeg']
880
+ @event.save!
881
+ @event.reload
882
+
883
+ expect(JSON.parse(@event.to_json)["images"]).to eq([{"url" => "/uploads/test.jpeg"}, {"url" => "/uploads/old.jpeg"}])
884
+ end
885
+
886
+ it "should return valid JSON when to_json is called on a collection containing uploader from a model" do
887
+ @event[:images] = ['test.jpeg']
888
+ @event.save!
889
+ @event.reload
890
+
891
+ expect(JSON.parse({:data => @event.images}.to_json)).to eq({"data"=>[{"url"=>"/uploads/test.jpeg"}]})
892
+ end
893
+
894
+ it "should return valid XML when to_xml is called when images is nil" do
895
+ hash = Hash.from_xml(@event.to_xml)["event"]
896
+
897
+ expect(@event[:images]).to be_nil
898
+ expect(hash.keys).to include("images")
899
+ expect(hash["images"]).to be_empty
900
+ end
901
+
902
+ it "should return valid XML when to_xml is called when images is present" do
903
+ @event[:images] = ['test.jpeg']
904
+ @event.save!
905
+ @event.reload
906
+
907
+ expect(Hash.from_xml(@event.to_xml)["event"]["images"]).to eq([{"url" => "/uploads/test.jpeg"}])
908
+ end
909
+
910
+ it "should respect options[:only] when passed to as_json for the serializable hash" do
911
+ @event[:images] = ['test.jpeg']
912
+ @event.save!
913
+ @event.reload
914
+
915
+ expect(@event.as_json(:only => [:foo])).to eq({"foo" => nil})
916
+ end
917
+
918
+ it "should respect options[:except] when passed to as_json for the serializable hash" do
919
+ @event[:images] = ['test.jpeg']
920
+ @event.save!
921
+ @event.reload
922
+
923
+ expect(@event.as_json(:except => [:id, :image, :images, :textfile, :foo])).to eq({"textfiles" => nil})
924
+ end
925
+ it "should respect both options[:only] and options[:except] when passed to as_json for the serializable hash" do
926
+ @event[:images] = ['test.jpeg']
927
+ @event.save!
928
+ @event.reload
929
+
930
+ expect(@event.as_json(:only => [:foo], :except => [:id])).to eq({"foo" => nil})
931
+ end
932
+
933
+ it "should respect options[:only] when passed to to_xml for the serializable hash" do
934
+ @event[:images] = ['test.jpeg']
935
+ @event.save!
936
+ @event.reload
937
+
938
+ expect(Hash.from_xml(@event.to_xml(only: [:foo]))["event"]["images"]).to be_nil
939
+ end
940
+
941
+ it "should respect options[:except] when passed to to_xml for the serializable hash" do
942
+ @event[:images] = ['test.jpeg']
943
+ @event.save!
944
+ @event.reload
945
+
946
+ expect(Hash.from_xml(@event.to_xml(except: [:images]))["event"]["images"]).to be_nil
947
+ end
948
+
949
+ it "should respect both options[:only] and options[:except] when passed to to_xml for the serializable hash" do
950
+ @event[:images] = ['test.jpeg']
951
+ @event.save!
952
+ @event.reload
953
+
954
+ expect(Hash.from_xml(@event.to_xml(only: [:foo], except: [:id]))["event"]["images"]).to be_nil
955
+ end
956
+ end
957
+
958
+ describe '#images=' do
959
+
960
+ it "should cache a file" do
961
+ @event.images = [stub_file('test.jpeg')]
962
+ expect(@event.images[0]).to be_an_instance_of(@uploader)
963
+ end
964
+
965
+ it "should write nothing to the database, to prevent overriden filenames to fail because of unassigned attributes" do
966
+ expect(@event[:images]).to be_nil
967
+ end
968
+
969
+ it "should copy a file into into the cache directory" do
970
+ @event.images = [stub_file('test.jpeg')]
971
+ expect(@event.images[0].current_path).to match(%r(^#{public_path('uploads/tmp')}))
972
+ end
973
+
974
+ it "should do nothing when nil is assigned" do
975
+ @event.images = nil
976
+ expect(@event.images).to be_empty
977
+ end
978
+
979
+ it "should do nothing when an empty string is assigned" do
980
+ @event.images = ''
981
+ expect(@event.images).to be_empty
982
+ end
983
+
984
+ context 'when validating white list integrity' do
985
+ before do
986
+ @uploader.class_eval do
987
+ def extension_whitelist
988
+ %w(txt)
989
+ end
990
+ end
991
+ end
992
+
993
+ it "should use I18n for integrity error messages" do
994
+ # Localize the error message to Dutch
995
+ change_locale_and_store_translations(:nl, :errors => {
996
+ :messages => {
997
+ :extension_whitelist_error => "Het opladen van %{extension} bestanden is niet toe gestaan. Geaccepteerde types: %{allowed_types}"
998
+ }
999
+ }) do
1000
+ # Assigning images triggers check_whitelist! and thus should be inside change_locale_and_store_translations
1001
+ @event.images = [stub_file('test.jpg')]
1002
+ expect(@event).to_not be_valid
1003
+ @event.valid?
1004
+ expect(@event.errors[:images]).to eq (['Het opladen van "jpg" bestanden is niet toe gestaan. Geaccepteerde types: txt'])
1005
+ end
1006
+ end
1007
+ end
1008
+
1009
+ context 'when validating black list integrity' do
1010
+ before do
1011
+ @uploader.class_eval do
1012
+ def extension_blacklist
1013
+ %w(jpg)
1014
+ end
1015
+ end
1016
+ end
1017
+
1018
+ it "should use I18n for integrity error messages" do
1019
+ # Localize the error message to Dutch
1020
+ change_locale_and_store_translations(:nl, :errors => {
1021
+ :messages => {
1022
+ :extension_blacklist_error => "You are not allowed to upload %{extension} files, prohibited types: %{prohibited_types}"
1023
+ }
1024
+ }) do
1025
+ # Assigning images triggers check_blacklist! and thus should be inside change_locale_and_store_translations
1026
+ @event.images = [stub_file('test.jpg')]
1027
+ expect(@event).to_not be_valid
1028
+ @event.valid?
1029
+ expect(@event.errors[:images]).to eq(['You are not allowed to upload "jpg" files, prohibited types: jpg'])
1030
+ end
1031
+ end
1032
+ end
1033
+
1034
+
1035
+ context 'when validating processing' do
1036
+ before do
1037
+ @uploader.class_eval do
1038
+ process :monkey
1039
+ def monkey
1040
+ raise CarrierWave::ProcessingError
1041
+ end
1042
+ end
1043
+ @event.images = [stub_file('test.jpg')]
1044
+ end
1045
+
1046
+ it "should make the record invalid when a processing error occurs" do
1047
+ expect(@event).to_not be_valid
1048
+ end
1049
+
1050
+ it "should use I18n for processing errors without messages" do
1051
+ @event.valid?
1052
+ expect(@event.errors[:images]).to eq(['failed to be processed'])
1053
+
1054
+ change_locale_and_store_translations(:pt, :activerecord => {
1055
+ :errors => {
1056
+ :messages => {
1057
+ :carrierwave_processing_error => 'falha ao processar imagesm.'
1058
+ }
1059
+ }
1060
+ }) do
1061
+ expect(@event).to_not be_valid
1062
+ expect(@event.errors[:images]).to eq(['falha ao processar imagesm.'])
1063
+ end
1064
+ end
1065
+ end
1066
+
1067
+ context 'when validating processing' do
1068
+ before do
1069
+ @uploader.class_eval do
1070
+ process :monkey
1071
+ def monkey
1072
+ raise CarrierWave::ProcessingError, "Ohh noez!"
1073
+ end
1074
+ end
1075
+ @event.images = [stub_file('test.jpg')]
1076
+ end
1077
+
1078
+ it "should make the record invalid when a processing error occurs" do
1079
+ expect(@event).to_not be_valid
1080
+ end
1081
+
1082
+ it "should use the error's messages for processing errors with messages" do
1083
+ @event.valid?
1084
+ expect(@event.errors[:images]).to eq(['Ohh noez!'])
1085
+
1086
+ change_locale_and_store_translations(:pt, :activerecord => {
1087
+ :errors => {
1088
+ :messages => {
1089
+ :carrierwave_processing_error => 'falha ao processar imagesm.'
1090
+ }
1091
+ }
1092
+ }) do
1093
+ expect(@event).to_not be_valid
1094
+ expect(@event.errors[:images]).to eq(['Ohh noez!'])
1095
+ end
1096
+ end
1097
+ end
1098
+ end
1099
+
1100
+ describe '#save' do
1101
+
1102
+ it "should do nothing when no file has been assigned" do
1103
+ expect(@event.save).to be_truthy
1104
+ expect(@event.images).to be_empty
1105
+ end
1106
+
1107
+ it "should copy the file to the upload directory when a file has been assigned" do
1108
+ @event.images = [stub_file('test.jpeg')]
1109
+ expect(@event.save).to be_truthy
1110
+ expect(@event.images[0]).to be_an_instance_of(@uploader)
1111
+ expect(@event.images[0].current_path).to eq public_path('uploads/test.jpeg')
1112
+ end
1113
+
1114
+ it "should do nothing when a validation fails" do
1115
+ Event.validate { |r| r.errors.add :textfile, "FAIL!" }
1116
+ @event.images = [stub_file('test.jpeg')]
1117
+
1118
+ expect(@event.save).to be_falsey
1119
+ expect(@event.images[0]).to be_an_instance_of(@uploader)
1120
+ expect(@event.images[0].current_path).to match(/^#{public_path('uploads/tmp')}/)
1121
+ end
1122
+
1123
+ it "should assign the filename to the database" do
1124
+ @event.images = [stub_file('test.jpeg')]
1125
+ expect(@event.save).to be_truthy
1126
+ @event.reload
1127
+ expect(@event[:images]).to eq(['test.jpeg'])
1128
+ expect(@event.images_identifiers[0]).to eq('test.jpeg')
1129
+ end
1130
+
1131
+ it "should preserve the images when nothing is assigned" do
1132
+ @event.images = [stub_file('test.jpeg')]
1133
+ expect(@event.save).to be_truthy
1134
+
1135
+ @event = Event.find(@event.id)
1136
+ @event.foo = "bar"
1137
+
1138
+ expect(@event.save).to be_truthy
1139
+ expect(@event[:images]).to eq(['test.jpeg'])
1140
+ expect(@event.images_identifiers[0]).to eq('test.jpeg')
1141
+ end
1142
+
1143
+ it "should remove the images if remove_images? returns true" do
1144
+ @event.images = [stub_file('test.jpeg')]
1145
+ @event.save!
1146
+ @event.remove_images = true
1147
+ @event.save!
1148
+ @event.reload
1149
+ expect(@event.images).to be_empty
1150
+ expect(@event[:images]).to eq(nil)
1151
+ expect(@event.images_identifiers[0]).to eq(nil)
1152
+ end
1153
+
1154
+ it "should mark images as changed when saving a new images" do
1155
+ expect(@event.images_changed?).to be_falsey
1156
+ @event.images = [stub_file("test.jpeg")]
1157
+ expect(@event.images_changed?).to be_truthy
1158
+ @event.save
1159
+ @event.reload
1160
+ expect(@event.images_changed?).to be_falsey
1161
+ @event.images = [stub_file("test.jpg")]
1162
+ expect(@event.images_changed?).to be_truthy
1163
+ expect(@event.changed_for_autosave?).to be_truthy
1164
+ end
1165
+ end
1166
+
1167
+ describe "remove_images!" do
1168
+ before do
1169
+ @event.images = [stub_file('test.jpeg')]
1170
+ @event.save!
1171
+ @event.remove_images!
1172
+ end
1173
+
1174
+ it "should clear the serialization column" do
1175
+ expect(@event.attributes['images']).to be_blank
1176
+ end
1177
+
1178
+ it "should return to false after being saved" do
1179
+ @event.save!
1180
+ expect(@event.remove_images).to eq(false)
1181
+ expect(@event.remove_images?).to eq(false)
1182
+ end
1183
+ end
1184
+
1185
+ describe "remove_images=" do
1186
+ it "should mark the images as changed if changed" do
1187
+ expect(@event.images_changed?).to be_falsey
1188
+ expect(@event.remove_images).to be_nil
1189
+ @event.remove_images = "1"
1190
+ expect(@event.images_changed?).to be_truthy
1191
+ end
1192
+ end
1193
+
1194
+ describe "#remote_images_urls=" do
1195
+ before do
1196
+ stub_request(:get, "www.example.com/test.jpg").to_return(body: File.read(file_path("test.jpg")))
1197
+ end
1198
+
1199
+ # FIXME ideally images_changed? and remote_images_urls_changed? would return true
1200
+ it "should mark images as changed when setting remote_images_urls" do
1201
+ expect(@event.images_changed?).to be_falsey
1202
+ @event.remote_images_urls = ['http://www.example.com/test.jpg']
1203
+ expect(@event.images_changed?).to be_truthy
1204
+ @event.save!
1205
+ @event.reload
1206
+ expect(@event.images_changed?).to be_falsey
1207
+ end
1208
+
1209
+ context 'when validating download' do
1210
+ before do
1211
+ @uploader.class_eval do
1212
+ def download! file
1213
+ raise CarrierWave::DownloadError
1214
+ end
1215
+ end
1216
+ @event.remote_images_urls = ['http://www.example.com/missing.jpg']
1217
+ end
1218
+
1219
+ it "should make the record invalid when a download error occurs" do
1220
+ expect(@event).to_not be_valid
1221
+ end
1222
+
1223
+ it "should use I18n for download errors without messages" do
1224
+ @event.valid?
1225
+ expect(@event.errors[:images]).to eq(['could not be downloaded'])
1226
+
1227
+ change_locale_and_store_translations(:pt, :activerecord => {
1228
+ :errors => {
1229
+ :messages => {
1230
+ :carrierwave_download_error => 'não pode ser descarregado'
1231
+ }
1232
+ }
1233
+ }) do
1234
+ expect(@event).to_not be_valid
1235
+ expect(@event.errors[:images]).to eq(['não pode ser descarregado'])
1236
+ end
1237
+ end
1238
+ end
1239
+
1240
+ end
1241
+
1242
+ describe '#destroy' do
1243
+
1244
+ it "should not raise an error with a custom filename" do
1245
+ @uploader.class_eval do
1246
+ def filename
1247
+ "page.jpeg"
1248
+ end
1249
+ end
1250
+
1251
+ @event.images = [stub_file('test.jpeg')]
1252
+ expect(@event.save).to be_truthy
1253
+ expect {
1254
+ @event.destroy
1255
+ }.to_not raise_error
1256
+ end
1257
+
1258
+ it "should do nothing when no file has been assigned" do
1259
+ expect(@event.save).to be_truthy
1260
+ @event.destroy
1261
+ end
1262
+
1263
+ it "should remove the file from the filesystem" do
1264
+ @event.images = [stub_file('test.jpeg')]
1265
+ expect(@event.save).to be_truthy
1266
+ expect(@event.images[0]).to be_an_instance_of(@uploader)
1267
+ expect(@event.images[0].current_path).to eq public_path('uploads/test.jpeg')
1268
+ @event.destroy
1269
+ expect(File.exist?(public_path('uploads/test.jpeg'))).to be_falsey
1270
+ end
1271
+
1272
+ end
1273
+
1274
+ describe 'with overriddent filename' do
1275
+
1276
+ describe '#save' do
1277
+
1278
+ before do
1279
+ @uploader.class_eval do
1280
+ def filename
1281
+ model.name + File.extname(super)
1282
+ end
1283
+ end
1284
+ allow(@event).to receive(:name).and_return('jonas')
1285
+ end
1286
+
1287
+ it "should copy the file to the upload directory when a file has been assigned" do
1288
+ @event.images = [stub_file('test.jpeg')]
1289
+ expect(@event.save).to be_truthy
1290
+ expect(@event.images[0]).to be_an_instance_of(@uploader)
1291
+ expect(@event.images[0].current_path).to eq(public_path('uploads/jonas.jpeg'))
1292
+ end
1293
+
1294
+ it "should assign an overridden filename to the database" do
1295
+ @event.images = [stub_file('test.jpeg')]
1296
+ expect(@event.save).to be_truthy
1297
+ @event.reload
1298
+ expect(@event[:images]).to eq(['jonas.jpeg'])
1299
+ end
1300
+
1301
+ end
1302
+
1303
+ end
1304
+
1305
+ describe 'with validates_presence_of' do
1306
+
1307
+ before do
1308
+ Event.validates_presence_of :images
1309
+ allow(@event).to receive(:name).and_return('jonas')
1310
+ end
1311
+
1312
+ it "should be valid if a file has been cached" do
1313
+ @event.images = [stub_file('test.jpeg')]
1314
+ expect(@event).to be_valid
1315
+ end
1316
+
1317
+ it "should not be valid if a file has not been cached" do
1318
+ expect(@event).to_not be_valid
1319
+ end
1320
+
1321
+ end
1322
+
1323
+ describe 'with validates_size_of' do
1324
+
1325
+ before do
1326
+ Event.validates_size_of :images, maximum: 2
1327
+ allow(@event).to receive(:name).and_return('jonas')
1328
+ end
1329
+
1330
+ it "should be valid if at the number criteria are met" do
1331
+ @event.images = [stub_file('test.jpeg'), stub_file('old.jpeg')]
1332
+ expect(@event).to be_valid
1333
+ end
1334
+
1335
+ it "should be invalid if size criteria are exceeded" do
1336
+ @event.images = [stub_file('test.jpeg'), stub_file('old.jpeg'), stub_file('new.jpeg')]
1337
+ expect(@event).to_not be_valid
1338
+ end
1339
+
1340
+ end
1341
+ end
1342
+
1343
+ describe '#mount_uploaders with mount_on' do
1344
+ describe '#avatar=' do
1345
+ it "should cache a file" do
1346
+ reset_class("Event")
1347
+ Event.mount_uploaders(:avatar, @uploader, mount_on: :images)
1348
+ @event = Event.new
1349
+ @event.avatar = [stub_file('test.jpeg')]
1350
+ @event.save
1351
+ @event.reload
1352
+
1353
+ expect(@event.avatar[0]).to be_an_instance_of(@uploader)
1354
+ expect(@event.images).to eq(['test.jpeg'])
1355
+ end
1356
+
1357
+ end
1358
+ end
1359
+
1360
+ describe '#mount_uploaders removing old files' do
1361
+ before do
1362
+ Event.mount_uploaders(:images, @uploader)
1363
+ @event.images = [stub_file('old.jpeg')]
1364
+
1365
+ expect(@event.save).to be_truthy
1366
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_truthy
1367
+ end
1368
+
1369
+ after do
1370
+ FileUtils.rm_rf(file_path("uploads"))
1371
+ end
1372
+
1373
+ describe 'normally' do
1374
+ it "should remove old file if old file had a different path" do
1375
+ @event.images = [stub_file('new.jpeg')]
1376
+ expect(@event.save).to be_truthy
1377
+ expect(File.exist?(public_path('uploads/new.jpeg'))).to be_truthy
1378
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_falsey
1379
+ end
1380
+
1381
+ it "should not remove old file if old file had a different path but config is false" do
1382
+ allow(@uploader).to receive(:remove_previously_stored_files_after_update).and_return(false)
1383
+ @event.images = [stub_file('new.jpeg')]
1384
+ expect(@event.save).to be_truthy
1385
+ expect(File.exist?(public_path('uploads/new.jpeg'))).to be_truthy
1386
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_truthy
1387
+ end
1388
+
1389
+ it "should not remove file if old file had the same path" do
1390
+ @event.images = [stub_file('old.jpeg')]
1391
+ expect(@event.save).to be_truthy
1392
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_truthy
1393
+ end
1394
+
1395
+ it "should not remove file if validations fail on save" do
1396
+ Event.validate { |r| r.errors.add :textfile, "FAIL!" }
1397
+ @event.images = [stub_file('new.jpeg')]
1398
+
1399
+ expect(@event.save).to be_falsey
1400
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_truthy
1401
+ end
1402
+ end
1403
+
1404
+ describe 'with an overriden filename' do
1405
+ before do
1406
+ @uploader.class_eval do
1407
+ def filename
1408
+ model.foo + File.extname(super)
1409
+ end
1410
+ end
1411
+
1412
+ @event.images = [stub_file('old.jpeg')]
1413
+ @event.foo = 'test'
1414
+ expect(@event.save).to be_truthy
1415
+ expect(File.exist?(public_path('uploads/test.jpeg'))).to be_truthy
1416
+ expect(@event.images[0].read).to eq('this is stuff')
1417
+ end
1418
+
1419
+ it "should not remove file if old file had the same dynamic path" do
1420
+ @event.images = [stub_file('test.jpeg')]
1421
+ expect(@event.save).to be_truthy
1422
+ expect(File.exist?(public_path('uploads/test.jpeg'))).to be_truthy
1423
+ end
1424
+
1425
+ it "should remove old file if old file had a different dynamic path" do
1426
+ @event.foo = "new"
1427
+ @event.images = [stub_file('test.jpeg')]
1428
+ expect(@event.save).to be_truthy
1429
+ expect(File.exist?(public_path('uploads/new.jpeg'))).to be_truthy
1430
+ expect(File.exist?(public_path('uploads/test.jpeg'))).to be_falsey
1431
+ end
1432
+ end
1433
+ end
1434
+
1435
+ describe '#mount_uploaders removing old files with versions' do
1436
+ before do
1437
+ @uploader.version :thumb
1438
+ Event.mount_uploaders(:images, @uploader)
1439
+ @event.images = [stub_file('old.jpeg')]
1440
+
1441
+ expect(@event.save).to be_truthy
1442
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_truthy
1443
+ expect(File.exist?(public_path('uploads/thumb_old.jpeg'))).to be_truthy
1444
+ end
1445
+
1446
+ after do
1447
+ FileUtils.rm_rf(file_path("uploads"))
1448
+ end
1449
+
1450
+ it "should remove old file if old file had a different path" do
1451
+ @event.images = [stub_file('new.jpeg')]
1452
+ expect(@event.save).to be_truthy
1453
+ expect(File.exist?(public_path('uploads/new.jpeg'))).to be_truthy
1454
+ expect(File.exist?(public_path('uploads/thumb_new.jpeg'))).to be_truthy
1455
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_falsey
1456
+ expect(File.exist?(public_path('uploads/thumb_old.jpeg'))).to be_falsey
1457
+ end
1458
+
1459
+ it "should not remove file if old file had the same path" do
1460
+ @event.images = [stub_file('old.jpeg')]
1461
+ expect(@event.save).to be_truthy
1462
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_truthy
1463
+ expect(File.exist?(public_path('uploads/thumb_old.jpeg'))).to be_truthy
1464
+ end
1465
+ end
1466
+
1467
+ describe '#mount_uploaders removing old files with multiple uploaders' do
1468
+ before do
1469
+ @uploader = Class.new(CarrierWave::Uploader::Base)
1470
+ @uploader1 = Class.new(CarrierWave::Uploader::Base)
1471
+ reset_class("Event")
1472
+ Event.mount_uploaders(:images, @uploader)
1473
+ Event.mount_uploaders(:textfiles, @uploader1)
1474
+ @event = Event.new
1475
+ @event.images = [stub_file('old.jpeg')]
1476
+ @event.textfiles = [stub_file('old.txt')]
1477
+
1478
+ expect(@event.save).to be_truthy
1479
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_truthy
1480
+ expect(File.exist?(public_path('uploads/old.txt'))).to be_truthy
1481
+ end
1482
+
1483
+ after do
1484
+ FileUtils.rm_rf(file_path("uploads"))
1485
+ end
1486
+
1487
+ it "should remove old file1 and file2 if old file1 and file2 had a different paths" do
1488
+ @event.images = [stub_file('new.jpeg')]
1489
+ @event.textfiles = [stub_file('new.txt')]
1490
+ expect(@event.save).to be_truthy
1491
+ expect(File.exist?(public_path('uploads/new.jpeg'))).to be_truthy
1492
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_falsey
1493
+ expect(File.exist?(public_path('uploads/new.txt'))).to be_truthy
1494
+ expect(File.exist?(public_path('uploads/old.txt'))).to be_falsey
1495
+ end
1496
+
1497
+ it "should remove old file1 but not file2 if old file1 had a different path but old file2 has the same path" do
1498
+ @event.images = [stub_file('new.jpeg')]
1499
+ @event.textfiles = [stub_file('old.txt')]
1500
+ expect(@event.save).to be_truthy
1501
+ expect(File.exist?(public_path('uploads/new.jpeg'))).to be_truthy
1502
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_falsey
1503
+ expect(File.exist?(public_path('uploads/old.txt'))).to be_truthy
1504
+ end
1505
+
1506
+ it "should not remove file1 or file2 if file1 and file2 have the same paths" do
1507
+ @event.images = [stub_file('old.jpeg')]
1508
+ @event.textfiles = [stub_file('old.txt')]
1509
+ expect(@event.save).to be_truthy
1510
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_truthy
1511
+ expect(File.exist?(public_path('uploads/old.txt'))).to be_truthy
1512
+ end
1513
+ end
1514
+
1515
+ describe '#mount_uploaders removing old files with mount_on' do
1516
+ before do
1517
+ Event.mount_uploaders(:avatar, @uploader, mount_on: :images)
1518
+ @event = Event.new
1519
+ @event.avatar = [stub_file('old.jpeg')]
1520
+
1521
+ expect(@event.save).to be_truthy
1522
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_truthy
1523
+ end
1524
+
1525
+ after do
1526
+ FileUtils.rm_rf(file_path("uploads"))
1527
+ end
1528
+
1529
+ it "should remove old file if old file had a different path" do
1530
+ @event.avatar = [stub_file('new.jpeg')]
1531
+ expect(@event.save).to be_truthy
1532
+ expect(File.exist?(public_path('uploads/new.jpeg'))).to be_truthy
1533
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_falsey
1534
+ end
1535
+
1536
+ it "should not remove file if old file had the same path" do
1537
+ @event.avatar = [stub_file('old.jpeg')]
1538
+ expect(@event.save).to be_truthy
1539
+ expect(File.exist?(public_path('uploads/old.jpeg'))).to be_truthy
1540
+ end
1541
+
1542
+ it "should not raise ArgumentError when with_lock method is called" do
1543
+ expect { @event.with_lock {} }.to_not raise_error
1544
+ end
1545
+ end
1546
+
1547
+ describe "#dup" do
1548
+ it "appropriately removes the model reference from the new models uploader" do
1549
+ Event.mount_uploader(:image, @uploader)
1550
+ @event.save
1551
+ new_event = @event.dup
1552
+
1553
+ expect(new_event.image.model).not_to eq @event
1554
+ end
1555
+ end
1556
+ end