spree_api 1.3.5 → 2.0.0.rc1

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 (91) hide show
  1. checksums.yaml +14 -6
  2. data/Rakefile +1 -1
  3. data/app/controllers/spree/api/addresses_controller.rb +0 -1
  4. data/app/controllers/spree/api/base_controller.rb +21 -9
  5. data/app/controllers/spree/api/checkouts_controller.rb +40 -20
  6. data/app/controllers/spree/api/countries_controller.rb +0 -1
  7. data/app/controllers/spree/api/inventory_units_controller.rb +1 -1
  8. data/app/controllers/spree/api/option_types_controller.rb +46 -0
  9. data/app/controllers/spree/api/option_values_controller.rb +56 -0
  10. data/app/controllers/spree/api/orders_controller.rb +1 -21
  11. data/app/controllers/spree/api/product_properties_controller.rb +0 -1
  12. data/app/controllers/spree/api/products_controller.rb +12 -27
  13. data/app/controllers/spree/api/properties_controller.rb +61 -0
  14. data/app/controllers/spree/api/shipments_controller.rb +51 -1
  15. data/app/controllers/spree/api/states_controller.rb +32 -0
  16. data/app/controllers/spree/api/stock_items_controller.rb +70 -0
  17. data/app/controllers/spree/api/stock_locations_controller.rb +45 -0
  18. data/app/controllers/spree/api/stock_movements_controller.rb +55 -0
  19. data/app/controllers/spree/api/taxonomies_controller.rb +5 -0
  20. data/app/controllers/spree/api/taxons_controller.rb +16 -2
  21. data/app/controllers/spree/api/variants_controller.rb +1 -1
  22. data/app/controllers/spree/api/zones_controller.rb +0 -1
  23. data/app/helpers/spree/api/api_helpers.rb +34 -7
  24. data/app/models/spree/api_configuration.rb +1 -2
  25. data/app/models/spree/line_item_decorator.rb +1 -1
  26. data/app/models/spree/order_decorator.rb +6 -169
  27. data/app/overrides/api_admin_user_edit_form.rb +7 -6
  28. data/app/views/spree/admin/users/_api_fields.html.erb +7 -8
  29. data/app/views/spree/api/addresses/show.v1.rabl +2 -2
  30. data/app/views/spree/api/adjustments/show.v1.rabl +2 -0
  31. data/app/views/spree/api/credit_cards/show.v1.rabl +2 -0
  32. data/app/views/spree/api/option_types/index.v1.rabl +3 -0
  33. data/app/views/spree/api/option_types/show.v1.rabl +5 -0
  34. data/app/views/spree/api/option_values/index.v1.rabl +3 -0
  35. data/app/views/spree/api/option_values/show.v1.rabl +2 -0
  36. data/app/views/spree/api/orders/could_not_apply_coupon.v1.rabl +2 -0
  37. data/app/views/spree/api/orders/delivery.v1.rabl +2 -2
  38. data/app/views/spree/api/orders/payment.v1.rabl +3 -0
  39. data/app/views/spree/api/orders/show.v1.rabl +8 -0
  40. data/app/views/spree/api/properties/index.v1.rabl +7 -0
  41. data/app/views/spree/api/properties/new.v1.rabl +2 -0
  42. data/app/views/spree/api/properties/show.v1.rabl +2 -0
  43. data/app/views/spree/api/shared/stock_location_required.v1.rabl +2 -0
  44. data/app/views/spree/api/shipments/show.v1.rabl +7 -0
  45. data/app/views/spree/api/states/index.v1.rabl +14 -0
  46. data/app/views/spree/api/states/show.v1.rabl +2 -0
  47. data/app/views/spree/api/stock_items/index.v1.rabl +7 -0
  48. data/app/views/spree/api/stock_items/show.v1.rabl +5 -0
  49. data/app/views/spree/api/stock_locations/index.v1.rabl +7 -0
  50. data/app/views/spree/api/stock_locations/show.v1.rabl +8 -0
  51. data/app/views/spree/api/stock_movements/index.v1.rabl +7 -0
  52. data/app/views/spree/api/stock_movements/show.v1.rabl +5 -0
  53. data/app/views/spree/api/taxonomies/jstree.rabl +8 -0
  54. data/app/views/spree/api/taxons/jstree.rabl +8 -0
  55. data/app/views/spree/api/variants/index.v1.rabl +14 -1
  56. data/app/views/spree/api/variants/variant.v1.rabl +0 -4
  57. data/config/locales/en.yml +1 -0
  58. data/config/routes.rb +29 -3
  59. data/lib/spree/api.rb +0 -2
  60. data/lib/spree/api/controller_setup.rb +6 -1
  61. data/lib/spree/api/testing_support/helpers.rb +1 -1
  62. data/lib/spree/api/testing_support/setup.rb +13 -0
  63. data/spec/controllers/spree/api/base_controller_spec.rb +14 -1
  64. data/spec/controllers/spree/api/checkouts_controller_spec.rb +59 -28
  65. data/spec/controllers/spree/api/line_items_controller_spec.rb +1 -5
  66. data/spec/controllers/spree/api/option_types_controller_spec.rb +116 -0
  67. data/spec/controllers/spree/api/option_values_controller_spec.rb +128 -0
  68. data/spec/controllers/spree/api/orders_controller_spec.rb +11 -93
  69. data/spec/controllers/spree/api/product_properties_controller_spec.rb +2 -2
  70. data/spec/controllers/spree/api/products_controller_spec.rb +18 -76
  71. data/spec/controllers/spree/api/properties_controller_spec.rb +89 -0
  72. data/spec/controllers/spree/api/return_authorizations_controller_spec.rb +1 -9
  73. data/spec/controllers/spree/api/shipments_controller_spec.rb +80 -5
  74. data/spec/controllers/spree/api/states_controller_spec.rb +76 -0
  75. data/spec/controllers/spree/api/stock_items_controller_spec.rb +88 -0
  76. data/spec/controllers/spree/api/stock_locations_controller_spec.rb +86 -0
  77. data/spec/controllers/spree/api/stock_movements_controller_spec.rb +72 -0
  78. data/spec/controllers/spree/api/taxonomies_controller_spec.rb +7 -0
  79. data/spec/controllers/spree/api/taxons_controller_spec.rb +29 -2
  80. data/spec/controllers/spree/api/unauthenticated_products_controller_spec.rb +1 -1
  81. data/spec/controllers/spree/api/variants_controller_spec.rb +5 -16
  82. data/spec/fixtures/thinking-cat.jpg +0 -0
  83. data/spec/models/spree/order_spec.rb +7 -328
  84. data/spec/spec_helper.rb +18 -2
  85. data/spree_api.gemspec +2 -1
  86. metadata +67 -16
  87. data/.rspec +0 -1
  88. data/app/controllers/spree/base_controller_decorator.rb +0 -15
  89. data/app/overrides/api_key_spree_layout.rb +0 -7
  90. data/app/views/spree/api/_key.html.erb +0 -4
  91. data/db/migrate/20131017162334_add_index_to_user_spree_api_key.rb +0 -7
