solidus_starter_frontend 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (301) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +57 -0
  3. data/.erb-lint.yml +22 -0
  4. data/.eslintrc +5 -0
  5. data/.gem_release.yml +5 -0
  6. data/.github/pull_request_template.md +28 -0
  7. data/.github/stale.yml +17 -0
  8. data/.gitignore +17 -0
  9. data/.hound.yml +16 -0
  10. data/.rspec +2 -0
  11. data/.rubocop.yml +19 -0
  12. data/.rubocop_todo.yml +229 -0
  13. data/.scss-lint.yml +4 -0
  14. data/Gemfile +34 -0
  15. data/LICENSE +26 -0
  16. data/README.md +69 -0
  17. data/Rakefile +6 -0
  18. data/app/assets/config/solidus_starter_frontend_manifest.js +2 -0
  19. data/app/assets/javascripts/spree/frontend.js +6 -0
  20. data/app/assets/javascripts/spree/frontend/cart.js +26 -0
  21. data/app/assets/javascripts/spree/frontend/checkout.js +34 -0
  22. data/app/assets/javascripts/spree/frontend/checkout/address.js +124 -0
  23. data/app/assets/javascripts/spree/frontend/checkout/payment.js +44 -0
  24. data/app/assets/javascripts/spree/frontend/locale_selector.js +9 -0
  25. data/app/assets/javascripts/spree/frontend/product.js +21 -0
  26. data/app/assets/javascripts/spree/frontend/solidus_starter_frontend.js +9 -0
  27. data/app/assets/javascripts/spree/frontend/utils.js.erb +18 -0
  28. data/app/assets/stylesheets/spree/frontend.css +8 -0
  29. data/app/assets/stylesheets/spree/frontend/base/_base.scss +29 -0
  30. data/app/assets/stylesheets/spree/frontend/base/_reset.scss +179 -0
  31. data/app/assets/stylesheets/spree/frontend/base/_responsive.scss +21 -0
  32. data/app/assets/stylesheets/spree/frontend/components/account/_account_order.scss +23 -0
  33. data/app/assets/stylesheets/spree/frontend/components/account/_account_summary.scss +17 -0
  34. data/app/assets/stylesheets/spree/frontend/components/auth/_auth_container.scss +11 -0
  35. data/app/assets/stylesheets/spree/frontend/components/auth/_auth_form.scss +5 -0
  36. data/app/assets/stylesheets/spree/frontend/components/brand/_logo.scss +4 -0
  37. data/app/assets/stylesheets/spree/frontend/components/buttons/_button_inline.scss +8 -0
  38. data/app/assets/stylesheets/spree/frontend/components/buttons/_button_primary.scss +26 -0
  39. data/app/assets/stylesheets/spree/frontend/components/cart/_cart_adjustments.scss +6 -0
  40. data/app/assets/stylesheets/spree/frontend/components/cart/_cart_amount_row.scss +11 -0
  41. data/app/assets/stylesheets/spree/frontend/components/cart/_cart_empty.scss +10 -0
  42. data/app/assets/stylesheets/spree/frontend/components/cart/_cart_footer.scss +20 -0
  43. data/app/assets/stylesheets/spree/frontend/components/cart/_cart_header.scss +12 -0
  44. data/app/assets/stylesheets/spree/frontend/components/cart/_cart_item.scss +86 -0
  45. data/app/assets/stylesheets/spree/frontend/components/cart/_cart_link.scss +22 -0
  46. data/app/assets/stylesheets/spree/frontend/components/cart/_cart_page.scss +15 -0
  47. data/app/assets/stylesheets/spree/frontend/components/cart/_cart_secondary_actions.scss +19 -0
  48. data/app/assets/stylesheets/spree/frontend/components/cart/_coupon_code.scss +8 -0
  49. data/app/assets/stylesheets/spree/frontend/components/cart/_item_info.scss +19 -0
  50. data/app/assets/stylesheets/spree/frontend/components/checkout/_checkout.scss +27 -0
  51. data/app/assets/stylesheets/spree/frontend/components/checkout/_checkout_header.scss +19 -0
  52. data/app/assets/stylesheets/spree/frontend/components/checkout/_checkout_summary.scss +31 -0
  53. data/app/assets/stylesheets/spree/frontend/components/checkout/_existing_cards.scss +27 -0
  54. data/app/assets/stylesheets/spree/frontend/components/checkout/_payment_method_controls.scss +5 -0
  55. data/app/assets/stylesheets/spree/frontend/components/checkout/_payment_method_selector.scss +14 -0
  56. data/app/assets/stylesheets/spree/frontend/components/checkout/_progress_steps.scss +38 -0
  57. data/app/assets/stylesheets/spree/frontend/components/checkout/_proposed_shipment.scss +18 -0
  58. data/app/assets/stylesheets/spree/frontend/components/checkout/_shipment_items.scss +50 -0
  59. data/app/assets/stylesheets/spree/frontend/components/checkout/_shipping_methods.scss +9 -0
  60. data/app/assets/stylesheets/spree/frontend/components/checkout/payments/_gateway_payment_method.scss +11 -0
  61. data/app/assets/stylesheets/spree/frontend/components/checkout/steps/_address_step.scss +20 -0
  62. data/app/assets/stylesheets/spree/frontend/components/checkout/steps/_confirm_step.scss +13 -0
  63. data/app/assets/stylesheets/spree/frontend/components/checkout/steps/_delivery_step.scss +13 -0
  64. data/app/assets/stylesheets/spree/frontend/components/checkout/steps/_payment_step.scss +13 -0
  65. data/app/assets/stylesheets/spree/frontend/components/forms/_address_inputs.scss +13 -0
  66. data/app/assets/stylesheets/spree/frontend/components/forms/inputs/_checkbox_input.scss +3 -0
  67. data/app/assets/stylesheets/spree/frontend/components/forms/inputs/_radio_input.scss +3 -0
  68. data/app/assets/stylesheets/spree/frontend/components/forms/inputs/_select_input.scss +27 -0
  69. data/app/assets/stylesheets/spree/frontend/components/forms/inputs/_text.scss +32 -0
  70. data/app/assets/stylesheets/spree/frontend/components/forms/inputs/_textarea_input.scss +25 -0
  71. data/app/assets/stylesheets/spree/frontend/components/general/_flash.scss +20 -0
  72. data/app/assets/stylesheets/spree/frontend/components/layout/_aside.scss +4 -0
  73. data/app/assets/stylesheets/spree/frontend/components/layout/_breadcrumbs.scss +16 -0
  74. data/app/assets/stylesheets/spree/frontend/components/layout/_category_navigation.scss +3 -0
  75. data/app/assets/stylesheets/spree/frontend/components/layout/_footer.scss +8 -0
  76. data/app/assets/stylesheets/spree/frontend/components/layout/_header.scss +12 -0
  77. data/app/assets/stylesheets/spree/frontend/components/layout/_horizontal_input_group.scss +7 -0
  78. data/app/assets/stylesheets/spree/frontend/components/layout/_top_bar.scss +44 -0
  79. data/app/assets/stylesheets/spree/frontend/components/navigation/_auth_link.scss +11 -0
  80. data/app/assets/stylesheets/spree/frontend/components/navigation/_categories.scss +29 -0
  81. data/app/assets/stylesheets/spree/frontend/components/navigation/_locale_selector.scss +21 -0
  82. data/app/assets/stylesheets/spree/frontend/components/navigation/_taxonomies.scss +7 -0
  83. data/app/assets/stylesheets/spree/frontend/components/navigation/_taxonomy.scss +28 -0
  84. data/app/assets/stylesheets/spree/frontend/components/orders/_address_overview.scss +27 -0
  85. data/app/assets/stylesheets/spree/frontend/components/orders/_coupon_codes.scss +4 -0
  86. data/app/assets/stylesheets/spree/frontend/components/orders/_line_items.scss +20 -0
  87. data/app/assets/stylesheets/spree/frontend/components/orders/_order_details.scss +18 -0
  88. data/app/assets/stylesheets/spree/frontend/components/orders/_order_item.scss +85 -0
  89. data/app/assets/stylesheets/spree/frontend/components/orders/_order_page.scss +41 -0
  90. data/app/assets/stylesheets/spree/frontend/components/orders/_order_shipments.scss +27 -0
  91. data/app/assets/stylesheets/spree/frontend/components/orders/_payment_info.scss +29 -0
  92. data/app/assets/stylesheets/spree/frontend/components/presentation/_hero.scss +18 -0
  93. data/app/assets/stylesheets/spree/frontend/components/products/_product_card.scss +35 -0
  94. data/app/assets/stylesheets/spree/frontend/components/products/_product_image.scss +7 -0
  95. data/app/assets/stylesheets/spree/frontend/components/products/_product_info.scss +14 -0
  96. data/app/assets/stylesheets/spree/frontend/components/products/_product_page.scss +31 -0
  97. data/app/assets/stylesheets/spree/frontend/components/products/_product_properties.scss +23 -0
  98. data/app/assets/stylesheets/spree/frontend/components/products/_product_submit.scss +9 -0
  99. data/app/assets/stylesheets/spree/frontend/components/products/_product_taxons.scss +27 -0
  100. data/app/assets/stylesheets/spree/frontend/components/products/_product_thumbnails.scss +7 -0
  101. data/app/assets/stylesheets/spree/frontend/components/products/_product_variants.scss +20 -0
  102. data/app/assets/stylesheets/spree/frontend/components/products/_products.scss +13 -0
  103. data/app/assets/stylesheets/spree/frontend/components/products/_products_by_taxon.scss +6 -0
  104. data/app/assets/stylesheets/spree/frontend/components/products/_products_grid.scss +18 -0
  105. data/app/assets/stylesheets/spree/frontend/components/search/_filter.scss +32 -0
  106. data/app/assets/stylesheets/spree/frontend/components/search/_search_bar.scss +34 -0
  107. data/app/assets/stylesheets/spree/frontend/components/typography/_hero_title.scss +6 -0
  108. data/app/assets/stylesheets/spree/frontend/components/typography/_subtitle.scss +7 -0
  109. data/app/assets/stylesheets/spree/frontend/placeholders/main.scss +5 -0
  110. data/app/assets/stylesheets/spree/frontend/screen.scss +89 -0
  111. data/app/assets/stylesheets/spree/frontend/solidus_starter_frontend.css +7 -0
  112. data/app/assets/stylesheets/spree/frontend/variables/_colors.scss +20 -0
  113. data/app/controllers/concerns/solidus_starter_frontend/auth_views.rb +16 -0
  114. data/app/controllers/concerns/solidus_starter_frontend/taxonomies.rb +16 -0
  115. data/app/controllers/spree/checkout_controller.rb +249 -0
  116. data/app/controllers/spree/coupon_codes_controller.rb +35 -0
  117. data/app/controllers/spree/home_controller.rb +13 -0
  118. data/app/controllers/spree/locale_controller.rb +20 -0
  119. data/app/controllers/spree/orders_controller.rb +126 -0
  120. data/app/controllers/spree/products_controller.rb +51 -0
  121. data/app/controllers/spree/store_controller.rb +31 -0
  122. data/app/controllers/spree/taxons_controller.rb +30 -0
  123. data/app/helpers/spree/orders_helper.rb +18 -0
  124. data/app/helpers/spree/taxon_filters_helper.rb +13 -0
  125. data/app/views/spree/address/_form_hidden.html.erb +12 -0
  126. data/app/views/spree/checkout/_terms_and_conditions.en.html.erb +1 -0
  127. data/app/views/spree/checkout/edit.html.erb +16 -0
  128. data/app/views/spree/checkout/existing_payment/_gateway.html.erb +9 -0
  129. data/app/views/spree/checkout/payment/_check.html.erb +0 -0
  130. data/app/views/spree/checkout/payment/_gateway.html.erb +43 -0
  131. data/app/views/spree/components/auth/_change_form.html.erb +40 -0
  132. data/app/views/spree/components/auth/_forgot_form.html.erb +28 -0
  133. data/app/views/spree/components/auth/_guest_form.html.erb +31 -0
  134. data/app/views/spree/components/auth/_login_form.html.erb +42 -0
  135. data/app/views/spree/components/auth/_signup_form.html.erb +48 -0
  136. data/app/views/spree/components/brand/_logo.html.erb +3 -0
  137. data/app/views/spree/components/buttons/_button_inline.html.erb +23 -0
  138. data/app/views/spree/components/buttons/_button_primary.html.erb +29 -0
  139. data/app/views/spree/components/cart/_cart_adjustment.html.erb +15 -0
  140. data/app/views/spree/components/cart/_cart_adjustments.html.erb +47 -0
  141. data/app/views/spree/components/cart/_cart_amount_row.html.erb +12 -0
  142. data/app/views/spree/components/cart/_cart_empty.html.erb +9 -0
  143. data/app/views/spree/components/cart/_cart_footer.html.erb +15 -0
  144. data/app/views/spree/components/cart/_cart_header.html.erb +17 -0
  145. data/app/views/spree/components/cart/_cart_item.html.erb +52 -0
  146. data/app/views/spree/components/cart/_cart_items.html.erb +23 -0
  147. data/app/views/spree/components/cart/_cart_link.html.erb +9 -0
  148. data/app/views/spree/components/cart/_cart_secondary_actions.html.erb +17 -0
  149. data/app/views/spree/components/cart/_item_info.html.erb +26 -0
  150. data/app/views/spree/components/checkout/_checkout_header.html.erb +8 -0
  151. data/app/views/spree/components/checkout/_checkout_step.html.erb +21 -0
  152. data/app/views/spree/components/checkout/_checkout_summary.html.erb +70 -0
  153. data/app/views/spree/components/checkout/_existing_cards.html.erb +39 -0
  154. data/app/views/spree/components/checkout/_payment_method_controls.html.erb +10 -0
  155. data/app/views/spree/components/checkout/_payment_method_selector.html.erb +14 -0
  156. data/app/views/spree/components/checkout/_proposed_shipment.erb +18 -0
  157. data/app/views/spree/components/checkout/_shipment_items.html.erb +22 -0
  158. data/app/views/spree/components/checkout/_shipping_methods.html.erb +20 -0
  159. data/app/views/spree/components/checkout/_unshippable_items.html.erb +7 -0
  160. data/app/views/spree/components/checkout/steps/_address_step.html.erb +60 -0
  161. data/app/views/spree/components/checkout/steps/_confirm_step.html.erb +31 -0
  162. data/app/views/spree/components/checkout/steps/_delivery_step.html.erb +31 -0
  163. data/app/views/spree/components/checkout/steps/_payment_step.html.erb +25 -0
  164. data/app/views/spree/components/forms/_address_inputs.html.erb +152 -0
  165. data/app/views/spree/components/forms/inputs/_checkbox_input.html.erb +29 -0
  166. data/app/views/spree/components/forms/inputs/_collection_select.html.erb +42 -0
  167. data/app/views/spree/components/forms/inputs/_radio_input.html.erb +29 -0
  168. data/app/views/spree/components/forms/inputs/_select_input.html.erb +31 -0
  169. data/app/views/spree/components/forms/inputs/_text.html.erb +54 -0
  170. data/app/views/spree/components/forms/inputs/_textarea_input.html.erb +42 -0
  171. data/app/views/spree/components/layout/_category_navigation.html.erb +3 -0
  172. data/app/views/spree/components/layout/_footer.html.erb +7 -0
  173. data/app/views/spree/components/layout/_header.html.erb +8 -0
  174. data/app/views/spree/components/layout/_top_bar.html.erb +8 -0
  175. data/app/views/spree/components/navigation/_auth_link.html.erb +1 -0
  176. data/app/views/spree/components/navigation/_breadcrumbs.html.erb +47 -0
  177. data/app/views/spree/components/navigation/_categories.html.erb +12 -0
  178. data/app/views/spree/components/navigation/_locale_selector.html.erb +25 -0
  179. data/app/views/spree/components/navigation/_taxonomies.html.erb +17 -0
  180. data/app/views/spree/components/navigation/_taxons.html.erb +17 -0
  181. data/app/views/spree/components/navigation/_taxons_tree.html.erb +29 -0
  182. data/app/views/spree/components/orders/_address_overview.html.erb +40 -0
  183. data/app/views/spree/components/orders/_coupon_code.html.erb +22 -0
  184. data/app/views/spree/components/orders/_line_items.html.erb +55 -0
  185. data/app/views/spree/components/orders/_order_details.html.erb +35 -0
  186. data/app/views/spree/components/orders/_order_item.html.erb +33 -0
  187. data/app/views/spree/components/orders/_order_items.html.erb +5 -0
  188. data/app/views/spree/components/orders/_order_shipments.html.erb +25 -0
  189. data/app/views/spree/components/orders/_payment_info.html.erb +31 -0
  190. data/app/views/spree/components/presentation/_hero.html.erb +14 -0
  191. data/app/views/spree/components/products/_product-card.html.erb +36 -0
  192. data/app/views/spree/components/products/_product_availability.html.erb +19 -0
  193. data/app/views/spree/components/products/_product_form.html.erb +21 -0
  194. data/app/views/spree/components/products/_product_image.html.erb +6 -0
  195. data/app/views/spree/components/products/_product_info.html.erb +9 -0
  196. data/app/views/spree/components/products/_product_promotions.html.erb +25 -0
  197. data/app/views/spree/components/products/_product_properties.html.erb +19 -0
  198. data/app/views/spree/components/products/_product_submit.html.erb +39 -0
  199. data/app/views/spree/components/products/_product_taxons.html.erb +15 -0
  200. data/app/views/spree/components/products/_product_thumbnails.html.erb +19 -0
  201. data/app/views/spree/components/products/_product_variants.html.erb +36 -0
  202. data/app/views/spree/components/products/_products-grid.html.erb +13 -0
  203. data/app/views/spree/components/products/_products.html.erb +28 -0
  204. data/app/views/spree/components/products/_products_by_taxon.html.erb +7 -0
  205. data/app/views/spree/components/products/_variants_list.html.erb +12 -0
  206. data/app/views/spree/components/search/_filter.html.erb +42 -0
  207. data/app/views/spree/components/search/_filters.html.erb +20 -0
  208. data/app/views/spree/components/search/_form.html.erb +12 -0
  209. data/app/views/spree/components/search/_products_search.html.erb +36 -0
  210. data/app/views/spree/components/search/_search_bar.html.erb +36 -0
  211. data/app/views/spree/components/typography/_hero_title.html.erb +11 -0
  212. data/app/views/spree/components/typography/_subtitle.html.erb +11 -0
  213. data/app/views/spree/home/index.html.erb +7 -0
  214. data/app/views/spree/layouts/spree_application.html.erb +27 -0
  215. data/app/views/spree/orders/edit.html.erb +21 -0
  216. data/app/views/spree/orders/show.html.erb +29 -0
  217. data/app/views/spree/products/index.html.erb +22 -0
  218. data/app/views/spree/products/show.html.erb +18 -0
  219. data/app/views/spree/shared/_image.html.erb +12 -0
  220. data/app/views/spree/shared/_link_to_cart.html.erb +1 -0
  221. data/app/views/spree/shared/_login_bar_items.html.erb +1 -0
  222. data/app/views/spree/shared/_shipment_tracking.html.erb +11 -0
  223. data/app/views/spree/shared/unauthorized.html.erb +0 -0
  224. data/app/views/spree/taxons/show.html.erb +17 -0
  225. data/bin/console +17 -0
  226. data/bin/r +13 -0
  227. data/bin/rails +7 -0
  228. data/bin/rake +7 -0
  229. data/bin/rspec +29 -0
  230. data/bin/sandbox +84 -0
  231. data/bin/sandbox_rails +18 -0
  232. data/bin/setup +8 -0
  233. data/bin/solidus_compare +155 -0
  234. data/config/initializers/assets.rb +1 -0
  235. data/config/initializers/canonical_rails.rb +16 -0
  236. data/config/locales/en.yml +5 -0
  237. data/config/routes.rb +33 -0
  238. data/config/solidus_compare.yml +33 -0
  239. data/docs/development.md +28 -0
  240. data/exe/solidus_starter_frontend +9 -0
  241. data/lib/generators/solidus_starter_frontend/install/install_generator.rb +15 -0
  242. data/lib/generators/solidus_starter_frontend/solidus_starter_frontend_generator.rb +30 -0
  243. data/lib/generators/solidus_starter_frontend/views/override_generator.rb +50 -0
  244. data/lib/solidus_starter_frontend.rb +12 -0
  245. data/lib/solidus_starter_frontend/config.rb +7 -0
  246. data/lib/solidus_starter_frontend/engine.rb +34 -0
  247. data/lib/solidus_starter_frontend/factories.rb +4 -0
  248. data/lib/solidus_starter_frontend/solidus_support_extensions.rb +9 -0
  249. data/lib/solidus_starter_frontend/version.rb +5 -0
  250. data/lib/solidus_starter_frontend_configuration.rb +8 -0
  251. data/lib/views/auth/spree/checkout/registration.html.erb +7 -0
  252. data/lib/views/auth/spree/components/navigation/_auth_link.html.erb +5 -0
  253. data/lib/views/auth/spree/user_passwords/edit.html.erb +7 -0
  254. data/lib/views/auth/spree/user_passwords/new.html.erb +5 -0
  255. data/lib/views/auth/spree/user_registrations/new.html.erb +7 -0
  256. data/lib/views/auth/spree/user_sessions/guest.html.erb +5 -0
  257. data/lib/views/auth/spree/user_sessions/new.html.erb +7 -0
  258. data/lib/views/auth/spree/users/edit.html.erb +45 -0
  259. data/lib/views/auth/spree/users/show.html.erb +55 -0
  260. data/solidus_starter_frontend.gemspec +43 -0
  261. data/spec/controllers/controller_helpers_spec.rb +29 -0
  262. data/spec/controllers/locale_controller_spec.rb +57 -0
  263. data/spec/controllers/spree/checkout_controller_spec.rb +563 -0
  264. data/spec/controllers/spree/checkout_controller_with_views_spec.rb +37 -0
  265. data/spec/controllers/spree/current_order_tracking_spec.rb +33 -0
  266. data/spec/controllers/spree/home_controller_spec.rb +29 -0
  267. data/spec/controllers/spree/orders_controller_ability_spec.rb +90 -0
  268. data/spec/controllers/spree/orders_controller_spec.rb +241 -0
  269. data/spec/controllers/spree/orders_controller_transitions_spec.rb +33 -0
  270. data/spec/controllers/spree/products_controller_spec.rb +38 -0
  271. data/spec/controllers/spree/taxons_controller_spec.rb +14 -0
  272. data/spec/fixtures/thinking-cat.jpg +0 -0
  273. data/spec/generators/solidus/views/override_generator_spec.rb +50 -0
  274. data/spec/helpers/base_helper_spec.rb +13 -0
  275. data/spec/helpers/order_helper_spec.rb +14 -0
  276. data/spec/helpers/taxon_filters_helper_spec.rb +12 -0
  277. data/spec/spec_helper.rb +64 -0
  278. data/spec/support/shared_contexts/checkout_setup.rb +12 -0
  279. data/spec/support/shared_contexts/custom_products.rb +28 -0
  280. data/spec/support/shared_contexts/locales.rb +16 -0
  281. data/spec/system/address_spec.rb +87 -0
  282. data/spec/system/automatic_promotion_adjustments_spec.rb +49 -0
  283. data/spec/system/caching/products_spec.rb +48 -0
  284. data/spec/system/caching/taxons_spec.rb +35 -0
  285. data/spec/system/cart_spec.rb +81 -0
  286. data/spec/system/checkout_confirm_insufficient_stock_spec.rb +71 -0
  287. data/spec/system/checkout_spec.rb +699 -0
  288. data/spec/system/checkout_unshippable_spec.rb +37 -0
  289. data/spec/system/coupon_code_spec.rb +267 -0
  290. data/spec/system/currency_spec.rb +20 -0
  291. data/spec/system/first_order_promotion_spec.rb +59 -0
  292. data/spec/system/free_shipping_promotions_spec.rb +60 -0
  293. data/spec/system/locale_spec.rb +26 -0
  294. data/spec/system/order_spec.rb +57 -0
  295. data/spec/system/products_spec.rb +302 -0
  296. data/spec/system/promotion_code_invalidation_spec.rb +54 -0
  297. data/spec/system/quantity_promotions_spec.rb +130 -0
  298. data/spec/system/taxons_spec.rb +158 -0
  299. data/spec/system/template_rendering_spec.rb +20 -0
  300. data/spec/views/spree/checkout/_summary_spec.rb +11 -0
  301. metadata +542 -0
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'taxons', type: :system, caching: true do
6
+ let!(:taxonomy) { create(:taxonomy) }
7
+ let!(:taxon) { create(:taxon, taxonomy: taxonomy, parent: taxonomy.root) }
8
+
9
+ before do
10
+ # Warm up the cache
11
+ visit spree.products_path
12
+
13
+ clear_cache_events
14
+ end
15
+
16
+ it "busts the cache when a taxon changes" do
17
+ taxon.touch(:updated_at)
18
+
19
+ visit spree.products_path
20
+ # Cache rewrites:
21
+ # - 2 x categories component
22
+ # - 1 x taxons list in search form
23
+ # - 1 x categories in navigation
24
+ expect(cache_writes.count).to eq(4)
25
+ end
26
+
27
+ it "busts the cache when max_level_in_taxons_menu conf changes" do
28
+ stub_spree_preferences(max_level_in_taxons_menu: 5)
29
+ visit spree.products_path
30
+
31
+ # Cache rewrites:
32
+ # - 2 x categories component
33
+ expect(cache_writes.count).to eq(2)
34
+ end
35
+ end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'Cart', type: :system, inaccessible: true do
6
+ before { create(:store) }
7
+
8
+ it "shows cart icon on non-cart pages" do
9
+ visit spree.root_path
10
+ expect(page).to have_selector("#link-to-cart a", visible: true)
11
+ end
12
+
13
+ it "prevents double clicking the remove button on cart", js: true do
14
+ @product = create(:product, name: "RoR Mug")
15
+
16
+ visit spree.root_path
17
+ click_link "RoR Mug"
18
+ click_button "add-to-cart-button"
19
+
20
+ # prevent form submit to verify button is disabled
21
+ page.execute_script("$('#update-cart').submit(function(){return false;})")
22
+
23
+ expect(page).not_to have_selector('button#update-button[disabled]')
24
+ find('.delete').click
25
+ expect(page).to have_selector('button#update-button[disabled]')
26
+ end
27
+
28
+ # Regression test for https://github.com/spree/spree/issues/2006
29
+ it "does not error out with a 404 when GET'ing to /orders/populate" do
30
+ visit '/orders/populate'
31
+ within(".error") do
32
+ expect(page).to have_content(I18n.t('spree.populate_get_error'))
33
+ end
34
+ end
35
+
36
+ it 'allows you to remove an item from the cart', js: true do
37
+ create(:product, name: "RoR Mug")
38
+ visit spree.root_path
39
+ click_link "RoR Mug"
40
+ click_button "add-to-cart-button"
41
+ find('.delete').click
42
+ expect(page).not_to have_content("Line items quantity must be an integer")
43
+ expect(page).not_to have_content("RoR Mug")
44
+ expect(page).to have_content("Your cart is empty")
45
+
46
+ within "#link-to-cart" do
47
+ expect(page).to have_content(/empty/i)
48
+ end
49
+ end
50
+
51
+ it 'allows you to empty the cart', js: true do
52
+ create(:product, name: "RoR Mug")
53
+ visit spree.root_path
54
+ click_link "RoR Mug"
55
+ click_button "add-to-cart-button"
56
+
57
+ expect(page).to have_content("RoR Mug")
58
+ click_on "Empty Cart"
59
+ expect(page).to have_content("Your cart is empty")
60
+
61
+ within "#link-to-cart" do
62
+ expect(page).to have_content(/empty/i)
63
+ end
64
+ end
65
+
66
+ # regression for https://github.com/spree/spree/issues/2276
67
+ context "product contains variants but no option values" do
68
+ let(:variant) { create(:variant) }
69
+ let(:product) { variant.product }
70
+
71
+ before { variant.option_values.destroy_all }
72
+
73
+ it "still adds product to cart", inaccessible: true do
74
+ visit spree.product_path(product)
75
+ click_button "add-to-cart-button"
76
+
77
+ visit spree.cart_path
78
+ expect(page).to have_content(product.name)
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'Checkout confirm page submission', type: :system do
6
+ include_context 'checkout setup'
7
+
8
+ context "when the product from the order is not backorderable but has enough stock quantity" do
9
+ let(:user) { create(:user) }
10
+
11
+ let(:order) { Spree::TestingSupport::OrderWalkthrough.up_to(:payment) }
12
+ let(:order_product) { order.products.first }
13
+ let(:order_stock_item) { order_product.stock_items.first }
14
+
15
+ before do
16
+ order_stock_item.update! backorderable: false
17
+ order_stock_item.set_count_on_hand(1)
18
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(current_order: order)
19
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(try_spree_current_user: user)
20
+ allow_any_instance_of(Spree::OrdersController).to receive_messages(try_spree_current_user: user)
21
+ end
22
+
23
+ context 'when there are not other backorderable stock locations' do
24
+ context 'when the customer is on the confirm page and the availabilty drops to zero' do
25
+ before do
26
+ visit spree.checkout_state_path(:confirm)
27
+ order_stock_item.set_count_on_hand(0)
28
+ end
29
+
30
+ it 'redirects to cart page and shows an unavailable product message' do
31
+ click_button "Place Order"
32
+ expect(page).to have_content "#{order_product.name} became unavailable"
33
+ expect(page).to have_current_path spree.cart_path
34
+ end
35
+ end
36
+ end
37
+
38
+ context 'when there is another backorderable stock location' do
39
+ before do
40
+ create :stock_location, backorderable_default: true, default: false
41
+ end
42
+
43
+ context 'when the customer is on the confirm page and the availabilty drops to zero' do
44
+ before do
45
+ visit spree.checkout_state_path(:confirm)
46
+ order_stock_item.set_count_on_hand(0)
47
+ end
48
+
49
+ it "redirects to the address checkout page and shows an availability changed message" do
50
+ click_button "Place Order"
51
+ error_message = "Quantity selected of #{order_product.name} is not available. Still, items may be available from another stock location, please try again."
52
+ expect(page).to have_content error_message
53
+ expect(page).to have_current_path spree.checkout_state_path(:address)
54
+ end
55
+
56
+ it "can still complete the order using the backorderable stock location by restarting the checkout" do
57
+ click_button "Place Order"
58
+ expect(page).to have_current_path spree.checkout_state_path(:address)
59
+ click_button "Save and Continue"
60
+ expect(page).to have_current_path spree.checkout_state_path(:delivery)
61
+ click_button "Save and Continue"
62
+ expect(page).to have_current_path spree.checkout_state_path(:payment)
63
+ click_button "Save and Continue"
64
+ expect(page).to have_current_path spree.checkout_state_path(:confirm)
65
+ click_button "Place Order"
66
+ expect(page).to have_content 'Your order has been processed successfully'
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,699 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'Checkout', type: :system, inaccessible: true do
6
+ include_context 'checkout setup'
7
+
8
+ context "visitor makes checkout as guest without registration" do
9
+ before(:each) do
10
+ stock_location.stock_items.update_all(count_on_hand: 1)
11
+ end
12
+
13
+ context "defaults to use billing address" do
14
+ before do
15
+ add_mug_to_cart
16
+ Spree::Order.last.update_column(:email, "test@example.com")
17
+ click_button "Checkout"
18
+ end
19
+
20
+ it 'should default checkbox to checked', js: true, inaccessible: true do
21
+ expect(find('input#order_use_billing')).to be_checked
22
+ end
23
+
24
+ it "should remain checked when used and visitor steps back to address step", js: true do
25
+ fill_in_address
26
+ expect(find('input#order_use_billing')).to be_checked
27
+ end
28
+ end
29
+
30
+ # Regression test for https://github.com/spree/spree/issues/4079
31
+ context "persists state when on address page" do
32
+ before do
33
+ add_mug_to_cart
34
+ click_button "Checkout"
35
+ end
36
+
37
+ it 'goes to address state', js: true do
38
+ expect(Spree::Order.count).to eq(1)
39
+ expect(Spree::Order.last.state).to eq("address")
40
+ end
41
+ end
42
+
43
+ # Regression test for https://github.com/spree/spree/issues/1596
44
+ context "full checkout" do
45
+ before do
46
+ shipping_method.calculator.update!(preferred_amount: 10)
47
+ mug.shipping_category = shipping_method.shipping_categories.first
48
+ mug.save!
49
+ end
50
+
51
+ it "does not break the per-item shipping method calculator", js: true do
52
+ add_mug_to_cart
53
+ click_button "Checkout"
54
+
55
+ fill_in "order_email", with: "test@example.com"
56
+ fill_in_address
57
+
58
+ click_button "Save and Continue"
59
+ expect(page).not_to have_content("undefined method `promotion'")
60
+ click_button "Save and Continue"
61
+ expect(page).to have_content("Shipping total:\n$10.00")
62
+ end
63
+ end
64
+
65
+ # Regression test for https://github.com/spree/spree/issues/4306
66
+ context "free shipping" do
67
+ before do
68
+ add_mug_to_cart
69
+ click_button "Checkout"
70
+ end
71
+
72
+ it "should not show 'Free Shipping' when there are no shipments", js: true do
73
+ within("#checkout-summary") do
74
+ expect(page).to_not have_content('Free Shipping')
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ context "displays default user addresses on address step" do
81
+ before do
82
+ stock_location.stock_items.update_all(count_on_hand: 1)
83
+ end
84
+
85
+ context "when user is logged in" do
86
+ let!(:user) do
87
+ create(:user, bill_address: saved_bill_address, ship_address: saved_ship_address)
88
+ end
89
+
90
+ let!(:order) do
91
+ order = Spree::Order.create!(
92
+ email: "spree@example.com",
93
+ store: Spree::Store.first || FactoryBot.create(:store)
94
+ )
95
+
96
+ order.reload
97
+ order.user = user
98
+ order.recalculate
99
+ order
100
+ end
101
+
102
+ before do
103
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(current_order: order)
104
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(try_spree_current_user: user)
105
+ allow_any_instance_of(Spree::OrdersController).to receive_messages(try_spree_current_user: user)
106
+
107
+ add_mug_to_cart
108
+ click_button "Checkout"
109
+ # We need an order reload here to get newly associated addresses.
110
+ # Then we go back to address where we are supposed to be redirected.
111
+ order.reload
112
+ visit spree.checkout_state_path(:address)
113
+ end
114
+
115
+ context "when user has default addresses saved" do
116
+ let(:saved_bill_address) { create(:address, firstname: 'Bill') }
117
+ let(:saved_ship_address) { create(:address, firstname: 'Steve') }
118
+
119
+ it 'shows the saved addresses', js: true do
120
+ within("#billing") do
121
+ expect(find_field('First Name').value).to eq 'Bill'
122
+ end
123
+
124
+ within("#shipping") do
125
+ expect(find_field('First Name').value).to eq 'Steve'
126
+ end
127
+ end
128
+ end
129
+
130
+ context "when user does not have default addresses saved" do
131
+ let(:saved_bill_address) { nil }
132
+ let(:saved_ship_address) { nil }
133
+
134
+ it 'shows an empty address', js: true do
135
+ within("#billing") do
136
+ expect(find_field('First Name').value).to be_blank
137
+ end
138
+
139
+ within("#shipping") do
140
+ expect(find('input[name*="firstname"]', visible: :hidden).value).to be_blank
141
+ end
142
+ end
143
+ end
144
+ end
145
+
146
+ context "when user is not logged in" do
147
+ context "and proceeds with guest checkout" do
148
+ it 'shows empty addresses', js: true do
149
+ add_mug_to_cart
150
+ click_button "Checkout"
151
+
152
+ within("#billing") do
153
+ expect(find_field('First Name').value).to be_blank
154
+ end
155
+
156
+ within("#shipping") do
157
+ expect(find('input[name*="firstname"]', visible: :hidden).value).to be_blank
158
+ end
159
+ end
160
+ end
161
+
162
+ context "and proceeds logging in" do
163
+ let!(:user) do
164
+ create(:user, bill_address: saved_bill_address, ship_address: saved_ship_address)
165
+ end
166
+
167
+ before do
168
+ add_mug_to_cart
169
+ click_button "Checkout"
170
+
171
+ # Simulate user login
172
+ Spree::Order.last.associate_user!(user)
173
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(try_spree_current_user: user)
174
+ allow_any_instance_of(Spree::OrdersController).to receive_messages(try_spree_current_user: user)
175
+
176
+ # Simulate redirect back to address after login
177
+ visit spree.checkout_state_path(:address)
178
+ end
179
+
180
+ context "when does not have saved addresses" do
181
+ let(:saved_bill_address) { nil }
182
+ let(:saved_ship_address) { nil }
183
+
184
+ it 'shows empty addresses', js: true do
185
+ within("#billing") do
186
+ expect(find_field('First Name').value).to be_blank
187
+ end
188
+
189
+ within("#shipping") do
190
+ expect(find('input[name*="firstname"]', visible: :hidden).value).to be_blank
191
+ end
192
+ end
193
+ end
194
+
195
+ # Regression test for https://github.com/solidusio/solidus/issues/1811
196
+ context "when does have saved addresses" do
197
+ let(:saved_bill_address) { create(:address, firstname: 'Bill') }
198
+ let(:saved_ship_address) { create(:address, firstname: 'Steve') }
199
+
200
+ it 'shows empty addresses', js: true do
201
+ within("#billing") do
202
+ expect(find_field('First Name').value).to eq 'Bill'
203
+ end
204
+
205
+ within("#shipping") do
206
+ expect(find_field('First Name').value).to eq 'Steve'
207
+ end
208
+ end
209
+ end
210
+ end
211
+ end
212
+ end
213
+
214
+ context "when order has only a void payment" do
215
+ let(:order) { Spree::TestingSupport::OrderWalkthrough.up_to(:payment) }
216
+
217
+ before do
218
+ user = create(:user)
219
+ order.user = user
220
+ order.recalculate
221
+
222
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(current_order: order)
223
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(try_spree_current_user: user)
224
+ end
225
+
226
+ it "does not allow successful order submission" do
227
+ visit spree.checkout_path
228
+ order.payments.first.update state: :void
229
+ click_button 'Place Order'
230
+ expect(page).to have_current_path spree.checkout_state_path(:payment)
231
+ end
232
+ end
233
+
234
+ # Regression test for https://github.com/spree/spree/issues/2694 and https://github.com/spree/spree/issues/4117
235
+ context "doesn't allow bad credit card numbers" do
236
+ let!(:payment_method) { create(:credit_card_payment_method) }
237
+ before(:each) do
238
+ order = Spree::TestingSupport::OrderWalkthrough.up_to(:delivery)
239
+
240
+ user = create(:user)
241
+ order.user = user
242
+ order.recalculate
243
+
244
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(current_order: order)
245
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(try_spree_current_user: user)
246
+ end
247
+
248
+ it "redirects to payment page", inaccessible: true do
249
+ visit spree.checkout_state_path(:delivery)
250
+ click_button "Save and Continue"
251
+ choose "Credit Card"
252
+ fill_in "Card Number", with: '123'
253
+ fill_in "Expiration", with: '04 / 20'
254
+ fill_in "Card Code", with: '123'
255
+ click_button "Save and Continue"
256
+ click_button "Place Order"
257
+ expect(page).to have_content("Bogus Gateway: Forced failure")
258
+ expect(page.current_url).to include("/checkout/payment")
259
+ end
260
+ end
261
+
262
+ context "and likes to double click buttons" do
263
+ let!(:user) { create(:user) }
264
+
265
+ let!(:order) do
266
+ order = Spree::TestingSupport::OrderWalkthrough.up_to(:delivery)
267
+
268
+ order.reload
269
+ order.user = user
270
+ order.recalculate
271
+ order
272
+ end
273
+
274
+ before(:each) do
275
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(current_order: order)
276
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(try_spree_current_user: user)
277
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(skip_state_validation?: true)
278
+ end
279
+
280
+ it "prevents double clicking the payment button on checkout", js: true do
281
+ visit spree.checkout_state_path(:payment)
282
+
283
+ # prevent form submit to verify button is disabled
284
+ page.execute_script("$('#checkout_form_payment').submit(function(){return false;})")
285
+
286
+ expect(page).not_to have_selector('button[disabled]')
287
+ click_button "Save and Continue"
288
+ expect(page).to have_selector('button[disabled]')
289
+ end
290
+
291
+ it "prevents double clicking the confirm button on checkout", js: true do
292
+ order.payments << create(:payment)
293
+ visit spree.checkout_state_path(:confirm)
294
+
295
+ # prevent form submit to verify button is disabled
296
+ page.execute_script("$('#checkout_form_confirm').submit(function(){return false;})")
297
+
298
+ expect(page).not_to have_selector('button.button-primary[disabled]')
299
+ click_button "Place Order"
300
+ expect(page).to have_selector('button.button-primary[disabled]')
301
+ end
302
+ end
303
+
304
+ context "when several payment methods are available" do
305
+ let(:credit_cart_payment) { create(:credit_card_payment_method) }
306
+ let(:check_payment) { create(:check_payment_method) }
307
+
308
+ after do
309
+ Capybara.ignore_hidden_elements = true
310
+ end
311
+
312
+ before do
313
+ Capybara.ignore_hidden_elements = false
314
+ order = Spree::TestingSupport::OrderWalkthrough.up_to(:delivery)
315
+ allow(order).to receive_messages(available_payment_methods: [check_payment, credit_cart_payment])
316
+ order.user = create(:user)
317
+ order.recalculate
318
+
319
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(current_order: order)
320
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(try_spree_current_user: order.user)
321
+
322
+ visit spree.checkout_state_path(:payment)
323
+ end
324
+
325
+ it "the first payment method should be selected", js: true do
326
+ payment_method_css = "#order_payments_attributes__payment_method_id_"
327
+ expect(find("#{payment_method_css}#{check_payment.id}")).to be_checked
328
+ expect(find("#{payment_method_css}#{credit_cart_payment.id}")).not_to be_checked
329
+ end
330
+
331
+ it "the fields for the other payment methods should be hidden", js: true do
332
+ payment_method_css = "#payment_method_"
333
+ expect(find("#{payment_method_css}#{check_payment.id}")).to be_visible
334
+ expect(find("#{payment_method_css}#{credit_cart_payment.id}")).not_to be_visible
335
+ end
336
+ end
337
+
338
+ context "user has payment sources", js: true do
339
+ before { Spree::PaymentMethod.all.each(&:really_destroy!) }
340
+ let!(:bogus) { create(:credit_card_payment_method) }
341
+ let(:user) { create(:user) }
342
+
343
+ let!(:credit_card) do
344
+ create(:credit_card, user_id: user.id, payment_method: bogus, gateway_customer_profile_id: "BGS-WEFWF")
345
+ end
346
+
347
+ before do
348
+ user.wallet.add(credit_card)
349
+ order = Spree::TestingSupport::OrderWalkthrough.up_to(:delivery)
350
+
351
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(current_order: order)
352
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(try_spree_current_user: user)
353
+ allow_any_instance_of(Spree::OrdersController).to receive_messages(try_spree_current_user: user)
354
+
355
+ visit spree.checkout_state_path(:payment)
356
+ end
357
+
358
+ it "selects first source available and customer moves on" do
359
+ expect(find("#use_existing_card_yes")).to be_checked
360
+
361
+ click_on "Save and Continue"
362
+ click_on "Place Order"
363
+ expect(page).to have_current_path(spree.order_path(Spree::Order.last))
364
+ expect(page).to have_current_path(spree.order_path(Spree::Order.last))
365
+ expect(page).to have_content("Ending in #{credit_card.last_digits}")
366
+ end
367
+
368
+ it "allows user to enter a new source" do
369
+ choose "use_existing_card_no"
370
+ fill_in_credit_card
371
+
372
+ click_on "Save and Continue"
373
+ click_on "Place Order"
374
+ expect(page).to have_current_path(spree.order_path(Spree::Order.last))
375
+ expect(page).to have_content('Ending in 1111')
376
+ end
377
+ end
378
+
379
+ # regression for https://github.com/spree/spree/issues/2921
380
+ context "goes back from payment to add another item", js: true do
381
+ let!(:store) { FactoryBot.create(:store) }
382
+ let!(:bag) { create(:product, name: "RoR Bag") }
383
+
384
+ it "transit nicely through checkout steps again" do
385
+ add_mug_to_cart
386
+ click_on "Checkout"
387
+ fill_in "order_email", with: "test@example.com"
388
+ fill_in_address
389
+ click_on "Save and Continue"
390
+ click_on "Save and Continue"
391
+ expect(page).to have_current_path(spree.checkout_state_path("payment"))
392
+
393
+ visit spree.root_path
394
+ click_link bag.name
395
+ click_button "add-to-cart-button"
396
+
397
+ click_on "Checkout"
398
+ # edit an address field
399
+ fill_in "order_bill_address_attributes_firstname", with: "Ryann"
400
+ click_on "Save and Continue"
401
+ click_on "Save and Continue"
402
+ click_on "Save and Continue"
403
+ click_on "Place Order"
404
+
405
+ expect(page).to have_current_path(spree.order_path(Spree::Order.last))
406
+ end
407
+ end
408
+
409
+ context "from payment step customer goes back to cart", js: true do
410
+ before do
411
+ add_mug_to_cart
412
+ click_on "Checkout"
413
+ fill_in "order_email", with: "test@example.com"
414
+ fill_in_address
415
+ click_on "Save and Continue"
416
+ click_on "Save and Continue"
417
+ expect(page).to have_current_path(spree.checkout_state_path("payment"))
418
+ end
419
+
420
+ context "and updates line item quantity and try to reach payment page" do
421
+ before do
422
+ visit spree.cart_path
423
+ within '.cart-item__quantity' do
424
+ fill_in first("input")["name"], with: 3
425
+ end
426
+
427
+ click_on "Update"
428
+ end
429
+
430
+ it "redirects user back to address step" do
431
+ visit spree.checkout_state_path("payment")
432
+ expect(page).to have_current_path(spree.checkout_state_path("address"))
433
+ end
434
+
435
+ it "updates shipments properly through step address -> delivery transitions" do
436
+ visit spree.checkout_state_path("payment")
437
+ click_on "Save and Continue"
438
+ click_on "Save and Continue"
439
+
440
+ expect(Spree::InventoryUnit.count).to eq 3
441
+ end
442
+ end
443
+
444
+ context "and adds new product to cart and try to reach payment page" do
445
+ let!(:bag) { create(:product, name: "RoR Bag") }
446
+
447
+ before do
448
+ visit spree.root_path
449
+ click_link bag.name
450
+ click_button "add-to-cart-button"
451
+ end
452
+
453
+ it "redirects user back to address step" do
454
+ visit spree.checkout_state_path("payment")
455
+ expect(page).to have_current_path(spree.checkout_state_path("address"))
456
+ end
457
+
458
+ it "updates shipments properly through step address -> delivery transitions" do
459
+ visit spree.checkout_state_path("payment")
460
+ click_on "Save and Continue"
461
+ click_on "Save and Continue"
462
+
463
+ expect(Spree::InventoryUnit.count).to eq 2
464
+ end
465
+ end
466
+ end
467
+
468
+ context "Coupon promotions", js: true do
469
+ let!(:promotion) { create(:promotion, name: "Huhuhu", code: "huhu") }
470
+ let!(:calculator) { Spree::Calculator::FlatPercentItemTotal.create(preferred_flat_percent: "10") }
471
+ let!(:action) { Spree::Promotion::Actions::CreateItemAdjustments.create(calculator: calculator) }
472
+
473
+ before do
474
+ promotion.actions << action
475
+
476
+ add_mug_to_cart
477
+ click_on "Checkout"
478
+
479
+ fill_in "order_email", with: "test@example.com"
480
+ fill_in_address
481
+ click_on "Save and Continue"
482
+
483
+ click_on "Save and Continue"
484
+ expect(page).to have_current_path(spree.checkout_state_path("payment"))
485
+ end
486
+
487
+ it "applies them & refreshes the page on user clicking the Apply Code button" do
488
+ fill_in "order_coupon_code", with: promotion.codes.first.value
489
+ click_on "Apply Code"
490
+
491
+ expect(page).to have_content(promotion.name)
492
+ expect(page).to have_content("-$2.00")
493
+ end
494
+
495
+ context "with invalid coupon" do
496
+ it "doesnt apply the promotion" do
497
+ fill_in "order_coupon_code", with: 'invalid'
498
+ click_on "Apply Code"
499
+
500
+ expect(page).to have_content(I18n.t('spree.coupon_code_not_found'))
501
+ end
502
+ end
503
+
504
+ context "doesn't fill in coupon code input" do
505
+ it "advances just fine" do
506
+ click_on "Save and Continue"
507
+ expect(page).to have_current_path(spree.checkout_state_path("confirm"))
508
+ end
509
+ end
510
+ end
511
+
512
+ context "order has only payment step", js: true do
513
+ before do
514
+ create(:credit_card_payment_method)
515
+ @old_checkout_flow = Spree::Order.checkout_flow
516
+ Spree::Order.class_eval do
517
+ checkout_flow do
518
+ go_to_state :payment
519
+ go_to_state :confirm
520
+ end
521
+ end
522
+
523
+ allow_any_instance_of(Spree::Order).to receive_messages email: "spree@commerce.com"
524
+
525
+ add_mug_to_cart
526
+ click_on "Checkout"
527
+ end
528
+
529
+ after do
530
+ Spree::Order.checkout_flow(&@old_checkout_flow)
531
+ end
532
+
533
+ it "goes right payment step and place order just fine" do
534
+ expect(page).to have_current_path(spree.checkout_state_path('payment'))
535
+
536
+ choose "Credit Card"
537
+ fill_in_credit_card
538
+ click_button "Save and Continue"
539
+
540
+ expect(current_path).to eq spree.checkout_state_path('confirm')
541
+ click_button "Place Order"
542
+ end
543
+ end
544
+
545
+ context "save my address" do
546
+ before do
547
+ stock_location.stock_items.update_all(count_on_hand: 1)
548
+ add_mug_to_cart
549
+ end
550
+
551
+ context 'as a guest' do
552
+ before do
553
+ Spree::Order.last.update_column(:email, "test@example.com")
554
+ click_button "Checkout"
555
+ end
556
+
557
+ it 'should not be displayed', js: true do
558
+ expect(page).to_not have_css("[data-hook=save_user_address]")
559
+ end
560
+ end
561
+
562
+ context 'as a User' do
563
+ before do
564
+ user = create(:user)
565
+ Spree::Order.last.update_column :user_id, user.id
566
+ allow_any_instance_of(Spree::OrdersController).to receive_messages(try_spree_current_user: user)
567
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(try_spree_current_user: user)
568
+ click_button "Checkout"
569
+ end
570
+
571
+ it 'should be displayed', js: true do
572
+ expect(page).to have_css('#save-user-address')
573
+ end
574
+ end
575
+ end
576
+
577
+ context "when order is completed" do
578
+ let!(:user) { create(:user) }
579
+ let!(:order) { Spree::TestingSupport::OrderWalkthrough.up_to(:delivery) }
580
+
581
+ before(:each) do
582
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(current_order: order)
583
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(try_spree_current_user: user)
584
+ allow_any_instance_of(Spree::OrdersController).to receive_messages(try_spree_current_user: user)
585
+
586
+ visit spree.checkout_state_path(:delivery)
587
+ click_button "Save and Continue"
588
+ click_button "Save and Continue"
589
+ click_button "Place Order"
590
+ end
591
+
592
+ it "displays a thank you message" do
593
+ expect(page).to have_content(I18n.t('spree.thank_you_for_your_order'), normalize_ws: true)
594
+ end
595
+
596
+ it "does not display a thank you message on that order future visits" do
597
+ visit spree.order_path(order)
598
+ expect(page).to_not have_content(I18n.t('spree.thank_you_for_your_order'))
599
+ end
600
+ end
601
+
602
+ context "with attempted XSS", js: true do
603
+ shared_examples "safe from XSS" do
604
+ # We need a country with states required but no states so that we have
605
+ # access to the state_name input
606
+ let!(:canada) { create(:country, name: 'Canada', iso: "CA", states_required: true) }
607
+ before do
608
+ canada.states.destroy_all
609
+ zone.members.create!(zoneable: canada)
610
+ end
611
+
612
+ it "displays the entered state name without evaluating" do
613
+ add_mug_to_cart
614
+ visit spree.checkout_state_path(:address)
615
+ fill_in_address
616
+
617
+ state_name_css = "order_bill_address_attributes_state_name"
618
+
619
+ select "Canada", from: "order_bill_address_attributes_country_id"
620
+ fill_in 'Customer E-Mail', with: 'test@example.com'
621
+ fill_in state_name_css, with: xss_string
622
+ fill_in "Zip", with: "H0H0H0"
623
+
624
+ click_on 'Save and Continue'
625
+ visit spree.checkout_state_path(:address)
626
+
627
+ expect(page).to have_field(state_name_css, with: xss_string)
628
+ end
629
+ end
630
+
631
+ let(:xss_string) { %(<script>throw("XSS")</script>) }
632
+ include_examples "safe from XSS"
633
+
634
+ context "escaped XSS string" do
635
+ let(:xss_string) { '\x27\x3e\x3cscript\x3ethrow(\x27XSS\x27)\x3c/script\x3e' }
636
+ include_examples "safe from XSS"
637
+ end
638
+ end
639
+
640
+ context "using credit card" do
641
+ let!(:payment_method) { create(:credit_card_payment_method) }
642
+
643
+ # Regression test for https://github.com/solidusio/solidus/issues/1421
644
+ it "works with card number 1", js: true do
645
+ add_mug_to_cart
646
+
647
+ click_on "Checkout"
648
+ fill_in "order_email", with: "test@example.com"
649
+ fill_in_address
650
+ click_on "Save and Continue"
651
+ click_on "Save and Continue"
652
+
653
+ fill_in_credit_card(number: "1")
654
+ click_on "Save and Continue"
655
+
656
+ expect(page).to have_current_path("/checkout/confirm")
657
+ end
658
+
659
+ it "works with card number 4111111111111111", js: true do
660
+ add_mug_to_cart
661
+
662
+ click_on "Checkout"
663
+ fill_in "order_email", with: "test@example.com"
664
+ fill_in_address
665
+ click_on "Save and Continue"
666
+ click_on "Save and Continue"
667
+
668
+ fill_in_credit_card
669
+ click_on "Save and Continue"
670
+
671
+ expect(page).to have_current_path("/checkout/confirm")
672
+ end
673
+ end
674
+
675
+ def fill_in_credit_card(number: "4111 1111 1111 1111")
676
+ fill_in "Name on card", with: 'Mary Doe'
677
+ fill_in_with_force "Card Number", with: number
678
+ fill_in_with_force "Expiration", with: "12 / 24"
679
+ fill_in "Card Code", with: "123"
680
+ end
681
+
682
+ def fill_in_address
683
+ address = "order_bill_address_attributes"
684
+ fill_in "#{address}_firstname", with: "Ryan"
685
+ fill_in "#{address}_lastname", with: "Bigg"
686
+ fill_in "#{address}_address1", with: "143 Swan Street"
687
+ fill_in "#{address}_city", with: "Richmond"
688
+ select "United States of America", from: "#{address}_country_id"
689
+ select "Alabama", from: "#{address}_state_id"
690
+ fill_in "#{address}_zipcode", with: "12345"
691
+ fill_in "#{address}_phone", with: "(555) 555-5555"
692
+ end
693
+
694
+ def add_mug_to_cart
695
+ visit spree.root_path
696
+ click_link mug.name
697
+ click_button "add-to-cart-button"
698
+ end
699
+ end