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,6 @@
1
+ require 'carrierwave/utilities/uri'
2
+
3
+ module CarrierWave
4
+ module Utilities
5
+ end
6
+ end
@@ -0,0 +1,21 @@
1
+ module CarrierWave
2
+ module Utilities
3
+ module Uri
4
+ # based on Ruby < 2.0's URI.encode
5
+ SAFE_STRING = URI::REGEXP::PATTERN::UNRESERVED + '\/'
6
+ UNSAFE = Regexp.new("[^#{SAFE_STRING}]", false)
7
+
8
+ private
9
+ def encode_path(path)
10
+ path.to_s.gsub(UNSAFE) do
11
+ us = $&
12
+ tmp = ''
13
+ us.each_byte do |uc|
14
+ tmp << sprintf('%%%02X', uc)
15
+ end
16
+ tmp
17
+ end
18
+ end
19
+ end # Uri
20
+ end # Utilities
21
+ end # CarrierWave
@@ -0,0 +1,78 @@
1
+ require 'active_model/validator'
2
+ require 'active_support/concern'
3
+
4
+ module CarrierWave
5
+
6
+ # == Active Model Presence Validator
7
+ module Validations
8
+ module ActiveModel
9
+ extend ActiveSupport::Concern
10
+
11
+ class ProcessingValidator < ::ActiveModel::EachValidator
12
+
13
+ def validate_each(record, attribute, value)
14
+ if e = record.send("#{attribute}_processing_error")
15
+ message = (e.message == e.class.to_s) ? :carrierwave_processing_error : e.message
16
+ record.errors.add(attribute, message)
17
+ end
18
+ end
19
+ end
20
+
21
+ class IntegrityValidator < ::ActiveModel::EachValidator
22
+
23
+ def validate_each(record, attribute, value)
24
+ if e = record.send("#{attribute}_integrity_error")
25
+ message = (e.message == e.class.to_s) ? :carrierwave_integrity_error : e.message
26
+ record.errors.add(attribute, message)
27
+ end
28
+ end
29
+ end
30
+
31
+ class DownloadValidator < ::ActiveModel::EachValidator
32
+
33
+ def validate_each(record, attribute, value)
34
+ if e = record.send("#{attribute}_download_error")
35
+ message = (e.message == e.class.to_s) ? :carrierwave_download_error : e.message
36
+ record.errors.add(attribute, message)
37
+ end
38
+ end
39
+ end
40
+
41
+ module HelperMethods
42
+
43
+ ##
44
+ # Makes the record invalid if the file couldn't be uploaded due to an integrity error
45
+ #
46
+ # Accepts the usual parameters for validations in Rails (:if, :unless, etc...)
47
+ #
48
+ def validates_integrity_of(*attr_names)
49
+ validates_with IntegrityValidator, _merge_attributes(attr_names)
50
+ end
51
+
52
+ ##
53
+ # Makes the record invalid if the file couldn't be processed (assuming the process failed
54
+ # with a CarrierWave::ProcessingError)
55
+ #
56
+ # Accepts the usual parameters for validations in Rails (:if, :unless, etc...)
57
+ #
58
+ def validates_processing_of(*attr_names)
59
+ validates_with ProcessingValidator, _merge_attributes(attr_names)
60
+ end
61
+ #
62
+ ##
63
+ # Makes the record invalid if the remote file couldn't be downloaded
64
+ #
65
+ # Accepts the usual parameters for validations in Rails (:if, :unless, etc...)
66
+ #
67
+ def validates_download_of(*attr_names)
68
+ validates_with DownloadValidator, _merge_attributes(attr_names)
69
+ end
70
+ end
71
+
72
+ included do
73
+ extend HelperMethods
74
+ include HelperMethods
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,3 @@
1
+ module CarrierWave
2
+ VERSION = "0.11.0"
3
+ end
@@ -0,0 +1,49 @@
1
+ class <%= class_name %>Uploader < CarrierWave::Uploader::Base
2
+
3
+ # Include RMagick or MiniMagick support:
4
+ # include CarrierWave::RMagick
5
+ # include CarrierWave::MiniMagick
6
+
7
+ # Choose what kind of storage to use for this uploader:
8
+ storage :file
9
+ # storage :fog
10
+
11
+ # Override the directory where uploaded files will be stored.
12
+ # This is a sensible default for uploaders that are meant to be mounted:
13
+ def store_dir
14
+ "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
15
+ end
16
+
17
+ # Provide a default URL as a default if there hasn't been a file uploaded:
18
+ # def default_url
19
+ # # For Rails 3.1+ asset pipeline compatibility:
20
+ # # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
21
+ #
22
+ # "/images/fallback/" + [version_name, "default.png"].compact.join('_')
23
+ # end
24
+
25
+ # Process files as they are uploaded:
26
+ # process scale: [200, 300]
27
+ #
28
+ # def scale(width, height)
29
+ # # do something
30
+ # end
31
+
32
+ # Create different versions of your uploaded files:
33
+ # version :thumb do
34
+ # process resize_to_fit: [50, 50]
35
+ # end
36
+
37
+ # Add a white list of extensions which are allowed to be uploaded.
38
+ # For images you might use something like this:
39
+ # def extension_whitelist
40
+ # %w(jpg jpeg gif png)
41
+ # end
42
+
43
+ # Override the filename of the uploaded files:
44
+ # Avoid using model.id or version_name here, see uploader/store.rb for details.
45
+ # def filename
46
+ # "something.jpg" if original_filename
47
+ # end
48
+
49
+ end
@@ -0,0 +1,7 @@
1
+ class UploaderGenerator < Rails::Generators::NamedBase
2
+ source_root File.expand_path("../templates", __FILE__)
3
+
4
+ def create_uploader_file
5
+ template "uploader.rb", File.join('app/uploaders', class_path, "#{file_name}_uploader.rb")
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/carrierwave.rb'}"
9
+ puts "Loading carrierwave gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
@@ -0,0 +1,138 @@
1
+ require 'spec_helper'
2
+ require 'carrierwave/orm/activerecord'
3
+
4
+ module Rails; end unless defined?(Rails)
5
+
6
+ describe CarrierWave::Compatibility::Paperclip do
7
+ let(:uploader_class) do
8
+ Class.new(CarrierWave::Uploader::Base) do
9
+ include CarrierWave::Compatibility::Paperclip
10
+
11
+ version :thumb
12
+ version :list
13
+ end
14
+ end
15
+
16
+ let(:model) { double('model') }
17
+
18
+ let(:uploader) { uploader_class.new(model, :monkey) }
19
+
20
+ before do
21
+ allow(Rails).to receive(:root).and_return('/rails/root')
22
+ allow(Rails).to receive(:env).and_return('test')
23
+ allow(model).to receive(:id).and_return(23)
24
+ allow(model).to receive(:ook).and_return('eek')
25
+ allow(model).to receive(:money).and_return('monkey.png')
26
+ end
27
+
28
+ after { FileUtils.rm_rf(public_path) }
29
+
30
+ describe '#store_path' do
31
+ subject { uploader.store_path("monkey.png") }
32
+
33
+ it "mimics paperclip default" do
34
+ is_expected.to eq("/rails/root/public/system/monkeys/23/original/monkey.png")
35
+ end
36
+
37
+ it "interpolates the root path" do
38
+ allow(uploader).to receive(:paperclip_path).and_return(":rails_root/foo/bar")
39
+ is_expected.to eq(Rails.root + "/foo/bar")
40
+ end
41
+
42
+ it "interpolates the attachment" do
43
+ allow(uploader).to receive(:paperclip_path).and_return("/foo/:attachment/bar")
44
+ is_expected.to eq("/foo/monkeys/bar")
45
+ end
46
+
47
+ it "interpolates the id" do
48
+ allow(uploader).to receive(:paperclip_path).and_return("/foo/:id/bar")
49
+ is_expected.to eq("/foo/23/bar")
50
+ end
51
+
52
+ it "interpolates the id partition" do
53
+ allow(uploader).to receive(:paperclip_path).and_return("/foo/:id_partition/bar")
54
+ is_expected.to eq("/foo/000/000/023/bar")
55
+ end
56
+
57
+ it "interpolates the basename" do
58
+ allow(uploader).to receive(:paperclip_path).and_return("/foo/:basename/bar")
59
+ is_expected.to eq("/foo/monkey/bar")
60
+ end
61
+
62
+ it "interpolates the extension" do
63
+ allow(uploader).to receive(:paperclip_path).and_return("/foo/:extension/bar")
64
+ is_expected.to eq("/foo/png/bar")
65
+ end
66
+ end
67
+
68
+ describe '.interpolate' do
69
+ subject { uploader.store_path("monkey.png") }
70
+
71
+ before do
72
+ uploader_class.interpolate :ook do |custom, style|
73
+ custom.model.ook
74
+ end
75
+
76
+ uploader_class.interpolate :aak do |model, style|
77
+ style
78
+ end
79
+ end
80
+
81
+ it 'allows you to add custom interpolations' do
82
+ allow(uploader).to receive(:paperclip_path).and_return("/foo/:id/:ook")
83
+ is_expected.to eq('/foo/23/eek')
84
+ end
85
+
86
+ it 'mimics paperclips arguments' do
87
+ allow(uploader).to receive(:paperclip_path).and_return("/foo/:aak")
88
+ is_expected.to eq('/foo/original')
89
+ end
90
+
91
+ context 'when multiple uploaders include the compatibility module' do
92
+ let(:uploader) { uploader_class_other.new(model, :monkey) }
93
+ let(:uploader_class_other) do
94
+ Class.new(CarrierWave::Uploader::Base) do
95
+ include CarrierWave::Compatibility::Paperclip
96
+
97
+ version :thumb
98
+ version :list
99
+ end
100
+ end
101
+
102
+ before { allow(uploader).to receive(:paperclip_path).and_return("/foo/:id/:ook") }
103
+
104
+ it "doesn't share custom interpolations" do
105
+ is_expected.to eq('/foo/23/:ook')
106
+ end
107
+ end
108
+
109
+ context 'when there are multiple versions' do
110
+ let(:complex_uploader_class) do
111
+ Class.new(CarrierWave::Uploader::Base) do
112
+ include CarrierWave::Compatibility::Paperclip
113
+
114
+ interpolate :ook do |model, style|
115
+ 'eek'
116
+ end
117
+
118
+ version :thumb
119
+ version :list
120
+
121
+ def paperclip_path
122
+ "#{public_path}/foo/:ook/:id/:style"
123
+ end
124
+ end
125
+ end
126
+
127
+ let(:uploader) { complex_uploader_class.new(model, :monkey) }
128
+ let!(:file) { File.open(file_path('test.jpg')) }
129
+
130
+ before { uploader.store!(file) }
131
+
132
+ it 'interpolates for all versions correctly' do
133
+ expect(uploader.thumb.path).to eq("#{public_path}/foo/eek/23/thumb")
134
+ expect(uploader.list.path).to eq("#{public_path}/foo/eek/23/list")
135
+ end
136
+ end
137
+ end
138
+ end
@@ -0,0 +1 @@
1
+ this is stuff
@@ -0,0 +1 @@
1
+ bork bork bork Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
@@ -0,0 +1 @@
1
+ bork bork bork Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
@@ -0,0 +1 @@
1
+ bork bork bork Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
@@ -0,0 +1 @@
1
+ this is stuff
@@ -0,0 +1 @@
1
+ this is stuff
@@ -0,0 +1 @@
1
+ bork bork bork Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
@@ -0,0 +1 @@
1
+ this is stuff
@@ -0,0 +1 @@
1
+ bork bork bork Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
@@ -0,0 +1 @@
1
+ this is stuff
@@ -0,0 +1 @@
1
+ this is stuff
@@ -0,0 +1 @@
1
+ this is stuff
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+ require 'generator_spec'
3
+ require 'generators/uploader_generator'
4
+
5
+ describe UploaderGenerator, :type => :generator do
6
+ destination(File.expand_path("../../tmp", __FILE__))
7
+
8
+ before { prepare_destination }
9
+
10
+ it "creates uploader file" do
11
+ run_generator %w(Avatar)
12
+ assert_file 'app/uploaders/avatar_uploader.rb', /class AvatarUploader < CarrierWave::Uploader::Base/
13
+ end
14
+
15
+ it "creates namespaced uploader file" do
16
+ run_generator %w(MyModule::Avatar)
17
+ assert_file 'app/uploaders/my_module/avatar_uploader.rb', /class MyModule::AvatarUploader < CarrierWave::Uploader::Base/
18
+ end
19
+ end
@@ -0,0 +1,913 @@
1
+ require 'spec_helper'
2
+
3
+ describe CarrierWave::Mount do
4
+ let(:klass) { Class.new.send(:extend, CarrierWave::Mount) }
5
+ let(:uploader) { Class.new(CarrierWave::Uploader::Base) }
6
+ let(:instance) { klass.new }
7
+ let(:test_file_name) { 'test.jpg' }
8
+ let(:new_file_name) { 'new.jpeg' }
9
+ let(:test_file_stub) { stub_file(test_file_name) }
10
+ let(:new_file_stub) { stub_file(new_file_name) }
11
+
12
+ after { FileUtils.rm_rf(public_path) }
13
+
14
+ describe '.mount_uploaders' do
15
+ before { klass.mount_uploaders(:images, uploader) }
16
+
17
+ describe "super behavior" do
18
+ before do
19
+ klass.class_eval do
20
+ def images_uploader
21
+ super
22
+ end
23
+
24
+ def images=(val)
25
+ super
26
+ end
27
+ end
28
+
29
+ instance.images = [stub_file(test_file_name)]
30
+ end
31
+
32
+ it "maintains the ability to super" do
33
+ expect(instance.images[0]).to be_an_instance_of(uploader)
34
+ end
35
+ end
36
+
37
+ describe "upload inheritance" do
38
+ let(:subclass) { Class.new(klass) }
39
+ let(:subclass_instance) { subclass.new }
40
+
41
+ before { subclass_instance.images = [test_file_stub, new_file_stub] }
42
+
43
+ it "inherits uploaders to subclasses" do
44
+ expect(subclass_instance.images[0]).to be_an_instance_of(uploader)
45
+ expect(subclass_instance.images[1]).to be_an_instance_of(uploader)
46
+ end
47
+ end
48
+
49
+ describe "upload marshalling" do
50
+ before do
51
+ Object.const_set("MyClass#{klass.object_id}".gsub('-', '_'), klass)
52
+ Object.const_set("Uploader#{uploader.object_id}".gsub('-', '_'), uploader)
53
+
54
+ uploader.class_eval do
55
+ def rotate
56
+ end
57
+ end
58
+
59
+ uploader.version :thumb do
60
+ process :rotate
61
+ end
62
+
63
+ instance.images = [test_file_stub]
64
+ end
65
+
66
+ it "allows marshalling uploaders and versions" do
67
+ expect { Marshal.dump(instance.images) }.not_to raise_error
68
+ end
69
+ end
70
+
71
+ describe "behavior of subclassed uploaders" do
72
+ let(:uploader_1) do
73
+ Class.new(CarrierWave::Uploader::Base) do
74
+ [:rotate, :compress, :encrypt, :shrink].each { |m| define_method(m) {} }
75
+ end.tap do |uploader|
76
+ uploader.process :rotate
77
+ uploader.version :thumb do
78
+ process :compress
79
+ end
80
+ end
81
+ end
82
+
83
+ let(:uploader_2) do
84
+ Class.new(uploader_1).tap do |uploader|
85
+ uploader.process :shrink
86
+ uploader.version :secret do
87
+ process :encrypt
88
+ end
89
+ end
90
+ end
91
+
92
+ let(:instance) do
93
+ klass.new.tap do |instance|
94
+ instance.images1 = [test_file_stub]
95
+ instance.images2 = [test_file_stub]
96
+ end
97
+ end
98
+
99
+ before do
100
+ klass.mount_uploaders(:images1, uploader_1)
101
+ klass.mount_uploaders(:images2, uploader_2)
102
+ end
103
+
104
+ context "defined version inheritance works" do
105
+ it { expect(instance.images1[0]).to respond_to(:thumb) }
106
+
107
+ it { expect(instance.images2[0]).to respond_to(:thumb) }
108
+ end
109
+
110
+ context "version inheritance defined in subclasses works" do
111
+ it { expect(instance.images1[0]).not_to respond_to(:secret) }
112
+
113
+ it { expect(instance.images2[0]).to respond_to(:secret) }
114
+ end
115
+
116
+ context "defined processors inheritance works" do
117
+ it { expect(uploader_1.processors).to eq([[:rotate, [], nil]]) }
118
+
119
+ it { expect(uploader_2.processors).to eq([[:rotate, [], nil], [:shrink, [], nil]]) }
120
+
121
+ it { expect(uploader_1.versions[:thumb].processors).to eq([[:compress, [], nil]]) }
122
+
123
+ it { expect(uploader_2.versions[:thumb].processors).to eq([[:compress, [], nil]]) }
124
+
125
+ it { expect(uploader_2.versions[:secret].processors).to eq([[:encrypt, [], nil]]) }
126
+ end
127
+ end
128
+
129
+ describe '#images' do
130
+ context "return an empty array when nothing has been assigned" do
131
+ before do
132
+ allow(instance).to receive(:read_uploader).with(:images).and_return(nil)
133
+ end
134
+
135
+ it { expect(instance.images).to eq [] }
136
+ end
137
+
138
+ context "returns an empty array when an empty string has been assigned" do
139
+ before do
140
+ allow(instance).to receive(:read_uploader).with(:images).and_return('')
141
+ end
142
+
143
+ it { expect(instance.images).to eq [] }
144
+ end
145
+
146
+ context "retrieves a file from the storage if a value is stored in the database" do
147
+ subject(:images) { instance.images }
148
+
149
+ before do
150
+ allow(instance).to receive(:read_uploader).with(:images).at_least(:once).and_return([test_file_name, new_file_name])
151
+ end
152
+
153
+ it { expect(images[0]).to be_an_instance_of(uploader) }
154
+ it { expect(images[1]).to be_an_instance_of(uploader) }
155
+ end
156
+
157
+ context "sets the path to the store dir" do
158
+ subject(:image) { instance.images.first }
159
+
160
+ before do
161
+ allow(instance).to receive(:read_uploader).with(:images).at_least(:once).and_return(test_file_name)
162
+ end
163
+
164
+ it { expect(image.current_path).to eq(public_path("uploads/#{test_file_name}")) }
165
+ end
166
+ end
167
+
168
+ describe '#images=' do
169
+ let(:old_image_stub) { stub_file('old.jpeg') }
170
+ let(:text_file_stub) { stub_file('bork.txt') }
171
+
172
+ context "caching images" do
173
+ before do
174
+ instance.images = [test_file_stub, old_image_stub]
175
+ end
176
+
177
+ it { expect(instance.images[0]).to be_an_instance_of(uploader) }
178
+
179
+ it { expect(instance.images[1]).to be_an_instance_of(uploader) }
180
+
181
+ it "copies files into the cache directory" do
182
+ expect(instance.images[0].current_path).to match(/^#{public_path('uploads/tmp')}/)
183
+ end
184
+ end
185
+
186
+ it "does nothing when nil is assigned" do
187
+ expect(instance).not_to receive(:write_uploader)
188
+ instance.images = nil
189
+ end
190
+
191
+ it "does nothing when an empty string is assigned" do
192
+ expect(instance).not_to receive(:write_uploader)
193
+
194
+ instance.images = [test_file_stub]
195
+ end
196
+
197
+ context "fails silently if the images fails a white list integrity check" do
198
+ before do
199
+ uploader.class_eval do
200
+ def extension_whitelist
201
+ %w(txt)
202
+ end
203
+ end
204
+
205
+ instance.images = [text_file_stub, test_file_stub]
206
+ end
207
+
208
+ it { expect(instance.images).to be_empty }
209
+ end
210
+
211
+ describe "fails silently if the images fails a black list integrity check" do
212
+ before do
213
+ uploader.class_eval do
214
+ def extension_blacklist
215
+ %w(jpg)
216
+ end
217
+ end
218
+
219
+ instance.images = [text_file_stub, test_file_stub]
220
+ end
221
+
222
+ it { expect(instance.images).to be_empty }
223
+ end
224
+
225
+ describe "fails silently if the images fails to be processed" do
226
+ before do
227
+ uploader.class_eval do
228
+ process :monkey
229
+ def monkey
230
+ raise CarrierWave::ProcessingError, "Ohh noez!"
231
+ end
232
+ end
233
+
234
+ instance.images = [test_file_stub]
235
+ end
236
+
237
+ it { expect(instance.images).to be_empty }
238
+ end
239
+ end
240
+
241
+ describe '#images?' do
242
+ subject { instance.images? }
243
+
244
+ context "false when nothing has been assigned" do
245
+ before { instance.images = nil }
246
+
247
+ it { is_expected.to be_falsey }
248
+ end
249
+
250
+ context "false when an empty string has been assigned" do
251
+ before { instance.images = '' }
252
+
253
+ it { is_expected.to be_falsey }
254
+ end
255
+
256
+ context "true when a file has been cached" do
257
+ before { instance.images = [test_file_stub] }
258
+
259
+ it { is_expected.to be_truthy }
260
+ end
261
+ end
262
+
263
+ describe '#images_urls' do
264
+ subject(:images_urls) { instance.images_urls }
265
+
266
+ describe "returns nil when nothing has been assigned" do
267
+ before do
268
+ allow(instance).to receive(:read_uploader).with(:images).and_return(nil)
269
+ end
270
+
271
+ it { is_expected.to be_empty }
272
+ end
273
+
274
+ describe "should return nil when an empty string has been assigned" do
275
+ before do
276
+ allow(instance).to receive(:read_uploader).with(:images).and_return('')
277
+ end
278
+
279
+ it { is_expected.to be_empty }
280
+ end
281
+
282
+ describe "gets the url from a retrieved file" do
283
+ before do
284
+ allow(instance).to receive(:read_uploader).at_least(:once).with(:images).and_return(test_file_name)
285
+ end
286
+
287
+ it { expect(images_urls.first).to eq("/uploads/#{test_file_name}") }
288
+ end
289
+
290
+ describe "gets the url from a cached file" do
291
+ before { instance.images = [test_file_stub] }
292
+
293
+ it { expect(images_urls[0]).to match(%r{uploads/tmp/[\d\-]+/test.jpg}) }
294
+ end
295
+
296
+ describe "gets the url from a cached file's version" do
297
+ before do
298
+ uploader.version(:thumb)
299
+ instance.images = [test_file_stub]
300
+ end
301
+
302
+ it { expect(instance.images_urls(:thumb)[0]).to match(%r{uploads/tmp/[\d\-]+/thumb_test.jpg}) }
303
+ end
304
+ end
305
+
306
+ describe '#images_cache' do
307
+ before do
308
+ allow(instance).to receive(:write_uploader)
309
+ allow(instance).to receive(:read_uploader).and_return(nil)
310
+ end
311
+
312
+ context "when nothing has been assigned" do
313
+ it { expect(instance.images_cache).to be_nil }
314
+ end
315
+
316
+ context "when a file has been stored" do
317
+ before do
318
+ instance.images = [test_file_stub]
319
+ instance.store_images!
320
+ end
321
+
322
+ it { expect(instance.images_cache).to be_nil }
323
+ end
324
+
325
+ context "when a file has been cached" do
326
+ let(:json_response) { JSON.parse(instance.images_cache) }
327
+
328
+ before do
329
+ instance.images = [test_file_stub, stub_file('old.jpeg')]
330
+ end
331
+
332
+ it { expect(json_response[0]).to match(%r(^[\d]+\-[\d]+\-[\d]{4}\-[\d]{4}/test\.jpg$)) }
333
+
334
+ it { expect(json_response[1]).to match(%r(^[\d]+\-[\d]+\-[\d]{4}\-[\d]{4}/old\.jpeg$)) }
335
+ end
336
+ end
337
+
338
+ describe '#images_cache=' do
339
+ before do
340
+ allow(instance).to receive(:write_uploader)
341
+ allow(instance).to receive(:read_uploader).and_return(nil)
342
+ CarrierWave::SanitizedFile.new(test_file_stub).copy_to(public_path('uploads/tmp/1369894322-123-0123-1234/test.jpg'))
343
+ end
344
+
345
+ before { instance.images_cache = images_cache }
346
+
347
+ context "does nothing when nil is assigned" do
348
+ let(:images_cache) { nil }
349
+
350
+ it { expect(instance.images).to be_empty }
351
+ end
352
+
353
+ context "does nothing when an empty string is assigned" do
354
+ let(:images_cache) { '' }
355
+
356
+ it { expect(instance.images).to be_empty }
357
+ end
358
+
359
+ context "retrieve from cache when a cache name is assigned" do
360
+ let(:images_cache) { ['1369894322-123-0123-1234/test.jpg'].to_json }
361
+
362
+ it { expect(instance.images[0].current_path).to eq(public_path('uploads/tmp/1369894322-123-0123-1234/test.jpg')) }
363
+ end
364
+
365
+ context "doesn't write over a previously assigned file" do
366
+ let(:images_cache) { ['1369894322-123-0123-1234/monkey.jpg'].to_json }
367
+
368
+ before { instance.images = [test_file_stub] }
369
+
370
+ it { expect(instance.images[0].current_path).to match(/test.jpg$/) }
371
+ end
372
+ end
373
+
374
+ describe "#remote_images_urls" do
375
+ subject { instance.remote_images_urls }
376
+
377
+ before { stub_request(:get, "www.example.com/#{test_file_name}").to_return(body: File.read(test_file_stub)) }
378
+
379
+ context "returns nil" do
380
+ it { is_expected.to be_nil }
381
+ end
382
+
383
+ context "returns previously cached URL" do
384
+ before { instance.remote_images_urls = ["http://www.example.com/test.jpg"] }
385
+
386
+ it { is_expected.to eq(["http://www.example.com/test.jpg"]) }
387
+ end
388
+ end
389
+
390
+ describe "#remote_images_urls=" do
391
+ subject(:images) { instance.images }
392
+
393
+ before do
394
+ stub_request(:get, "www.example.com/#{test_file_name}").to_return(body: File.read(test_file_stub))
395
+ instance.remote_images_urls = remote_images_url
396
+ end
397
+
398
+ context "does nothing when nil is assigned" do
399
+ let(:remote_images_url) { nil }
400
+
401
+ it { is_expected.to be_empty }
402
+ end
403
+
404
+ context "does nothing when an empty string is assigned" do
405
+ let(:remote_images_url) { '' }
406
+
407
+ it { is_expected.to be_empty }
408
+ end
409
+
410
+ context "retrieves from cache when a cache name is assigned" do
411
+ subject { images[0].current_path }
412
+
413
+ let(:remote_images_url) { ["http://www.example.com/test.jpg"] }
414
+
415
+ it { is_expected.to match(/test.jpg$/) }
416
+ end
417
+
418
+ context "writes over a previously assigned file" do
419
+ subject { images[0].current_path }
420
+
421
+ let(:remote_images_url) { ["http://www.example.com/test.jpg"] }
422
+
423
+ before do
424
+ instance.images = [stub_file("portrait.jpg")]
425
+ instance.remote_images_urls = remote_images_url
426
+ end
427
+
428
+ it { is_expected.to match(/test.jpg$/) }
429
+ end
430
+ end
431
+
432
+ describe '#store_images!' do
433
+ before do
434
+ allow(instance).to receive(:write_uploader)
435
+ allow(instance).to receive(:read_uploader).and_return(nil)
436
+ end
437
+
438
+ context "does nothing when no file has been uploaded" do
439
+ before { instance.store_images! }
440
+
441
+ it { expect(instance.images).to be_empty }
442
+ end
443
+
444
+ context "stores an assigned file" do
445
+ let(:images) { [test_file_stub] }
446
+
447
+ before do
448
+ instance.images = images
449
+ instance.store_images!
450
+ end
451
+
452
+ it { expect(instance.images[0].current_path).to eq(public_path("uploads/#{test_file_name}")) }
453
+ end
454
+
455
+ context "removes an uploaded file when remove_images is true" do
456
+ let(:images) { [test_file_stub] }
457
+
458
+ before do
459
+ instance.images = images
460
+ @image_path = instance.images[0].current_path.dup
461
+ instance.remove_images = true
462
+ instance.store_images!
463
+ end
464
+
465
+ it { expect(instance.images).to be_empty }
466
+
467
+ it { expect(File.exist?(@image_path)).to be_falsey }
468
+ end
469
+ end
470
+
471
+ describe '#remove_images!' do
472
+ before do
473
+ allow(instance).to receive(:write_uploader)
474
+ allow(instance).to receive(:read_uploader).and_return(nil)
475
+ end
476
+
477
+ context "does nothing when no file has been uploaded" do
478
+ before { instance.remove_images! }
479
+
480
+ it { expect(instance.images).to be_empty }
481
+ end
482
+
483
+ context "removes an uploaded file" do
484
+ before do
485
+ instance.images = [test_file_stub]
486
+ @image_path = instance.images[0].current_path
487
+ instance.remove_images!
488
+ end
489
+
490
+ it { expect(instance.images).to be_empty }
491
+
492
+ it { expect(File.exist?(@image_path)).to be_falsey }
493
+ end
494
+ end
495
+
496
+ describe '#remove_images' do
497
+ before { instance.remove_images = true }
498
+
499
+ it "stores a value" do
500
+ expect(instance.remove_images).to be_truthy
501
+ end
502
+ end
503
+
504
+ describe '#remove_images?' do
505
+ subject { instance.remove_images? }
506
+
507
+ let(:remove_images) { true }
508
+
509
+ before { instance.remove_images = remove_images }
510
+
511
+ it "when value is true" do
512
+ is_expected.to be_truthy
513
+ end
514
+
515
+ context "when value is false" do
516
+ let(:remove_images) { false }
517
+
518
+ it { is_expected.to be_falsey }
519
+ end
520
+
521
+ context "when value is ''" do
522
+ let(:remove_images) { '' }
523
+
524
+ it { is_expected.to be_falsey }
525
+ end
526
+
527
+ context "when value is 0" do
528
+ let(:remove_images) { "0" }
529
+
530
+ it { is_expected.to be_falsey }
531
+ end
532
+
533
+ context "when value is false" do
534
+ let(:remove_images) { 'false' }
535
+
536
+ it { is_expected.to be_falsey }
537
+ end
538
+ end
539
+
540
+ describe '#images_integrity_error' do
541
+ subject(:images_integrity_error) { instance.images_integrity_error }
542
+
543
+ describe "default behaviour" do
544
+ it { is_expected.to be_nil }
545
+ end
546
+
547
+ context "when a file is cached" do
548
+ before { instance.images = test_file_stub }
549
+
550
+ it { is_expected.to be_nil }
551
+ end
552
+
553
+ describe "when an integrity check fails" do
554
+ before do
555
+ uploader.class_eval do
556
+ def extension_whitelist
557
+ %w(txt)
558
+ end
559
+ end
560
+ end
561
+
562
+ context "when file is cached" do
563
+ before { instance.images = [test_file_stub] }
564
+
565
+ it { is_expected.to be_an_instance_of(CarrierWave::IntegrityError) }
566
+
567
+ it "has an error message" do
568
+ expect(images_integrity_error.message.lines.grep(/^You are not allowed to upload/)).to be_truthy
569
+ end
570
+ end
571
+
572
+ context "when file was downloaded" do
573
+ before do
574
+ stub_request(:get, "www.example.com/#{test_file_name}").to_return(body: File.read(test_file_stub))
575
+ instance.remote_images_urls = ["http://www.example.com/#{test_file_name}"]
576
+ end
577
+
578
+ it { is_expected.to be_an_instance_of(CarrierWave::IntegrityError) }
579
+
580
+ it "has an error message" do
581
+ expect(images_integrity_error.message.lines.grep(/^You are not allowed to upload/)).to be_truthy
582
+ end
583
+ end
584
+
585
+ context "when file is assigned and remote_iamges_url is blank" do
586
+ before do
587
+ instance.images = [test_file_stub]
588
+ instance.remote_images_urls = ""
589
+ end
590
+
591
+ it { is_expected.to be_an_instance_of(CarrierWave::IntegrityError) }
592
+
593
+ it "has an error message" do
594
+ expect(images_integrity_error.message.lines.grep(/^You are not allowed to upload/)).to be_truthy
595
+ end
596
+ end
597
+ end
598
+ end
599
+
600
+ describe '#images_processing_error' do
601
+ subject(:images_processing_error) { instance.images_processing_error }
602
+
603
+ describe "default behavior" do
604
+ it { is_expected.to be_nil }
605
+ end
606
+
607
+ context "when file is cached" do
608
+ before { instance.images = [test_file_stub] }
609
+
610
+ it { is_expected.to be_nil }
611
+ end
612
+
613
+ describe "when an processing error occurs" do
614
+ before do
615
+ uploader.class_eval do
616
+ process :monkey
617
+ def monkey
618
+ raise CarrierWave::ProcessingError, "Ohh noez!"
619
+ end
620
+ end
621
+ end
622
+
623
+ context "when file is cached" do
624
+ before { instance.images = [test_file_stub] }
625
+
626
+ it { is_expected.to be_an_instance_of(CarrierWave::ProcessingError) }
627
+ end
628
+
629
+ context "when file was downloaded" do
630
+ before do
631
+ stub_request(:get, "www.example.com/#{test_file_name}").to_return(body: File.read(test_file_stub))
632
+ instance.remote_images_urls = ["http://www.example.com/#{test_file_name}"]
633
+ end
634
+
635
+ it { is_expected.to be_an_instance_of(CarrierWave::ProcessingError) }
636
+ end
637
+ end
638
+ end
639
+
640
+ describe '#images_download_error' do
641
+ subject(:images_download_error) { instance.images_download_error }
642
+
643
+ before do
644
+ stub_request(:get, "www.example.com/#{test_file_name}").to_return(body: File.read(test_file_stub))
645
+ stub_request(:get, "www.example.com/missing.jpg").to_return(status: 404)
646
+ end
647
+
648
+ describe "default behaviour" do
649
+ it { expect(instance.images_download_error).to be_nil }
650
+ end
651
+
652
+ context "when file download was successful" do
653
+ before { instance.remote_images_urls = ["http://www.example.com/#{test_file_name}"] }
654
+
655
+ it { is_expected.to be_nil }
656
+ end
657
+
658
+ context "when file couldn't be found" do
659
+ before { instance.remote_images_urls = ["http://www.example.com/missing.jpg"] }
660
+
661
+ it { is_expected.to be_an_instance_of(CarrierWave::DownloadError) }
662
+ end
663
+ end
664
+
665
+ describe '#write_images_identifier' do
666
+ after { instance.write_images_identifier }
667
+
668
+ it "writes to the column" do
669
+ expect(instance).to receive(:write_uploader).with(:images, [test_file_name]).at_least(:once)
670
+ instance.images = [test_file_stub]
671
+ instance.write_images_identifier
672
+ end
673
+
674
+ context "when remove_images is true" do
675
+ before do
676
+ instance.images = [test_file_name]
677
+ instance.store_images!
678
+ instance.remove_images = true
679
+ end
680
+
681
+ it "removes from the column when remove_images is true" do
682
+ expect(instance).to receive(:write_uploader).with(:images, nil)
683
+ end
684
+ end
685
+ end
686
+
687
+ describe '#images_identifiers' do
688
+ it "returns the identifier from the mounted column" do
689
+ expect(instance).to receive(:read_uploader).with(:images).and_return(test_file_name)
690
+ expect(instance.images_identifiers).to eq([test_file_name])
691
+ end
692
+ end
693
+ end
694
+
695
+ describe '#mount_uploaders without an uploader' do
696
+ let(:klass) do
697
+ Class.new.tap do |k|
698
+ k.send(:extend, CarrierWave::Mount)
699
+ k.mount_uploaders(:images)
700
+ end
701
+ end
702
+
703
+ let(:instance) { klass.new }
704
+
705
+ describe '#images' do
706
+ before do
707
+ allow(instance).to receive(:read_uploader).and_return(test_file_name)
708
+ end
709
+
710
+ it "returns an instance of a subclass of CarrierWave::Uploader::Base" do
711
+ expect(instance.images[0]).to be_a(CarrierWave::Uploader::Base)
712
+ end
713
+
714
+ it "sets the path to the store dir" do
715
+ expect(instance.images[0].current_path).to eq(public_path("uploads/#{test_file_name}"))
716
+ end
717
+ end
718
+ end
719
+
720
+ describe '#mount_uploaders with a block' do
721
+ describe 'and no uploader given' do
722
+ subject(:last_image) { instance.images[0] }
723
+
724
+ let(:klass) do
725
+ Class.new do |k|
726
+ k.send(:extend, CarrierWave::Mount)
727
+ k.mount_uploaders(:images) do
728
+ def monkey
729
+ 'blah'
730
+ end
731
+ end
732
+ end
733
+ end
734
+
735
+ before { instance.images = [test_file_stub] }
736
+
737
+ it "returns an instance of a subclass of CarrierWave::Uploader::Base" do
738
+ is_expected.to be_a(CarrierWave::Uploader::Base)
739
+ end
740
+
741
+ it "applies any custom modifications" do
742
+ expect(last_image.monkey).to eq("blah")
743
+ end
744
+ end
745
+
746
+ describe 'and an uploader given' do
747
+ let!(:uploader) do
748
+ Class.new(CarrierWave::Uploader::Base).tap do |u|
749
+ u.version :thumb do
750
+ version :mini
751
+ version :maxi
752
+ end
753
+ end
754
+ end
755
+
756
+ let(:klass) do
757
+ Class.new.tap do |k|
758
+ k.send(:extend, CarrierWave::Mount)
759
+ k.mount_uploaders(:images, uploader) do
760
+ def fish
761
+ 'blub'
762
+ end
763
+ end
764
+ end
765
+ end
766
+
767
+ let(:first_image) { instance.images[0] }
768
+
769
+ before { instance.images = [test_file_stub] }
770
+
771
+ it "returns an instance of the uploader specified" do
772
+ expect(first_image).to be_a_kind_of(uploader)
773
+ end
774
+
775
+ it "applies any custom modifications to the instance" do
776
+ expect(first_image.fish).to eq("blub")
777
+ end
778
+
779
+ it "applies any custom modifications to all defined versions" do
780
+ expect(first_image.thumb.fish).to eq("blub")
781
+ expect(first_image.thumb.mini.fish).to eq("blub")
782
+ expect(first_image.thumb.maxi.fish).to eq("blub")
783
+ end
784
+
785
+ it "applies any custom modifications to the uploader class" do
786
+ expect(uploader.new).not_to respond_to(:fish)
787
+ end
788
+ end
789
+ end
790
+
791
+ describe '#mount_uploaders with :ignore_integrity_errors => false' do
792
+ let(:klass) do
793
+ Class.new.tap do |k|
794
+ k.send(:extend, CarrierWave::Mount)
795
+ k.mount_uploaders(:images, uploader, :ignore_integrity_errors => false)
796
+ end
797
+ end
798
+
799
+ let(:uploader) do
800
+ Class.new(CarrierWave::Uploader::Base).tap do |u|
801
+ u.class_eval do
802
+ def extension_whitelist
803
+ %w(txt)
804
+ end
805
+ end
806
+ end
807
+ end
808
+
809
+ context "when a cached image fails an integrity check" do
810
+ it { expect(running { instance.images = [test_file_stub] }).to raise_error(CarrierWave::IntegrityError) }
811
+ end
812
+
813
+ context "when a downloaded image fails an integity check" do
814
+ before do
815
+ stub_request(:get, "www.example.com/#{test_file_name}").to_return(body: test_file_stub)
816
+ end
817
+
818
+ it { expect(running {instance.remote_images_urls = ["http://www.example.com/#{test_file_name}"]}).to raise_error(CarrierWave::IntegrityError) }
819
+ end
820
+ end
821
+
822
+ describe '#mount_uploaders with :ignore_processing_errors => false' do
823
+ let(:klass) do
824
+ Class.new.tap do |k|
825
+ k.send(:extend, CarrierWave::Mount)
826
+ k.mount_uploaders(:images, uploader, :ignore_processing_errors => false)
827
+ end
828
+ end
829
+
830
+ let(:uploader) do
831
+ Class.new(CarrierWave::Uploader::Base).tap do |u|
832
+ u.class_eval do
833
+ process :monkey
834
+ def monkey
835
+ raise CarrierWave::ProcessingError, "Ohh noez!"
836
+ end
837
+ end
838
+ end
839
+ end
840
+
841
+ context "when a cached image fails an integrity check" do
842
+ it { expect(running { instance.images = [test_file_stub] }).to raise_error(CarrierWave::ProcessingError) }
843
+ end
844
+
845
+ context "when a downloaded image fails an integity check" do
846
+ before do
847
+ stub_request(:get, "www.example.com/#{test_file_name}").to_return(body: test_file_stub)
848
+ end
849
+
850
+ it { expect(running {instance.remote_images_urls = ["http://www.example.com/#{test_file_name}"]}).to raise_error(CarrierWave::ProcessingError) }
851
+ end
852
+ end
853
+
854
+ describe '#mount_uploaders with :ignore_download_errors => false' do
855
+ let(:klass) do
856
+ Class.new.tap do |k|
857
+ k.send(:extend, CarrierWave::Mount)
858
+ k.mount_uploaders(:images, uploader, ignore_download_errors: false)
859
+ end
860
+ end
861
+
862
+ let(:uploader) { Class.new(CarrierWave::Uploader::Base) }
863
+
864
+ before do
865
+ uploader.class_eval do
866
+ def download! uri
867
+ raise CarrierWave::DownloadError
868
+ end
869
+ end
870
+ end
871
+
872
+ context "when the image fail to be processed" do
873
+ it { expect(running {instance.remote_images_urls = ["http://www.example.com/#{test_file_name}"]}).to raise_error(CarrierWave::DownloadError) }
874
+ end
875
+ end
876
+
877
+ describe '#mount_uploaders with :mount_on => :monkey' do
878
+ let(:klass) do
879
+ Class.new.tap do |k|
880
+ k.send(:extend, CarrierWave::Mount)
881
+ k.mount_uploaders(:images, uploader, mount_on: :monkey)
882
+ end
883
+ end
884
+
885
+ let(:uploader) { Class.new(CarrierWave::Uploader::Base) }
886
+
887
+ describe '#images' do
888
+ context "when a value is store in the database" do
889
+ it "retrieves a file from the storage" do
890
+ expect(instance).to receive(:read_uploader).at_least(:once).with(:monkey).and_return([test_file_name])
891
+ expect(instance.images[0]).to be_an_instance_of(uploader)
892
+ expect(instance.images[0].current_path).to eq(public_path("uploads/#{test_file_name}"))
893
+ end
894
+ end
895
+ end
896
+
897
+ describe '#write_images_identifier' do
898
+ it "writes to the given column" do
899
+ expect(instance).to receive(:write_uploader).with(:monkey, [test_file_name])
900
+ instance.images = [test_file_stub]
901
+ instance.write_images_identifier
902
+ end
903
+
904
+ it "removes from the given column when remove_images is true" do
905
+ instance.images = [test_file_stub]
906
+ instance.store_images!
907
+ instance.remove_images = true
908
+ expect(instance).to receive(:write_uploader).with(:monkey, nil)
909
+ instance.write_images_identifier
910
+ end
911
+ end
912
+ end
913
+ end