harpiya_api 4.3.0.alpha

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 (249) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +5 -0
  4. data/LICENSE +26 -0
  5. data/Rakefile +29 -0
  6. data/app/assets/javascripts/harpiya/api/main.js +36 -0
  7. data/app/assets/javascripts/harpiya/api/storefront/cart.js +49 -0
  8. data/app/controllers/concerns/harpiya/api/v2/storefront/order_concern.rb +52 -0
  9. data/app/controllers/harpiya/api/base_controller.rb +171 -0
  10. data/app/controllers/harpiya/api/errors_controller.rb +9 -0
  11. data/app/controllers/harpiya/api/v1/addresses_controller.rb +46 -0
  12. data/app/controllers/harpiya/api/v1/checkouts_controller.rb +106 -0
  13. data/app/controllers/harpiya/api/v1/classifications_controller.rb +20 -0
  14. data/app/controllers/harpiya/api/v1/countries_controller.rb +22 -0
  15. data/app/controllers/harpiya/api/v1/credit_cards_controller.rb +26 -0
  16. data/app/controllers/harpiya/api/v1/customer_returns_controller.rb +25 -0
  17. data/app/controllers/harpiya/api/v1/images_controller.rb +58 -0
  18. data/app/controllers/harpiya/api/v1/inventory_units_controller.rb +54 -0
  19. data/app/controllers/harpiya/api/v1/line_items_controller.rb +70 -0
  20. data/app/controllers/harpiya/api/v1/option_types_controller.rb +60 -0
  21. data/app/controllers/harpiya/api/v1/option_values_controller.rb +62 -0
  22. data/app/controllers/harpiya/api/v1/orders_controller.rb +156 -0
  23. data/app/controllers/harpiya/api/v1/payments_controller.rb +82 -0
  24. data/app/controllers/harpiya/api/v1/product_properties_controller.rb +73 -0
  25. data/app/controllers/harpiya/api/v1/products_controller.rb +131 -0
  26. data/app/controllers/harpiya/api/v1/promotions_controller.rb +30 -0
  27. data/app/controllers/harpiya/api/v1/properties_controller.rb +70 -0
  28. data/app/controllers/harpiya/api/v1/reimbursements_controller.rb +25 -0
  29. data/app/controllers/harpiya/api/v1/return_authorizations_controller.rb +70 -0
  30. data/app/controllers/harpiya/api/v1/shipments_controller.rb +196 -0
  31. data/app/controllers/harpiya/api/v1/states_controller.rb +36 -0
  32. data/app/controllers/harpiya/api/v1/stock_items_controller.rb +82 -0
  33. data/app/controllers/harpiya/api/v1/stock_locations_controller.rb +53 -0
  34. data/app/controllers/harpiya/api/v1/stock_movements_controller.rb +45 -0
  35. data/app/controllers/harpiya/api/v1/stores_controller.rb +56 -0
  36. data/app/controllers/harpiya/api/v1/taxonomies_controller.rb +67 -0
  37. data/app/controllers/harpiya/api/v1/taxons_controller.rb +100 -0
  38. data/app/controllers/harpiya/api/v1/users_controller.rb +97 -0
  39. data/app/controllers/harpiya/api/v1/variants_controller.rb +81 -0
  40. data/app/controllers/harpiya/api/v1/zones_controller.rb +55 -0
  41. data/app/controllers/harpiya/api/v2/base_controller.rb +167 -0
  42. data/app/controllers/harpiya/api/v2/platform/addresses_controller.rb +19 -0
  43. data/app/controllers/harpiya/api/v2/platform/countries_controller.rb +19 -0
  44. data/app/controllers/harpiya/api/v2/platform/menu_items_controller.rb +35 -0
  45. data/app/controllers/harpiya/api/v2/platform/menus_controller.rb +19 -0
  46. data/app/controllers/harpiya/api/v2/platform/option_types_controller.rb +15 -0
  47. data/app/controllers/harpiya/api/v2/platform/option_values_controller.rb +19 -0
  48. data/app/controllers/harpiya/api/v2/platform/products_controller.rb +27 -0
  49. data/app/controllers/harpiya/api/v2/platform/resource_controller.rb +102 -0
  50. data/app/controllers/harpiya/api/v2/platform/taxons_controller.rb +27 -0
  51. data/app/controllers/harpiya/api/v2/platform/users_controller.rb +23 -0
  52. data/app/controllers/harpiya/api/v2/resource_controller.rb +59 -0
  53. data/app/controllers/harpiya/api/v2/storefront/account/addresses_controller.rb +75 -0
  54. data/app/controllers/harpiya/api/v2/storefront/account/credit_cards_controller.rb +39 -0
  55. data/app/controllers/harpiya/api/v2/storefront/account/orders_controller.rb +46 -0
  56. data/app/controllers/harpiya/api/v2/storefront/account_controller.rb +52 -0
  57. data/app/controllers/harpiya/api/v2/storefront/cart_controller.rb +195 -0
  58. data/app/controllers/harpiya/api/v2/storefront/checkout_controller.rb +136 -0
  59. data/app/controllers/harpiya/api/v2/storefront/countries_controller.rb +50 -0
  60. data/app/controllers/harpiya/api/v2/storefront/menus_controller.rb +42 -0
  61. data/app/controllers/harpiya/api/v2/storefront/order_status_controller.rb +34 -0
  62. data/app/controllers/harpiya/api/v2/storefront/products_controller.rb +55 -0
  63. data/app/controllers/harpiya/api/v2/storefront/stores_controller.rb +23 -0
  64. data/app/controllers/harpiya/api/v2/storefront/taxons_controller.rb +47 -0
  65. data/app/helpers/harpiya/api/api_helpers.rb +190 -0
  66. data/app/helpers/harpiya/api/v2/collection_options_helpers.rb +46 -0
  67. data/app/helpers/harpiya/api/v2/display_money_helper.rb +43 -0
  68. data/app/models/concerns/harpiya/user_api_authentication.rb +19 -0
  69. data/app/models/concerns/harpiya/user_api_methods.rb +7 -0
  70. data/app/models/harpiya/api_configuration.rb +8 -0
  71. data/app/models/harpiya/api_dependencies.rb +98 -0
  72. data/app/serializers/concerns/harpiya/api/v2/resource_serializer_concern.rb +16 -0
  73. data/app/serializers/harpiya/api/v2/base_serializer.rb +32 -0
  74. data/app/serializers/harpiya/api/v2/platform/address_serializer.rb +15 -0
  75. data/app/serializers/harpiya/api/v2/platform/base_serializer.rb +10 -0
  76. data/app/serializers/harpiya/api/v2/platform/country_serializer.rb +13 -0
  77. data/app/serializers/harpiya/api/v2/platform/image_serializer.rb +11 -0
  78. data/app/serializers/harpiya/api/v2/platform/menu_item_serializer.rb +22 -0
  79. data/app/serializers/harpiya/api/v2/platform/menu_serializer.rb +14 -0
  80. data/app/serializers/harpiya/api/v2/platform/option_type_serializer.rb +13 -0
  81. data/app/serializers/harpiya/api/v2/platform/option_value_serializer.rb +13 -0
  82. data/app/serializers/harpiya/api/v2/platform/product_property_serializer.rb +11 -0
  83. data/app/serializers/harpiya/api/v2/platform/product_serializer.rb +28 -0
  84. data/app/serializers/harpiya/api/v2/platform/state_serializer.rb +13 -0
  85. data/app/serializers/harpiya/api/v2/platform/store_serializer.rb +14 -0
  86. data/app/serializers/harpiya/api/v2/platform/taxon_image_serializer.rb +11 -0
  87. data/app/serializers/harpiya/api/v2/platform/taxon_serializer.rb +37 -0
  88. data/app/serializers/harpiya/api/v2/platform/taxonomy_serializer.rb +11 -0
  89. data/app/serializers/harpiya/api/v2/platform/user_serializer.rb +21 -0
  90. data/app/serializers/harpiya/api/v2/platform/variant_serializer.rb +15 -0
  91. data/app/serializers/harpiya/v2/storefront/address_serializer.rb +20 -0
  92. data/app/serializers/harpiya/v2/storefront/base_serializer.rb +10 -0
  93. data/app/serializers/harpiya/v2/storefront/cart_serializer.rb +36 -0
  94. data/app/serializers/harpiya/v2/storefront/country_serializer.rb +24 -0
  95. data/app/serializers/harpiya/v2/storefront/credit_card_serializer.rb +13 -0
  96. data/app/serializers/harpiya/v2/storefront/estimated_shipping_rate_serializer.rb +29 -0
  97. data/app/serializers/harpiya/v2/storefront/image_serializer.rb +11 -0
  98. data/app/serializers/harpiya/v2/storefront/line_item_serializer.rb +19 -0
  99. data/app/serializers/harpiya/v2/storefront/menu_item_serializer.rb +38 -0
  100. data/app/serializers/harpiya/v2/storefront/menu_serializer.rb +14 -0
  101. data/app/serializers/harpiya/v2/storefront/option_type_serializer.rb +13 -0
  102. data/app/serializers/harpiya/v2/storefront/option_value_serializer.rb +13 -0
  103. data/app/serializers/harpiya/v2/storefront/payment_method_serializer.rb +11 -0
  104. data/app/serializers/harpiya/v2/storefront/payment_serializer.rb +15 -0
  105. data/app/serializers/harpiya/v2/storefront/product_property_serializer.rb +19 -0
  106. data/app/serializers/harpiya/v2/storefront/product_serializer.rb +67 -0
  107. data/app/serializers/harpiya/v2/storefront/promotion_serializer.rb +12 -0
  108. data/app/serializers/harpiya/v2/storefront/shipment_serializer.rb +20 -0
  109. data/app/serializers/harpiya/v2/storefront/shipping_rate_serializer.rb +16 -0
  110. data/app/serializers/harpiya/v2/storefront/state_serializer.rb +11 -0
  111. data/app/serializers/harpiya/v2/storefront/stock_location_serializer.rb +11 -0
  112. data/app/serializers/harpiya/v2/storefront/store_credit_category_serializer.rb +11 -0
  113. data/app/serializers/harpiya/v2/storefront/store_credit_event_serializer.rb +15 -0
  114. data/app/serializers/harpiya/v2/storefront/store_credit_serializer.rb +17 -0
  115. data/app/serializers/harpiya/v2/storefront/store_credit_type_serializer.rb +11 -0
  116. data/app/serializers/harpiya/v2/storefront/store_serializer.rb +23 -0
  117. data/app/serializers/harpiya/v2/storefront/taxon_image_serializer.rb +11 -0
  118. data/app/serializers/harpiya/v2/storefront/taxon_serializer.rb +36 -0
  119. data/app/serializers/harpiya/v2/storefront/taxonomy_serializer.rb +11 -0
  120. data/app/serializers/harpiya/v2/storefront/user_serializer.rb +31 -0
  121. data/app/serializers/harpiya/v2/storefront/variant_serializer.rb +49 -0
  122. data/app/services/harpiya/api/error_handler.rb +40 -0
  123. data/app/views/harpiya/api/errors/gateway_error.rabl +2 -0
  124. data/app/views/harpiya/api/errors/invalid_api_key.rabl +2 -0
  125. data/app/views/harpiya/api/errors/invalid_resource.rabl +3 -0
  126. data/app/views/harpiya/api/errors/must_specify_api_key.rabl +2 -0
  127. data/app/views/harpiya/api/errors/not_found.rabl +2 -0
  128. data/app/views/harpiya/api/errors/unauthorized.rabl +2 -0
  129. data/app/views/harpiya/api/v1/addresses/show.rabl +10 -0
  130. data/app/views/harpiya/api/v1/adjustments/show.rabl +4 -0
  131. data/app/views/harpiya/api/v1/countries/index.rabl +7 -0
  132. data/app/views/harpiya/api/v1/countries/show.rabl +5 -0
  133. data/app/views/harpiya/api/v1/credit_cards/index.rabl +7 -0
  134. data/app/views/harpiya/api/v1/credit_cards/show.rabl +3 -0
  135. data/app/views/harpiya/api/v1/customer_returns/index.rabl +7 -0
  136. data/app/views/harpiya/api/v1/images/index.rabl +4 -0
  137. data/app/views/harpiya/api/v1/images/new.rabl +3 -0
  138. data/app/views/harpiya/api/v1/images/show.rabl +6 -0
  139. data/app/views/harpiya/api/v1/inventory_units/show.rabl +2 -0
  140. data/app/views/harpiya/api/v1/line_items/new.rabl +3 -0
  141. data/app/views/harpiya/api/v1/line_items/show.rabl +14 -0
  142. data/app/views/harpiya/api/v1/option_types/index.rabl +3 -0
  143. data/app/views/harpiya/api/v1/option_types/new.rabl +3 -0
  144. data/app/views/harpiya/api/v1/option_types/show.rabl +5 -0
  145. data/app/views/harpiya/api/v1/option_values/index.rabl +3 -0
  146. data/app/views/harpiya/api/v1/option_values/new.rabl +3 -0
  147. data/app/views/harpiya/api/v1/option_values/show.rabl +2 -0
  148. data/app/views/harpiya/api/v1/orders/address.rabl +0 -0
  149. data/app/views/harpiya/api/v1/orders/canceled.rabl +0 -0
  150. data/app/views/harpiya/api/v1/orders/cart.rabl +0 -0
  151. data/app/views/harpiya/api/v1/orders/complete.rabl +0 -0
  152. data/app/views/harpiya/api/v1/orders/could_not_apply_coupon.rabl +2 -0
  153. data/app/views/harpiya/api/v1/orders/could_not_transition.rabl +3 -0
  154. data/app/views/harpiya/api/v1/orders/index.rabl +7 -0
  155. data/app/views/harpiya/api/v1/orders/insufficient_quantity.rabl +2 -0
  156. data/app/views/harpiya/api/v1/orders/invalid_shipping_method.rabl +2 -0
  157. data/app/views/harpiya/api/v1/orders/mine.rabl +9 -0
  158. data/app/views/harpiya/api/v1/orders/order.rabl +10 -0
  159. data/app/views/harpiya/api/v1/orders/payment.rabl +3 -0
  160. data/app/views/harpiya/api/v1/orders/show.rabl +51 -0
  161. data/app/views/harpiya/api/v1/payments/credit_over_limit.rabl +2 -0
  162. data/app/views/harpiya/api/v1/payments/index.rabl +7 -0
  163. data/app/views/harpiya/api/v1/payments/new.rabl +5 -0
  164. data/app/views/harpiya/api/v1/payments/show.rabl +2 -0
  165. data/app/views/harpiya/api/v1/payments/update_forbidden.rabl +2 -0
  166. data/app/views/harpiya/api/v1/product_properties/index.rabl +7 -0
  167. data/app/views/harpiya/api/v1/product_properties/new.rabl +2 -0
  168. data/app/views/harpiya/api/v1/product_properties/show.rabl +2 -0
  169. data/app/views/harpiya/api/v1/products/index.rabl +9 -0
  170. data/app/views/harpiya/api/v1/products/new.rabl +3 -0
  171. data/app/views/harpiya/api/v1/products/product.rabl +1 -0
  172. data/app/views/harpiya/api/v1/products/show.rabl +36 -0
  173. data/app/views/harpiya/api/v1/promotions/handler.rabl +5 -0
  174. data/app/views/harpiya/api/v1/promotions/show.rabl +2 -0
  175. data/app/views/harpiya/api/v1/properties/index.rabl +7 -0
  176. data/app/views/harpiya/api/v1/properties/new.rabl +2 -0
  177. data/app/views/harpiya/api/v1/properties/show.rabl +2 -0
  178. data/app/views/harpiya/api/v1/reimbursements/index.rabl +7 -0
  179. data/app/views/harpiya/api/v1/return_authorizations/index.rabl +7 -0
  180. data/app/views/harpiya/api/v1/return_authorizations/new.rabl +3 -0
  181. data/app/views/harpiya/api/v1/return_authorizations/show.rabl +2 -0
  182. data/app/views/harpiya/api/v1/shared/stock_location_required.rabl +2 -0
  183. data/app/views/harpiya/api/v1/shipments/big.rabl +48 -0
  184. data/app/views/harpiya/api/v1/shipments/cannot_ready_shipment.rabl +2 -0
  185. data/app/views/harpiya/api/v1/shipments/mine.rabl +9 -0
  186. data/app/views/harpiya/api/v1/shipments/show.rabl +32 -0
  187. data/app/views/harpiya/api/v1/shipments/small.rabl +37 -0
  188. data/app/views/harpiya/api/v1/shipping_rates/show.rabl +2 -0
  189. data/app/views/harpiya/api/v1/states/index.rabl +12 -0
  190. data/app/views/harpiya/api/v1/states/show.rabl +2 -0
  191. data/app/views/harpiya/api/v1/stock_items/index.rabl +7 -0
  192. data/app/views/harpiya/api/v1/stock_items/show.rabl +5 -0
  193. data/app/views/harpiya/api/v1/stock_locations/index.rabl +7 -0
  194. data/app/views/harpiya/api/v1/stock_locations/show.rabl +8 -0
  195. data/app/views/harpiya/api/v1/stock_movements/index.rabl +7 -0
  196. data/app/views/harpiya/api/v1/stock_movements/show.rabl +5 -0
  197. data/app/views/harpiya/api/v1/stores/index.rabl +4 -0
  198. data/app/views/harpiya/api/v1/stores/show.rabl +2 -0
  199. data/app/views/harpiya/api/v1/tags/index.rabl +9 -0
  200. data/app/views/harpiya/api/v1/taxonomies/index.rabl +7 -0
  201. data/app/views/harpiya/api/v1/taxonomies/jstree.rabl +7 -0
  202. data/app/views/harpiya/api/v1/taxonomies/nested.rabl +11 -0
  203. data/app/views/harpiya/api/v1/taxonomies/new.rabl +3 -0
  204. data/app/views/harpiya/api/v1/taxonomies/show.rabl +15 -0
  205. data/app/views/harpiya/api/v1/taxons/index.rabl +10 -0
  206. data/app/views/harpiya/api/v1/taxons/jstree.rabl +7 -0
  207. data/app/views/harpiya/api/v1/taxons/new.rabl +3 -0
  208. data/app/views/harpiya/api/v1/taxons/show.rabl +6 -0
  209. data/app/views/harpiya/api/v1/taxons/taxons.rabl +5 -0
  210. data/app/views/harpiya/api/v1/users/index.rabl +7 -0
  211. data/app/views/harpiya/api/v1/users/new.rabl +3 -0
  212. data/app/views/harpiya/api/v1/users/show.rabl +11 -0
  213. data/app/views/harpiya/api/v1/variants/big.rabl +14 -0
  214. data/app/views/harpiya/api/v1/variants/index.rabl +9 -0
  215. data/app/views/harpiya/api/v1/variants/new.rabl +2 -0
  216. data/app/views/harpiya/api/v1/variants/show.rabl +3 -0
  217. data/app/views/harpiya/api/v1/variants/small.rabl +18 -0
  218. data/app/views/harpiya/api/v1/zones/index.rabl +7 -0
  219. data/app/views/harpiya/api/v1/zones/show.rabl +6 -0
  220. data/config/initializers/doorkeeper.rb +48 -0
  221. data/config/initializers/json_api_mime_types.rb +8 -0
  222. data/config/initializers/rabl.rb +9 -0
  223. data/config/initializers/user_class_extensions.rb +7 -0
  224. data/config/locales/en.yml +36 -0
  225. data/config/routes.rb +295 -0
  226. data/db/migrate/20100107141738_add_api_key_to_harpiya_users.rb +7 -0
  227. data/db/migrate/20120411123334_resize_api_key_field.rb +7 -0
  228. data/db/migrate/20120530054546_rename_api_key_to_harpiya_api_key.rb +7 -0
  229. data/db/migrate/20131017162334_add_index_to_user_harpiya_api_key.rb +7 -0
  230. data/db/migrate/20180320110726_create_doorkeeper_tables.rb +69 -0
  231. data/docs/oauth/index.yml +140 -0
  232. data/docs/v2/platform/index.yaml +599 -0
  233. data/docs/v2/storefront/index.yaml +5585 -0
  234. data/harpiya_api.gemspec +36 -0
  235. data/lib/harpiya/api.rb +11 -0
  236. data/lib/harpiya/api/controller_setup.rb +19 -0
  237. data/lib/harpiya/api/engine.rb +30 -0
  238. data/lib/harpiya/api/responders.rb +11 -0
  239. data/lib/harpiya/api/responders/rabl_template.rb +28 -0
  240. data/lib/harpiya/api/testing_support/caching.rb +10 -0
  241. data/lib/harpiya/api/testing_support/helpers.rb +44 -0
  242. data/lib/harpiya/api/testing_support/setup.rb +16 -0
  243. data/lib/harpiya/api/testing_support/v2/base.rb +13 -0
  244. data/lib/harpiya/api/testing_support/v2/current_order.rb +79 -0
  245. data/lib/harpiya/api/testing_support/v2/platform_contexts.rb +213 -0
  246. data/lib/harpiya_api.rb +4 -0
  247. data/script/rails +9 -0
  248. data/spec/fixtures/thinking-cat.jpg +0 -0
  249. metadata +418 -0