@@ -40,7 +40,7 @@ module Spree
40
40
  json_response['pages'].should == 2
41
41
  end
42
42
 
43
- it 'can query the results through a paramter' do
43
+ it 'can query the results through a parameter' do
44
44
  Spree::ProductProperty.last.update_attribute(:value, 'loose')
45
45
  property = Spree::ProductProperty.last
46
46
  api_get :index, :q => { :value_cont => 'loose' }
@@ -91,7 +91,7 @@ module Spree
91
91
  response.status.should == 200
92
92
  end
93
93
 
94
- it "can delete a variant" do
94
+ it "can delete a product property" do
95
95
  api_delete :destroy, :id => property_1.property_name
96
96
  response.status.should == 204
97
97
  lambda { property_1.reload }.should raise_error(ActiveRecord::RecordNotFound)
@@ -7,11 +7,7 @@ module Spree
7
7
 
8
8
  let!(:product) { create(:product) }
9
9
  let!(:inactive_product) { create(:product, :available_on => Time.now.tomorrow, :name => "inactive") }
10
- let(:attributes) { [:id, :name, :description, :price, :available_on, :permalink, :count_on_hand, :meta_description, :meta_keywords, :taxon_ids] }
11
- let(:product_hash) do
12
- { :name => "The Other Product",
13
- :price => 19.99 }
14
- end
10
+ let(:attributes) { [:id, :name, :description, :price, :available_on, :permalink, :meta_description, :meta_keywords, :taxon_ids] }
15
11
 
