spree_api 1.2.0 → 1.2.2

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 (55) hide show
  1. data/app/controllers/spree/api/v1/addresses_controller.rb +2 -0
  2. data/app/controllers/spree/api/v1/base_controller.rb +12 -3
  3. data/app/controllers/spree/api/v1/countries_controller.rb +4 -1
  4. data/app/controllers/spree/api/v1/images_controller.rb +4 -1
  5. data/app/controllers/spree/api/v1/line_items_controller.rb +1 -1
  6. data/app/controllers/spree/api/v1/orders_controller.rb +10 -16
  7. data/app/controllers/spree/api/v1/payments_controller.rb +5 -1
  8. data/app/controllers/spree/api/v1/product_properties_controller.rb +64 -0
  9. data/app/controllers/spree/api/v1/products_controller.rb +2 -7
  10. data/app/controllers/spree/api/v1/return_authorizations_controller.rb +53 -0
  11. data/app/controllers/spree/api/v1/shipments_controller.rb +3 -0
  12. data/app/controllers/spree/api/v1/taxonomies_controller.rb +5 -2
  13. data/app/controllers/spree/api/v1/taxons_controller.rb +1 -1
  14. data/app/controllers/spree/api/v1/variants_controller.rb +21 -3
  15. data/app/controllers/spree/api/v1/zones_controller.rb +2 -2
  16. data/app/helpers/spree/api/api_helpers.rb +8 -0
  17. data/app/models/spree/api_configuration.rb +5 -0
  18. data/app/models/spree/order_decorator.rb +1 -0
  19. data/app/views/spree/api/v1/countries/index.rabl +7 -2
  20. data/app/views/spree/api/v1/countries/show.rabl +2 -2
  21. data/app/views/spree/api/v1/orders/index.rabl +1 -1
  22. data/app/views/spree/api/v1/orders/show.rabl +4 -1
  23. data/app/views/spree/api/v1/payments/index.rabl +7 -2
  24. data/app/views/spree/api/v1/product_properties/index.rabl +7 -0
  25. data/app/views/spree/api/v1/product_properties/new.rabl +2 -0
  26. data/app/views/spree/api/v1/product_properties/show.rabl +2 -0
  27. data/app/views/spree/api/v1/products/index.rabl +2 -1
  28. data/app/views/spree/api/v1/return_authorizations/index.rabl +7 -0
  29. data/app/views/spree/api/v1/return_authorizations/new.rabl +3 -0
  30. data/app/views/spree/api/v1/return_authorizations/show.rabl +2 -0
  31. data/app/views/spree/api/v1/taxonomies/index.rabl +7 -2
  32. data/app/views/spree/api/v1/variants/index.rabl +10 -3
  33. data/app/views/spree/api/v1/zones/index.rabl +7 -2
  34. data/config/routes.rb +3 -8
  35. data/lib/spree/api/engine.rb +4 -0
  36. data/spec/controllers/spree/api/v1/addresses_controller_spec.rb +29 -7
  37. data/spec/controllers/spree/api/v1/base_controller_spec.rb +1 -0
  38. data/spec/controllers/spree/api/v1/countries_controller_spec.rb +25 -1
  39. data/spec/controllers/spree/api/v1/images_controller_spec.rb +42 -21
  40. data/spec/controllers/spree/api/v1/line_items_controller_spec.rb +1 -1
  41. data/spec/controllers/spree/api/v1/orders_controller_spec.rb +51 -1
  42. data/spec/controllers/spree/api/v1/payments_controller_spec.rb +44 -3
  43. data/spec/controllers/spree/api/v1/product_properties_controller_spec.rb +117 -0
  44. data/spec/controllers/spree/api/v1/products_controller_spec.rb +33 -17
  45. data/spec/controllers/spree/api/v1/return_authorizations_controller_spec.rb +155 -0
  46. data/spec/controllers/spree/api/v1/shipments_controller_spec.rb +18 -3
  47. data/spec/controllers/spree/api/v1/taxonomies_controller_spec.rb +22 -3
  48. data/spec/controllers/spree/api/v1/taxons_controller_spec.rb +8 -3
  49. data/spec/controllers/spree/api/v1/unauthenticated_products_controller_spec.rb +26 -0
  50. data/spec/controllers/spree/api/v1/variants_controller_spec.rb +68 -4
  51. data/spec/controllers/spree/api/v1/zones_controller_spec.rb +46 -11
  52. data/spec/shared_examples/protect_product_actions.rb +17 -0
  53. data/spec/spec_helper.rb +5 -0
  54. data/spree_api.gemspec +0 -1
  55. metadata +28 -22
