spree_api 1.3.0.rc1 → 1.3.0.rc2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. data/app/controllers/spree/api/addresses_controller.rb +4 -1
  2. data/app/controllers/spree/api/base_controller.rb +9 -0
  3. data/app/controllers/spree/api/countries_controller.rb +4 -0
  4. data/app/controllers/spree/api/images_controller.rb +6 -3
  5. data/app/controllers/spree/api/line_items_controller.rb +5 -3
  6. data/app/controllers/spree/api/orders_controller.rb +5 -1
  7. data/app/controllers/spree/api/payments_controller.rb +7 -2
  8. data/app/controllers/spree/api/product_properties_controller.rb +7 -3
  9. data/app/controllers/spree/api/products_controller.rb +7 -3
  10. data/app/controllers/spree/api/return_authorizations_controller.rb +7 -3
  11. data/app/controllers/spree/api/shipments_controller.rb +4 -2
  12. data/app/controllers/spree/api/taxonomies_controller.rb +7 -3
  13. data/app/controllers/spree/api/taxons_controller.rb +7 -3
  14. data/app/controllers/spree/api/v1/base_controller.rb +111 -0
  15. data/app/controllers/spree/api/v1/inventory_units_controller.rb +50 -0
  16. data/app/controllers/spree/api/variants_controller.rb +7 -3
  17. data/app/controllers/spree/api/zones_controller.rb +8 -5
  18. data/app/helpers/spree/api/api_helpers.rb +5 -0
  19. data/app/views/spree/api/v1/inventory_units/show.rabl +2 -0
  20. data/config/routes.rb +2 -1
  21. data/lib/spree/api/responders.rb +11 -0
  22. data/lib/spree/api/responders/rabl_template.rb +22 -0
  23. data/lib/spree_api.rb +1 -0
  24. data/spec/controllers/spree/api/base_controller_spec.rb +7 -0
  25. data/spec/controllers/spree/api/v1/inventory_units_controller_spec.rb +46 -0
  26. data/spec/controllers/spree/api/zones_controller_spec.rb +22 -0
  27. metadata +12 -5
@@ -1,16 +1,19 @@
1
1
  module Spree
2
2
  module Api
3
3
  class AddressesController < Spree::Api::BaseController
4
+ respond_to :json
5
+
4
6
  def show
5
7
  @address = Address.find(params[:id])
6
8
  authorize! :read, @address
9
+ respond_with(@address)
7
10
  end
8
11
 
9
12
  def update
10
13
  @address = Address.find(params[:id])
11
14
  authorize! :read, @address
12
15
  @address.update_attributes(params[:address])
13
- render :show, :status => 200
16
+ respond_with(@address, :default_template => :show)
14
17
  end
15
18
  end
16
19
  end
@@ -2,6 +2,9 @@ module Spree
2
2
  module Api
3
3
  class BaseController < ActionController::Metal
4
4
  include Spree::Api::ControllerSetup
5
+ include ::ActionController::Head
6
+
7
+ self.responder = Spree::Api::Responders::AppResponder
5
8
 
6
9
  attr_accessor :current_api_user
7
10
 
@@ -10,6 +13,7 @@ module Spree
10
13
  before_filter :authenticate_user
11
14
  after_filter :set_jsonp_format
12
15
 
16
+ rescue_from Exception, :with => :error_during_processing
13
17
  rescue_from CanCan::AccessDenied, :with => :unauthorized
14
18
  rescue_from ActiveRecord::RecordNotFound, :with => :not_found
15
19
 
@@ -62,6 +66,11 @@ module Spree
62
66
  render "spree/api/errors/unauthorized", :status => 401 and return
63
67
  end
64
68
 
69
+ def error_during_processing(exception)
70
+ render :text => { exception: exception.message }.to_json,
71
+ :status => 422 and return
72
+ end
73
+
65
74
  def requires_authentication?
66
75
  Spree::Api::Config[:requires_authentication]
67
76
  end
@@ -1,13 +1,17 @@
1
1
  module Spree
2
2
  module Api
3
3
  class CountriesController < Spree::Api::BaseController
4
+ respond_to :json
5
+
4
6
  def index
5
7
  @countries = Country.ransack(params[:q]).result.includes(:states).order('name ASC')
6
8
  .page(params[:page]).per(params[:per_page])
9
+ respond_with(@countries)
7
10
  end
8
11
 
9
12
  def show
10
13
  @country = Country.find(params[:id])
14
+ respond_with(@country)
11
15
  end
12
16
  end