16
12
  before do
17
13
  stub_authentication!
@@ -26,16 +22,30 @@ module Spree
26
22
  json_response["pages"].should == 1
27
23
  end
28
24
 
25
+ it "retrieves a list of products by id" do
26
+ api_get :index, :ids => [product.id]
27
+ json_response["products"].first.should have_attributes(attributes)
28
+ json_response["count"].should == 1
29
+ json_response["current_page"].should == 1
30
+ json_response["pages"].should == 1
31
+ end
32
+
33
+ it "does not return inactive products when queried by ids" do
34
+ api_get :index, :ids => [inactive_product.id]
35
+ json_response["count"].should == 0
36
+ end
37
+
29
38
  it "does not list unavailable products" do
30
39
  api_get :index
31
40
  json_response["products"].first["name"].should_not eq("inactive")
32
41
  end
33
42
 
34
43
  context "pagination" do
44
+ default_per_page(1)
35
45
 
36
46
  it "can select the next page of products" do
37
47
  second_product = create(:product)
38
- api_get :index, :page => 2, :per_page => 1
48
+ api_get :index, :page => 2
39
49
  json_response["products"].first.should have_attributes(attributes)
40
50
  json_response["total_count"].should == 2
41
51
  json_response["current_page"].should == 2
@@ -76,7 +86,6 @@ module Spree
76
86
  json_response.should have_attributes(attributes)
77
87
  json_response['variants'].first.should have_attributes([:name,
78
88
  :is_master,
79
- :count_on_hand,
80
89
  :price,
81
90
  :images])
82
91
 
@@ -161,79 +170,12 @@ module Spree
161
170
  end
162
171
 
163
172
  it "can create a new product" do
164
- api_post :create, :product => product_hash
173
+ api_post :create, :product => { :name => "The Other Product",
174
+ :price => 19.99 }
165
175
  json_response.should have_attributes(attributes)
166
176
  response.status.should == 201
167
177
  end
168
178
 
169
- describe "creating products with" do
170
- it "embedded variants" do
171
- def attributes_for_variant
172
- h = attributes_for(:variant).except(:is_master, :product)
173
- h.delete(:option_values)
174
- h.merge({
175
- options: [
176
- { name: "size", value: "small" },
177
- { name: "color", value: "black" }
178
- ]
179
- })
180
- end
181
-
182
- attributes = product_hash
183
-
184
- attributes.merge!({
185
- shipping_category_id: 1,
186
-
187
- option_types: ['size', 'color'],
188
-
189
- variants_attributes: [
190
- attributes_for_variant,
191
- attributes_for_variant
192
- ]
193
- })
194
-
195
- api_post :create, :product => attributes
196
-
197
- expect(json_response['variants'].count).to eq(3) # 1 master + 2 variants
198
- expect(json_response['variants'][1]['option_values'][0]['name']).to eq('small')
199
- expect(json_response['variants'][1]['option_values'][0]['option_type_name']).to eq('size')
200
-
201
- expect(json_response['option_types'].count).to eq(2) # size, color
202
- end
203
-
204
- it "embedded product_properties" do
205
- attributes = product_hash
206
-
207
- attributes.merge!({
208
- shipping_category_id: 1,
209
-
210
- product_properties_attributes: [{
211
- property_name: "fabric",
212
- value: "cotton"
213
- }]
214
- })
215
-
216
- api_post :create, :product => attributes
217
-
218
- expect(json_response['product_properties'][0]['property_name']).to eq('fabric')
219
- expect(json_response['product_properties'][0]['value']).to eq('cotton')
220
- end
221
-
222
- it "option_types even if without variants" do
223
- attributes = product_hash
224
-
225
- attributes.merge!({
226
- shipping_category_id: 1,
227
-
228
- option_types: ['size', 'color']
229
- })
230
-
231
- api_post :create, :product => attributes
232
-
233
- expect(json_response['option_types'].count).to eq(2)
234
- end
235
- end
236
-
237
179
  # Regression test for #2140