@@ -63,6 +63,14 @@ module Spree
63
63
  def taxon_attributes
64
64
  [:id, :name, :permalink, :position, :parent_id, :taxonomy_id]
65
65
  end
66
+
67
+ def return_authorization_attributes
68
+ [:id, :number, :state, :amount, :order_id, :reason, :created_at, :updated_at]
69
+ end
70
+
71
+ def country_attributes
72
+ [:id, :iso_name, :iso, :iso3, :name, :numcode]
73
+ end
66
74
  end
67
75
  end
68
76
  end
@@ -0,0 +1,5 @@
1
+ module Spree
2
+ class ApiConfiguration < Preferences::Configuration
3
+ preference :requires_authentication, :boolean, :default => true
4
+ end
5
+ end
@@ -1,6 +1,7 @@
1
1
  Spree::Order.class_eval do
2
2
  def self.build_from_api(user, params)
3
3
  order = create
4
+ params[:line_items_attributes] ||= []
4
5
  params[:line_items_attributes].each do |line_item|
5
6
  order.add_variant(Spree::Variant.find(line_item[:variant_id]), line_item[:quantity])
6
7
  end
@@ -1,2 +1,7 @@
1
- collection @countries
2
- extends "spree/api/v1/countries/show"
1
+ object false
2
+ child(@countries => :countries) do
3
+ attributes *country_attributes
4
+ end
5
+ node(:count) { @countries.count }
6
+ node(:current_page) { params[:page] || 1 }
7
+ node(:pages) { @countries.num_pages }
@@ -1,5 +1,5 @@
1
1
  object @country
2
- attributes :id, :iso_name, :iso, :iso3, :name, :numcode
2
+ attributes *country_attributes
3
3
  child :states => :states do
4
4
  attributes :id, :name, :abbr, :country_id
5
- end
5
+ end
@@ -1,5 +1,5 @@
1
1
  object false
2
- child(@orders) do
2
+ child(@orders => :orders) do
3
3
  attributes *order_attributes
4
4
  end
5
5
  node(:count) { @orders.count }
@@ -1,6 +1,9 @@
1
1
  object @order
2
2
  attributes *order_attributes
3
- extends "spree/api/v1/orders/#{@order.state}"
3
+
4
+ if lookup_context.find_all("spree/api/v1/orders/#{@order.state}").present?
5
+ extends "spree/api/v1/orders/#{@order.state}"
6
+ end
4
7
 
5
8
  child :billing_address => :bill_address do
6
9
  extends "spree/api/v1/addresses/show"
@@ -1,2 +1,7 @@
1
- collection @payments
2
- attributes *payment_attributes
1
+ object false
2
+ child(@payments => :payments) do
3
+ attributes *payment_attributes
4
+ end
5
+ node(:count) { @payments.count }
6
+ node(:current_page) { params[:page] || 1 }
7
+ node(:pages) { @payments.num_pages }
@@ -0,0 +1,7 @@
1
+ object false
2
+ child(@product_properties => :product_properties) do
3
+ attributes *product_property_attributes
4
+ end
5
+ node(:count) { @product_properties.count }
6
+ node(:current_page) { params[:page] || 1 }
7
+ node(:pages) { @product_properties.num_pages }
@@ -0,0 +1,2 @@
1
+ node(:attributes) { [*product_property_attributes] }
2
+ node(:required_attributes) { [] }
@@ -0,0 +1,2 @@
1
+ object @product_property
2
+ attributes *product_property_attributes
@@ -1,5 +1,6 @@
1
1
  object false
2
- node(:count) { @products.total_count }
2
+ node(:count) { @products.count }
3
+ node(:total_count) { @products.total_count }
3
4
  node(:current_page) { params[:page] ? params[:page].to_i : 1 }
4
5
  node(:pages) { @products.num_pages }
5
6
  child(@products) do
