spree_api 1.2.0 → 1.2.2

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