238
180
  context "with authentication_required set to false" do
239
181
  before do
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+ module Spree
3
+ describe Spree::Api::PropertiesController do
4
+ render_views
5
+
6
+ let!(:property_1) { Property.create!(:name => "foo", :presentation => "Foo") }
7
+ let!(:property_2) { Property.create!(:name => "bar", :presentation => "Bar") }
8
+
9
+ let(:attributes) { [:id, :name, :presentation] }
10
+
11
+ before do
12
+ stub_authentication!
13
+ end
14
+
15
+ it "can see a list of all properties" do
16
+ api_get :index
17
+ json_response["properties"].count.should eq(2)
18
+ json_response["properties"].first.should have_attributes(attributes)
19
+ end
20
+
21
+ it "can control the page size through a parameter" do
22
+ api_get :index, :per_page => 1
23
+ json_response['properties'].count.should == 1
24
+ json_response['current_page'].should == 1
25
+ json_response['pages'].should == 2
26
+ end
27
+
28
+ it 'can query the results through a parameter' do
29
+ api_get :index, :q => { :name_cont => 'ba' }
30
+ json_response['count'].should == 1
31
+ json_response['properties'].first['presentation'].should eq property_2.presentation
32
+ end
33
+
34
+ it "can see a single property" do
35
+ api_get :show, :id => property_1.id
36
+ json_response.should have_attributes(attributes)
37
+ end
38
+
39
+ it "can see a property by name" do
40
+ api_get :show, :id => property_1.name
41
+ json_response.should have_attributes(attributes)
42
+ end
43
+
44
+ it "can learn how to create a new property" do
45
+ api_get :new
46
+ json_response["attributes"].should == attributes.map(&:to_s)
47
+ json_response["required_attributes"].should be_empty
48
+ end
49
+
50
+ it "cannot create a new property if not an admin" do
51
+ api_post :create, :property => { :name => "My Property 3" }
52
+ assert_unauthorized!
53
+ end
54
+
55
+ it "cannot update a property" do
56
+ api_put :update, :id => property_1.name, :property => { :presentation => "my value 456" }
57
+ assert_unauthorized!
58
+ end
59
+
60
+ it "cannot delete a property" do
61
+ api_delete :destroy, :id => property_1.id
62
+ assert_unauthorized!
63
+ lambda { property_1.reload }.should_not raise_error
64
+ end
65
+
66
+ context "as an admin" do
67
+ sign_in_as_admin!
68
+
69
+ it "can create a new property" do
70
+ Spree::Property.count.should == 2
71
+ api_post :create, :property => { :name => "My Property 3", :presentation => "my value 3" }
72
+ json_response.should have_attributes(attributes)
73
+ response.status.should == 201
74
+ Spree::Property.count.should == 3
75
+ end
76
+
77
+ it "can update a property" do
78
+ api_put :update, :id => property_1.name, :property => { :presentation => "my value 456" }
79
+ response.status.should == 200
80
+ end
81
+
82
+ it "can delete a property" do
83
+ api_delete :destroy, :id => property_1.name
84
+ response.status.should == 204
85
+ lambda { property_1.reload }.should raise_error(ActiveRecord::RecordNotFound)
86
+ end
87
+ end
88
+ end
89
+ end
@@ -4,15 +4,7 @@ module Spree
4
4
  describe Api::ReturnAuthorizationsController do