13
17
  end
@@ -1,28 +1,31 @@
1
1
  module Spree
2
2
  module Api
3
3
  class ImagesController < Spree::Api::BaseController
4
+ respond_to :json
5
+
4
6
  def show
5
7
  @image = Image.find(params[:id])
8
+ respond_with(@image)
6
9
  end
7
10
 
8
11
  def create
9
12
  authorize! :create, Image
10
13
  @image = Image.create(params[:image])
11
- render :show, :status => 201
14
+ respond_with(@image, :status => 201, :default_template => :show)
12
15
  end
13
16
 
14
17
  def update
15
18
  authorize! :update, Image
16
19
  @image = Image.find(params[:id])
17
20
  @image.update_attributes(params[:image])
18
- render :show, :status => 200
21
+ respond_with(@image, :default_template => :show)
19
22
  end
20
23
 
21
24
  def destroy
22
25
  authorize! :delete, Image
23
26
  @image = Image.find(params[:id])
24
27
  @image.destroy
25
- render :text => nil, :status => 204
28
+ respond_with(@image, :status => 204)
26
29
  end
27
30
  end
28
31
  end
@@ -1,11 +1,13 @@
1
1
  module Spree
2
2
  module Api
3
3
  class LineItemsController < Spree::Api::BaseController
4
+ respond_to :json
5
+
4
6
  def create
5
7
  authorize! :read, order
6
8
  @line_item = order.line_items.build(params[:line_item], :as => :api)
7
9
  if @line_item.save
8
- render :show, :status => 201
10
+ respond_with(@line_item, :status => 201, :default_template => :show)
9
11
  else
10
12
  invalid_resource!(@line_item)
11
13
  end
@@ -15,7 +17,7 @@ module Spree
15
17
  authorize! :read, order
16
18
  @line_item = order.line_items.find(params[:id])
17
19
  if @line_item.update_attributes(params[:line_item])
18
- render :show
20
+ respond_with(@line_item, :default_template => :show)
19
21
  else
20
22
  invalid_resource!(@line_item)
21
23
  end
@@ -25,7 +27,7 @@ module Spree
25
27
  authorize! :read, order
26
28
  @line_item = order.line_items.find(params[:id])
27
29
  @line_item.destroy
28
- render :text => nil, :status => 204
30
+ respond_with(@line_item, :status => 204)
29
31
  end
30
32
 
31
33
  private
@@ -1,15 +1,19 @@
1
1
  module Spree
2
2
  module Api
3
3
  class OrdersController < Spree::Api::BaseController
4
+ respond_to :json
5
+
4
6
  before_filter :authorize_read!, :except => [:index, :search, :create]
5
7
 
6
8
  def index
7
9
  # should probably look at turning this into a CanCan step
8
10
  raise CanCan::AccessDenied unless current_api_user.has_spree_role?("admin")
9
11
  @orders = Order.ransack(params[:q]).result.page(params[:page]).per(params[:per_page])
12
+ respond_with(@orders)
10
13
  end
11
14
 
12
15
  def show
16
+ respond_with(@order)
13
17
  end
14
18
 
15
19
  def create
@@ -21,7 +25,7 @@ module Spree
21
25
  authorize! :update, Order
22
26
  if order.update_attributes(nested_params)
23
27
  order.update!
24
- render :show
28
+ respond_with(order, :default_template => :show)
25
29
  else
26
30
  invalid_resource!(order)
27
31
  end
@@ -1,27 +1,32 @@
1
1
  module Spree
2
2
  module Api
3
3
  class PaymentsController < Spree::Api::BaseController
4
+ respond_to :json
5
+
4
6
  before_filter :find_order
5
7
  before_filter :find_payment, :only => [:show, :authorize, :purchase, :capture, :void, :credit]
6
8
 
7
9
  def index
8
10
  @payments = @order.payments.ransack(params[:q]).result.page(params[:page]).per(params[:per_page])
11
+ respond_with(@payments)
9
12
  end
10
13
 
11
14
  def new
12
15
  @payment_methods = Spree::PaymentMethod.where(:environment => Rails.env)
16
+ respond_with(@payment_method)
13
17
  end
14
18
 
15
19
  def create
16
20
  @payment = @order.payments.build(params[:payment])
17
21
  if @payment.save
18
- render :show, :status => 201
22
+ respond_with(@payment, :status => 201, :default_template => :show)
19
23
  else
20
24
  invalid_resource!(@payment)
21
25
  end
22
26
  end
23
27
 
