solidus_starter_frontend 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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