5
5
  render_views
6
6
 
7
- let!(:order) do
8
- order = create(:order)
9
- order.line_items << create(:line_item)
10
- order.shipments << create(:shipment, :state => 'shipped')
11
- order.finalize!
12
- order.shipments.update_all(:state => 'shipped')
13
- order.inventory_units.update_all(:state => 'shipped')
14
- order
15
- end
7
+ let!(:order) { create(:shipped_order) }
16
8
 
17
9
  let(:product) { create(:product) }
18
10
  let(:attributes) { [:id, :reason, :amount, :state] }
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  describe Spree::Api::ShipmentsController do
4
4
  render_views
5
5
  let!(:shipment) { create(:shipment) }
6
- let!(:attributes) { [:id, :tracking, :number, :cost, :shipped_at] }
6
+ let!(:attributes) { [:id, :tracking, :number, :cost, :shipped_at, :stock_location_name, :order_id, :shipping_rates, :shipping_method, :inventory_units] }
7
7
 
8
8
  before do
9
9
  stub_authentication!
@@ -24,8 +24,56 @@ describe Spree::Api::ShipmentsController do
24
24
  end
25
25
 
26
26
  context "as an admin" do
27
+ let!(:order) { shipment.order }
28
+ let!(:stock_location) { create(:stock_location_with_items) }
29
+ let!(:variant) { create(:variant) }
27
30
  sign_in_as_admin!
28
31
 
32
+ it 'can create a new shipment' do
33
+ params = {
34
+ variant_id: stock_location.stock_items.first.variant.to_param,
35
+ order_id: order.number,
36
+ stock_location_id: stock_location.to_param,
37
+ }
38
+
39
+ api_post :create, params
40
+ response.status.should == 200
41
+ json_response.should have_attributes(attributes)
42
+ end
43
+
44
+ it 'can update a shipment' do
45
+ params = {
46
+ shipment: {
47
+ stock_location_id: stock_location.to_param
48
+ }
49
+ }
50
+
51
+ api_put :update, params
52
+ response.status.should == 200
53
+ json_response['stock_location_name'].should == stock_location.name
54
+ end
55
+
56
+ it "can unlock a shipment's adjustment when updating" do
57
+ Spree::Calculator::FlatRate.any_instance.stub(:preferred_amount => 5)
58
+ adjustment = order.adjustments.create(amount: 1, label: 'shipping')
59
+ adjustment.source = shipment
60
+ adjustment.originator = shipment.shipping_method
61
+ adjustment.save!
62
+
63
+ params = {
64
+ order_id: order.number,
65
+ id: order.shipments.first.to_param,
66
+ shipment: {
67
+ unlock: 'yes'
68
+ }
69
+ }
70
+
71
+ api_put :update, params
72
+ response.status.should == 200
73
+ json_response.should have_attributes(attributes)
74
+ shipment.reload.adjustment.amount.should == 5
75
+ end
76
+
29
77
  it "can make a shipment ready" do
30
78
  Spree::Order.any_instance.stub(:paid? => true, :complete? => true)
31
79
  api_put :ready
@@ -41,17 +89,44 @@ describe Spree::Api::ShipmentsController do
41
89
  response.status.should == 422
42
90
  end
43
91
 