24
28
  def show
29
+ respond_with(@payment)
25
30
  end
26
31
 
27
32
  def authorize
@@ -64,7 +69,7 @@ module Spree
64
69
 
65
70
  begin
66
71
  @payment.send("#{action}!", *args)
67
- render :show
72
+ respond_with(@payment, :default_template => :show)
68
73
  rescue Spree::Core::GatewayError => e
69
74
  @error = e.message
70
75
  render "spree/api/errors/gateway_error", :status => 422
@@ -1,15 +1,19 @@
1
1
  module Spree
2
2
  module Api
3
3
  class ProductPropertiesController < Spree::Api::BaseController
4
+ respond_to :json
5
+
4
6
  before_filter :find_product
5
7
  before_filter :product_property, :only => [:show, :update, :destroy]
6
8
 
7
9
  def index
8
10
  @product_properties = @product.product_properties.ransack(params[:q]).result
9
11
  .page(params[:page]).per(params[:per_page])
12
+ respond_with(@product_properties)
10
13
  end
11
14
 
12
15
  def show
16
+ respond_with(@product_property)
13
17
  end
14
18
 
15
19
  def new
@@ -19,7 +23,7 @@ module Spree
19
23
  authorize! :create, ProductProperty
20
24
  @product_property = @product.product_properties.new(params[:product_property])
21
25
  if @product_property.save
22
- render :show, :status => 201
26
+ respond_with(@product_property, :status => 201, :default_template => :show)
23
27
  else
24
28
  invalid_resource!(@product_property)
25
29
  end
@@ -28,7 +32,7 @@ module Spree
28
32
  def update
29
33
  authorize! :update, ProductProperty
30
34
  if @product_property && @product_property.update_attributes(params[:product_property])
31
- render :show, :status => 200
35
+ respond_with(@product_property, :status => 200, :default_template => :show)
32
36
  else
33
37
  invalid_resource!(@product_property)
34
38
  end
@@ -38,7 +42,7 @@ module Spree
38
42
  authorize! :delete, ProductProperty
39
43
  if(@product_property)
40
44
  @product_property.destroy
41
- render :text => nil, :status => 204
45
+ respond_with(@product_property, :status => 204)
42
46
  else
43
47
  invalid_resource!(@product_property)
44
48
  end
@@ -1,12 +1,16 @@
1
1
  module Spree
2
2
  module Api
3
3
  class ProductsController < Spree::Api::BaseController
4
+ respond_to :json
5
+
4
6
  def index
5
7
  @products = product_scope.ransack(params[:q]).result.page(params[:page]).per(params[:per_page])
8
+ respond_with(@products)
6
9
  end
7
10
 
8
11
  def show
9
12
  @product = find_product(params[:id])
13
+ respond_with(@product)
10
14
  end
11
15
 
12
16
  def new
@@ -17,7 +21,7 @@ module Spree
17
21
  params[:product][:available_on] ||= Time.now
18
22
  @product = Product.new(params[:product])
19
23
  if @product.save
20
- render :show, :status => 201
24
+ respond_with(@product, :status => 201, :default_template => :show)
21
25
  else
22
26
  invalid_resource!(@product)
23
27
  end
@@ -27,7 +31,7 @@ module Spree
27
31
  authorize! :update, Product
28
32
  @product = find_product(params[:id])
29
33
  if @product.update_attributes(params[:product])
30
- render :show, :status => 200
34
+ respond_with(@product, :status => 200, :default_template => :show)
31
35
  else
32
36
  invalid_resource!(@product)
33
37
  end
@@ -38,7 +42,7 @@ module Spree
38
42
  @product = find_product(params[:id])
39
43
  @product.update_attribute(:deleted_at, Time.now)
40
44
  @product.variants_including_master.update_all(:deleted_at => Time.now)
41
- render :text => nil, :status => 204
45
+ respond_with(@product, :status => 204)
42
46
  end
43
47
  end
44
48
  end
@@ -1,21 +1,25 @@
1
1
  module Spree
2
2
  module Api
3
3
  class ReturnAuthorizationsController < Spree::Api::BaseController
4
+ respond_to :json
5
+
4
6
  before_filter :authorize_admin!
5
7
 
6
8
  def index
7
9
  @return_authorizations = order.return_authorizations.ransack(params[:q]).result
8
10
  .page(params[:page]).per(params[:per_page])
11
+ respond_with(@return_authorizations)
9
12
  end
10
13
 
11
14
  def show
12
15
  @return_authorization = order.return_authorizations.find(params[:id])