@@ -0,0 +1,7 @@
1
+ object false
2
+ child(@return_authorizations => :return_authorizations) do
3
+ attributes *return_authorization_attributes
4
+ end
5
+ node(:count) { @return_authorizations.count }
6
+ node(:current_page) { params[:page] || 1 }
7
+ node(:pages) { @return_authorizations.num_pages }
@@ -0,0 +1,3 @@
1
+ object false
2
+ node(:attributes) { [*return_authorization_attributes] }
3
+ node(:required_attributes) { required_fields_for(Spree::ReturnAuthorization) }
@@ -0,0 +1,2 @@
1
+ object @return_authorization
2
+ attributes *return_authorization_attributes
@@ -1,2 +1,7 @@
1
- collection @taxonomies
2
- extends "spree/api/v1/taxonomies/show"
1
+ object false
2
+ child(@taxonomies => :taxonomies) do
3
+ extends "spree/api/v1/taxonomies/show"
4
+ end
5
+ node(:count) { @taxonomies.count }
6
+ node(:current_page) { params[:page] || 1 }
7
+ node(:pages) { @taxonomies.num_pages }
@@ -1,3 +1,10 @@
1
- collection @variants
2
- attributes *variant_attributes
3
- child(:option_values => :option_values) { attributes *option_value_attributes }
1
+ object false
2
+ node(:count) { @variants.count }
3
+ node(:total_count) { @variants.total_count }
4
+ node(:current_page) { params[:page] ? params[:page].to_i : 1 }
5
+ node(:pages) { @variants.num_pages }
6
+
7
+ child(@variants => :variants) do
8
+ attributes *variant_attributes
9
+ child(:option_values => :option_values) { attributes *option_value_attributes }
10
+ end
@@ -1,2 +1,7 @@
1
- collection @zones
2
- extends 'spree/api/v1/zones/show'
1
+ object false
2
+ child(@zones => :zones) do
3
+ extends 'spree/api/v1/zones/show'
4
+ end
5
+ node(:count) { @zones.count }
6
+ node(:current_page) { params[:page] || 1 }
7
+ node(:pages) { @zones.num_pages }
data/config/routes.rb CHANGED
@@ -11,22 +11,16 @@ Spree::Core::Engine.routes.prepend do
11
11
  namespace :api do
12
12
  scope :module => :v1 do
13
13
  resources :products do
14
- collection do
15
- get :search
16
- end
17
-
18
14
  resources :variants
15
+ resources :product_properties
19
16
  end
20
17
 
21
18
  resources :images
22
-
23
19
  resources :variants, :only => [:index] do
24
20
  end
25
21
 
26
22
  resources :orders do
27
- collection do
28
- get :search
29
- end
23
+ resources :return_authorizations
30
24
  member do
31
25
  put :address
32
26
  put :delivery
@@ -38,6 +32,7 @@ Spree::Core::Engine.routes.prepend do
38
32
  resources :payments do
39
33
  member do
40
34
  put :authorize
35
+ put :capture
41
36
  put :purchase
42
37
  put :void
43
38
  put :credit
@@ -6,6 +6,10 @@ module Spree
6
6
  isolate_namespace Spree
7
7
  engine_name 'spree_api'
8
8
 
9
+ initializer "spree.api.environment", :before => :load_config_initializers do |app|
10
+ Spree::Api::Config = Spree::ApiConfiguration.new
11
+ end
12
+
9
13
  def self.activate
10
14
  Dir.glob(File.join(File.dirname(__FILE__), "../../../app/**/*_decorator*.rb")) do |c|
11
15
  Rails.configuration.cache_classes ? require(c) : load(c)
@@ -9,15 +9,37 @@ module Spree
9
9
  @address = create(:address)
10
10
  end
11
11
 
12
- it "gets an address" do
13
- api_get :show, :id => @address.id
14
- json_response['address']['address1'].should eq @address.address1
12
+ context "with their own address" do
13
+ before do
14
+ Address.any_instance.stub :user => current_api_user
15
+ end
16
+
17
+ it "gets an address" do
18
+ api_get :show, :id => @address.id
19
+ json_response['address']['address1'].should eq @address.address1
20
+ end
21
+
22
+ it "updates an address" do
23
+ api_put :update, :id => @address.id,
24
+ :address => { :address1 => "123 Test Lane" }
25
+ json_response['address']['address1'].should eq '123 Test Lane'
26
+ end
15
27
  end
16
28
 