@@ -0,0 +1,36 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require_relative '../core/lib/harpiya/core/version.rb'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "harpiya_api"
6
+ s.version = Harpiya.version
7
+ s.authors = ["Ryan Bigg"]
8
+ s.email = ["ryan@harpiyacommerce.com"]
9
+ s.summary = %q{Harpiya's API}
10
+ s.description = %q{Harpiya's API}
11
+ s.homepage = 'https://harpiyacommerce.org'
12
+ s.license = 'BSD-3-Clause'
13
+
14
+ s.metadata = {
15
+ "bug_tracker_uri" => "https://github.com/harpiya/harpiya/issues",
16
+ "changelog_uri" => "https://github.com/harpiya/harpiya/releases/tag/v#{s.version}",
17
+ "documentation_uri" => "https://guides.harpiyacommerce.org/",
18
+ "source_code_uri" => "https://github.com/harpiya/harpiya/tree/v#{s.version}",
19
+ }
20
+
21
+ s.required_ruby_version = '>= 2.5'
22
+
23
+ s.files = `git ls-files`.split($\).reject { |f| f.match(/^spec/) && !f.match(/^spec\/fixtures/) }
24
+ s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
25
+ s.require_paths = ["lib"]
26
+
27
+ s.add_development_dependency 'jsonapi-rspec'
28
+ s.add_development_dependency 'rswag-specs'
29
+ s.add_development_dependency 'multi_json'
30
+
31
+ s.add_dependency 'harpiya_core', s.version
32
+ s.add_dependency 'rabl', '~> 0.14', '>= 0.14.2'
33
+ s.add_dependency 'jsonapi-serializer', '~> 2.1'
34
+ s.add_dependency 'doorkeeper', '~> 5.2', '>= 5.2.1'
35
+ s.add_dependency 'responders'
36
+ end
@@ -0,0 +1,11 @@
1
+ require 'harpiya/core'
2
+
3
+ require 'rabl'
4
+ require 'responders'
5
+
6
+ module Harpiya
7
+ module Api
8
+ end
9
+ end
10
+
11
+ require 'harpiya/api/engine'
@@ -0,0 +1,19 @@
1
+ require 'harpiya/api/responders'
2
+
3
+ module Harpiya
4
+ module Api
5
+ module ControllerSetup
6
+ def self.included(klass)
7
+ klass.class_eval do
8
+ include CanCan::ControllerAdditions
9
+
10
+ prepend_view_path Rails.root + 'app/views'
11
+ append_view_path File.expand_path('../../../app/views', File.dirname(__FILE__))
12
+
13
+ self.responder = Harpiya::Api::Responders::AppResponder
14
+ respond_to :json
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,30 @@
1
+ require 'rails/engine'
2
+
3
+ module Harpiya
4
+ module Api
5
+ class Engine < Rails::Engine
6
+ isolate_namespace Harpiya
7
+ engine_name 'harpiya_api'
8
+
9
+ # sets the manifests / assets to be precompiled, even when initialize_on_precompile is false
10
+ initializer 'harpiya.assets.precompile', group: :all do |app|
11
+ app.config.assets.precompile += %w[
12
+ harpiya/api/all*
13
+ ]
14
+ end
15
+
16
+ initializer 'harpiya.api.environment', before: :load_config_initializers do |_app|
17
+ Harpiya::Api::Config = Harpiya::ApiConfiguration.new
18
+ Harpiya::Api::Dependencies = Harpiya::ApiDependencies.new
19
+ end
20
+
21
+ initializer 'harpiya.api.checking_migrations' do
22
+ Migrations.new(config, engine_name).check
23
+ end
24
+
25
+ def self.root
26
+ @root ||= Pathname.new(File.expand_path('../../..', __dir__))
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,11 @@
1
+ require 'harpiya/api/responders/rabl_template'
2
+
3
+ module Harpiya
4
+ module Api
5
+ module Responders
6
+ class AppResponder < ActionController::Responder
7
+ include RablTemplate
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,28 @@
1
+ module Harpiya
2
+ module Api
3
+ module Responders
4
+ module RablTemplate
5
+ def to_format
6
+ if template
7
+ render template, status: options[:status] || 200
8
+ else
9
+ super
10
+ end
11
+ rescue ActionView::MissingTemplate => e
12
+ api_behavior
13
+ end
14
+
15
+ def template
16
+ options[:default_template]
17
+ end
18
+
19
+ def api_behavior
20
+ if controller.params[:action] == 'destroy'
21
+ # Render a blank template
22
+ super
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,10 @@
1
+ RSpec.configure do |config|
2
+ config.before(:each, caching: true) do
3
+ ActionController::Base.perform_caching = true
4
+ end
5
+
6
+ config.after(:each, caching: true) do
7
+ ActionController::Base.perform_caching = false
8
+ Rails.cache.clear
9
+ end
10
+ end
@@ -0,0 +1,44 @@
1
+ module Harpiya
2
+ module Api
3
+ module TestingSupport
4
+ module Helpers
5
+ def json_response
6
+ case body = JSON.parse(response.body)
7
+ when Hash
8
+ body.with_indifferent_access
9
+ when Array
10
+ body
11
+ end
12
+ end
13
+
14
+ def assert_not_found!
15
+ expect(json_response).to eq('error' => 'The resource you were looking for could not be found.')
16
+ expect(response.status).to eq 404
17
+ end
18
+
19
+ def assert_unauthorized!
20
+ expect(json_response).to eq('error' => 'You are not authorized to perform that action.')
21
+ expect(response.status).to eq 401
22
+ end
23
+
24
+ def stub_authentication!
25
+ allow(Harpiya.user_class).to receive(:find_by).with(hash_including(:harpiya_api_key)) { current_api_user }
26
+ end
27
+
28
+ # This method can be overriden (with a let block) inside a context
29
+ # For instance, if you wanted to have an admin user instead.
30
+ def current_api_user
31
+ @current_api_user ||= stub_model(Harpiya.user_class, email: 'harpiya@example.com')
32
+ end
33
+
34
+ def image(filename)
35
+ File.open(Harpiya::Api::Engine.root + 'spec/fixtures' + filename)
36
+ end
37
+
38
+ def upload_image(filename)
39
+ fixture_file_upload(image(filename).path, 'image/jpg')
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,16 @@
1
+ module Harpiya
2
+ module Api
3
+ module TestingSupport
4
+ module Setup
5
+ def sign_in_as_admin!
6
+ let!(:current_api_user) do
7
+ user = stub_model(Harpiya.user_class)
8
+ allow(user).to receive_message_chain(:harpiya_roles, :pluck).and_return(['admin'])
9
+ allow(user).to receive(:has_harpiya_role?).with('admin').and_return(true)
10
+ user
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,13 @@
1
+ shared_context 'API v2 tokens' do
2
+ let(:token) { Doorkeeper::AccessToken.create!(resource_owner_id: user.id, expires_in: nil) }
3
+ let(:headers_bearer) { { 'Authorization' => "Bearer #{token.token}" } }
4
+ let(:headers_order_token) { { 'X-Harpiya-Order-Token' => order.token } }
5
+ end
6
+
7
+ [200, 201, 204, 400, 401, 404, 403, 422].each do |status_code|
8
+ shared_examples "returns #{status_code} HTTP status" do
9
+ it "returns #{status_code}" do
10
+ expect(response.status).to eq(status_code)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,79 @@
1
+ def ensure_order_totals
2
+ order.update_totals
3
+ order.persist_totals
4
+ end
5
+
6
+ shared_context 'creates order with line item' do
7
+ let!(:line_item) { create(:line_item, order: order, currency: currency) }
8
+ let!(:headers) { headers_bearer }
9
+
10
+ before { ensure_order_totals }
11
+ end
12
+
13
+ shared_context 'creates guest order with guest token' do
14
+ let(:guest_token) { 'guest_token' }
15
+ let!(:order) { create(:order, token: guest_token, store: store, currency: currency) }
16
+ let!(:line_item) { create(:line_item, order: order, currency: currency) }
17
+ let!(:headers) { headers_order_token }
18
+
19
+ before { ensure_order_totals }
20
+ end
21
+
22
+ shared_examples 'returns valid cart JSON' do
23
+ it 'returns a valid cart JSON response' do
24
+ order.reload
25
+ expect(json_response['data']).to be_present
26
+ expect(json_response['data']).to have_id(order.id.to_s)
27
+ expect(json_response['data']).to have_type('cart')
28
+ expect(json_response['data']).to have_attribute(:number).with_value(order.number)
29
+ expect(json_response['data']).to have_attribute(:state).with_value(order.state)
30
+ expect(json_response['data']).to have_attribute(:payment_state).with_value(order.payment_state)
31
+ expect(json_response['data']).to have_attribute(:shipment_state).with_value(order.shipment_state)
32
+ expect(json_response['data']).to have_attribute(:token).with_value(order.token)
33
+ expect(json_response['data']).to have_attribute(:total).with_value(order.total.to_s)
34
+ expect(json_response['data']).to have_attribute(:item_total).with_value(order.item_total.to_s)
35
+ expect(json_response['data']).to have_attribute(:ship_total).with_value(order.ship_total.to_s)
36
+ expect(json_response['data']).to have_attribute(:adjustment_total).with_value(order.adjustment_total.to_s)
37
+ expect(json_response['data']).to have_attribute(:included_tax_total).with_value(order.included_tax_total.to_s)
38
+ expect(json_response['data']).to have_attribute(:additional_tax_total).with_value(order.additional_tax_total.to_s)
39
+ expect(json_response['data']).to have_attribute(:display_additional_tax_total).with_value(order.display_additional_tax_total.to_s)
40
+ expect(json_response['data']).to have_attribute(:display_included_tax_total).with_value(order.display_included_tax_total.to_s)
41
+ expect(json_response['data']).to have_attribute(:tax_total).with_value(order.tax_total.to_s)
42
+ expect(json_response['data']).to have_attribute(:currency).with_value(order.currency.to_s)
43
+ expect(json_response['data']).to have_attribute(:email).with_value(order.email)
44
+ expect(json_response['data']).to have_attribute(:display_item_total).with_value(order.display_item_total.to_s)
45
+ expect(json_response['data']).to have_attribute(:display_ship_total).with_value(order.display_ship_total.to_s)
46
+ expect(json_response['data']).to have_attribute(:display_adjustment_total).with_value(order.display_adjustment_total.to_s)
47
+ expect(json_response['data']).to have_attribute(:display_tax_total).with_value(order.display_tax_total.to_s)
48
+ expect(json_response['data']).to have_attribute(:item_count).with_value(order.item_count)
49
+ expect(json_response['data']).to have_attribute(:special_instructions).with_value(order.special_instructions)
50
+ expect(json_response['data']).to have_attribute(:promo_total).with_value(order.promo_total.to_s)
51
+ expect(json_response['data']).to have_attribute(:display_promo_total).with_value(order.display_promo_total.to_s)
52
+ expect(json_response['data']).to have_attribute(:display_total).with_value(order.display_total.to_s)
53
+ expect(json_response['data']).to have_attribute(:pre_tax_item_amount).with_value(order.pre_tax_item_amount.to_s)
54
+ expect(json_response['data']).to have_attribute(:display_pre_tax_item_amount).with_value(order.display_pre_tax_item_amount.to_s)
55
+ expect(json_response['data']).to have_attribute(:pre_tax_total).with_value(order.pre_tax_total.to_s)
56
+ expect(json_response['data']).to have_attribute(:display_pre_tax_total).with_value(order.display_pre_tax_total.to_s)
57
+ expect(json_response['data']).to have_relationships(:user, :line_items, :variants, :billing_address, :shipping_address, :payments, :shipments, :promotions)
58
+ end
59
+ end
60
+
61
+ shared_examples 'no current order' do
62
+ context "order doesn't exist" do
63
+ before do
64
+ order.destroy
65
+ execute
66
+ end
67
+
68
+ it_behaves_like 'returns 404 HTTP status'
69
+ end
70
+
71
+ context 'already completed order' do
72
+ before do
73
+ order.update_column(:completed_at, Time.current)
74
+ execute
75
+ end
76
+
77
+ it_behaves_like 'returns 404 HTTP status'
78
+ end
79
+ end
@@ -0,0 +1,213 @@
1
+ class String
2
+ def articleize
3
+ %w(a e i o u).include?(self[0].downcase) ? "an #{self}" : "a #{self}"
4
+ end
5
+ end
6
+
7
+ shared_context 'Platform API v2' do
8
+ let(:admin_app) { Doorkeeper::Application.find_or_create_by!(name: 'Admin Panel', scopes: 'admin', redirect_uri: '') }
9
+ let(:read_app) { Doorkeeper::Application.find_or_create_by!(name: 'Read App', scopes: 'read', redirect_uri: '') }
10
+ let(:oauth_token) do
11
+ Doorkeeper::AccessToken.create!(
12
+ application_id: admin_app.id,
13
+ scopes: admin_app.scopes
14
+ )
15
+ end
16
+ let(:read_oauth_token) do
17
+ Doorkeeper::AccessToken.create!(
18
+ application_id: read_app.id,
19
+ scopes: read_app.scopes
20
+ )
21
+ end
22
+ let(:user_oauth_token) do
23
+ Doorkeeper::AccessToken.create!(
24
+ resource_owner_id: user.id,
25
+ application_id: admin_app.id,
26
+ scopes: admin_app.scopes
27
+ )
28
+ end
29
+
30
+ let(:valid_authorization) { "Bearer #{oauth_token.token}" }
31
+ let(:valid_read_authorization) { "Bearer #{read_oauth_token.token}" }
32
+ let(:valid_user_authorization) { "Bearer #{user_oauth_token.token}" }
33
+ let(:bogus_authorization) { "Bearer #{::Base64.strict_encode64('bogus:bogus')}" }
34
+
35
+ let(:Authorization) { valid_authorization }
36
+ end
37
+
38
+ shared_context 'jsonapi pagination' do
39
+ let(:page) { 1 }
40
+ let(:per_page) { '' }
41
+ parameter name: :page, in: :query, type: :integer, example: 1
42
+ parameter name: :per_page, in: :query, type: :integer, example: 50
43
+ end
44
+
45
+ JSON_API_INCLUDES_DESCRIPTION = 'Select which associated resources you would like to fetch'\
46
+ ', see: <a href="https://jsonapi.org/format/#fetching-includes">'\
47
+ 'https://jsonapi.org/format/#fetching-includes</a>'.freeze
48
+ JSON_API_FILTER_DESCRIPTION = ''
49
+
50
+ def json_api_include_parameter(example = '')
51
+ let(:include) { nil }
52
+ parameter name: :include, in: :query, type: :string, descripton: JSON_API_INCLUDES_DESCRIPTION, example: example
53
+ end
54
+
55
+ def json_api_filter_parameter(example = '')
56
+ let(:filter) { nil }
57
+ parameter name: :filter, in: :query, type: :string, descripton: JSON_API_FILTER_DESCRIPTION, example: example
58
+ end
59
+
60
+ shared_examples 'authentication failed' do
61
+ response '401', 'Authentication Failed' do
62
+ let(:Authorization) { bogus_authorization }
63
+ schema '$ref' => '#/components/schemas/error'
64
+ run_test!
65
+ end
66
+ end
67
+
68
+ shared_examples 'record not found' do
69
+ response '404', 'Record not found' do
70
+ let(:id) { 'invalid' }
71
+ schema '$ref' => '#/components/schemas/error'
72
+ run_test!
73
+ end
74
+ end
75
+
76
+ shared_examples 'record found' do
77
+ response '200', 'Record found' do
78
+ schema '$ref' => '#/components/schemas/resource'
79
+ run_test!
80
+ end
81
+ end
82
+
83
+ shared_examples 'record deleted' do
84
+ response '204', 'Record deleted' do
85
+ run_test!
86
+ end
87
+ end
88
+
89
+ shared_examples 'records returned' do
90
+ response '200', 'Records returned' do
91
+ schema '$ref' => '#/components/schemas/resources_list'
92
+ run_test!
93
+ end
94
+ end
95
+
96
+ shared_examples 'record created' do
97
+ response '201', 'record created' do
98
+ schema '$ref' => '#/components/schemas/resource'
99
+ run_test!
100
+ end
101
+ end
102
+
103
+ shared_examples 'record updated' do
104
+ response '200', 'record updated' do
105
+ schema '$ref' => '#/components/schemas/resource'
106
+ run_test!
107
+ end
108
+ end
109
+
110
+ shared_examples 'invalid request' do |param_name|
111
+ response '422', 'invalid request' do
112
+ let(param_name) { invalid_param_value }
113
+ schema '$ref' => '#/components/schemas/validation_errors'
114
+ run_test!
115
+ end
116
+ end
117
+
118
+ # index action
119
+ shared_examples 'GET records list' do |resource_name, include_example, filter_example|
120
+ get "Returns a list of #{resource_name.pluralize}" do
121
+ tags resource_name.pluralize
122
+ security [ bearer_auth: [] ]
123
+ include_context 'jsonapi pagination'
124
+ json_api_include_parameter(include_example)
125
+ json_api_filter_parameter(filter_example)
126
+
127
+ before { records_list }
128
+
129
+ it_behaves_like 'records returned'
130
+ it_behaves_like 'authentication failed'
131
+ end
132
+ end
133
+
134
+ # show
135
+ shared_examples 'GET record' do |resource_name, include_example|
136
+ get "Returns #{resource_name.articleize}" do
137
+ tags resource_name.pluralize
138
+ security [ bearer_auth: [] ]
139
+ parameter name: :id, in: :path, type: :string
140
+ json_api_include_parameter(include_example)
141
+
142
+ it_behaves_like 'record found'
143
+ it_behaves_like 'record not found'
144
+ it_behaves_like 'authentication failed'
145
+ end
146
+ end
147
+
148
+ # create
149
+ shared_examples 'POST create record' do |resource_name, include_example|
150
+ param_name = resource_name.parameterize.to_sym
151
+
152
+ post "Creates #{resource_name.articleize}" do
153
+ tags resource_name.pluralize
154
+ consumes 'application/json'
155
+ security [ bearer_auth: [] ]
156
+ parameter name: param_name, in: :body, schema: { '$ref' => "#/components/schemas/#{param_name}_params" }
157
+ json_api_include_parameter(include_example)
158
+
159
+ let(param_name) { valid_create_param_value }
160
+
161
+ it_behaves_like 'record created'
162
+ it_behaves_like 'invalid request', param_name
163
+ end
164
+ end
165
+
166
+ # update
167
+ shared_examples 'PUT update record' do |resource_name, include_example|
168
+ param_name = resource_name.parameterize.to_sym
169
+
170
+ put "Updates #{resource_name.articleize}" do
171
+ tags resource_name.pluralize
172
+ security [ bearer_auth: [] ]
173
+ consumes 'application/json'
174
+ parameter name: :id, in: :path, type: :string
175
+ parameter name: param_name, in: :body, schema: { '$ref' => "#/components/schemas/#{param_name}_params" }
176
+ json_api_include_parameter(include_example)
177
+
178
+ let(param_name) { valid_update_param_value }
179
+
180
+ it_behaves_like 'record updated'
181
+ it_behaves_like 'invalid request', param_name
182
+ it_behaves_like 'record not found'
183
+ it_behaves_like 'authentication failed'
184
+ end
185
+ end
186
+
187
+ # destroy
188
+ shared_examples 'DELETE record' do |resource_name|
189
+ delete "Deletes #{resource_name.articleize}" do
190
+ tags resource_name.pluralize
191
+ security [ bearer_auth: [] ]
192
+ parameter name: :id, in: :path, type: :string
193
+
194
+ it_behaves_like 'record deleted'
195
+ it_behaves_like 'record not found'
196
+ it_behaves_like 'authentication failed'
197
+ end
198
+ end
199
+
200
+ shared_examples 'CRUD examples' do |resource_name, include_example, filter_example|
201
+ resource_path = resource_name.pluralize.parameterize
202
+
203
+ path "/api/v2/platform/#{resource_path}" do
204
+ include_examples 'GET records list', resource_name, include_example, filter_example
205
+ include_examples 'POST create record', resource_name, include_example
206
+ end
207
+
208
+ path "/api/v2/platform/#{resource_path}/{id}" do
209
+ include_examples 'GET record', resource_name, include_example
210
+ include_examples 'PUT update record', resource_name, include_example
211
+ include_examples 'DELETE record', resource_name
212
+ end
213
+ end