16
+ respond_with(@return_authorization)
13
17
  end
14
18
 
15
19
  def create
16
20
  @return_authorization = order.return_authorizations.build(params[:return_authorization], :as => :api)
17
21
  if @return_authorization.save
18
- render :show, :status => 201
22
+ respond_with(@return_authorization, :status => 201, :default_template => :show)
19
23
  else
20
24
  invalid_resource!(@return_authorization)
21
25
  end
@@ -24,7 +28,7 @@ module Spree
24
28
  def update
25
29
  @return_authorization = order.return_authorizations.find(params[:id])
26
30
  if @return_authorization.update_attributes(params[:return_authorization])
27
- render :show
31
+ respond_with(@return_authorization, :default_template => :show)
28
32
  else
29
33
  invalid_resource!(@return_authorization)
30
34
  end
@@ -33,7 +37,7 @@ module Spree
33
37
  def destroy
34
38
  @return_authorization = order.return_authorizations.find(params[:id])
35
39
  @return_authorization.destroy
36
- render :text => nil, :status => 204
40
+ respond_with(@return_authorization, :status => 204)
37
41
  end
38
42
 
39
43
  private
@@ -1,6 +1,8 @@
1
1
  module Spree
2
2
  module Api
3
3
  class ShipmentsController < Spree::Api::BaseController
4
+ respond_to :json
5
+
4
6
  before_filter :find_order
5
7
  before_filter :find_and_update_shipment, :only => [:ship, :ready]
6
8
 
@@ -13,7 +15,7 @@ module Spree
13
15
  render "spree/api/shipments/cannot_ready_shipment", :status => 422 and return
14
16
  end
15
17
  end
16
- render :show
18
+ respond_with(@shipment, :default_template => :show)
17
19
  end
18
20
 
19
21
  def ship
@@ -21,7 +23,7 @@ module Spree
21
23
  unless @shipment.shipped?
22
24
  @shipment.ship!
23
25
  end
24
- render :show
26
+ respond_with(@shipment, :default_template => :show)
25
27
  end
26
28
 
27
29
  private
@@ -1,20 +1,24 @@
1
1
  module Spree
2
2
  module Api
3
3
  class TaxonomiesController < Spree::Api::BaseController
4
+ respond_to :json
5
+
4
6
  def index
5
7
  @taxonomies = Taxonomy.order('name').includes(:root => :children).ransack(params[:q]).result
6
8
  .page(params[:page]).per(params[:per_page])
9
+ respond_with(@taxonomies)
7
10
  end
8
11
 
9
12
  def show
10
13
  @taxonomy = Taxonomy.find(params[:id])
14
+ respond_with(@taxonomy)
11
15
  end
12
16
 
13
17
  def create
14
18
  authorize! :create, Taxonomy
15
19
  @taxonomy = Taxonomy.new(params[:taxonomy])
16
20
  if @taxonomy.save
17
- render :show, :status => 201
21
+ respond_with(@taxonomy, :status => 201, :default_template => :show)
18
22
  else
19
23
  invalid_resource!(@taxonomy)
20
24
  end
@@ -23,7 +27,7 @@ module Spree
23
27
  def update
24
28
  authorize! :update, Taxonomy
25
29
  if taxonomy.update_attributes(params[:taxonomy])
26
- render :show, :status => 200
30
+ respond_with(taxonomy, :status => 200, :default_template => :show)
27
31
  else
28
32
  invalid_resource!(taxonomy)
29
33
  end
@@ -32,7 +36,7 @@ module Spree
32
36
  def destroy
33
37
  authorize! :delete, Taxonomy
34
38
  taxonomy.destroy
35
- render :text => nil, :status => 204
39
+ respond_with(taxonomy, :status => 204)
36
40
  end
37
41
 
38
42
  private
@@ -1,19 +1,23 @@
1
1
  module Spree
2
2
  module Api
3
3
  class TaxonsController < Spree::Api::BaseController
4
+ respond_to :json
5
+
4
6
  def index
5
7
  @taxons = taxonomy.root.children
8
+ respond_with(@taxons)
6
9
  end
7
10
 
8
11
  def show
9
12
  @taxon = taxon
13
+ respond_with(@taxon)
10
14
  end
11
15
 
12
16
  def create
13
17
  authorize! :create, Taxon
14
18
  @taxon = Taxon.new(params[:taxon])
15
19
  if @taxon.save
16
- render :show, :status => 201
20
+ respond_with(@taxon, :status => 201, :default_template => :show)
17
21
  else