92
+ context 'for completed shipments' do
93
+ let(:order) { create :completed_order_with_totals }
94
+
95
+ let!(:resource_scoping) { { :order_id => order.to_param, :id => order.shipments.first.to_param } }
96
+
97
+ it 'can add a variant to a shipment' do
98
+ params = {
99
+ variant_id: variant.to_param,
100
+ quantity: 2
101
+ }
102
+ api_put :add, params
103
+ response.status.should == 200
104
+ json_response['inventory_units'].select { |h| h['variant_id'] == variant.id }.size.should == 2
105
+ end
106
+
107
+ it 'can remove a variant from a shipment' do
108
+ order.contents.add(variant, 2)
109
+
110
+ params = {
111
+ variant_id: variant.to_param,
112
+ quantity: 1
113
+ }
114
+
115
+ api_put :remove, params
116
+ response.status.should == 200
117
+ json_response['inventory_units'].select { |h| h['variant_id'] == variant.id }.size.should == 1
118
+ end
119
+ end
120
+
44
121
  context "can transition a shipment from ready to ship" do
45
122
  before do
46
123
  Spree::Order.any_instance.stub(:paid? => true, :complete? => true)
47
124
  # For the shipment notification email
48
- Spree::MailMethod.create!(
49
- :environment => Rails.env,
50
- :preferred_mails_from => "spree@example.com"
51
- )
125
+ Spree::Config[:mails_from] = "spree@example.com"
52
126
 
53
127
  shipment.update!(shipment.order)
54
128
  shipment.state.should == "ready"
129
+ Spree::ShippingRate.any_instance.stub(:cost => 5)
55
130
  end
56
131
 
57
132
  it "can transition a shipment from ready to ship" do
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ describe Api::StatesController do
5
+ render_views
6
+
7
+ let!(:state) { create(:state, :name => "Victoria") }
8
+ let(:attributes) { [:id, :name, :abbr, :country_id] }
9
+
10
+ before do
11
+ stub_authentication!
12
+ end
13
+
14
+ it "gets all states" do
15
+ api_get :index
16
+ json_response["states"].first.should have_attributes(attributes)
17
+ json_response['states'].first['name'].should eq(state.name)
18
+ end
19
+
20
+ context "pagination" do
21
+ before do
22
+ State.should_receive(:scoped).and_return(@scope = stub)
23
+ @scope.stub_chain(:ransack, :result, :includes, :order).and_return(@scope)
24
+ end
25
+
26
+ it "does not paginate states results when asked not to do so" do
27
+ @scope.should_not_receive(:page)
28
+ @scope.should_not_receive(:per)
29
+ api_get :index
30
+ end
31
+
32
+ it "paginates when page parameter is passed through" do
33
+ @scope.should_receive(:page).with(1).and_return(@scope)
34
+ @scope.should_receive(:per).with(nil)
35
+ api_get :index, :page => 1
36
+ end
37
+
38
+ it "paginates when per_page parameter is passed through" do
39
+ @scope.should_receive(:page).with(nil).and_return(@scope)
40
+ @scope.should_receive(:per).with(25)
41
+ api_get :index, :per_page => 25
42
+ end
43
+ end
44
+
45
+
46
+ context "with two states" do
47
+ before { create(:state, :name => "New South Wales") }
48
+
49
+ it "gets all states for a country" do
50
+ country = create(:country, :states_required => true)
51
+ state.country = country
52
+ state.save
53
+
54
+ api_get :index, :country_id => country.id
55
+ json_response["states"].first.should have_attributes(attributes)
56
+ json_response["states"].count.should == 1
57
+ json_response["states_required"] = true
58
+ end
59
+
60
+ it "can view all states" do
61
+ api_get :index
62
+ json_response["states"].first.should have_attributes(attributes)
63
+ end
64
+
65
+ it 'can query the results through a paramter' do
66
+ api_get :index, :q => { :name_cont => 'Vic' }
67
+ json_response['states'].first['name'].should eq("Victoria")
68
+ end
69
+ end
70
+
71
+ it "can view a state" do
72
+ api_get :show, :id => state.id
73
+ json_response.should have_attributes(attributes)
74
+ end
75
+ end
76
+ end