17
- it "updates an address" do
18
- api_put :update, :id => @address.id,
19
- :address => { :address1 => "123 Test Lane" }
20
- json_response['address']['address1'].should eq '123 Test Lane'
29
+ context "on somebody else's address" do
30
+ before do
31
+ Address.any_instance.stub :user => stub_model(Spree::LegacyUser)
32
+ end
33
+
34
+ it "cannot retreive address information" do
35
+ api_get :show, :id => @address.id
36
+ assert_unauthorized!
37
+ end
38
+
39
+ it "cannot update address information" do
40
+ api_get :update, :id => @address.id
41
+ assert_unauthorized!
42
+ end
21
43
  end
22
44
  end
23
45
  end
@@ -1,6 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Spree::Api::V1::BaseController do
4
+ render_views
4
5
  controller(Spree::Api::V1::BaseController) do
5
6
  def index
6
7
  render :json => { "products" => [] }
@@ -12,7 +12,31 @@ module Spree
12
12
 
13
13
  it "gets all countries" do
14
14
  api_get :index
15
- json_response.first['country']['iso3'].should eq @country.iso3
15
+ json_response["countries"].first['country']['iso3'].should eq @country.iso3
16
+ end
17
+
18
+ context "with two countries" do
19
+ before { @zambia = create(:country, :name => "Zambia") }
20
+
21
+ it "can view all countries" do
22
+ api_get :index
23
+ json_response['count'].should == 2
24
+ json_response['current_page'].should == 1
25
+ json_response['pages'].should == 1
26
+ end
27
+
28
+ it 'can query the results through a paramter' do
29
+ api_get :index, :q => { :name_cont => 'zam' }
30
+ json_response['count'].should == 1
31
+ json_response['countries'].first['country']['name'].should eq @zambia.name
32
+ end
33
+
34
+ it 'can control the page size through a parameter' do
35
+ api_get :index, :per_page => 1
36
+ json_response['count'].should == 1
37
+ json_response['current_page'].should == 1
38
+ json_response['pages'].should == 2
39
+ end
16
40
  end
17
41
 
18
42
  it "includes states" do
@@ -13,32 +13,53 @@ module Spree
13
13
  stub_authentication!
14
14
  end
15
15
 
16
- it "can upload a new image for a variant" do
17
- lambda do
18
- api_post :create,
19
- :image => { :attachment => upload_image('thinking-cat.jpg'),
20
- :viewable_type => 'Spree::Variant',
21
- :viewable_id => product.master.to_param }
22
- response.status.should == 201
23
- json_response.should have_attributes(attributes)
24
- end.should change(Image, :count).by(1)
16
+ context "as an admin" do
17
+ sign_in_as_admin!
18
+
19
+ it "can upload a new image for a variant" do
20
+ lambda do
21
+ api_post :create,
22
+ :image => { :attachment => upload_image('thinking-cat.jpg'),
23
+ :viewable_type => 'Spree::Variant',
24
+ :viewable_id => product.master.to_param }
25
+ response.status.should == 201
26
+ json_response.should have_attributes(attributes)
27
+ end.should change(Image, :count).by(1)
28
+ end
29
+
30
+ context "working with an existing image" do
31
+ let!(:product_image) { product.master.images.create!(:attachment => image('thinking-cat.jpg')) }
32
+
33
+ it "can update image data" do
34
+ product_image.position.should == 1
35
+ api_post :update, :image => { :position => 2 }, :id => product_image.id
36
+ response.status.should == 200
37
+ json_response.should have_attributes(attributes)
38
+ product_image.reload.position.should == 2
39
+ end
40
+
41
+ it "can delete an image" do
42
+ api_delete :destroy, :id => product_image.id
43
+ response.status.should == 204
44
+ lambda { product_image.reload }.should raise_error(ActiveRecord::RecordNotFound)
45
+ end
46
+ end
25
47
  end
26
48
 
27
- context "working with an existing image" do
28
- let!(:product_image) { product.master.images.create!(:attachment => image('thinking-cat.jpg')) }
49
+ context "as a non-admin" do
50
+ it "cannot create an image" do
51
+ api_post :create
52
+ assert_unauthorized!
53
+ end
29
54
 
30
- it "can update image data" do
31
- product_image.position.should == 1
32
- api_post :update, :image => { :position => 2 }, :id => product_image.id
33
- response.status.should == 200
34
- json_response.should have_attributes(attributes)
35
- product_image.reload.position.should == 2
55
+ it "cannot update an image" do
56
+ api_put :update, :id => 1
57
+ assert_unauthorized!
36
58
  end
37
59
 