18
22
  invalid_resource!(@taxon)
19
23
  end
@@ -22,7 +26,7 @@ module Spree
22
26
  def update
23
27
  authorize! :update, Taxon
24
28
  if taxon.update_attributes(params[:taxon])
25
- render :show, :status => 200
29
+ respond_with(taxon, :status => 200, :default_template => :show)
26
30
  else
27
31
  invalid_resource!(taxon)
28
32
  end
@@ -31,7 +35,7 @@ module Spree
31
35
  def destroy
32
36
  authorize! :delete, Taxon
33
37
  taxon.destroy
34
- render :text => nil, :status => 204
38
+ respond_with(taxon, :status => 204)
35
39
  end
36
40
 
37
41
  private
@@ -0,0 +1,111 @@
1
+ module Spree
2
+ module Api
3
+ module V1
4
+ class BaseController < ActionController::Metal
5
+ include Spree::Api::ControllerSetup
6
+
7
+ attr_accessor :current_api_user
8
+
9
+ before_filter :set_content_type
10
+ before_filter :check_for_api_key, :if => :requires_authentication?
11
+ before_filter :authenticate_user
12
+
13
+ rescue_from Exception, :with => :error_during_processing
14
+ rescue_from CanCan::AccessDenied, :with => :unauthorized
15
+ rescue_from ActiveRecord::RecordNotFound, :with => :not_found
16
+
17
+ helper Spree::Api::ApiHelpers
18
+
19
+ def map_nested_attributes_keys(klass, attributes)
20
+ nested_keys = klass.nested_attributes_options.keys
21
+ attributes.inject({}) do |h, (k,v)|
22
+ key = nested_keys.include?(k.to_sym) ? "#{k}_attributes" : k
23
+ h[key] = v
24
+ h
25
+ end.with_indifferent_access
26
+ end
27
+
28
+ private
29
+
30
+ def set_content_type
31
+ content_type = case params[:format]
32
+ when "json"
33
+ "application/json"
34
+ when "xml"
35
+ "text/xml"
36
+ end
37
+ headers["Content-Type"] = content_type
38
+ end
39
+
40
+ def check_for_api_key
41
+ render "spree/api/v1/errors/must_specify_api_key", :status => 401 and return if api_key.blank?
42
+ end
43
+
44
+ def authenticate_user
45
+ if requires_authentication? || api_key.present?
46
+ unless @current_api_user = Spree.user_class.find_by_spree_api_key(api_key)
47
+ render "spree/api/v1/errors/invalid_api_key", :status => 401 and return
48
+ end
49
+ else
50
+ # Effectively, an anonymous user
51
+ @current_api_user = Spree.user_class.new
52
+ end
53
+ end
54
+
55
+ def unauthorized
56
+ render "spree/api/v1/errors/unauthorized", :status => 401 and return
57
+ end
58
+
59
+ def requires_authentication?
60
+ Spree::Api::Config[:requires_authentication]
61
+ end
62
+
63
+ def not_found
64
+ render "spree/api/v1/errors/not_found", :status => 404 and return
65
+ end
66
+
67
+ def error_during_processing(exception)
68
+ render :text => { exception: exception.message }.to_json,
69
+ :status => 422 and return
70
+ end
71
+
72
+ def current_ability
73
+ Spree::Ability.new(current_api_user)
74
+ end
75
+
76
+ def invalid_resource!(resource)
77
+ @resource = resource
78
+ render "spree/api/v1/errors/invalid_resource", :status => 422
79
+ end
80
+
81
+ def api_key
82
+ request.headers["X-Spree-Token"] || params[:token]
83
+ end
84
+ helper_method :api_key
85
+
86
+ def find_product(id)
87
+ begin
88
+ product_scope.find_by_permalink!(id.to_s)
89
+ rescue ActiveRecord::RecordNotFound
90
+ product_scope.find(id)
91
+ end
92
+ end
93
+
94
+ def product_scope
95
+ if current_api_user.has_spree_role?("admin")
96
+ scope = Product
97
+ unless params[:show_deleted]
98
+ scope = scope.not_deleted
99
+ end
100
+ else
101
+ scope = Product.active
102
+ end
103
+
104
+ scope.includes(:master)
105
+ end
106
+
107
+ end
108
+ end
109
+ end
110
+ end
111
+
@@ -0,0 +1,50 @@
1
+ module Spree
2
+ module Api
3
+ module V1
4
+ class InventoryUnitsController < Spree::Api::V1::BaseController
5
+ before_filter :prepare_event, :only => :update
6
+
7
+ def show
8
+ @inventory_unit = inventory_unit
9
+ end
10
+
11
+ def update
12
+ authorize! :update, Order
13
+
14
+ inventory_unit.transaction do
15
+ if inventory_unit.update_attributes(params[:inventory_unit])
16
+ fire
17
+ render :show, :status => 200
18
+ else
19
+ invalid_resource!(inventory_unit)
20
+ end
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def inventory_unit
27
+ @inventory_unit ||= InventoryUnit.find(params[:id])
28
+ end
29
+
30
+ def prepare_event
31
+ return unless @event = params[:fire]
32
+
33
+ can_event = "can_#{@event}?"
34
+
35
+ unless inventory_unit.respond_to?(can_event) &&
36
+ inventory_unit.send(can_event)
37
+ render :text => { exception: "cannot transition to #{@event}" }.to_json,
38
+ :status => 200
39
+ false
40
+ end
41
+ end
42
+
43
+ def fire
44
+ inventory_unit.send("#{@event}!") if @event
45
+ end
46
+
47
+ end
48
+ end
49
+ end
50
+ end
@@ -1,15 +1,19 @@
1
1
  module Spree
