spree_api 1.3.0.rc1 → 1.3.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
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