diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index 768ce4363e..8cab053e4b 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -1170,7 +1170,7 @@ Style/FrozenStringLiteralComment:
- 'engines/order_management/app/services/reports/renderers/base.rb'
- 'engines/order_management/app/services/reports/report_data/base.rb'
- 'engines/web/app/controllers/web/angular_templates_controller.rb'
- - 'engines/web/app/controllers/web/api/cookies_consent_controller.rb'
+ - 'engines/web/app/controllers/web/api/v0/cookies_consent_controller.rb'
- 'engines/web/app/controllers/web/application_controller.rb'
- 'engines/web/app/helpers/web/cookies_policy_helper.rb'
- 'engines/web/lib/web/cookies_consent.rb'
diff --git a/app/assets/javascripts/admin/bulk_product_update.js.coffee b/app/assets/javascripts/admin/bulk_product_update.js.coffee
index 4e2bd45d70..f2d8f9ddcf 100644
--- a/app/assets/javascripts/admin/bulk_product_update.js.coffee
+++ b/app/assets/javascripts/admin/bulk_product_update.js.coffee
@@ -147,7 +147,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout
if confirm("Are you sure?")
$http(
method: "DELETE"
- url: "/api/products/" + product.id
+ url: "/api/v0/products/" + product.id
).success (data) ->
$scope.products.splice $scope.products.indexOf(product), 1
DirtyProducts.deleteProduct product.id
@@ -162,7 +162,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout
if confirm(t("are_you_sure"))
$http(
method: "DELETE"
- url: "/api/products/" + product.permalink_live + "/variants/" + variant.id
+ url: "/api/v0/products/" + product.permalink_live + "/variants/" + variant.id
).success (data) ->
$scope.removeVariant(product, variant)
else
diff --git a/app/assets/javascripts/admin/enterprise_fees/directives/delete_resource.js.coffee b/app/assets/javascripts/admin/enterprise_fees/directives/delete_resource.js.coffee
index ba37f0518f..7e7a8206c4 100644
--- a/app/assets/javascripts/admin/enterprise_fees/directives/delete_resource.js.coffee
+++ b/app/assets/javascripts/admin/enterprise_fees/directives/delete_resource.js.coffee
@@ -1,7 +1,7 @@
angular.module('admin.enterpriseFees').directive 'spreeDeleteResource', ->
(scope, element, attrs) ->
if scope.enterprise_fee.id
- url = '/api/enterprise_fees/' + scope.enterprise_fee.id
+ url = '/api/v0/enterprise_fees/' + scope.enterprise_fee.id
html = ''
#var html = '
Delete';
element.append html
diff --git a/app/assets/javascripts/admin/index_utils/services/resources.js.coffee b/app/assets/javascripts/admin/index_utils/services/resources.js.coffee
index 65dad204d4..58664b6895 100644
--- a/app/assets/javascripts/admin/index_utils/services/resources.js.coffee
+++ b/app/assets/javascripts/admin/index_utils/services/resources.js.coffee
@@ -1,5 +1,5 @@
angular.module("admin.indexUtils").factory "resources", ($resource) ->
- LineItem = $resource '/api/orders/:order_number/line_items/:line_item_id.json',
+ LineItem = $resource '/api/v0/orders/:order_number/line_items/:line_item_id.json',
{ order_number: '@order_number', line_item_id: '@line_item_id'},
'update': { method: 'PUT' }
Customer = $resource '/admin/customers/:customer_id.json',
diff --git a/app/assets/javascripts/admin/order_cycles/services/exchange_product.js.coffee b/app/assets/javascripts/admin/order_cycles/services/exchange_product.js.coffee
index f21698da33..79e0dd6ce6 100644
--- a/app/assets/javascripts/admin/order_cycles/services/exchange_product.js.coffee
+++ b/app/assets/javascripts/admin/order_cycles/services/exchange_product.js.coffee
@@ -1,5 +1,5 @@
angular.module('admin.orderCycles').factory('ExchangeProduct', ($resource) ->
- ExchangeProductResource = $resource('/api/exchanges/:exchange_id/products.json', {}, {
+ ExchangeProductResource = $resource('/api/v0/exchanges/:exchange_id/products.json', {}, {
'index': { method: 'GET' }
'variant_count': { method: 'GET', params: { action_name: "variant_count" }}
})
diff --git a/app/assets/javascripts/admin/products/services/product_image_service.js.coffee b/app/assets/javascripts/admin/products/services/product_image_service.js.coffee
index 8b0f273e8b..3d36d0a914 100644
--- a/app/assets/javascripts/admin/products/services/product_image_service.js.coffee
+++ b/app/assets/javascripts/admin/products/services/product_image_service.js.coffee
@@ -8,7 +8,7 @@ angular.module("ofn.admin").factory "ProductImageService", (FileUploader, SpreeA
autoUpload: true
configure: (product) =>
- @imageUploader.url = "/api/product_images/#{product.id}"
+ @imageUploader.url = "/api/v0/product_images/#{product.id}"
@imagePreview = product.image_url
@imageUploader.onSuccessItem = (image, response) =>
product.thumb_url = response.thumb_url
diff --git a/app/assets/javascripts/admin/resources/resources/enterprise_resource.js.coffee b/app/assets/javascripts/admin/resources/resources/enterprise_resource.js.coffee
index e7e773a42a..f3d2128e20 100644
--- a/app/assets/javascripts/admin/resources/resources/enterprise_resource.js.coffee
+++ b/app/assets/javascripts/admin/resources/resources/enterprise_resource.js.coffee
@@ -9,12 +9,12 @@ angular.module("admin.resources").factory 'EnterpriseResource', ($resource) ->
'update':
method: 'PUT'
'removeLogo':
- url: '/api/enterprises/:id/logo.json'
+ url: '/api/v0/enterprises/:id/logo.json'
method: 'DELETE'
'removePromoImage':
- url: '/api/enterprises/:id/promo_image.json'
+ url: '/api/v0/enterprises/:id/promo_image.json'
method: 'DELETE'
'removeTermsAndConditions':
- url: '/api/enterprises/:id/terms_and_conditions.json'
+ url: '/api/v0/enterprises/:id/terms_and_conditions.json'
method: 'DELETE'
})
diff --git a/app/assets/javascripts/admin/resources/resources/order_resource.js.coffee b/app/assets/javascripts/admin/resources/resources/order_resource.js.coffee
index 534833d1c9..a6642072ab 100644
--- a/app/assets/javascripts/admin/resources/resources/order_resource.js.coffee
+++ b/app/assets/javascripts/admin/resources/resources/order_resource.js.coffee
@@ -1,17 +1,17 @@
angular.module("admin.resources").factory 'OrderResource', ($resource) ->
$resource('/admin/orders/:id/:action.json', {}, {
'index':
- url: '/api/orders.json'
+ url: '/api/v0/orders.json'
method: 'GET'
'update':
method: 'PUT'
'capture':
- url: '/api/orders/:id/capture.json'
+ url: '/api/v0/orders/:id/capture.json'
method: 'PUT'
params:
id: '@id'
'ship':
- url: '/api/orders/:id/ship.json'
+ url: '/api/v0/orders/:id/ship.json'
method: 'PUT'
params:
id: '@id'
diff --git a/app/assets/javascripts/admin/resources/resources/product_resource.js.coffee b/app/assets/javascripts/admin/resources/resources/product_resource.js.coffee
index b630c1f8cd..7d842d8eed 100644
--- a/app/assets/javascripts/admin/resources/resources/product_resource.js.coffee
+++ b/app/assets/javascripts/admin/resources/resources/product_resource.js.coffee
@@ -1,6 +1,6 @@
angular.module("admin.resources").factory 'ProductResource', ($resource) ->
$resource('/admin/product/:id/:action.json', {}, {
'index':
- url: '/api/products/bulk_products.json'
+ url: '/api/v0/products/bulk_products.json'
method: 'GET'
})
diff --git a/app/assets/javascripts/admin/services/bulk_products.js.coffee b/app/assets/javascripts/admin/services/bulk_products.js.coffee
index 72e9715c9e..1c33fcb6cf 100644
--- a/app/assets/javascripts/admin/services/bulk_products.js.coffee
+++ b/app/assets/javascripts/admin/services/bulk_products.js.coffee
@@ -10,8 +10,8 @@ angular.module("ofn.admin").factory "BulkProducts", (ProductResource, dataFetche
angular.extend(@pagination, data.pagination)
cloneProduct: (product) ->
- $http.post("/api/products/" + product.id + "/clone").success (data) =>
- dataFetcher("/api/products/" + data.id + "?template=bulk_show").then (newProduct) =>
+ $http.post("/api/v0/products/" + product.id + "/clone").success (data) =>
+ dataFetcher("/api/v0/products/" + data.id + "?template=bulk_show").then (newProduct) =>
@unpackProduct newProduct
@insertProductAfter(product, newProduct)
diff --git a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee
index b890d2ffd5..51dc72be08 100644
--- a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee
+++ b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee
@@ -42,7 +42,7 @@ angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl",
$scope.fetchProducts()
$scope.fetchProducts = ->
- url = "/api/products/overridable?page=::page::;per_page=100"
+ url = "/api/v0/products/overridable?page=::page::;per_page=100"
PagedFetcher.fetch url, $scope.addProducts
$scope.addProducts = (data) ->
diff --git a/app/assets/javascripts/darkswarm/controllers/hub_node_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/hub_node_controller.js.coffee
index f96d2d454f..4f1d935aec 100644
--- a/app/assets/javascripts/darkswarm/controllers/hub_node_controller.js.coffee
+++ b/app/assets/javascripts/darkswarm/controllers/hub_node_controller.js.coffee
@@ -24,7 +24,7 @@ Darkswarm.controller "HubNodeCtrl", ($scope, HashNavigation, CurrentHub, $http,
$scope.shopfront_loading = true
$scope.toggle_tab(event)
- $http.get("/api/shops/" + $scope.hub.id)
+ $http.get("/api/v0/shops/" + $scope.hub.id)
.success (data) ->
$scope.shopfront_loading = false
$scope.hub = data
diff --git a/app/assets/javascripts/darkswarm/controllers/producer_node_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/producer_node_controller.js.coffee
index 3aa5045bee..230592a7a6 100644
--- a/app/assets/javascripts/darkswarm/controllers/producer_node_controller.js.coffee
+++ b/app/assets/javascripts/darkswarm/controllers/producer_node_controller.js.coffee
@@ -24,7 +24,7 @@ Darkswarm.controller "ProducerNodeCtrl", ($scope, HashNavigation, $anchorScroll,
$scope.shopfront_loading = true
$scope.toggle_tab(event)
- $http.get("/api/shops/" + $scope.producer.id)
+ $http.get("/api/v0/shops/" + $scope.producer.id)
.success (data) ->
$scope.shopfront_loading = false
$scope.producer = data
diff --git a/app/assets/javascripts/darkswarm/services/customer.js.coffee b/app/assets/javascripts/darkswarm/services/customer.js.coffee
index fa3b1b532f..7bad3a7b89 100644
--- a/app/assets/javascripts/darkswarm/services/customer.js.coffee
+++ b/app/assets/javascripts/darkswarm/services/customer.js.coffee
@@ -1,5 +1,5 @@
angular.module("Darkswarm").factory 'Customer', ($resource, $injector, Messages) ->
- Customer = $resource('/api/customers/:id/:action.json', {}, {
+ Customer = $resource('/api/v0/customers/:id/:action.json', {}, {
'index':
method: 'GET'
isArray: true
diff --git a/app/assets/javascripts/darkswarm/services/enterprise_image_service.js.coffee b/app/assets/javascripts/darkswarm/services/enterprise_image_service.js.coffee
index c8cd64e93a..13cd140cc4 100644
--- a/app/assets/javascripts/darkswarm/services/enterprise_image_service.js.coffee
+++ b/app/assets/javascripts/darkswarm/services/enterprise_image_service.js.coffee
@@ -8,5 +8,5 @@ Darkswarm.factory "EnterpriseImageService", (FileUploader, spreeApiKey) ->
autoUpload: true
configure: (enterprise) =>
- @imageUploader.url = "/api/enterprises/#{enterprise.id}/update_image"
+ @imageUploader.url = "/api/v0/enterprises/#{enterprise.id}/update_image"
@imageUploader.onSuccessItem = (image, response) => @imageSrc = response
diff --git a/app/assets/javascripts/darkswarm/services/enterprise_modal.js.coffee b/app/assets/javascripts/darkswarm/services/enterprise_modal.js.coffee
index 37dafef776..4eab4d79ac 100644
--- a/app/assets/javascripts/darkswarm/services/enterprise_modal.js.coffee
+++ b/app/assets/javascripts/darkswarm/services/enterprise_modal.js.coffee
@@ -5,7 +5,7 @@ Darkswarm.factory "EnterpriseModal", ($modal, $rootScope, $http)->
scope = $rootScope.$new(true) # Spawn an isolate to contain the enterprise
scope.embedded_layout = window.location.search.indexOf("embedded_shopfront=true") != -1
- $http.get("/api/shops/" + enterprise.id).success (data) ->
+ $http.get("/api/v0/shops/" + enterprise.id).success (data) ->
scope.enterprise = data
$modal.open(templateUrl: "enterprise_modal.html", scope: scope)
.error (data) ->
diff --git a/app/assets/javascripts/darkswarm/services/enterprise_registration_service.js.coffee b/app/assets/javascripts/darkswarm/services/enterprise_registration_service.js.coffee
index dc9f6617ee..019f293117 100644
--- a/app/assets/javascripts/darkswarm/services/enterprise_registration_service.js.coffee
+++ b/app/assets/javascripts/darkswarm/services/enterprise_registration_service.js.coffee
@@ -18,7 +18,7 @@ Darkswarm.factory "EnterpriseRegistrationService", ($http, RegistrationService,
Loading.message = t('creating') + " " + @enterprise.name
$http(
method: "POST"
- url: "/api/enterprises"
+ url: "/api/v0/enterprises"
data:
enterprise: @prepare()
params:
@@ -42,7 +42,7 @@ Darkswarm.factory "EnterpriseRegistrationService", ($http, RegistrationService,
Loading.message = t('updating') + " " + @enterprise.name
$http(
method: "PUT"
- url: "/api/enterprises/#{@enterprise.id}"
+ url: "/api/v0/enterprises/#{@enterprise.id}"
data:
enterprise: @prepare()
params:
diff --git a/app/assets/javascripts/darkswarm/services/order_cycle_resource.js.coffee b/app/assets/javascripts/darkswarm/services/order_cycle_resource.js.coffee
index ba8d5266fe..b8dd81d42c 100644
--- a/app/assets/javascripts/darkswarm/services/order_cycle_resource.js.coffee
+++ b/app/assets/javascripts/darkswarm/services/order_cycle_resource.js.coffee
@@ -1,21 +1,21 @@
Darkswarm.factory 'OrderCycleResource', ($resource) ->
- $resource('/api/order_cycles/:id.json', {}, {
+ $resource('/api/v0/order_cycles/:id.json', {}, {
'products':
method: 'GET'
isArray: true
- url: '/api/order_cycles/:id/products.json'
+ url: '/api/v0/order_cycles/:id/products.json'
params:
id: '@id'
'taxons':
method: 'GET'
isArray: true
- url: '/api/order_cycles/:id/taxons.json'
+ url: '/api/v0/order_cycles/:id/taxons.json'
params:
id: '@id'
'properties':
method: 'GET'
isArray: true
- url: '/api/order_cycles/:id/properties.json'
+ url: '/api/v0/order_cycles/:id/properties.json'
params:
id: '@id'
})
diff --git a/app/assets/javascripts/darkswarm/services/shops_resource.js.coffee b/app/assets/javascripts/darkswarm/services/shops_resource.js.coffee
index 2726b25496..946eb21832 100644
--- a/app/assets/javascripts/darkswarm/services/shops_resource.js.coffee
+++ b/app/assets/javascripts/darkswarm/services/shops_resource.js.coffee
@@ -1,7 +1,7 @@
Darkswarm.factory 'ShopsResource', ($resource) ->
- $resource('/api/shops/:id.json', {}, {
+ $resource('/api/v0/shops/:id.json', {}, {
'closed_shops':
method: 'GET'
isArray: true
- url: '/api/shops/closed_shops.json'
+ url: '/api/v0/shops/closed_shops.json'
})
diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb
deleted file mode 100644
index 3ec78c85d4..0000000000
--- a/app/controllers/api/base_controller.rb
+++ /dev/null
@@ -1,103 +0,0 @@
-# Base controller for OFN's API
-require_dependency 'spree/api/controller_setup'
-require "spree/core/controller_helpers/ssl"
-
-module Api
- class BaseController < ActionController::Metal
- include RawParams
- include ActionController::StrongParameters
- include ActionController::RespondWith
- include Spree::Api::ControllerSetup
- include Spree::Core::ControllerHelpers::SSL
- include ::ActionController::Head
- include ::ActionController::ConditionalGet
- include ActionView::Layouts
-
- layout false
-
- attr_accessor :current_api_user
-
- before_action :set_content_type
- before_action :authenticate_user
-
- rescue_from Exception, with: :error_during_processing
- rescue_from CanCan::AccessDenied, with: :unauthorized
- rescue_from ActiveRecord::RecordNotFound, with: :not_found
-
- helper Spree::Api::ApiHelpers
-
- ssl_allowed
-
- # Include these because we inherit from ActionController::Metal
- # rather than ActionController::Base and these are required for AMS
- include ActionController::Serialization
- include ActionController::UrlFor
- include Rails.application.routes.url_helpers
-
- use_renderers :json
- check_authorization
-
- def respond_with_conflict(json_hash)
- render json: json_hash, status: :conflict
- end
-
- private
-
- # Use logged in user (spree_current_user) for API authentication (current_api_user)
- def authenticate_user
- return if @current_api_user = spree_current_user
-
- if api_key.blank?
- # An anonymous user
- @current_api_user = Spree.user_class.new
- return
- end
-
- return if @current_api_user = Spree.user_class.find_by(spree_api_key: api_key.to_s)
-
- invalid_api_key
- end
-
- def set_content_type
- headers["Content-Type"] = "application/json"
- end
-
- def error_during_processing(exception)
- Bugsnag.notify(exception)
-
- render(json: { exception: exception.message },
- status: :unprocessable_entity) && return
- end
-
- def current_ability
- Spree::Ability.new(current_api_user)
- end
-
- def api_key
- request.headers["X-Spree-Token"] || params[:token]
- end
- helper_method :api_key
-
- def invalid_resource!(resource)
- @resource = resource
- render(json: { error: I18n.t(:invalid_resource, scope: "spree.api"),
- errors: @resource.errors },
- status: :unprocessable_entity)
- end
-
- def invalid_api_key
- render(json: { error: I18n.t(:invalid_api_key, key: api_key, scope: "spree.api") },
- status: :unauthorized) && return
- end
-
- def unauthorized
- render(json: { error: I18n.t(:unauthorized, scope: "spree.api") },
- status: :unauthorized) && return
- end
-
- def not_found
- render(json: { error: I18n.t(:resource_not_found, scope: "spree.api") },
- status: :not_found) && return
- end
- end
-end
diff --git a/app/controllers/api/customers_controller.rb b/app/controllers/api/customers_controller.rb
deleted file mode 100644
index 7cb702a824..0000000000
--- a/app/controllers/api/customers_controller.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-module Api
- class CustomersController < Api::BaseController
- skip_authorization_check only: :index
-
- def index
- @customers = current_api_user.customers
- render json: @customers, each_serializer: CustomerSerializer
- end
-
- def update
- @customer = Customer.find(params[:id])
- authorize! :update, @customer
-
- client_secret = RecurringPayments.setup_for(@customer) if params[:customer][:allow_charges]
-
- if @customer.update(customer_params)
- add_recurring_payment_info(client_secret)
- render json: @customer, serializer: CustomerSerializer, status: :ok
- else
- invalid_resource!(@customer)
- end
- end
-
- private
-
- def add_recurring_payment_info(client_secret)
- return unless client_secret
-
- @customer.gateway_recurring_payment_client_secret = client_secret
- @customer.gateway_shop_id = @customer.enterprise.stripe_account&.stripe_user_id
- end
-
- def customer_params
- params.require(:customer).permit(:code, :email, :enterprise_id, :allow_charges)
- end
- end
-end
diff --git a/app/controllers/api/enterprise_attachment_controller.rb b/app/controllers/api/enterprise_attachment_controller.rb
deleted file mode 100644
index d9b619ab8e..0000000000
--- a/app/controllers/api/enterprise_attachment_controller.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-# frozen_string_literal: true
-
-require 'api/admin/enterprise_serializer'
-
-module Api
- class EnterpriseAttachmentController < Api::BaseController
- class MissingImplementationError < StandardError; end
- class UnknownEnterpriseAuthorizationActionError < StandardError; end
-
- before_action :load_enterprise
-
- respond_to :json
-
- def destroy
- return respond_with_conflict(error: destroy_attachment_does_not_exist_error_message) unless @enterprise.public_send("#{attachment_name}?")
-
- @enterprise.update!(attachment_name => nil)
- render json: @enterprise, serializer: Admin::EnterpriseSerializer, spree_current_user: spree_current_user
- end
-
- protected
-
- def attachment_name
- raise MissingImplementationError, "Method attachment_name should be defined"
- end
-
- def enterprise_authorize_action
- raise MissingImplementationError, "Method enterprise_authorize_action should be defined"
- end
-
- def load_enterprise
- @enterprise = Enterprise.find_by(permalink: params[:enterprise_id].to_s)
- raise UnknownEnterpriseAuthorizationActionError if enterprise_authorize_action.blank?
-
- authorize!(enterprise_authorize_action, @enterprise)
- end
-
- def destroy_attachment_does_not_exist_error_message
- I18n.t("api.enterprise_#{attachment_name}.destroy_attachment_does_not_exist")
- end
- end
-end
diff --git a/app/controllers/api/enterprise_fees_controller.rb b/app/controllers/api/enterprise_fees_controller.rb
deleted file mode 100644
index 3252961f97..0000000000
--- a/app/controllers/api/enterprise_fees_controller.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-module Api
- class EnterpriseFeesController < Api::BaseController
- respond_to :json
-
- def destroy
- authorize! :destroy, enterprise_fee
-
- if enterprise_fee.destroy
- render plain: I18n.t(:successfully_removed), status: :no_content
- else
- render plain: enterprise_fee.errors.full_messages.first, status: :forbidden
- end
- end
-
- private
-
- def enterprise_fee
- @enterprise_fee ||= EnterpriseFee.find_by id: params[:id]
- end
- end
-end
diff --git a/app/controllers/api/enterprises_controller.rb b/app/controllers/api/enterprises_controller.rb
deleted file mode 100644
index bcec80f3a6..0000000000
--- a/app/controllers/api/enterprises_controller.rb
+++ /dev/null
@@ -1,78 +0,0 @@
-module Api
- class EnterprisesController < Api::BaseController
- before_action :override_owner, only: [:create, :update]
- before_action :check_type, only: :update
- before_action :override_sells, only: [:create, :update]
- before_action :override_visible, only: [:create, :update]
- respond_to :json
-
- def create
- authorize! :create, Enterprise
-
- # params[:user_ids] breaks the enterprise creation
- # We remove them from params and save them after creating the enterprise
- user_ids = enterprise_params.delete(:user_ids)
- @enterprise = Enterprise.new(enterprise_params)
- if @enterprise.save
- @enterprise.user_ids = user_ids
- render json: @enterprise.id, status: :created
- else
- invalid_resource!(@enterprise)
- end
- end
-
- def update
- @enterprise = Enterprise.find_by(permalink: params[:id]) || Enterprise.find(params[:id])
- authorize! :update, @enterprise
-
- if @enterprise.update(enterprise_params)
- render json: @enterprise.id, status: :ok
- else
- invalid_resource!(@enterprise)
- end
- end
-
- def update_image
- @enterprise = Enterprise.find_by(permalink: params[:id]) || Enterprise.find(params[:id])
- authorize! :update, @enterprise
-
- if params[:logo] && @enterprise.update( logo: params[:logo] )
- render plain: @enterprise.logo.url(:medium), status: :ok
- elsif params[:promo] && @enterprise.update( promo_image: params[:promo] )
- render plain: @enterprise.promo_image.url(:medium), status: :ok
- else
- invalid_resource!(@enterprise)
- end
- end
-
- private
-
- def override_owner
- enterprise_params[:owner_id] = current_api_user.id
- end
-
- def check_type
- enterprise_params.delete :type unless current_api_user.admin?
- end
-
- def override_sells
- has_hub = current_api_user.owned_enterprises.is_hub.any?
- new_enterprise_is_producer = !!enterprise_params[:is_primary_producer]
-
- enterprise_params[:sells] = if has_hub && !new_enterprise_is_producer
- 'any'
- else
- 'unspecified'
- end
- end
-
- def override_visible
- enterprise_params[:visible] = false
- end
-
- def enterprise_params
- @enterprise_params ||= PermittedAttributes::Enterprise.new(params).call.
- to_h.with_indifferent_access
- end
- end
-end
diff --git a/app/controllers/api/exchange_products_controller.rb b/app/controllers/api/exchange_products_controller.rb
deleted file mode 100644
index b43321841c..0000000000
--- a/app/controllers/api/exchange_products_controller.rb
+++ /dev/null
@@ -1,100 +0,0 @@
-# frozen_string_literal: true
-
-# This controller lists products that can be added to an exchange
-#
-# Pagination is optional and can be required by using param[:page]
-module Api
- class ExchangeProductsController < Api::BaseController
- include PaginationData
- DEFAULT_PER_PAGE = 100
-
- skip_authorization_check only: [:index]
-
- # If exchange_id is present in the URL:
- # Lists Products that can be added to that Exchange
- #
- # If exchange_id is not present in the URL:
- # Lists Products of the Enterprise given that can be added to the given Order Cycle
- # In this case parameters are: enterprise_id, order_cycle_id and incoming
- # (order_cycle_id is not necessary for incoming exchanges)
- def index
- if exchange_params[:exchange_id].present?
- load_data_from_exchange
- else
- load_data_from_other_params
- end
-
- render_variant_count && return if params[:action_name] == "variant_count"
-
- render_paginated_products paginated_products
- end
-
- private
-
- def render_variant_count
- render plain: {
- count: variants.count
- }.to_json
- end
-
- def variants
- renderer.exchange_variants(@incoming, @enterprise)
- end
-
- def products
- renderer.exchange_products(@incoming, @enterprise)
- end
-
- def renderer
- @renderer ||= ExchangeProductsRenderer.
- new(@order_cycle, spree_current_user)
- end
-
- def paginated_products
- return products unless pagination_required?
-
- products.
- page(params[:page]).
- per(params[:per_page] || DEFAULT_PER_PAGE)
- end
-
- def load_data_from_exchange
- exchange = Exchange.find_by(id: exchange_params[:exchange_id])
-
- @order_cycle = exchange.order_cycle
- @incoming = exchange.incoming
- @enterprise = exchange.sender
- end
-
- def load_data_from_other_params
- @enterprise = Enterprise.find_by(id: exchange_params[:enterprise_id])
-
- # This will be a string (eg "true") when it arrives via params, but we want a boolean
- @incoming = ActiveModel::Type::Boolean.new.cast exchange_params[:incoming]
-
- if exchange_params[:order_cycle_id]
- @order_cycle = OrderCycle.find_by(id: exchange_params[:order_cycle_id])
- elsif !@incoming
- raise "order_cycle_id is required to list products for new outgoing exchange"
- end
- end
-
- def render_paginated_products(paginated_products)
- serialized_products = ActiveModel::ArraySerializer.new(
- paginated_products,
- each_serializer: Api::Admin::ForOrderCycle::SuppliedProductSerializer,
- order_cycle: @order_cycle
- )
-
- render json: {
- products: serialized_products,
- pagination: pagination_data(paginated_products)
- }
- end
-
- def exchange_params
- params.permit(:enterprise_id, :exchange_id, :order_cycle_id, :incoming).
- to_h.with_indifferent_access
- end
- end
-end
diff --git a/app/controllers/api/logos_controller.rb b/app/controllers/api/logos_controller.rb
deleted file mode 100644
index 0c4b4c2f45..0000000000
--- a/app/controllers/api/logos_controller.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-module Api
- class LogosController < Api::EnterpriseAttachmentController
- private
-
- def attachment_name
- :logo
- end
-
- def enterprise_authorize_action
- case action_name.to_sym
- when :destroy
- :remove_logo
- end
- end
- end
-end
diff --git a/app/controllers/api/order_cycles_controller.rb b/app/controllers/api/order_cycles_controller.rb
deleted file mode 100644
index c40ec641b2..0000000000
--- a/app/controllers/api/order_cycles_controller.rb
+++ /dev/null
@@ -1,101 +0,0 @@
-module Api
- class OrderCyclesController < Api::BaseController
- include EnterprisesHelper
- include ApiActionCaching
-
- skip_authorization_check
- skip_before_action :authenticate_user, :ensure_api_key, only: [:taxons, :properties]
-
- caches_action :taxons, :properties,
- expires_in: CacheService::FILTERS_EXPIRY,
- cache_path: proc { |controller| controller.request.url }
-
- def products
- return render_no_products unless order_cycle.open?
-
- products = ProductsRenderer.new(
- distributor,
- order_cycle,
- customer,
- search_params
- ).products_json
-
- render plain: products
- rescue ProductsRenderer::NoProducts
- render_no_products
- end
-
- def taxons
- taxons = Spree::Taxon.
- joins(:products).
- where(spree_products: { id: distributed_products }).
- select('DISTINCT spree_taxons.*')
-
- render plain: ActiveModel::ArraySerializer.new(
- taxons, each_serializer: Api::TaxonSerializer
- ).to_json
- end
-
- def properties
- render plain: ActiveModel::ArraySerializer.new(
- product_properties | producer_properties, each_serializer: Api::PropertySerializer
- ).to_json
- end
-
- private
-
- def render_no_products
- render status: :not_found, json: {}
- end
-
- def product_properties
- Spree::Property.
- joins(:products).
- where(spree_products: { id: distributed_products }).
- select('DISTINCT spree_properties.*')
- end
-
- def producer_properties
- producers = Enterprise.
- joins(:supplied_products).
- where(spree_products: { id: distributed_products })
-
- Spree::Property.
- joins(:producer_properties).
- where(producer_properties: { producer_id: producers }).
- select('DISTINCT spree_properties.*')
- end
-
- def search_params
- permitted_search_params = params.slice :q, :page, :per_page
-
- if permitted_search_params.key? :q
- permitted_search_params[:q].slice!(*permitted_ransack_params)
- end
-
- permitted_search_params
- end
-
- def permitted_ransack_params
- [:name_or_meta_keywords_or_variants_display_as_or_variants_display_name_or_supplier_name_cont,
- :properties_id_or_supplier_properties_id_in_any,
- :primary_taxon_id_in_any]
- end
-
- def distributor
- @distributor ||= Enterprise.find_by(id: params[:distributor])
- end
-
- def order_cycle
- @order_cycle ||= OrderCycle.find_by(id: params[:id])
- end
-
- def customer
- @current_api_user.andand.customer_of(distributor) || nil
- end
-
- def distributed_products
- OrderCycleDistributedProducts.new(distributor, order_cycle, customer).products_relation
- end
- end
-end
diff --git a/app/controllers/api/orders_controller.rb b/app/controllers/api/orders_controller.rb
deleted file mode 100644
index a0a4a0c013..0000000000
--- a/app/controllers/api/orders_controller.rb
+++ /dev/null
@@ -1,67 +0,0 @@
-module Api
- class OrdersController < Api::BaseController
- include PaginationData
-
- def show
- authorize! :read, order
- render json: order, serializer: Api::OrderDetailedSerializer, current_order: order
- end
-
- def index
- authorize! :admin, Spree::Order
-
- orders = SearchOrders.new(params, current_api_user).orders
-
- render json: {
- orders: serialized_orders(orders),
- pagination: pagination_data(orders)
- }
- end
-
- def ship
- authorize! :admin, order
-
- if order.ship
- render json: order.reload, serializer: Api::Admin::OrderSerializer, status: :ok
- else
- render json: { error: I18n.t('api.orders.failed_to_update') }, status: :unprocessable_entity
- end
- end
-
- def capture
- authorize! :admin, order
-
- pending_payment = order.pending_payments.first
-
- return payment_capture_failed unless order.payment_required? && pending_payment
-
- if pending_payment.capture!
- render json: order.reload, serializer: Api::Admin::OrderSerializer, status: :ok
- else
- payment_capture_failed
- end
- rescue Spree::Core::GatewayError => e
- error_during_processing(e)
- end
-
- private
-
- def payment_capture_failed
- render json: { error: I18n.t(:payment_processing_failed) }, status: :unprocessable_entity
- end
-
- def serialized_orders(orders)
- ActiveModel::ArraySerializer.new(
- orders,
- each_serializer: Api::Admin::OrderSerializer
- )
- end
-
- def order
- @order ||= Spree::Order.
- where(number: params[:id]).
- includes(line_items: { variant: [:product, :stock_items, :default_price] }).
- first!
- end
- end
-end
diff --git a/app/controllers/api/product_images_controller.rb b/app/controllers/api/product_images_controller.rb
deleted file mode 100644
index e688a03e6e..0000000000
--- a/app/controllers/api/product_images_controller.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-module Api
- class ProductImagesController < Api::BaseController
- respond_to :json
-
- def update_product_image
- @product = Spree::Product.find(params[:product_id])
- authorize! :update, @product
-
- if @product.images.first.nil?
- @image = Spree::Image.create(attachment: params[:file], viewable_id: @product.master.id, viewable_type: 'Spree::Variant')
- render json: @image, serializer: ImageSerializer, status: :created
- else
- @image = @product.images.first
- @image.update(attachment: params[:file])
- render json: @image, serializer: ImageSerializer, status: :ok
- end
- end
- end
-end
diff --git a/app/controllers/api/products_controller.rb b/app/controllers/api/products_controller.rb
deleted file mode 100644
index d8fab1067a..0000000000
--- a/app/controllers/api/products_controller.rb
+++ /dev/null
@@ -1,159 +0,0 @@
-require 'open_food_network/permissions'
-require 'spree/core/product_duplicator'
-
-module Api
- class ProductsController < Api::BaseController
- include PaginationData
- respond_to :json
- DEFAULT_PER_PAGE = 15
-
- before_action :set_default_available_on, only: :create
-
- skip_authorization_check only: [:show, :bulk_products, :overridable]
-
- def show
- @product = find_product(params[:id])
- render json: @product, serializer: Api::Admin::ProductSerializer
- end
-
- def create
- authorize! :create, Spree::Product
- @product = Spree::Product.new(product_params)
-
- begin
- if @product.save
- render json: @product, serializer: Api::Admin::ProductSerializer, status: :created
- else
- invalid_resource!(@product)
- end
- rescue ActiveRecord::RecordNotUnique
- @product.permalink = nil
- retry
- end
- end
-
- def update
- authorize! :update, Spree::Product
- @product = find_product(params[:id])
- if @product.update(product_params)
- render json: @product, serializer: Api::Admin::ProductSerializer, status: :ok
- else
- invalid_resource!(@product)
- end
- end
-
- def destroy
- authorize! :delete, Spree::Product
- @product = find_product(params[:id])
- authorize! :delete, @product
- @product.destroy
- render json: @product, serializer: Api::Admin::ProductSerializer, status: :no_content
- end
-
- def bulk_products
- product_query = OpenFoodNetwork::Permissions.
- new(current_api_user).
- editable_products.
- merge(product_scope)
-
- if params[:import_date].present?
- product_query = product_query.
- imported_on(params[:import_date]).
- group_by_products_id
- end
-
- @products = product_query.
- ransack(query_params_with_defaults).
- result.
- page(params[:page] || 1).
- per(params[:per_page] || DEFAULT_PER_PAGE)
-
- render_paged_products @products
- end
-
- def overridable
- producer_ids = OpenFoodNetwork::Permissions.new(current_api_user).
- variant_override_producers.by_name.select('enterprises.id')
-
- @products = paged_products_for_producers producer_ids
-
- render_paged_products @products, ::Api::Admin::ProductSimpleSerializer
- end
-
- # POST /api/products/:product_id/clone
- #
- def clone
- authorize! :create, Spree::Product
- original_product = find_product(params[:product_id])
- authorize! :update, original_product
-
- @product = original_product.duplicate
-
- render json: @product, serializer: Api::Admin::ProductSerializer, status: :created
- end
-
- private
-
- def find_product(id)
- product_scope.find_by!(permalink: id.to_s)
- rescue ActiveRecord::RecordNotFound
- product_scope.find(id)
- end
-
- def product_scope
- if current_api_user.has_spree_role?("admin") || current_api_user.enterprises.present?
- scope = Spree::Product
- if params[:show_deleted]
- scope = scope.with_deleted
- end
- else
- scope = Spree::Product.active
- end
-
- scope.includes(product_query_includes)
- end
-
- def product_query_includes
- [
- master: [:images],
- variants: [:default_price, :stock_locations, :stock_items, :variant_overrides,
- { option_values: :option_type }]
- ]
- end
-
- def paged_products_for_producers(producer_ids)
- Spree::Product.where(nil).
- merge(product_scope).
- includes(variants: [:product, :default_price, :stock_items]).
- where(supplier_id: producer_ids).
- by_producer.by_name.
- ransack(params[:q]).result.
- page(params[:page]).per(params[:per_page])
- end
-
- def render_paged_products(products, product_serializer = ::Api::Admin::ProductSerializer)
- serialized_products = ActiveModel::ArraySerializer.new(
- products,
- each_serializer: product_serializer
- )
-
- render json: {
- products: serialized_products,
- pagination: pagination_data(products)
- }
- end
-
- def query_params_with_defaults
- (params[:q] || {}).reverse_merge(s: 'created_at desc')
- end
-
- def product_params
- @product_params ||=
- params.permit(product: PermittedAttributes::Product.attributes)[:product].to_h
- end
-
- def set_default_available_on
- product_params[:available_on] ||= Time.zone.now
- end
- end
-end
diff --git a/app/controllers/api/promo_images_controller.rb b/app/controllers/api/promo_images_controller.rb
deleted file mode 100644
index 9cdb799931..0000000000
--- a/app/controllers/api/promo_images_controller.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-module Api
- class PromoImagesController < Api::EnterpriseAttachmentController
- private
-
- def attachment_name
- :promo_image
- end
-
- def enterprise_authorize_action
- case action_name.to_sym
- when :destroy
- :remove_promo_image
- end
- end
- end
-end
diff --git a/app/controllers/api/shipments_controller.rb b/app/controllers/api/shipments_controller.rb
deleted file mode 100644
index b9a5f4340b..0000000000
--- a/app/controllers/api/shipments_controller.rb
+++ /dev/null
@@ -1,112 +0,0 @@
-require 'open_food_network/scope_variant_to_hub'
-
-module Api
- class ShipmentsController < Api::BaseController
- respond_to :json
-
- before_action :find_order
- before_action :find_and_update_shipment, only: [:ship, :ready, :add, :remove]
-
- def create
- variant = scoped_variant(params[:variant_id])
- quantity = params[:quantity].to_i
- @shipment = get_or_create_shipment(params[:stock_location_id])
-
- @order.contents.add(variant, quantity, nil, @shipment)
-
- @shipment.refresh_rates
- @shipment.save!
-
- render json: @shipment.reload, serializer: Api::ShipmentSerializer, status: :ok
- end
-
- def update
- authorize! :read, Spree::Shipment
- @shipment = @order.shipments.find_by!(number: params[:id])
- params[:shipment] ||= []
- unlock = params[:shipment].delete(:unlock)
-
- if unlock == 'yes'
- @shipment.fee_adjustment.open
- end
-
- @shipment.update(shipment_params[:shipment])
-
- if unlock == 'yes'
- @shipment.fee_adjustment.close
- end
-
- render json: @shipment.reload, serializer: Api::ShipmentSerializer, status: :ok
- end
-
- def ready
- authorize! :read, Spree::Shipment
- unless @shipment.ready?
- if @shipment.can_ready?
- @shipment.ready!
- else
- render(json: { error: I18n.t(:cannot_ready, scope: "spree.api.shipment") },
- status: :unprocessable_entity) && return
- end
- end
- render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok
- end
-
- def ship
- authorize! :read, Spree::Shipment
- unless @shipment.shipped?
- @shipment.ship!
- end
- render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok
- end
-
- def add
- variant = scoped_variant(params[:variant_id])
- quantity = params[:quantity].to_i
-
- @order.contents.add(variant, quantity, nil, @shipment)
-
- render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok
- end
-
- def remove
- variant = scoped_variant(params[:variant_id])
- quantity = params[:quantity].to_i
-
- @order.contents.remove(variant, quantity, @shipment)
- @shipment.reload if @shipment.persisted?
-
- render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok
- end
-
- private
-
- def find_order
- @order = Spree::Order.find_by!(number: params[:order_id])
- authorize! :read, @order
- end
-
- def find_and_update_shipment
- @shipment = @order.shipments.find_by!(number: params[:id])
- @shipment.update(shipment_params[:shipment]) if shipment_params[:shipment].present?
- @shipment.reload
- end
-
- def scoped_variant(variant_id)
- variant = Spree::Variant.find(variant_id)
- OpenFoodNetwork::ScopeVariantToHub.new(@order.distributor).scope(variant)
- variant
- end
-
- def get_or_create_shipment(stock_location_id)
- @order.shipment || @order.shipments.create(stock_location_id: stock_location_id)
- end
-
- def shipment_params
- params.permit(
- [:id, :order_id, :variant_id, :quantity,
- { shipment: [:tracking, :selected_shipping_rate_id] }]
- )
- end
- end
-end
diff --git a/app/controllers/api/shops_controller.rb b/app/controllers/api/shops_controller.rb
deleted file mode 100644
index 377e849378..0000000000
--- a/app/controllers/api/shops_controller.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-# frozen_string_literal: true
-
-module Api
- class ShopsController < BaseController
- respond_to :json
- skip_authorization_check only: [:show, :closed_shops]
-
- def show
- enterprise = Enterprise.find_by(id: params[:id])
-
- render plain: Api::EnterpriseShopfrontSerializer.new(enterprise).to_json, status: :ok
- end
-
- def closed_shops
- @active_distributor_ids = []
- @earliest_closing_times = []
-
- serialized_closed_shops = ActiveModel::ArraySerializer.new(
- ShopsListService.new.closed_shops,
- each_serializer: Api::EnterpriseSerializer,
- data: OpenFoodNetwork::EnterpriseInjectionData.new
- )
-
- render json: serialized_closed_shops
- end
- end
-end
diff --git a/app/controllers/api/states_controller.rb b/app/controllers/api/states_controller.rb
deleted file mode 100644
index 0ad0b991d4..0000000000
--- a/app/controllers/api/states_controller.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-# frozen_string_literal: true
-
-module Api
- class StatesController < Api::BaseController
- respond_to :json
-
- skip_authorization_check
-
- def index
- render json: states, each_serializer: Api::StateSerializer, status: :ok
- end
-
- def show
- @state = scope.find(params[:id])
- render json: @state, serializer: Api::StateSerializer, status: :ok
- end
-
- private
-
- def scope
- if params[:country_id]
- @country = Spree::Country.find(params[:country_id])
- @country.states
- else
- Spree::State.all
- end
- end
-
- def states
- states = scope.ransack(params[:q]).result.
- includes(:country).order('name ASC')
-
- if pagination?
- states = states.page(params[:page]).per(params[:per_page])
- end
-
- states
- end
-
- def pagination?
- params[:page] || params[:per_page]
- end
- end
-end
diff --git a/app/controllers/api/statuses_controller.rb b/app/controllers/api/statuses_controller.rb
deleted file mode 100644
index 24714b6a0d..0000000000
--- a/app/controllers/api/statuses_controller.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-module Api
- class StatusesController < ::BaseController
- respond_to :json
-
- def job_queue
- render json: { alive: job_queue_alive? }
- end
-
- private
-
- def job_queue_alive?
- Spree::Config.last_job_queue_heartbeat_at.present? &&
- Time.parse(Spree::Config.last_job_queue_heartbeat_at).in_time_zone > 6.minutes.ago
- end
- end
-end
diff --git a/app/controllers/api/taxonomies_controller.rb b/app/controllers/api/taxonomies_controller.rb
deleted file mode 100644
index 356d84d676..0000000000
--- a/app/controllers/api/taxonomies_controller.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-module Api
- class TaxonomiesController < Api::BaseController
- respond_to :json
-
- skip_authorization_check only: :jstree
-
- def jstree
- @taxonomy = Spree::Taxonomy.find(params[:id])
- render json: @taxonomy.root, serializer: Api::TaxonJstreeSerializer
- end
- end
-end
diff --git a/app/controllers/api/taxons_controller.rb b/app/controllers/api/taxons_controller.rb
deleted file mode 100644
index 491cf75954..0000000000
--- a/app/controllers/api/taxons_controller.rb
+++ /dev/null
@@ -1,76 +0,0 @@
-module Api
- class TaxonsController < Api::BaseController
- respond_to :json
-
- skip_authorization_check only: [:index, :show, :jstree]
-
- def index
- @taxons = if taxonomy
- taxonomy.root.children
- elsif params[:ids]
- Spree::Taxon.where(id: raw_params[:ids].split(","))
- else
- Spree::Taxon.ransack(raw_params[:q]).result
- end
- render json: @taxons, each_serializer: Api::TaxonSerializer
- end
-
- def jstree
- @taxon = taxon
- render json: @taxon.children, each_serializer: Api::TaxonJstreeSerializer
- end
-
- def create
- authorize! :create, Spree::Taxon
- @taxon = Spree::Taxon.new(taxon_params)
- @taxon.taxonomy_id = params[:taxonomy_id]
- taxonomy = Spree::Taxonomy.find_by(id: params[:taxonomy_id])
-
- if taxonomy.nil?
- @taxon.errors[:taxonomy_id] = I18n.t(:invalid_taxonomy_id, scope: 'spree.api')
- invalid_resource!(@taxon) && return
- end
-
- @taxon.parent_id = taxonomy.root.id unless params.dig(:taxon, :parent_id)
-
- if @taxon.save
- render json: @taxon, serializer: Api::TaxonSerializer, status: :created
- else
- invalid_resource!(@taxon)
- end
- end
-
- def update
- authorize! :update, Spree::Taxon
- if taxon.update(taxon_params)
- render json: taxon, serializer: Api::TaxonSerializer, status: :ok
- else
- invalid_resource!(taxon)
- end
- end
-
- def destroy
- authorize! :delete, Spree::Taxon
- taxon.destroy
- render json: taxon, serializer: Api::TaxonSerializer, status: :no_content
- end
-
- private
-
- def taxonomy
- return if params[:taxonomy_id].blank?
-
- @taxonomy ||= Spree::Taxonomy.find(params[:taxonomy_id])
- end
-
- def taxon
- @taxon ||= taxonomy.taxons.find(params[:id])
- end
-
- def taxon_params
- return if params[:taxon].blank?
-
- params.require(:taxon).permit([:name, :parent_id])
- end
- end
-end
diff --git a/app/controllers/api/terms_and_conditions_controller.rb b/app/controllers/api/terms_and_conditions_controller.rb
deleted file mode 100644
index d49721c04a..0000000000
--- a/app/controllers/api/terms_and_conditions_controller.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-module Api
- class TermsAndConditionsController < Api::EnterpriseAttachmentController
- private
-
- def attachment_name
- :terms_and_conditions
- end
-
- def enterprise_authorize_action
- case action_name.to_sym
- when :destroy
- :remove_terms_and_conditions
- end
- end
- end
-end
diff --git a/app/controllers/api/v0/base_controller.rb b/app/controllers/api/v0/base_controller.rb
new file mode 100644
index 0000000000..83ed8578d5
--- /dev/null
+++ b/app/controllers/api/v0/base_controller.rb
@@ -0,0 +1,107 @@
+# frozen_string_literal: true
+
+# Base controller for OFN's API
+require_dependency 'spree/api/controller_setup'
+require "spree/core/controller_helpers/ssl"
+
+module Api
+ module V0
+ class BaseController < ActionController::Metal
+ include RawParams
+ include ActionController::StrongParameters
+ include ActionController::RespondWith
+ include Spree::Api::ControllerSetup
+ include Spree::Core::ControllerHelpers::SSL
+ include ::ActionController::Head
+ include ::ActionController::ConditionalGet
+ include ActionView::Layouts
+
+ layout false
+
+ attr_accessor :current_api_user
+
+ before_action :set_content_type
+ before_action :authenticate_user
+
+ rescue_from Exception, with: :error_during_processing
+ rescue_from CanCan::AccessDenied, with: :unauthorized
+ rescue_from ActiveRecord::RecordNotFound, with: :not_found
+
+ helper Spree::Api::ApiHelpers
+
+ ssl_allowed
+
+ # Include these because we inherit from ActionController::Metal
+ # rather than ActionController::Base and these are required for AMS
+ include ActionController::Serialization
+ include ActionController::UrlFor
+ include Rails.application.routes.url_helpers
+
+ use_renderers :json
+ check_authorization
+
+ def respond_with_conflict(json_hash)
+ render json: json_hash, status: :conflict
+ end
+
+ private
+
+ # Use logged in user (spree_current_user) for API authentication (current_api_user)
+ def authenticate_user
+ return if @current_api_user = spree_current_user
+
+ if api_key.blank?
+ # An anonymous user
+ @current_api_user = Spree.user_class.new
+ return
+ end
+
+ return if @current_api_user = Spree.user_class.find_by(spree_api_key: api_key.to_s)
+
+ invalid_api_key
+ end
+
+ def set_content_type
+ headers["Content-Type"] = "application/json"
+ end
+
+ def error_during_processing(exception)
+ Bugsnag.notify(exception)
+
+ render(json: { exception: exception.message },
+ status: :unprocessable_entity) && return
+ end
+
+ def current_ability
+ Spree::Ability.new(current_api_user)
+ end
+
+ def api_key
+ request.headers["X-Spree-Token"] || params[:token]
+ end
+ helper_method :api_key
+
+ def invalid_resource!(resource)
+ @resource = resource
+ render(json: { error: I18n.t(:invalid_resource, scope: "spree.api"),
+ errors: @resource.errors },
+ status: :unprocessable_entity)
+ end
+
+ def invalid_api_key
+ render(json: { error: I18n.t(:invalid_api_key, key: api_key, scope: "spree.api") },
+ status: :unauthorized) && return
+ end
+
+ def unauthorized
+ render(json: { error: I18n.t(:unauthorized, scope: "spree.api") },
+ status: :unauthorized) && return
+ end
+
+ def not_found
+ render(json: { error: I18n.t(:resource_not_found, scope: "spree.api") },
+ status: :not_found) && return
+ end
+ end
+ end
+end
diff --git a/app/controllers/api/v0/customers_controller.rb b/app/controllers/api/v0/customers_controller.rb
new file mode 100644
index 0000000000..a10b65bed7
--- /dev/null
+++ b/app/controllers/api/v0/customers_controller.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+module Api
+ module V0
+ class CustomersController < Api::V0::BaseController
+ skip_authorization_check only: :index
+
+ def index
+ @customers = current_api_user.customers
+ render json: @customers, each_serializer: CustomerSerializer
+ end
+
+ def update
+ @customer = Customer.find(params[:id])
+ authorize! :update, @customer
+
+ client_secret = RecurringPayments.setup_for(@customer) if params[:customer][:allow_charges]
+
+ if @customer.update(customer_params)
+ add_recurring_payment_info(client_secret)
+ render json: @customer, serializer: CustomerSerializer, status: :ok
+ else
+ invalid_resource!(@customer)
+ end
+ end
+
+ private
+
+ def add_recurring_payment_info(client_secret)
+ return unless client_secret
+
+ @customer.gateway_recurring_payment_client_secret = client_secret
+ @customer.gateway_shop_id = @customer.enterprise.stripe_account&.stripe_user_id
+ end
+
+ def customer_params
+ params.require(:customer).permit(:code, :email, :enterprise_id, :allow_charges)
+ end
+ end
+ end
+end
diff --git a/app/controllers/api/v0/enterprise_attachment_controller.rb b/app/controllers/api/v0/enterprise_attachment_controller.rb
new file mode 100644
index 0000000000..6e183371a1
--- /dev/null
+++ b/app/controllers/api/v0/enterprise_attachment_controller.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+require 'api/admin/enterprise_serializer'
+
+module Api
+ module V0
+ class EnterpriseAttachmentController < Api::V0::BaseController
+ class MissingImplementationError < StandardError; end
+
+ class UnknownEnterpriseAuthorizationActionError < StandardError; end
+
+ before_action :load_enterprise
+
+ respond_to :json
+
+ def destroy
+ unless @enterprise.public_send("#{attachment_name}?")
+ return respond_with_conflict(error: destroy_attachment_does_not_exist_error_message)
+ end
+
+ @enterprise.update!(attachment_name => nil)
+ render json: @enterprise,
+ serializer: Admin::EnterpriseSerializer,
+ spree_current_user: spree_current_user
+ end
+
+ protected
+
+ def attachment_name
+ raise MissingImplementationError, "Method attachment_name should be defined"
+ end
+
+ def enterprise_authorize_action
+ raise MissingImplementationError, "Method enterprise_authorize_action should be defined"
+ end
+
+ def load_enterprise
+ @enterprise = Enterprise.find_by(permalink: params[:enterprise_id].to_s)
+ raise UnknownEnterpriseAuthorizationActionError if enterprise_authorize_action.blank?
+
+ authorize!(enterprise_authorize_action, @enterprise)
+ end
+
+ def destroy_attachment_does_not_exist_error_message
+ I18n.t("api.enterprise_#{attachment_name}.destroy_attachment_does_not_exist")
+ end
+ end
+ end
+end
diff --git a/app/controllers/api/v0/enterprise_fees_controller.rb b/app/controllers/api/v0/enterprise_fees_controller.rb
new file mode 100644
index 0000000000..45957672a7
--- /dev/null
+++ b/app/controllers/api/v0/enterprise_fees_controller.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module Api
+ module V0
+ class EnterpriseFeesController < Api::V0::BaseController
+ respond_to :json
+
+ def destroy
+ authorize! :destroy, enterprise_fee
+
+ if enterprise_fee.destroy
+ render plain: I18n.t(:successfully_removed), status: :no_content
+ else
+ render plain: enterprise_fee.errors.full_messages.first, status: :forbidden
+ end
+ end
+
+ private
+
+ def enterprise_fee
+ @enterprise_fee ||= EnterpriseFee.find_by id: params[:id]
+ end
+ end
+ end
+end
diff --git a/app/controllers/api/v0/enterprises_controller.rb b/app/controllers/api/v0/enterprises_controller.rb
new file mode 100644
index 0000000000..0cd9435963
--- /dev/null
+++ b/app/controllers/api/v0/enterprises_controller.rb
@@ -0,0 +1,82 @@
+# frozen_string_literal: true
+
+module Api
+ module V0
+ class EnterprisesController < Api::V0::BaseController
+ before_action :override_owner, only: [:create, :update]
+ before_action :check_type, only: :update
+ before_action :override_sells, only: [:create, :update]
+ before_action :override_visible, only: [:create, :update]
+ respond_to :json
+
+ def create
+ authorize! :create, Enterprise
+
+ # params[:user_ids] breaks the enterprise creation
+ # We remove them from params and save them after creating the enterprise
+ user_ids = enterprise_params.delete(:user_ids)
+ @enterprise = Enterprise.new(enterprise_params)
+ if @enterprise.save
+ @enterprise.user_ids = user_ids
+ render json: @enterprise.id, status: :created
+ else
+ invalid_resource!(@enterprise)
+ end
+ end
+
+ def update
+ @enterprise = Enterprise.find_by(permalink: params[:id]) || Enterprise.find(params[:id])
+ authorize! :update, @enterprise
+
+ if @enterprise.update(enterprise_params)
+ render json: @enterprise.id, status: :ok
+ else
+ invalid_resource!(@enterprise)
+ end
+ end
+
+ def update_image
+ @enterprise = Enterprise.find_by(permalink: params[:id]) || Enterprise.find(params[:id])
+ authorize! :update, @enterprise
+
+ if params[:logo] && @enterprise.update( logo: params[:logo] )
+ render plain: @enterprise.logo.url(:medium), status: :ok
+ elsif params[:promo] && @enterprise.update( promo_image: params[:promo] )
+ render plain: @enterprise.promo_image.url(:medium), status: :ok
+ else
+ invalid_resource!(@enterprise)
+ end
+ end
+
+ private
+
+ def override_owner
+ enterprise_params[:owner_id] = current_api_user.id
+ end
+
+ def check_type
+ enterprise_params.delete :type unless current_api_user.admin?
+ end
+
+ def override_sells
+ has_hub = current_api_user.owned_enterprises.is_hub.any?
+ new_enterprise_is_producer = !!enterprise_params[:is_primary_producer]
+
+ enterprise_params[:sells] = if has_hub && !new_enterprise_is_producer
+ 'any'
+ else
+ 'unspecified'
+ end
+ end
+
+ def override_visible
+ enterprise_params[:visible] = false
+ end
+
+ def enterprise_params
+ @enterprise_params ||= PermittedAttributes::Enterprise.new(params).call.
+ to_h.with_indifferent_access
+ end
+ end
+ end
+end
diff --git a/app/controllers/api/v0/exchange_products_controller.rb b/app/controllers/api/v0/exchange_products_controller.rb
new file mode 100644
index 0000000000..fde6abf174
--- /dev/null
+++ b/app/controllers/api/v0/exchange_products_controller.rb
@@ -0,0 +1,102 @@
+# frozen_string_literal: true
+
+# This controller lists products that can be added to an exchange
+#
+# Pagination is optional and can be required by using param[:page]
+module Api
+ module V0
+ class ExchangeProductsController < Api::V0::BaseController
+ include PaginationData
+ DEFAULT_PER_PAGE = 100
+
+ skip_authorization_check only: [:index]
+
+ # If exchange_id is present in the URL:
+ # Lists Products that can be added to that Exchange
+ #
+ # If exchange_id is not present in the URL:
+ # Lists Products of the Enterprise given that can be added to the given Order Cycle
+ # In this case parameters are: enterprise_id, order_cycle_id and incoming
+ # (order_cycle_id is not necessary for incoming exchanges)
+ def index
+ if exchange_params[:exchange_id].present?
+ load_data_from_exchange
+ else
+ load_data_from_other_params
+ end
+
+ render_variant_count && return if params[:action_name] == "variant_count"
+
+ render_paginated_products paginated_products
+ end
+
+ private
+
+ def render_variant_count
+ render plain: {
+ count: variants.count
+ }.to_json
+ end
+
+ def variants
+ renderer.exchange_variants(@incoming, @enterprise)
+ end
+
+ def products
+ renderer.exchange_products(@incoming, @enterprise)
+ end
+
+ def renderer
+ @renderer ||= ExchangeProductsRenderer.
+ new(@order_cycle, spree_current_user)
+ end
+
+ def paginated_products
+ return products unless pagination_required?
+
+ products.
+ page(params[:page]).
+ per(params[:per_page] || DEFAULT_PER_PAGE)
+ end
+
+ def load_data_from_exchange
+ exchange = Exchange.find_by(id: exchange_params[:exchange_id])
+
+ @order_cycle = exchange.order_cycle
+ @incoming = exchange.incoming
+ @enterprise = exchange.sender
+ end
+
+ def load_data_from_other_params
+ @enterprise = Enterprise.find_by(id: exchange_params[:enterprise_id])
+
+ # This will be a string (eg "true") when it arrives via params, but we want a boolean
+ @incoming = ActiveModel::Type::Boolean.new.cast exchange_params[:incoming]
+
+ if exchange_params[:order_cycle_id]
+ @order_cycle = OrderCycle.find_by(id: exchange_params[:order_cycle_id])
+ elsif !@incoming
+ raise "order_cycle_id is required to list products for new outgoing exchange"
+ end
+ end
+
+ def render_paginated_products(paginated_products)
+ serialized_products = ActiveModel::ArraySerializer.new(
+ paginated_products,
+ each_serializer: Api::Admin::ForOrderCycle::SuppliedProductSerializer,
+ order_cycle: @order_cycle
+ )
+
+ render json: {
+ products: serialized_products,
+ pagination: pagination_data(paginated_products)
+ }
+ end
+
+ def exchange_params
+ params.permit(:enterprise_id, :exchange_id, :order_cycle_id, :incoming).
+ to_h.with_indifferent_access
+ end
+ end
+ end
+end
diff --git a/app/controllers/api/v0/logos_controller.rb b/app/controllers/api/v0/logos_controller.rb
new file mode 100644
index 0000000000..0e710d8bf2
--- /dev/null
+++ b/app/controllers/api/v0/logos_controller.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+module Api
+ module V0
+ class LogosController < Api::V0::EnterpriseAttachmentController
+ private
+
+ def attachment_name
+ :logo
+ end
+
+ def enterprise_authorize_action
+ case action_name.to_sym
+ when :destroy
+ :remove_logo
+ end
+ end
+ end
+ end
+end
diff --git a/app/controllers/api/v0/order_cycles_controller.rb b/app/controllers/api/v0/order_cycles_controller.rb
new file mode 100644
index 0000000000..88241b23a4
--- /dev/null
+++ b/app/controllers/api/v0/order_cycles_controller.rb
@@ -0,0 +1,105 @@
+# frozen_string_literal: true
+
+module Api
+ module V0
+ class OrderCyclesController < Api::V0::BaseController
+ include EnterprisesHelper
+ include ApiActionCaching
+
+ skip_authorization_check
+ skip_before_action :authenticate_user, :ensure_api_key, only: [:taxons, :properties]
+
+ caches_action :taxons, :properties,
+ expires_in: CacheService::FILTERS_EXPIRY,
+ cache_path: proc { |controller| controller.request.url }
+
+ def products
+ return render_no_products unless order_cycle.open?
+
+ products = ProductsRenderer.new(
+ distributor,
+ order_cycle,
+ customer,
+ search_params
+ ).products_json
+
+ render plain: products
+ rescue ProductsRenderer::NoProducts
+ render_no_products
+ end
+
+ def taxons
+ taxons = Spree::Taxon.
+ joins(:products).
+ where(spree_products: { id: distributed_products }).
+ select('DISTINCT spree_taxons.*')
+
+ render plain: ActiveModel::ArraySerializer.new(
+ taxons, each_serializer: Api::TaxonSerializer
+ ).to_json
+ end
+
+ def properties
+ render plain: ActiveModel::ArraySerializer.new(
+ product_properties | producer_properties, each_serializer: Api::PropertySerializer
+ ).to_json
+ end
+
+ private
+
+ def render_no_products
+ render status: :not_found, json: {}
+ end
+
+ def product_properties
+ Spree::Property.
+ joins(:products).
+ where(spree_products: { id: distributed_products }).
+ select('DISTINCT spree_properties.*')
+ end
+
+ def producer_properties
+ producers = Enterprise.
+ joins(:supplied_products).
+ where(spree_products: { id: distributed_products })
+
+ Spree::Property.
+ joins(:producer_properties).
+ where(producer_properties: { producer_id: producers }).
+ select('DISTINCT spree_properties.*')
+ end
+
+ def search_params
+ permitted_search_params = params.slice :q, :page, :per_page
+
+ if permitted_search_params.key? :q
+ permitted_search_params[:q].slice!(*permitted_ransack_params)
+ end
+
+ permitted_search_params
+ end
+
+ def permitted_ransack_params
+ [:name_or_meta_keywords_or_variants_display_as_or_variants_display_name_or_supplier_name_cont,
+ :properties_id_or_supplier_properties_id_in_any,
+ :primary_taxon_id_in_any]
+ end
+
+ def distributor
+ @distributor ||= Enterprise.find_by(id: params[:distributor])
+ end
+
+ def order_cycle
+ @order_cycle ||= OrderCycle.find_by(id: params[:id])
+ end
+
+ def customer
+ @current_api_user.andand.customer_of(distributor) || nil
+ end
+
+ def distributed_products
+ OrderCycleDistributedProducts.new(distributor, order_cycle, customer).products_relation
+ end
+ end
+ end
+end
diff --git a/app/controllers/api/v0/orders_controller.rb b/app/controllers/api/v0/orders_controller.rb
new file mode 100644
index 0000000000..48a40e13cc
--- /dev/null
+++ b/app/controllers/api/v0/orders_controller.rb
@@ -0,0 +1,72 @@
+# frozen_string_literal: true
+
+module Api
+ module V0
+ class OrdersController < Api::V0::BaseController
+ include PaginationData
+
+ def show
+ authorize! :read, order
+ render json: order, serializer: Api::OrderDetailedSerializer, current_order: order
+ end
+
+ def index
+ authorize! :admin, Spree::Order
+
+ orders = SearchOrders.new(params, current_api_user).orders
+
+ render json: {
+ orders: serialized_orders(orders),
+ pagination: pagination_data(orders)
+ }
+ end
+
+ def ship
+ authorize! :admin, order
+
+ if order.ship
+ render json: order.reload, serializer: Api::Admin::OrderSerializer, status: :ok
+ else
+ render json: { error: I18n.t('api.orders.failed_to_update') },
+ status: :unprocessable_entity
+ end
+ end
+
+ def capture
+ authorize! :admin, order
+
+ pending_payment = order.pending_payments.first
+
+ return payment_capture_failed unless order.payment_required? && pending_payment
+
+ if pending_payment.capture!
+ render json: order.reload, serializer: Api::Admin::OrderSerializer, status: :ok
+ else
+ payment_capture_failed
+ end
+ rescue Spree::Core::GatewayError => e
+ error_during_processing(e)
+ end
+
+ private
+
+ def payment_capture_failed
+ render json: { error: I18n.t(:payment_processing_failed) }, status: :unprocessable_entity
+ end
+
+ def serialized_orders(orders)
+ ActiveModel::ArraySerializer.new(
+ orders,
+ each_serializer: Api::Admin::OrderSerializer
+ )
+ end
+
+ def order
+ @order ||= Spree::Order.
+ where(number: params[:id]).
+ includes(line_items: { variant: [:product, :stock_items, :default_price] }).
+ first!
+ end
+ end
+ end
+end
diff --git a/app/controllers/api/v0/product_images_controller.rb b/app/controllers/api/v0/product_images_controller.rb
new file mode 100644
index 0000000000..fbceddb4fe
--- /dev/null
+++ b/app/controllers/api/v0/product_images_controller.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module Api
+ module V0
+ class ProductImagesController < Api::V0::BaseController
+ respond_to :json
+
+ def update_product_image
+ @product = Spree::Product.find(params[:product_id])
+ authorize! :update, @product
+
+ if @product.images.first.nil?
+ @image = Spree::Image.create(
+ attachment: params[:file],
+ viewable_id: @product.master.id,
+ viewable_type: 'Spree::Variant'
+ )
+ render json: @image, serializer: ImageSerializer, status: :created
+ else
+ @image = @product.images.first
+ @image.update(attachment: params[:file])
+ render json: @image, serializer: ImageSerializer, status: :ok
+ end
+ end
+ end
+ end
+end
diff --git a/app/controllers/api/v0/products_controller.rb b/app/controllers/api/v0/products_controller.rb
new file mode 100644
index 0000000000..571b16b3e0
--- /dev/null
+++ b/app/controllers/api/v0/products_controller.rb
@@ -0,0 +1,163 @@
+# frozen_string_literal: true
+
+require 'open_food_network/permissions'
+require 'spree/core/product_duplicator'
+
+module Api
+ module V0
+ class ProductsController < Api::V0::BaseController
+ include PaginationData
+ respond_to :json
+ DEFAULT_PER_PAGE = 15
+
+ before_action :set_default_available_on, only: :create
+
+ skip_authorization_check only: [:show, :bulk_products, :overridable]
+
+ def show
+ @product = find_product(params[:id])
+ render json: @product, serializer: Api::Admin::ProductSerializer
+ end
+
+ def create
+ authorize! :create, Spree::Product
+ @product = Spree::Product.new(product_params)
+
+ begin
+ if @product.save
+ render json: @product, serializer: Api::Admin::ProductSerializer, status: :created
+ else
+ invalid_resource!(@product)
+ end
+ rescue ActiveRecord::RecordNotUnique
+ @product.permalink = nil
+ retry
+ end
+ end
+
+ def update
+ authorize! :update, Spree::Product
+ @product = find_product(params[:id])
+ if @product.update(product_params)
+ render json: @product, serializer: Api::Admin::ProductSerializer, status: :ok
+ else
+ invalid_resource!(@product)
+ end
+ end
+
+ def destroy
+ authorize! :delete, Spree::Product
+ @product = find_product(params[:id])
+ authorize! :delete, @product
+ @product.destroy
+ render json: @product, serializer: Api::Admin::ProductSerializer, status: :no_content
+ end
+
+ def bulk_products
+ product_query = OpenFoodNetwork::Permissions.
+ new(current_api_user).
+ editable_products.
+ merge(product_scope)
+
+ if params[:import_date].present?
+ product_query = product_query.
+ imported_on(params[:import_date]).
+ group_by_products_id
+ end
+
+ @products = product_query.
+ ransack(query_params_with_defaults).
+ result.
+ page(params[:page] || 1).
+ per(params[:per_page] || DEFAULT_PER_PAGE)
+
+ render_paged_products @products
+ end
+
+ def overridable
+ producer_ids = OpenFoodNetwork::Permissions.new(current_api_user).
+ variant_override_producers.by_name.select('enterprises.id')
+
+ @products = paged_products_for_producers producer_ids
+
+ render_paged_products @products, ::Api::Admin::ProductSimpleSerializer
+ end
+
+ # POST /api/products/:product_id/clone
+ #
+ def clone
+ authorize! :create, Spree::Product
+ original_product = find_product(params[:product_id])
+ authorize! :update, original_product
+
+ @product = original_product.duplicate
+
+ render json: @product, serializer: Api::Admin::ProductSerializer, status: :created
+ end
+
+ private
+
+ def find_product(id)
+ product_scope.find_by!(permalink: id.to_s)
+ rescue ActiveRecord::RecordNotFound
+ product_scope.find(id)
+ end
+
+ def product_scope
+ if current_api_user.has_spree_role?("admin") || current_api_user.enterprises.present?
+ scope = Spree::Product
+ if params[:show_deleted]
+ scope = scope.with_deleted
+ end
+ else
+ scope = Spree::Product.active
+ end
+
+ scope.includes(product_query_includes)
+ end
+
+ def product_query_includes
+ [
+ master: [:images],
+ variants: [:default_price, :stock_locations, :stock_items, :variant_overrides,
+ { option_values: :option_type }]
+ ]
+ end
+
+ def paged_products_for_producers(producer_ids)
+ Spree::Product.where(nil).
+ merge(product_scope).
+ includes(variants: [:product, :default_price, :stock_items]).
+ where(supplier_id: producer_ids).
+ by_producer.by_name.
+ ransack(params[:q]).result.
+ page(params[:page]).per(params[:per_page])
+ end
+
+ def render_paged_products(products, product_serializer = ::Api::Admin::ProductSerializer)
+ serialized_products = ActiveModel::ArraySerializer.new(
+ products,
+ each_serializer: product_serializer
+ )
+
+ render json: {
+ products: serialized_products,
+ pagination: pagination_data(products)
+ }
+ end
+
+ def query_params_with_defaults
+ (params[:q] || {}).reverse_merge(s: 'created_at desc')
+ end
+
+ def product_params
+ @product_params ||=
+ params.permit(product: PermittedAttributes::Product.attributes)[:product].to_h
+ end
+
+ def set_default_available_on
+ product_params[:available_on] ||= Time.zone.now
+ end
+ end
+ end
+end
diff --git a/app/controllers/api/v0/promo_images_controller.rb b/app/controllers/api/v0/promo_images_controller.rb
new file mode 100644
index 0000000000..13822324ff
--- /dev/null
+++ b/app/controllers/api/v0/promo_images_controller.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+module Api
+ module V0
+ class PromoImagesController < Api::V0::EnterpriseAttachmentController
+ private
+
+ def attachment_name
+ :promo_image
+ end
+
+ def enterprise_authorize_action
+ case action_name.to_sym
+ when :destroy
+ :remove_promo_image
+ end
+ end
+ end
+ end
+end
diff --git a/app/controllers/api/v0/shipments_controller.rb b/app/controllers/api/v0/shipments_controller.rb
new file mode 100644
index 0000000000..ec452b2869
--- /dev/null
+++ b/app/controllers/api/v0/shipments_controller.rb
@@ -0,0 +1,116 @@
+# frozen_string_literal: true
+
+require 'open_food_network/scope_variant_to_hub'
+
+module Api
+ module V0
+ class ShipmentsController < Api::V0::BaseController
+ respond_to :json
+
+ before_action :find_order
+ before_action :find_and_update_shipment, only: [:ship, :ready, :add, :remove]
+
+ def create
+ variant = scoped_variant(params[:variant_id])
+ quantity = params[:quantity].to_i
+ @shipment = get_or_create_shipment(params[:stock_location_id])
+
+ @order.contents.add(variant, quantity, nil, @shipment)
+
+ @shipment.refresh_rates
+ @shipment.save!
+
+ render json: @shipment.reload, serializer: Api::ShipmentSerializer, status: :ok
+ end
+
+ def update
+ authorize! :read, Spree::Shipment
+ @shipment = @order.shipments.find_by!(number: params[:id])
+ params[:shipment] ||= []
+ unlock = params[:shipment].delete(:unlock)
+
+ if unlock == 'yes'
+ @shipment.fee_adjustment.open
+ end
+
+ @shipment.update(shipment_params[:shipment])
+
+ if unlock == 'yes'
+ @shipment.fee_adjustment.close
+ end
+
+ render json: @shipment.reload, serializer: Api::ShipmentSerializer, status: :ok
+ end
+
+ def ready
+ authorize! :read, Spree::Shipment
+ unless @shipment.ready?
+ if @shipment.can_ready?
+ @shipment.ready!
+ else
+ render(json: { error: I18n.t(:cannot_ready, scope: "spree.api.shipment") },
+ status: :unprocessable_entity) && return
+ end
+ end
+ render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok
+ end
+
+ def ship
+ authorize! :read, Spree::Shipment
+ unless @shipment.shipped?
+ @shipment.ship!
+ end
+ render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok
+ end
+
+ def add
+ variant = scoped_variant(params[:variant_id])
+ quantity = params[:quantity].to_i
+
+ @order.contents.add(variant, quantity, nil, @shipment)
+
+ render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok
+ end
+
+ def remove
+ variant = scoped_variant(params[:variant_id])
+ quantity = params[:quantity].to_i
+
+ @order.contents.remove(variant, quantity, @shipment)
+ @shipment.reload if @shipment.persisted?
+
+ render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok
+ end
+
+ private
+
+ def find_order
+ @order = Spree::Order.find_by!(number: params[:order_id])
+ authorize! :read, @order
+ end
+
+ def find_and_update_shipment
+ @shipment = @order.shipments.find_by!(number: params[:id])
+ @shipment.update(shipment_params[:shipment]) if shipment_params[:shipment].present?
+ @shipment.reload
+ end
+
+ def scoped_variant(variant_id)
+ variant = Spree::Variant.find(variant_id)
+ OpenFoodNetwork::ScopeVariantToHub.new(@order.distributor).scope(variant)
+ variant
+ end
+
+ def get_or_create_shipment(stock_location_id)
+ @order.shipment || @order.shipments.create(stock_location_id: stock_location_id)
+ end
+
+ def shipment_params
+ params.permit(
+ [:id, :order_id, :variant_id, :quantity,
+ { shipment: [:tracking, :selected_shipping_rate_id] }]
+ )
+ end
+ end
+ end
+end
diff --git a/app/controllers/api/v0/shops_controller.rb b/app/controllers/api/v0/shops_controller.rb
new file mode 100644
index 0000000000..a76a506a85
--- /dev/null
+++ b/app/controllers/api/v0/shops_controller.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module Api
+ module V0
+ class ShopsController < BaseController
+ respond_to :json
+ skip_authorization_check only: [:show, :closed_shops]
+
+ def show
+ enterprise = Enterprise.find_by(id: params[:id])
+
+ render plain: Api::EnterpriseShopfrontSerializer.new(enterprise).to_json, status: :ok
+ end
+
+ def closed_shops
+ @active_distributor_ids = []
+ @earliest_closing_times = []
+
+ serialized_closed_shops = ActiveModel::ArraySerializer.new(
+ ShopsListService.new.closed_shops,
+ each_serializer: Api::EnterpriseSerializer,
+ data: OpenFoodNetwork::EnterpriseInjectionData.new
+ )
+
+ render json: serialized_closed_shops
+ end
+ end
+ end
+end
diff --git a/app/controllers/api/v0/states_controller.rb b/app/controllers/api/v0/states_controller.rb
new file mode 100644
index 0000000000..c64a077f76
--- /dev/null
+++ b/app/controllers/api/v0/states_controller.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+module Api
+ module V0
+ class StatesController < Api::V0::BaseController
+ respond_to :json
+
+ skip_authorization_check
+
+ def index
+ render json: states, each_serializer: Api::StateSerializer, status: :ok
+ end
+
+ def show
+ @state = scope.find(params[:id])
+ render json: @state, serializer: Api::StateSerializer, status: :ok
+ end
+
+ private
+
+ def scope
+ if params[:country_id]
+ @country = Spree::Country.find(params[:country_id])
+ @country.states
+ else
+ Spree::State.all
+ end
+ end
+
+ def states
+ states = scope.ransack(params[:q]).result.
+ includes(:country).order('name ASC')
+
+ if pagination?
+ states = states.page(params[:page]).per(params[:per_page])
+ end
+
+ states
+ end
+
+ def pagination?
+ params[:page] || params[:per_page]
+ end
+ end
+ end
+end
diff --git a/app/controllers/api/v0/statuses_controller.rb b/app/controllers/api/v0/statuses_controller.rb
new file mode 100644
index 0000000000..17a0eaa3cf
--- /dev/null
+++ b/app/controllers/api/v0/statuses_controller.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+module Api
+ module V0
+ class StatusesController < ::BaseController
+ respond_to :json
+
+ def job_queue
+ render json: { alive: job_queue_alive? }
+ end
+
+ private
+
+ def job_queue_alive?
+ Spree::Config.last_job_queue_heartbeat_at.present? &&
+ Time.parse(Spree::Config.last_job_queue_heartbeat_at).in_time_zone > 6.minutes.ago
+ end
+ end
+ end
+end
diff --git a/app/controllers/api/v0/taxonomies_controller.rb b/app/controllers/api/v0/taxonomies_controller.rb
new file mode 100644
index 0000000000..bf6077a9e1
--- /dev/null
+++ b/app/controllers/api/v0/taxonomies_controller.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Api
+ module V0
+ class TaxonomiesController < Api::V0::BaseController
+ respond_to :json
+
+ skip_authorization_check only: :jstree
+
+ def jstree
+ @taxonomy = Spree::Taxonomy.find(params[:id])
+ render json: @taxonomy.root, serializer: Api::TaxonJstreeSerializer
+ end
+ end
+ end
+end
diff --git a/app/controllers/api/v0/taxons_controller.rb b/app/controllers/api/v0/taxons_controller.rb
new file mode 100644
index 0000000000..12ed6a15a4
--- /dev/null
+++ b/app/controllers/api/v0/taxons_controller.rb
@@ -0,0 +1,78 @@
+module Api
+ module V0
+ class TaxonsController < Api::V0::BaseController
+ respond_to :json
+
+ skip_authorization_check only: [:index, :show, :jstree]
+
+ def index
+ @taxons = if taxonomy
+ taxonomy.root.children
+ elsif params[:ids]
+ Spree::Taxon.where(id: raw_params[:ids].split(","))
+ else
+ Spree::Taxon.ransack(raw_params[:q]).result
+ end
+ render json: @taxons, each_serializer: Api::TaxonSerializer
+ end
+
+ def jstree
+ @taxon = taxon
+ render json: @taxon.children, each_serializer: Api::TaxonJstreeSerializer
+ end
+
+ def create
+ authorize! :create, Spree::Taxon
+ @taxon = Spree::Taxon.new(taxon_params)
+ @taxon.taxonomy_id = params[:taxonomy_id]
+ taxonomy = Spree::Taxonomy.find_by(id: params[:taxonomy_id])
+
+ if taxonomy.nil?
+ @taxon.errors[:taxonomy_id] = I18n.t(:invalid_taxonomy_id, scope: 'spree.api')
+ invalid_resource!(@taxon) && return
+ end
+
+ @taxon.parent_id = taxonomy.root.id unless params.dig(:taxon, :parent_id)
+
+ if @taxon.save
+ render json: @taxon, serializer: Api::TaxonSerializer, status: :created
+ else
+ invalid_resource!(@taxon)
+ end
+ end
+
+ def update
+ authorize! :update, Spree::Taxon
+ if taxon.update(taxon_params)
+ render json: taxon, serializer: Api::TaxonSerializer, status: :ok
+ else
+ invalid_resource!(taxon)
+ end
+ end
+
+ def destroy
+ authorize! :delete, Spree::Taxon
+ taxon.destroy
+ render json: taxon, serializer: Api::TaxonSerializer, status: :no_content
+ end
+
+ private
+
+ def taxonomy
+ return if params[:taxonomy_id].blank?
+
+ @taxonomy ||= Spree::Taxonomy.find(params[:taxonomy_id])
+ end
+
+ def taxon
+ @taxon ||= taxonomy.taxons.find(params[:id])
+ end
+
+ def taxon_params
+ return if params[:taxon].blank?
+
+ params.require(:taxon).permit([:name, :parent_id])
+ end
+ end
+ end
+end
diff --git a/app/controllers/api/v0/terms_and_conditions_controller.rb b/app/controllers/api/v0/terms_and_conditions_controller.rb
new file mode 100644
index 0000000000..e5089c5c2e
--- /dev/null
+++ b/app/controllers/api/v0/terms_and_conditions_controller.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+module Api
+ module V0
+ class TermsAndConditionsController < Api::V0::EnterpriseAttachmentController
+ private
+
+ def attachment_name
+ :terms_and_conditions
+ end
+
+ def enterprise_authorize_action
+ case action_name.to_sym
+ when :destroy
+ :remove_terms_and_conditions
+ end
+ end
+ end
+ end
+end
diff --git a/app/controllers/api/v0/variants_controller.rb b/app/controllers/api/v0/variants_controller.rb
new file mode 100644
index 0000000000..e1846ebe32
--- /dev/null
+++ b/app/controllers/api/v0/variants_controller.rb
@@ -0,0 +1,81 @@
+# frozen_string_literal: true
+
+module Api
+ module V0
+ class VariantsController < Api::V0::BaseController
+ respond_to :json
+
+ skip_authorization_check only: [:index, :show]
+ before_action :product
+
+ def index
+ @variants = scope.includes(option_values: :option_type).ransack(params[:q]).result
+ render json: @variants, each_serializer: Api::VariantSerializer
+ end
+
+ def show
+ @variant = scope.includes(option_values: :option_type).find(params[:id])
+ render json: @variant, serializer: Api::VariantSerializer
+ end
+
+ def create
+ authorize! :create, Spree::Variant
+ @variant = scope.new(variant_params)
+ if @variant.save
+ render json: @variant, serializer: Api::VariantSerializer, status: :created
+ else
+ invalid_resource!(@variant)
+ end
+ end
+
+ def update
+ authorize! :update, Spree::Variant
+ @variant = scope.find(params[:id])
+ if @variant.update(variant_params)
+ render json: @variant, serializer: Api::VariantSerializer, status: :ok
+ else
+ invalid_resource!(@product)
+ end
+ end
+
+ def destroy
+ authorize! :delete, Spree::Variant
+ @variant = scope.find(params[:id])
+ authorize! :delete, @variant
+
+ VariantDeleter.new.delete(@variant)
+ render json: @variant, serializer: Api::VariantSerializer, status: :no_content
+ end
+
+ private
+
+ def product
+ @product ||= Spree::Product.find_by(permalink: params[:product_id]) if params[:product_id]
+ end
+
+ def scope
+ if @product
+ variants = if current_api_user.has_spree_role?("admin") || params[:show_deleted]
+ @product.variants_including_master.with_deleted
+ else
+ @product.variants_including_master
+ end
+ else
+ variants = Spree::Variant.where(nil)
+ if current_api_user.has_spree_role?("admin")
+ unless params[:show_deleted]
+ variants = Spree::Variant.active
+ end
+ else
+ variants = variants.active
+ end
+ end
+ variants
+ end
+
+ def variant_params
+ params.require(:variant).permit(PermittedAttributes::Variant.attributes)
+ end
+ end
+ end
+end
diff --git a/app/controllers/api/variants_controller.rb b/app/controllers/api/variants_controller.rb
deleted file mode 100644
index 47b12e1e92..0000000000
--- a/app/controllers/api/variants_controller.rb
+++ /dev/null
@@ -1,77 +0,0 @@
-module Api
- class VariantsController < Api::BaseController
- respond_to :json
-
- skip_authorization_check only: [:index, :show]
- before_action :product
-
- def index
- @variants = scope.includes(option_values: :option_type).ransack(params[:q]).result
- render json: @variants, each_serializer: Api::VariantSerializer
- end
-
- def show
- @variant = scope.includes(option_values: :option_type).find(params[:id])
- render json: @variant, serializer: Api::VariantSerializer
- end
-
- def create
- authorize! :create, Spree::Variant
- @variant = scope.new(variant_params)
- if @variant.save
- render json: @variant, serializer: Api::VariantSerializer, status: :created
- else
- invalid_resource!(@variant)
- end
- end
-
- def update
- authorize! :update, Spree::Variant
- @variant = scope.find(params[:id])
- if @variant.update(variant_params)
- render json: @variant, serializer: Api::VariantSerializer, status: :ok
- else
- invalid_resource!(@product)
- end
- end
-
- def destroy
- authorize! :delete, Spree::Variant
- @variant = scope.find(params[:id])
- authorize! :delete, @variant
-
- VariantDeleter.new.delete(@variant)
- render json: @variant, serializer: Api::VariantSerializer, status: :no_content
- end
-
- private
-
- def product
- @product ||= Spree::Product.find_by(permalink: params[:product_id]) if params[:product_id]
- end
-
- def scope
- if @product
- variants = if current_api_user.has_spree_role?("admin") || params[:show_deleted]
- @product.variants_including_master.with_deleted
- else
- @product.variants_including_master
- end
- else
- variants = Spree::Variant.where(nil)
- if current_api_user.has_spree_role?("admin")
- unless params[:show_deleted]
- variants = Spree::Variant.active
- end
- else
- variants = variants.active
- end
- end
- variants
- end
-
- def variant_params
- params.require(:variant).permit(PermittedAttributes::Variant.attributes)
- end
- end
-end
diff --git a/app/controllers/spree/admin/products_controller.rb b/app/controllers/spree/admin/products_controller.rb
index 0860d5a5a5..1ab8005090 100644
--- a/app/controllers/spree/admin/products_controller.rb
+++ b/app/controllers/spree/admin/products_controller.rb
@@ -80,7 +80,7 @@ module Spree
product_set.collection.each { |p| authorize! :update, p }
if product_set.save
- redirect_to main_app.bulk_products_api_products_path(bulk_index_query)
+ redirect_to main_app.bulk_products_api_v0_products_path(bulk_index_query)
elsif product_set.errors.present?
render json: { errors: product_set.errors }, status: :bad_request
else
diff --git a/app/views/spree/admin/shared/_routes.html.erb b/app/views/spree/admin/shared/_routes.html.erb
index 438d257af9..418359b5e7 100644
--- a/app/views/spree/admin/shared/_routes.html.erb
+++ b/app/views/spree/admin/shared/_routes.html.erb
@@ -7,8 +7,8 @@
}
Spree.routes = <%== {
:variants_search => spree.admin_search_variants_path(:format => 'json'),
- :taxons_search => main_app.api_taxons_path(:format => 'json'),
- :orders_api => main_app.api_orders_path,
- :states_search => main_app.api_states_path(:format => 'json')
+ :taxons_search => main_app.api_v0_taxons_path(:format => 'json'),
+ :orders_api => main_app.api_v0_orders_path,
+ :states_search => main_app.api_v0_states_path(:format => 'json')
}.to_json %>;
diff --git a/app/views/spree/admin/taxonomies/edit.haml b/app/views/spree/admin/taxonomies/edit.haml
index eb43b8fa84..7f37454aec 100755
--- a/app/views/spree/admin/taxonomies/edit.haml
+++ b/app/views/spree/admin/taxonomies/edit.haml
@@ -17,7 +17,7 @@
= label_tag nil, t("spree.tree")
%br/
:javascript
- Spree.routes.taxonomy_taxons_path = "#{main_app.api_taxonomy_taxons_path(@taxonomy)}";
+ Spree.routes.taxonomy_taxons_path = "#{main_app.api_v0_taxonomy_taxons_path(@taxonomy)}";
Spree.routes.admin_taxonomy_taxons_path = "#{spree.admin_taxonomy_taxons_path(@taxonomy)}";
#taxonomy_tree.tree
#progress{style: "display:none;"}
diff --git a/config/routes/api.rb b/config/routes/api.rb
index 6bdfd5dcb3..69f41549f2 100644
--- a/config/routes/api.rb
+++ b/config/routes/api.rb
@@ -1,80 +1,84 @@
Openfoodnetwork::Application.routes.draw do
namespace :api do
- resources :products do
- collection do
- get :bulk_products
- get :overridable
- end
- post :clone
+ namespace :v0 do
+ resources :products do
+ collection do
+ get :bulk_products
+ get :overridable
+ end
+ post :clone
- resources :variants
- end
-
- resources :variants, :only => [:index]
-
- resources :orders, only: [:index, :show] do
- member do
- put :capture
- put :ship
+ resources :variants
end
- resources :shipments, :only => [:create, :update] do
+ resources :variants, :only => [:index]
+
+ resources :orders, only: [:index, :show] do
member do
- put :ready
+ put :capture
put :ship
- put :add
- put :remove
+ end
+
+ resources :shipments, :only => [:create, :update] do
+ member do
+ put :ready
+ put :ship
+ put :add
+ put :remove
+ end
end
end
- end
- resources :enterprises do
- post :update_image, on: :member
+ resources :enterprises do
+ post :update_image, on: :member
- resource :logo, only: [:destroy]
- resource :promo_image, only: [:destroy]
- resource :terms_and_conditions, only: [:destroy]
- end
-
- resources :shops, only: [:show] do
- collection do
- get :closed_shops
+ resource :logo, only: [:destroy]
+ resource :promo_image, only: [:destroy]
+ resource :terms_and_conditions, only: [:destroy]
end
- end
- resources :order_cycles do
- get :products, on: :member
- get :taxons, on: :member
- get :properties, on: :member
- end
-
- resources :exchanges, only: [:show], to: 'exchange_products#index' do
- get :products, to: 'exchange_products#index'
- end
-
- resource :status do
- get :job_queue
- end
-
- resources :customers, only: [:index, :update]
-
- resources :enterprise_fees, only: [:destroy]
-
- post '/product_images/:product_id', to: 'product_images#update_product_image'
-
- resources :states, :only => [:index, :show]
-
- resources :taxons, :only => [:index]
-
- resources :taxonomies do
- member do
- get :jstree
+ resources :shops, only: [:show] do
+ collection do
+ get :closed_shops
+ end
end
- resources :taxons do
+
+ resources :order_cycles do
+ get :products, on: :member
+ get :taxons, on: :member
+ get :properties, on: :member
+ end
+
+ resources :exchanges, only: [:show], to: 'exchange_products#index' do
+ get :products, to: 'exchange_products#index'
+ end
+
+ resource :status do
+ get :job_queue
+ end
+
+ resources :customers, only: [:index, :update]
+
+ resources :enterprise_fees, only: [:destroy]
+
+ post '/product_images/:product_id', to: 'product_images#update_product_image'
+
+ resources :states, :only => [:index, :show]
+
+ resources :taxons, :only => [:index]
+
+ resources :taxonomies do
member do
get :jstree
end
+ resources :taxons do
+ member do
+ get :jstree
+ end
+ end
end
end
+
+ match '*path', to: redirect(path: "/api/v0/%{path}"), via: :all, constraints: { path: /(?!v[0-9]).+/ }
end
end
diff --git a/engines/web/app/assets/javascripts/web/cookies_banner/cookies_banner_controller.js.coffee b/engines/web/app/assets/javascripts/web/cookies_banner/cookies_banner_controller.js.coffee
index a35951943a..b9ee459a78 100644
--- a/engines/web/app/assets/javascripts/web/cookies_banner/cookies_banner_controller.js.coffee
+++ b/engines/web/app/assets/javascripts/web/cookies_banner/cookies_banner_controller.js.coffee
@@ -1,6 +1,6 @@
Darkswarm.controller "CookiesBannerCtrl", ($scope, CookiesBannerService, $http, $window)->
$scope.acceptCookies = ->
- $http.post('/api/cookies/consent')
+ $http.post('/api/v0/cookies/consent')
CookiesBannerService.close()
CookiesBannerService.disable()
diff --git a/engines/web/app/controllers/web/api/cookies_consent_controller.rb b/engines/web/app/controllers/web/api/cookies_consent_controller.rb
deleted file mode 100644
index e0ea13bafe..0000000000
--- a/engines/web/app/controllers/web/api/cookies_consent_controller.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-require_dependency 'web/cookies_consent'
-
-module Web
- module Api
- class CookiesConsentController < BaseController
- include ActionController::Cookies
- respond_to :json
-
- def show
- render json: { cookies_consent: cookies_consent.exists? }
- end
-
- def create
- cookies_consent.set
- show
- end
-
- def destroy
- cookies_consent.destroy
- show
- end
-
- private
-
- def cookies_consent
- @cookies_consent ||= Web::CookiesConsent.new(cookies, request.host)
- end
- end
- end
-end
diff --git a/engines/web/app/controllers/web/api/v0/cookies_consent_controller.rb b/engines/web/app/controllers/web/api/v0/cookies_consent_controller.rb
new file mode 100644
index 0000000000..606ad3e237
--- /dev/null
+++ b/engines/web/app/controllers/web/api/v0/cookies_consent_controller.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+require_dependency 'web/cookies_consent'
+
+module Web
+ module Api
+ module V0
+ class CookiesConsentController < BaseController
+ include ActionController::Cookies
+ respond_to :json
+
+ def show
+ render json: { cookies_consent: cookies_consent.exists? }
+ end
+
+ def create
+ cookies_consent.set
+ show
+ end
+
+ def destroy
+ cookies_consent.destroy
+ show
+ end
+
+ private
+
+ def cookies_consent
+ @cookies_consent ||= Web::CookiesConsent.new(cookies, request.host)
+ end
+ end
+ end
+ end
+end
diff --git a/engines/web/config/routes.rb b/engines/web/config/routes.rb
index 4b6440e06a..b2a060617a 100644
--- a/engines/web/config/routes.rb
+++ b/engines/web/config/routes.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: true
Openfoodnetwork::Application.routes.append do
- scope '/api/cookies' do
- resource :consent, only: [:show, :create, :destroy], controller: "web/api/cookies_consent"
+ scope '/api/v0/cookies' do
+ resource :consent, only: [:show, :create, :destroy], controller: "web/api/v0/cookies_consent"
end
get "/angular-templates/:id", to: "web/angular_templates#show", constraints: { name: %r{[\/\w\.]+} }
diff --git a/spec/controllers/api/base_controller_spec.rb b/spec/controllers/api/v0/base_controller_spec.rb
similarity index 96%
rename from spec/controllers/api/base_controller_spec.rb
rename to spec/controllers/api/v0/base_controller_spec.rb
index 385e2cfe10..ec9875723b 100644
--- a/spec/controllers/api/base_controller_spec.rb
+++ b/spec/controllers/api/v0/base_controller_spec.rb
@@ -2,9 +2,9 @@
require 'spec_helper'
-describe Api::BaseController do
+describe Api::V0::BaseController do
render_views
- controller(Api::BaseController) do
+ controller(Api::V0::BaseController) do
skip_authorization_check only: :index
def index
diff --git a/spec/controllers/api/customers_controller_spec.rb b/spec/controllers/api/v0/customers_controller_spec.rb
similarity index 97%
rename from spec/controllers/api/customers_controller_spec.rb
rename to spec/controllers/api/v0/customers_controller_spec.rb
index 2034d3118e..f06116a5ab 100644
--- a/spec/controllers/api/customers_controller_spec.rb
+++ b/spec/controllers/api/v0/customers_controller_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
module Api
- describe CustomersController, type: :controller do
+ describe V0::CustomersController, type: :controller do
include AuthenticationHelper
render_views
diff --git a/spec/controllers/api/enterprise_fees_controller_spec.rb b/spec/controllers/api/v0/enterprise_fees_controller_spec.rb
similarity index 91%
rename from spec/controllers/api/enterprise_fees_controller_spec.rb
rename to spec/controllers/api/v0/enterprise_fees_controller_spec.rb
index 85979beacb..40ed1e78e2 100644
--- a/spec/controllers/api/enterprise_fees_controller_spec.rb
+++ b/spec/controllers/api/v0/enterprise_fees_controller_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
module Api
- describe EnterpriseFeesController, type: :controller do
+ describe V0::EnterpriseFeesController, type: :controller do
include AuthenticationHelper
let!(:unreferenced_fee) { create(:enterprise_fee) }
diff --git a/spec/controllers/api/enterprises_controller_spec.rb b/spec/controllers/api/v0/enterprises_controller_spec.rb
similarity index 97%
rename from spec/controllers/api/enterprises_controller_spec.rb
rename to spec/controllers/api/v0/enterprises_controller_spec.rb
index cfc29f9358..32a1c067e2 100644
--- a/spec/controllers/api/enterprises_controller_spec.rb
+++ b/spec/controllers/api/v0/enterprises_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Api::EnterprisesController, type: :controller do
+describe Api::V0::EnterprisesController, type: :controller do
render_views
let(:enterprise) { create(:distributor_enterprise) }
diff --git a/spec/controllers/api/exchange_products_controller_spec.rb b/spec/controllers/api/v0/exchange_products_controller_spec.rb
similarity index 95%
rename from spec/controllers/api/exchange_products_controller_spec.rb
rename to spec/controllers/api/v0/exchange_products_controller_spec.rb
index a0ae941c8a..01394ec215 100644
--- a/spec/controllers/api/exchange_products_controller_spec.rb
+++ b/spec/controllers/api/v0/exchange_products_controller_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
module Api
- describe ExchangeProductsController, type: :controller do
+ describe V0::ExchangeProductsController, type: :controller do
include AuthenticationHelper
let(:order_cycle) { create(:order_cycle) }
@@ -54,7 +54,7 @@ module Api
let(:products_relation) { Spree::Product.includes(:variants).where("spree_variants.id": exchange.variants.map(&:id)) }
before do
- stub_const("#{Api::ExchangeProductsController}::DEFAULT_PER_PAGE", 1)
+ stub_const("#{Api::V0::ExchangeProductsController}::DEFAULT_PER_PAGE", 1)
end
describe "when a specific page is requested" do
diff --git a/spec/controllers/api/logos_controller_spec.rb b/spec/controllers/api/v0/logos_controller_spec.rb
similarity index 98%
rename from spec/controllers/api/logos_controller_spec.rb
rename to spec/controllers/api/v0/logos_controller_spec.rb
index e6e929d423..32815be1c4 100644
--- a/spec/controllers/api/logos_controller_spec.rb
+++ b/spec/controllers/api/v0/logos_controller_spec.rb
@@ -3,7 +3,7 @@
require "spec_helper"
module Api
- describe LogosController, type: :controller do
+ describe V0::LogosController, type: :controller do
include AuthenticationHelper
let(:admin_user) { create(:admin_user) }
diff --git a/spec/controllers/api/order_cycles_controller_spec.rb b/spec/controllers/api/v0/order_cycles_controller_spec.rb
similarity index 99%
rename from spec/controllers/api/order_cycles_controller_spec.rb
rename to spec/controllers/api/v0/order_cycles_controller_spec.rb
index d41d26aa43..274b9152fd 100644
--- a/spec/controllers/api/order_cycles_controller_spec.rb
+++ b/spec/controllers/api/v0/order_cycles_controller_spec.rb
@@ -3,7 +3,7 @@
require "spec_helper"
module Api
- describe OrderCyclesController, type: :controller do
+ describe V0::OrderCyclesController, type: :controller do
let!(:distributor) { create(:distributor_enterprise) }
let!(:order_cycle) { create(:simple_order_cycle, distributors: [distributor]) }
let!(:exchange) { order_cycle.exchanges.to_enterprises(distributor).outgoing.first }
diff --git a/spec/controllers/api/orders_controller_spec.rb b/spec/controllers/api/v0/orders_controller_spec.rb
similarity index 99%
rename from spec/controllers/api/orders_controller_spec.rb
rename to spec/controllers/api/v0/orders_controller_spec.rb
index d310aef486..cfae14f85a 100644
--- a/spec/controllers/api/orders_controller_spec.rb
+++ b/spec/controllers/api/v0/orders_controller_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
module Api
- describe OrdersController, type: :controller do
+ describe V0::OrdersController, type: :controller do
include AuthenticationHelper
render_views
diff --git a/spec/controllers/api/product_images_controller_spec.rb b/spec/controllers/api/v0/product_images_controller_spec.rb
similarity index 95%
rename from spec/controllers/api/product_images_controller_spec.rb
rename to spec/controllers/api/v0/product_images_controller_spec.rb
index b4858ae49e..311654b745 100644
--- a/spec/controllers/api/product_images_controller_spec.rb
+++ b/spec/controllers/api/v0/product_images_controller_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
module Api
- describe ProductImagesController, type: :controller do
+ describe V0::ProductImagesController, type: :controller do
include AuthenticationHelper
render_views
diff --git a/spec/controllers/api/products_controller_spec.rb b/spec/controllers/api/v0/products_controller_spec.rb
similarity index 99%
rename from spec/controllers/api/products_controller_spec.rb
rename to spec/controllers/api/v0/products_controller_spec.rb
index f0ee86d736..8af0985e48 100644
--- a/spec/controllers/api/products_controller_spec.rb
+++ b/spec/controllers/api/v0/products_controller_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require 'spree/core/product_duplicator'
-describe Api::ProductsController, type: :controller do
+describe Api::V0::ProductsController, type: :controller do
render_views
let(:supplier) { create(:supplier_enterprise) }
diff --git a/spec/controllers/api/promo_images_controller_spec.rb b/spec/controllers/api/v0/promo_images_controller_spec.rb
similarity index 98%
rename from spec/controllers/api/promo_images_controller_spec.rb
rename to spec/controllers/api/v0/promo_images_controller_spec.rb
index 9fe559456e..6c8d0f1319 100644
--- a/spec/controllers/api/promo_images_controller_spec.rb
+++ b/spec/controllers/api/v0/promo_images_controller_spec.rb
@@ -3,7 +3,7 @@
require "spec_helper"
module Api
- describe PromoImagesController, type: :controller do
+ describe V0::PromoImagesController, type: :controller do
include AuthenticationHelper
let(:admin_user) { create(:admin_user) }
diff --git a/spec/controllers/api/shipments_controller_spec.rb b/spec/controllers/api/v0/shipments_controller_spec.rb
similarity index 99%
rename from spec/controllers/api/shipments_controller_spec.rb
rename to spec/controllers/api/v0/shipments_controller_spec.rb
index f82b30e1e5..26e6a6b29c 100644
--- a/spec/controllers/api/shipments_controller_spec.rb
+++ b/spec/controllers/api/v0/shipments_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Api::ShipmentsController, type: :controller do
+describe Api::V0::ShipmentsController, type: :controller do
render_views
let!(:shipment) { create(:shipment) }
diff --git a/spec/controllers/api/shops_controller_spec.rb b/spec/controllers/api/v0/shops_controller_spec.rb
similarity index 96%
rename from spec/controllers/api/shops_controller_spec.rb
rename to spec/controllers/api/v0/shops_controller_spec.rb
index 0e699b2e73..2863aaef53 100644
--- a/spec/controllers/api/shops_controller_spec.rb
+++ b/spec/controllers/api/v0/shops_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Api::ShopsController, type: :controller do
+describe Api::V0::ShopsController, type: :controller do
include AuthenticationHelper
render_views
diff --git a/spec/controllers/api/states_controller_spec.rb b/spec/controllers/api/v0/states_controller_spec.rb
similarity index 98%
rename from spec/controllers/api/states_controller_spec.rb
rename to spec/controllers/api/v0/states_controller_spec.rb
index 548fcb0ad1..e9d9d11ad9 100644
--- a/spec/controllers/api/states_controller_spec.rb
+++ b/spec/controllers/api/v0/states_controller_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
module Api
- describe StatesController do
+ describe V0::StatesController do
render_views
let!(:state) { create(:state, name: "Victoria") }
diff --git a/spec/controllers/api/statuses_controller_spec.rb b/spec/controllers/api/v0/statuses_controller_spec.rb
similarity index 93%
rename from spec/controllers/api/statuses_controller_spec.rb
rename to spec/controllers/api/v0/statuses_controller_spec.rb
index 40132eed5c..e79dca33a3 100644
--- a/spec/controllers/api/statuses_controller_spec.rb
+++ b/spec/controllers/api/v0/statuses_controller_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
module Api
- describe StatusesController, type: :controller do
+ describe V0::StatusesController, type: :controller do
render_views
describe "job queue status" do
diff --git a/spec/controllers/api/taxonomies_controller_spec.rb b/spec/controllers/api/v0/taxonomies_controller_spec.rb
similarity index 96%
rename from spec/controllers/api/taxonomies_controller_spec.rb
rename to spec/controllers/api/v0/taxonomies_controller_spec.rb
index 8f080c9748..8948465864 100644
--- a/spec/controllers/api/taxonomies_controller_spec.rb
+++ b/spec/controllers/api/v0/taxonomies_controller_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
module Api
- describe TaxonomiesController do
+ describe V0::TaxonomiesController do
render_views
let(:taxonomy) { create(:taxonomy) }
diff --git a/spec/controllers/api/taxons_controller_spec.rb b/spec/controllers/api/v0/taxons_controller_spec.rb
similarity index 98%
rename from spec/controllers/api/taxons_controller_spec.rb
rename to spec/controllers/api/v0/taxons_controller_spec.rb
index f006bc3b6c..8f2b18c942 100644
--- a/spec/controllers/api/taxons_controller_spec.rb
+++ b/spec/controllers/api/v0/taxons_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Api::TaxonsController do
+describe Api::V0::TaxonsController do
render_views
let(:taxonomy) { create(:taxonomy) }
diff --git a/spec/controllers/api/terms_and_conditions_controller_spec.rb b/spec/controllers/api/v0/terms_and_conditions_controller_spec.rb
similarity index 96%
rename from spec/controllers/api/terms_and_conditions_controller_spec.rb
rename to spec/controllers/api/v0/terms_and_conditions_controller_spec.rb
index ca6a38290c..68439f74cf 100644
--- a/spec/controllers/api/terms_and_conditions_controller_spec.rb
+++ b/spec/controllers/api/v0/terms_and_conditions_controller_spec.rb
@@ -3,7 +3,7 @@
require "spec_helper"
module Api
- describe TermsAndConditionsController, type: :controller do
+ describe V0::TermsAndConditionsController, type: :controller do
include AuthenticationHelper
let(:enterprise_owner) { create(:user) }
diff --git a/spec/controllers/api/variants_controller_spec.rb b/spec/controllers/api/v0/variants_controller_spec.rb
similarity index 98%
rename from spec/controllers/api/variants_controller_spec.rb
rename to spec/controllers/api/v0/variants_controller_spec.rb
index 4a26422b62..a7b3d70b81 100644
--- a/spec/controllers/api/variants_controller_spec.rb
+++ b/spec/controllers/api/v0/variants_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Api::VariantsController, type: :controller do
+describe Api::V0::VariantsController, type: :controller do
render_views
let(:supplier) { FactoryBot.create(:supplier_enterprise) }
diff --git a/spec/controllers/spree/admin/products_controller_spec.rb b/spec/controllers/spree/admin/products_controller_spec.rb
index 081b85ebd8..7ee42b9aa2 100644
--- a/spec/controllers/spree/admin/products_controller_spec.rb
+++ b/spec/controllers/spree/admin/products_controller_spec.rb
@@ -66,7 +66,7 @@ describe Spree::Admin::ProductsController, type: :controller do
]
expect(response).to redirect_to(
- '/api/products/bulk_products'
+ '/api/v0/products/bulk_products'
)
end
end
diff --git a/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb b/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb
index c13e0dd8b1..892438c003 100644
--- a/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb
+++ b/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb
@@ -16,7 +16,7 @@ feature '
let!(:new_product) { create(:product, supplier: supplier_enterprise) }
before do
- stub_const("#{Api::ExchangeProductsController}::DEFAULT_PER_PAGE", 1)
+ stub_const("#{Api::V0::ExchangeProductsController}::DEFAULT_PER_PAGE", 1)
login_as_admin_and_visit admin_order_cycle_incoming_path(order_cycle)
expect(page).to have_content "1 / 2 selected"
diff --git a/spec/features/consumer/caching/shops_caching_spec.rb b/spec/features/consumer/caching/shops_caching_spec.rb
index f9684c2378..25ac1a1918 100644
--- a/spec/features/consumer/caching/shops_caching_spec.rb
+++ b/spec/features/consumer/caching/shops_caching_spec.rb
@@ -47,8 +47,8 @@ feature "Shops caching", js: true, caching: true do
let(:exchange) { order_cycle.exchanges.to_enterprises(distributor).outgoing.first }
let(:test_domain) { "#{Capybara.current_session.server.host}:#{Capybara.current_session.server.port}" }
- let(:taxons_key) { "views/#{test_domain}/api/order_cycles/#{order_cycle.id}/taxons.json?distributor=#{distributor.id}" }
- let(:properties_key) { "views/#{test_domain}/api/order_cycles/#{order_cycle.id}/properties.json?distributor=#{distributor.id}" }
+ let(:taxons_key) { "views/#{test_domain}/api/v0/order_cycles/#{order_cycle.id}/taxons.json?distributor=#{distributor.id}" }
+ let(:properties_key) { "views/#{test_domain}/api/v0/order_cycles/#{order_cycle.id}/properties.json?distributor=#{distributor.id}" }
let(:options) { { expires_in: CacheService::FILTERS_EXPIRY } }
before do
diff --git a/spec/javascripts/unit/admin/bulk_product_update_spec.js.coffee b/spec/javascripts/unit/admin/bulk_product_update_spec.js.coffee
index 81ea716f98..9369342591 100644
--- a/spec/javascripts/unit/admin/bulk_product_update_spec.js.coffee
+++ b/spec/javascripts/unit/admin/bulk_product_update_spec.js.coffee
@@ -820,7 +820,7 @@ describe "AdminProductEditCtrl", ->
}
]
$scope.dirtyProducts = {}
- $httpBackend.expectDELETE("/api/products/13").respond 200, "data"
+ $httpBackend.expectDELETE("/api/v0/products/13").respond 200, "data"
$scope.deleteProduct $scope.products[1]
$httpBackend.flush()
@@ -839,7 +839,7 @@ describe "AdminProductEditCtrl", ->
DirtyProducts.addProductProperty 9, "someProperty", "something"
DirtyProducts.addProductProperty 13, "name", "P1"
- $httpBackend.expectDELETE("/api/products/13").respond 200, "data"
+ $httpBackend.expectDELETE("/api/v0/products/13").respond 200, "data"
$scope.deleteProduct $scope.products[1]
$httpBackend.flush()
expect($scope.products).toEqual [
@@ -901,7 +901,7 @@ describe "AdminProductEditCtrl", ->
}
]
$scope.dirtyProducts = {}
- $httpBackend.expectDELETE("/api/products/apples/variants/3").respond 200, "data"
+ $httpBackend.expectDELETE("/api/v0/products/apples/variants/3").respond 200, "data"
$scope.deleteVariant $scope.products[0], $scope.products[0].variants[0]
$httpBackend.flush()
@@ -931,7 +931,7 @@ describe "AdminProductEditCtrl", ->
DirtyProducts.addVariantProperty 9, 4, "price", 6.0
DirtyProducts.addProductProperty 13, "name", "P1"
- $httpBackend.expectDELETE("/api/products/apples/variants/3").respond 200, "data"
+ $httpBackend.expectDELETE("/api/v0/products/apples/variants/3").respond 200, "data"
$scope.deleteVariant $scope.products[0], $scope.products[0].variants[0]
$httpBackend.flush()
expect($scope.products[0].variants).toEqual [
diff --git a/spec/javascripts/unit/admin/enterprises/services/enterprises_spec.js.coffee b/spec/javascripts/unit/admin/enterprises/services/enterprises_spec.js.coffee
index 47c669e105..0e2101f0af 100644
--- a/spec/javascripts/unit/admin/enterprises/services/enterprises_spec.js.coffee
+++ b/spec/javascripts/unit/admin/enterprises/services/enterprises_spec.js.coffee
@@ -127,7 +127,7 @@ describe "Enterprises service", ->
beforeEach ->
enterprise = new EnterpriseResource({ id: 15, permalink: "enterprise1", name: "Enterprise 1", logo: {} })
- $httpBackend.expectDELETE("/api/enterprises/enterprise1/logo.json").respond 200, { id: 15, name: "Enterprise 1"}
+ $httpBackend.expectDELETE("/api/v0/enterprises/enterprise1/logo.json").respond 200, { id: 15, name: "Enterprise 1"}
Enterprises.removeLogo(enterprise).then( -> resolved = true)
$httpBackend.flush()
@@ -144,7 +144,7 @@ describe "Enterprises service", ->
beforeEach ->
enterprise = new EnterpriseResource( { id: 15, permalink: "enterprise1", name: "Enterprise 1" } )
- $httpBackend.expectDELETE("/api/enterprises/enterprise1/logo.json").respond 409, { error: "obj" }
+ $httpBackend.expectDELETE("/api/v0/enterprises/enterprise1/logo.json").respond 409, { error: "obj" }
Enterprises.removeLogo(enterprise).catch( -> rejected = true)
$httpBackend.flush()
@@ -162,7 +162,7 @@ describe "Enterprises service", ->
beforeEach ->
enterprise = new EnterpriseResource({ id: 15, permalink: "enterprise1", name: "Enterprise 1", promo_image: {} })
- $httpBackend.expectDELETE("/api/enterprises/enterprise1/promo_image.json").respond 200, { id: 15, name: "Enterprise 1"}
+ $httpBackend.expectDELETE("/api/v0/enterprises/enterprise1/promo_image.json").respond 200, { id: 15, name: "Enterprise 1"}
Enterprises.removePromoImage(enterprise).then( -> resolved = true)
$httpBackend.flush()
@@ -179,7 +179,7 @@ describe "Enterprises service", ->
beforeEach ->
enterprise = new EnterpriseResource( { id: 15, permalink: "enterprise1", name: "Enterprise 1" } )
- $httpBackend.expectDELETE("/api/enterprises/enterprise1/promo_image.json").respond 409, { error: "obj" }
+ $httpBackend.expectDELETE("/api/v0/enterprises/enterprise1/promo_image.json").respond 409, { error: "obj" }
Enterprises.removePromoImage(enterprise).catch( -> rejected = true)
$httpBackend.flush()
diff --git a/spec/javascripts/unit/admin/line_items/controllers/line_items_controller_spec.js.coffee b/spec/javascripts/unit/admin/line_items/controllers/line_items_controller_spec.js.coffee
index 4bc5513310..31a32f256a 100644
--- a/spec/javascripts/unit/admin/line_items/controllers/line_items_controller_spec.js.coffee
+++ b/spec/javascripts/unit/admin/line_items/controllers/line_items_controller_spec.js.coffee
@@ -45,7 +45,7 @@ describe "LineItemsCtrl", ->
index: jasmine.createSpy('index').and.returnValue(lineItem)
all: [lineItem]
- httpBackend.expectGET("/api/orders.json?q%5Bcompleted_at_gteq%5D=SomeDate&q%5Bcompleted_at_lt%5D=SomeDate&q%5Bcompleted_at_not_null%5D=true&q%5Bdistributor_id_eq%5D=&q%5Border_cycle_id_eq%5D=&q%5Bstate_not_eq%5D=canceled").respond {orders: [order], pagination: {page: 1, pages: 1, results: 1}}
+ httpBackend.expectGET("/api/v0/orders.json?q%5Bcompleted_at_gteq%5D=SomeDate&q%5Bcompleted_at_lt%5D=SomeDate&q%5Bcompleted_at_not_null%5D=true&q%5Bdistributor_id_eq%5D=&q%5Border_cycle_id_eq%5D=&q%5Bstate_not_eq%5D=canceled").respond {orders: [order], pagination: {page: 1, pages: 1, results: 1}}
httpBackend.expectGET("/admin/enterprises/visible.json?ams_prefix=basic&q%5Bsells_in%5D%5B%5D=own&q%5Bsells_in%5D%5B%5D=any").respond [distributor]
httpBackend.expectGET("/admin/order_cycles.json?ams_prefix=basic&as=distributor&q%5Borders_close_at_gt%5D=SomeDate").respond [orderCycle]
httpBackend.expectGET("/admin/enterprises/visible.json?ams_prefix=basic&q%5Bis_primary_producer_eq%5D=true").respond [supplier]
diff --git a/spec/javascripts/unit/admin/orders/services/orders_spec.js.coffee b/spec/javascripts/unit/admin/orders/services/orders_spec.js.coffee
index 8372ee6819..9c19b2268d 100644
--- a/spec/javascripts/unit/admin/orders/services/orders_spec.js.coffee
+++ b/spec/javascripts/unit/admin/orders/services/orders_spec.js.coffee
@@ -19,7 +19,7 @@ describe "Orders service", ->
beforeEach ->
response = { orders: [{ id: 5, name: 'Order 1'}], pagination: {page: 1, pages: 1, results: 1} }
- $httpBackend.expectGET('/api/orders.json').respond 200, response
+ $httpBackend.expectGET('/api/v0/orders.json').respond 200, response
result = Orders.index()
$httpBackend.flush()
diff --git a/spec/javascripts/unit/admin/services/bulk_products_spec.js.coffee b/spec/javascripts/unit/admin/services/bulk_products_spec.js.coffee
index 4fc1cca031..ece9d1f244 100644
--- a/spec/javascripts/unit/admin/services/bulk_products_spec.js.coffee
+++ b/spec/javascripts/unit/admin/services/bulk_products_spec.js.coffee
@@ -13,9 +13,9 @@ describe "BulkProducts service", ->
BulkProducts.products = [
id: 13
]
- $httpBackend.expectPOST("/api/products/13/clone").respond 201,
+ $httpBackend.expectPOST("/api/v0/products/13/clone").respond 201,
id: 17
- $httpBackend.expectGET("/api/products/17?template=bulk_show").respond 200, [
+ $httpBackend.expectGET("/api/v0/products/17?template=bulk_show").respond 200, [
id: 17
]
BulkProducts.cloneProduct BulkProducts.products[0]
@@ -30,8 +30,8 @@ describe "BulkProducts service", ->
spyOn(BulkProducts, "insertProductAfter")
spyOn(BulkProducts, "unpackProduct")
BulkProducts.products = [originalProduct]
- $httpBackend.expectPOST("/api/products/16/clone").respond 201, clonedProduct
- $httpBackend.expectGET("/api/products/17?template=bulk_show").respond 200, clonedProduct
+ $httpBackend.expectPOST("/api/v0/products/16/clone").respond 201, clonedProduct
+ $httpBackend.expectGET("/api/v0/products/17?template=bulk_show").respond 200, clonedProduct
BulkProducts.cloneProduct BulkProducts.products[0]
$httpBackend.flush()
expect(BulkProducts.unpackProduct).toHaveBeenCalledWith clonedProduct
diff --git a/spec/javascripts/unit/darkswarm/services/credit_cards_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/credit_cards_spec.js.coffee
index 6e614cffe6..8b421e33ec 100644
--- a/spec/javascripts/unit/darkswarm/services/credit_cards_spec.js.coffee
+++ b/spec/javascripts/unit/darkswarm/services/credit_cards_spec.js.coffee
@@ -36,7 +36,7 @@ describe 'CreditCards service', ->
it "loads a success flash", ->
CreditCards.setDefault(card2)
- $httpBackend.expectGET('/api/customers.json').respond 200, []
+ $httpBackend.expectGET('/api/v0/customers.json').respond 200, []
$httpBackend.flush()
expect(RailsFlashLoader.loadFlash).toHaveBeenCalledWith({success: t('js.default_card_updated')})
diff --git a/spec/javascripts/unit/darkswarm/services/customer_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/customer_spec.js.coffee
index 33a1d72cdc..a3f9a561ac 100644
--- a/spec/javascripts/unit/darkswarm/services/customer_spec.js.coffee
+++ b/spec/javascripts/unit/darkswarm/services/customer_spec.js.coffee
@@ -17,14 +17,14 @@ describe 'Customer', ->
it "nests the params inside 'customer'", ->
$httpBackend
- .expectPUT('/api/customers/3.json', { customer: { id: 3 } })
+ .expectPUT('/api/v0/customers/3.json', { customer: { id: 3 } })
.respond 200, response
customer.update()
$httpBackend.flush()
describe "when the request succeeds", ->
it "shows a success flash", ->
- $httpBackend.expectPUT('/api/customers/3.json').respond 200, response
+ $httpBackend.expectPUT('/api/v0/customers/3.json').respond 200, response
customer.update()
$httpBackend.flush()
expect(RailsFlashLoaderMock.loadFlash)
@@ -32,7 +32,7 @@ describe 'Customer', ->
describe "when the request fails", ->
it "shows a error flash", ->
- $httpBackend.expectPUT('/api/customers/3.json').respond 400, { error: 'Some error' }
+ $httpBackend.expectPUT('/api/v0/customers/3.json').respond 400, { error: 'Some error' }
customer.update()
$httpBackend.flush()
expect(RailsFlashLoaderMock.loadFlash)
diff --git a/spec/javascripts/unit/darkswarm/services/customers_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/customers_spec.js.coffee
index 9680b89341..eaf788e9fe 100644
--- a/spec/javascripts/unit/darkswarm/services/customers_spec.js.coffee
+++ b/spec/javascripts/unit/darkswarm/services/customers_spec.js.coffee
@@ -16,7 +16,7 @@ describe 'Customers', ->
it "asks for customers and returns @all, promises to populate via @load", ->
spyOn(Customers,'load').and.callThrough()
- $httpBackend.expectGET('/api/customers.json').respond 200, customerList
+ $httpBackend.expectGET('/api/v0/customers.json').respond 200, customerList
result = Customers.index()
$httpBackend.flush()
expect(Customers.load).toHaveBeenCalled()
diff --git a/spec/javascripts/unit/darkswarm/services/enterprise_registration_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/enterprise_registration_spec.js.coffee
index 4952c3c4fc..db1c801729 100644
--- a/spec/javascripts/unit/darkswarm/services/enterprise_registration_spec.js.coffee
+++ b/spec/javascripts/unit/darkswarm/services/enterprise_registration_spec.js.coffee
@@ -32,7 +32,7 @@ describe "EnterpriseRegistrationService", ->
describe "success", ->
beforeEach ->
spyOn(RegistrationServiceMock, "select")
- $httpBackend.expectPOST("/api/enterprises?token=keykeykeykey").respond 200, 6
+ $httpBackend.expectPOST("/api/v0/enterprises?token=keykeykeykey").respond 200, 6
EnterpriseRegistrationService.create()
$httpBackend.flush()
@@ -46,7 +46,7 @@ describe "EnterpriseRegistrationService", ->
beforeEach ->
spyOn(RegistrationServiceMock, "select")
spyOn(window, "alert")
- $httpBackend.expectPOST("/api/enterprises?token=keykeykeykey").respond 400, 6
+ $httpBackend.expectPOST("/api/v0/enterprises?token=keykeykeykey").respond 400, 6
EnterpriseRegistrationService.create()
$httpBackend.flush()
@@ -60,7 +60,7 @@ describe "EnterpriseRegistrationService", ->
beforeEach ->
spyOn(RegistrationServiceMock, "select")
spyOn(window, "alert")
- $httpBackend.expectPOST("/api/enterprises?token=keykeykeykey").respond 400, {"error": "Invalid resource. Please fix errors and try again.", "errors": {"name": ["has already been taken. If this is your enterprise and you would like to claim ownership, please contact the current manager of this profile at owner@example.com."], "permalink": [] }}
+ $httpBackend.expectPOST("/api/v0/enterprises?token=keykeykeykey").respond 400, {"error": "Invalid resource. Please fix errors and try again.", "errors": {"name": ["has already been taken. If this is your enterprise and you would like to claim ownership, please contact the current manager of this profile at owner@example.com."], "permalink": [] }}
EnterpriseRegistrationService.create()
$httpBackend.flush()
@@ -78,7 +78,7 @@ describe "EnterpriseRegistrationService", ->
describe "success", ->
beforeEach ->
- $httpBackend.expectPUT("/api/enterprises/78?token=keykeykeykey").respond 200, 6
+ $httpBackend.expectPUT("/api/v0/enterprises/78?token=keykeykeykey").respond 200, 6
EnterpriseRegistrationService.update('step')
$httpBackend.flush()
@@ -88,7 +88,7 @@ describe "EnterpriseRegistrationService", ->
describe "failure", ->
beforeEach ->
spyOn(window, "alert")
- $httpBackend.expectPUT("/api/enterprises/78?token=keykeykeykey").respond 400, 6
+ $httpBackend.expectPUT("/api/v0/enterprises/78?token=keykeykeykey").respond 400, 6
EnterpriseRegistrationService.update('step')
$httpBackend.flush()
diff --git a/spec/javascripts/unit/darkswarm/services/products_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/products_spec.js.coffee
index d0114c05dd..df6446b433 100644
--- a/spec/javascripts/unit/darkswarm/services/products_spec.js.coffee
+++ b/spec/javascripts/unit/darkswarm/services/products_spec.js.coffee
@@ -13,7 +13,7 @@ describe 'Products service', ->
properties = null
taxons = null
GmapsGeo = {}
- endpoint = "/api/order_cycles/1/products.json?distributor=1"
+ endpoint = "/api/v0/order_cycles/1/products.json?distributor=1"
beforeEach ->
product =
diff --git a/spec/requests/api/orders_spec.rb b/spec/requests/api/orders_spec.rb
index 50b2c677ff..556ff4a619 100644
--- a/spec/requests/api/orders_spec.rb
+++ b/spec/requests/api/orders_spec.rb
@@ -2,8 +2,8 @@
require 'swagger_helper'
-describe 'api/orders', type: :request do
- path '/api/orders' do
+describe 'api/v0/orders', type: :request do
+ path '/api/v0/orders' do
get('list orders') do
tags 'Orders'
# type should be replaced with swagger 3.01 valid schema: {type: string} when rswag #317 is resolved:
diff --git a/spec/requests/api/routes_spec.rb b/spec/requests/api/routes_spec.rb
new file mode 100644
index 0000000000..fa7d1b20bc
--- /dev/null
+++ b/spec/requests/api/routes_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+# test a single endpoint to make sure the redirects are working as intended.
+require 'spec_helper'
+
+describe 'Orders Cycles endpoint', type: :request do
+ let(:distributor) { create(:distributor_enterprise) }
+ let(:order_cycle) { create(:order_cycle, distributors: [distributor]) }
+
+ context "requesting the latest version" do
+ let(:path) { "/api/order_cycles/#{order_cycle.id}/products?distributor=#{distributor.id}" }
+
+ it "redirects to v0, preserving URL params" do
+ get path
+ expect(response).to redirect_to(
+ "/api/v0/order_cycles/#{order_cycle.id}/products?distributor=#{distributor.id}"
+ )
+ end
+ end
+
+ context "requesting a specific API version" do
+ let(:path) { "/api/v0/order_cycles/#{order_cycle.id}/products?distributor=#{distributor.id}" }
+
+ it "does not redirect" do
+ get path
+ expect(response.status).to eq(200)
+ end
+ end
+end