2
2
  module Api
3
3
  class VariantsController < Spree::Api::BaseController
4
+ respond_to :json
5
+
4
6
  before_filter :product
5
7
 
6
8
  def index
7
9
  @variants = scope.includes(:option_values).ransack(params[:q]).result.
8
10
  page(params[:page]).per(params[:per_page])
11
+ respond_with(@variants)
9
12
  end
10
13
 
11
14
  def show
12
15
  @variant = scope.includes(:option_values).find(params[:id])
16
+ respond_with(@variant)
13
17
  end
14
18
 
15
19
  def new
@@ -19,7 +23,7 @@ module Spree
19
23
  authorize! :create, Variant
20
24
  @variant = scope.new(params[:product])
21
25
  if @variant.save
22
- render :show, :status => 201
26
+ respond_with(@variant, :status => 201, :default_template => :show)
23
27
  else
24
28
  invalid_resource!(@variant)
25
29
  end
@@ -29,7 +33,7 @@ module Spree
29
33
  authorize! :update, Variant
30
34
  @variant = scope.find(params[:id])
31
35
  if @variant.update_attributes(params[:variant])
32
- render :show, :status => 200
36
+ respond_with(@variant, :status => 200, :default_template => :show)
33
37
  else
34
38
  invalid_resource!(@product)
35
39
  end
@@ -39,7 +43,7 @@ module Spree
39
43
  authorize! :delete, Variant
40
44
  @variant = scope.find(params[:id])
41
45
  @variant.destroy
42
- render :text => nil, :status => 204
46
+ respond_with(@variant, :status => 204)
43
47
  end
44
48
 
45
49
  private
@@ -1,19 +1,22 @@
1
1
  module Spree
2
2
  module Api
3
3
  class ZonesController < Spree::Api::BaseController
4
+ respond_to :json
5
+
4
6
  def index
5
7
  @zones = Zone.order('name ASC').ransack(params[:q]).result.page(params[:page]).per(params[:per_page])
8
+ respond_with(@zones)
6
9
  end
7
10
 
8
11
  def show
9
- zone
12
+ respond_with(zone)
10
13
  end
11
14
 
12
15
  def create
13
16
  authorize! :create, Zone
14
17
  @zone = Zone.new(map_nested_attributes_keys(Spree::Zone, params[:zone]))
15
18
  if @zone.save
16
- render :show, :status => 201
19
+ respond_with(@zone, :status => 201, :default_template => :show)
17
20
  else
18
21
  invalid_resource!(@zone)
19
22
  end
@@ -22,16 +25,16 @@ module Spree
22
25
  def update
23
26
  authorize! :update, Zone
24
27
  if zone.update_attributes(map_nested_attributes_keys(Spree::Zone, params[:zone]))
25
- render :show, :status => 200
28
+ respond_with(zone, :status => 200, :default_template => :show)
26
29
  else
27
- invalid_resource!(@zone)
30
+ invalid_resource!(zone)
28
31
  end
29
32
  end
30
33
 
31
34
  def destroy
32
35
  authorize! :delete, Zone
33
36
  zone.destroy
34
- render :text => nil, :status => 204
37
+ respond_with(zone, :status => 204)
35
38
  end
36
39
 
37
40
  private