38
- it "can delete an image" do
39
- api_delete :destroy, :id => product_image.id
40
- response.status.should == 200
41
- lambda { product_image.reload }.should raise_error(ActiveRecord::RecordNotFound)
60
+ it "cannot delete an image" do
61
+ api_delete :destroy, :id => 1
62
+ assert_unauthorized!
42
63
  end
43
64
  end
44
65
  end
@@ -47,7 +47,7 @@ module Spree
47
47
  it "can delete a line item on the order" do
48
48
  line_item = order.line_items.first
49
49
  api_delete :destroy, :id => line_item.id
50
- response.status.should == 200
50
+ response.status.should == 204
51
51
  lambda { line_item.reload }.should raise_error(ActiveRecord::RecordNotFound)
52
52
  end
53
53
  end
@@ -28,6 +28,13 @@ module Spree
28
28
  json_response.should have_attributes(attributes)
29
29
  end
30
30
 
31
+ # Regression test for #1992
32
+ it "can view an order not in a standard state" do
33
+ Order.any_instance.stub :user => current_api_user
34
+ order.update_column(:state, 'shipped')
35
+ api_get :show, :id => order.to_param
36
+ end
37
+
31
38
  it "can not view someone else's order" do
32
39
  Order.any_instance.stub :user => stub_model(Spree::LegacyUser)
33
40
  api_get :show, :id => order.to_param
@@ -54,7 +61,7 @@ module Spree
54
61
  it "can create an order" do
55
62
  variant = create(:variant)
56
63
  api_post :create, :order => { :line_items => [{ :variant_id => variant.to_param, :quantity => 5 }] }
57
- response.status.should == 200
64
+ response.status.should == 201
58
65
  order = Order.last
59
66
  order.line_items.count.should == 1
60
67
  order.line_items.first.variant.should == variant
@@ -62,6 +69,13 @@ module Spree
62
69
  json_response["order"]["state"].should == "address"
63
70
  end
64
71
 
72
+ it "can create an order without any parameters" do
73
+ lambda { api_post :create }.should_not raise_error(NoMethodError)
74
+ response.status.should == 201
75
+ order = Order.last
76
+ json_response["order"]["state"].should == "address"
77
+ end
78
+
65
79
  context "working with an order" do
66
80
  before do
67
81
  Order.any_instance.stub :user => current_api_user
@@ -97,6 +111,15 @@ module Spree
97
111
  json_response["order"]["shipping_methods"].should_not be_empty
98
112
  end
99
113
 
114
+ it "can add just shipping address information to an order" do
115
+ api_put :address, :id => order.to_param, :shipping_address => shipping_address
116
+ response.status.should == 200
117
+ order.reload
118
+ order.shipping_address.reload
119
+ order.shipping_address.firstname.should == shipping_address[:firstname]
120
+ order.bill_address.should be_nil
121
+ end
122
+
100
123
  it "cannot use an address that has no valid shipping methods" do
101
124
  shipping_method.destroy
102
125
  api_put :address, :id => order.to_param, :shipping_address => shipping_address, :billing_address => billing_address
@@ -165,6 +188,14 @@ module Spree
165
188
  context "as an admin" do
166
189
  sign_in_as_admin!
167
190
 
191
+ context "with no orders" do
192
+ before { Spree::Order.delete_all }
193
+ it "still returns a root :orders key" do
194
+ api_get :index
195
+ json_response["orders"].should == []
196
+ end
197
+ end
198
+
168
199
  context "with two orders" do
169
200
  before { create(:order) }
170
201
 
@@ -187,6 +218,25 @@ module Spree
187
218
  end
188
219
  end
189
220
 
221
+ context "search" do
222
+ before do
223
+ create(:order)
224
+ Spree::Order.last.update_attribute(:email, 'spree@spreecommerce.com')
225
+ end
226
+
227
+ let(:expected_result) { Spree::Order.last }
228
+
229
+ it "can query the results through a parameter" do
230
+ api_get :index, :q => { :email_cont => 'spree' }
231
+ json_response["orders"].count.should == 1
232
+ json_response["orders"].first.should have_attributes(attributes)
233
+ json_response["orders"].first["order"]["email"].should == expected_result.email
234
+ json_response["count"].should == 1
235
+ json_response["current_page"].should == 1
236
+ json_response["pages"].should == 1
237
+ end
238
+ end
239
+
190
240
  context "can cancel an order" do
191
241
  before do
192
242
  order.completed_at = Time.now