@@ -64,6 +64,11 @@ module Spree
64
64
  [:id, :name, :permalink, :position, :parent_id, :taxonomy_id]
65
65
  end
66
66
 
67
+ def inventory_unit_attributes
68
+ [:id, :lock_version, :state, :variant_id, :order_id,
69
+ :shipment_id, :return_authorization_id]
70
+ end
71
+
67
72
  def return_authorization_attributes
68
73
  [:id, :number, :state, :amount, :order_id, :reason, :created_at, :updated_at]
69
74
  end
@@ -0,0 +1,2 @@
1
+ object @inventory_unit
2
+ attributes *inventory_unit_attributes
data/config/routes.rb CHANGED
@@ -8,7 +8,7 @@ Spree::Core::Engine.routes.prepend do
8
8
  end
9
9
  end
10
10
 
11
- namespace :api do
11
+ namespace :api, :defaults => { :format => 'json' } do
12
12
  resources :products do
13
13
  resources :variants
14
14
  resources :product_properties
@@ -52,5 +52,6 @@ Spree::Core::Engine.routes.prepend do
52
52
  resources :taxonomies do
53
53
  resources :taxons
54
54
  end
55
+ resources :inventory_units, :only => [:show, :update]
55
56
  end
56
57
  end
@@ -0,0 +1,11 @@
1
+ require 'spree/api/responders/rabl_template'
2
+
3
+ module Spree
4
+ module Api
5
+ module Responders
6
+ class AppResponder < ActionController::Responder
7
+ include RablTemplate
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,22 @@
1
+ module Spree
2
+ module Api
3
+ module Responders
4
+ module RablTemplate
5
+ def to_format
6
+ if template
7
+ render template.to_sym, :status => options[:status] || 200
8
+ else
9
+ super
10
+ end
11
+
12
+ rescue ActionView::MissingTemplate => e
13
+ api_behavior(e)
14
+ end
15
+
16
+ def template
17
+ request.headers['X-Spree-Template'] || controller.params[:template] || options[:default_template]
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
data/lib/spree_api.rb CHANGED
@@ -1,2 +1,3 @@
1
1
  require 'spree/api'
2
+ require 'spree/api/responders'
2
3
  require 'versioncake'
@@ -28,6 +28,13 @@ describe Spree::Api::BaseController do
28
28
  end
29
29
  end
30
30
 
31
+ it 'handles exceptions' do
32
+ subject.should_receive(:authenticate_user).and_return(true)
33
+ subject.should_receive(:index).and_raise(Exception.new("no joy"))
34
+ get :index, :token => "fake_key"
35
+ json_response.should == { "exception" => "no joy" }
36
+ end
37
+
31
38
  it "maps symantec keys to nested_attributes keys" do
32
39
  klass = stub(:nested_attributes_options => { :line_items => {},
33
40
  :bill_address => {} })
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ describe Api::V1::InventoryUnitsController do
5
+ render_views
6
+
7
+ before do
8
+ stub_authentication!
9
+ @inventory_unit = create(:inventory_unit)
10
+ end
11
+
12
+ it "gets an inventory unit" do
13
+ api_get :show, :id => @inventory_unit.id
14
+ json_response['state'].should eq @inventory_unit.state
15
+ end
16
+
17
+ it "updates an inventory unit (only shipment is accessable by default)" do
18
+ api_put :update, :id => @inventory_unit.id,
19
+ :inventory_unit => { :shipment => nil }
20
+ json_response['shipment_id'].should be_nil
21
+ end
22
+
23
+ context 'fires state event' do
24
+ it 'if supplied with :fire param' do
25
+ api_put :update, :id => @inventory_unit.id,
26
+ :fire => 'ship',
27
+ :inventory_unit => { :shipment => nil }
28
+
29
+ json_response['state'].should eq 'shipped'
30
+ end
31
+
32
+ it 'and returns exception if cannot fire' do
33
+ api_put :update, :id => @inventory_unit.id,
34
+ :fire => 'return'
35
+ json_response['exception'].should match /cannot transition to return/
36
+ end
37
+
38
+ it 'and returns exception bad state' do
39
+ api_put :update, :id => @inventory_unit.id,
40
+ :fire => 'bad'
41
+ json_response['exception'].should match /cannot transition to bad/
42
+ end
43
+ end
44
+
45
+ end
46
+ end
@@ -38,6 +38,28 @@ module Spree
38
38
  json_response['zone_members'].size.should eq @zone.zone_members.count
39
39
  end
40
40
 
41
+ context "specifying a rabl template to use" do
42
+ before do
43
+ Spree::Api::ZonesController.class_eval do
44
+ def custom_show
45
+ respond_with(zone)
46
+ end
47
+ end
48
+ end
49
+
50
+ it "uses the specified template" do
51
+ request.env['X-Spree-Template'] = 'show'
52
+ api_get :custom_show, :id => @zone.id
53
+ response.should render_template('spree/api/zones/show')
54
+ end
55
+
56
+ it "falls back to the default template if the specified template does not exist" do
57
+ request.env['X-Spree-Template'] = 'invoice'
58
+ api_get :show, :id => @zone.id
59
+ response.should render_template('spree/api/zones/show')
60
+ end
61
+ end
62
+
41
63
  context "as an admin" do
42
64
  sign_in_as_admin!
43
65
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0.rc1
4
+ version: 1.3.0.rc2
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-04 00:00:00.000000000 Z
12
+ date: 2012-12-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: spree_core
@@ -18,7 +18,7 @@ dependencies:
18
18
  requirements:
19
19
  - - '='
20
20
  - !ruby/object:Gem::Version
21
- version: 1.3.0.rc1
21
+ version: 1.3.0.rc2
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - '='
28
28
  - !ruby/object:Gem::Version
29
- version: 1.3.0.rc1
29
+ version: 1.3.0.rc2
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: versioncake
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -100,6 +100,8 @@ files:
100
100
  - app/controllers/spree/api/shipments_controller.rb
101
101
  - app/controllers/spree/api/taxonomies_controller.rb
102
102
  - app/controllers/spree/api/taxons_controller.rb
103
+ - app/controllers/spree/api/v1/base_controller.rb
104
+ - app/controllers/spree/api/v1/inventory_units_controller.rb
103
105
  - app/controllers/spree/api/variants_controller.rb
104
106
  - app/controllers/spree/api/zones_controller.rb
105
107
  - app/helpers/spree/api/api_helpers.rb
@@ -156,6 +158,7 @@ files:
156
158
  - app/views/spree/api/taxons/new.v1.rabl
157
159
  - app/views/spree/api/taxons/show.v1.rabl
158
160
  - app/views/spree/api/taxons/taxons.v1.rabl
161
+ - app/views/spree/api/v1/inventory_units/show.rabl
159
162
  - app/views/spree/api/variants/index.v1.rabl
160
163
  - app/views/spree/api/variants/new.v1.rabl
161
164
  - app/views/spree/api/variants/show.v1.rabl
@@ -171,6 +174,8 @@ files:
171
174
  - lib/spree/api.rb
172
175
  - lib/spree/api/controller_setup.rb
173
176
  - lib/spree/api/engine.rb
177
+ - lib/spree/api/responders.rb
178
+ - lib/spree/api/responders/rabl_template.rb
174
179
  - lib/spree/api/testing_support/helpers.rb
175
180
  - lib/spree/api/testing_support/setup.rb
176
181
  - lib/spree/api/version.rb
@@ -190,6 +195,7 @@ files:
190
195
  - spec/controllers/spree/api/taxonomies_controller_spec.rb
191
196
  - spec/controllers/spree/api/taxons_controller_spec.rb
192
197
  - spec/controllers/spree/api/unauthenticated_products_controller_spec.rb
198
+ - spec/controllers/spree/api/v1/inventory_units_controller_spec.rb
193
199
  - spec/controllers/spree/api/variants_controller_spec.rb
194
200
  - spec/controllers/spree/api/zones_controller_spec.rb
195
201
  - spec/fixtures/thinking-cat.jpg
@@ -215,7 +221,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
215
221
  version: '0'
216
222
  segments:
217
223
  - 0
218
- hash: 1028675823196415570
224
+ hash: 1644200171498071678
219
225
  required_rubygems_version: !ruby/object:Gem::Requirement
220
226
  none: false
221
227
  requirements:
@@ -243,6 +249,7 @@ test_files:
243
249
  - spec/controllers/spree/api/taxonomies_controller_spec.rb
244
250
  - spec/controllers/spree/api/taxons_controller_spec.rb
245
251
  - spec/controllers/spree/api/unauthenticated_products_controller_spec.rb
252
+ - spec/controllers/spree/api/v1/inventory_units_controller_spec.rb
246
253
  - spec/controllers/spree/api/variants_controller_spec.rb
247
254
  - spec/controllers/spree/api/zones_controller_spec.rb
248
255
  - spec/fixtures/thinking-cat.jpg