spree_api 3.1.5 → 3.1.6
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.
- checksums.yaml +4 -4
- data/app/controllers/spree/api/v1/product_properties_controller.rb +7 -10
- data/app/views/spree/api/v1/countries/index.v1.rabl +1 -1
- data/app/views/spree/api/v1/credit_cards/index.v1.rabl +1 -1
- data/app/views/spree/api/v1/orders/index.v1.rabl +1 -1
- data/app/views/spree/api/v1/orders/mine.v1.rabl +1 -1
- data/app/views/spree/api/v1/payments/index.v1.rabl +1 -1
- data/app/views/spree/api/v1/product_properties/index.v1.rabl +1 -1
- data/app/views/spree/api/v1/products/index.v1.rabl +1 -1
- data/app/views/spree/api/v1/properties/index.v1.rabl +1 -1
- data/app/views/spree/api/v1/return_authorizations/index.v1.rabl +1 -1
- data/app/views/spree/api/v1/shipments/mine.v1.rabl +1 -1
- data/app/views/spree/api/v1/states/index.v1.rabl +1 -1
- data/app/views/spree/api/v1/stock_items/index.v1.rabl +1 -1
- data/app/views/spree/api/v1/stock_locations/index.v1.rabl +1 -1
- data/app/views/spree/api/v1/stock_movements/index.v1.rabl +1 -1
- data/app/views/spree/api/v1/taxonomies/index.v1.rabl +1 -1
- data/app/views/spree/api/v1/taxons/index.v1.rabl +1 -1
- data/app/views/spree/api/v1/users/index.v1.rabl +1 -1
- data/app/views/spree/api/v1/zones/index.v1.rabl +1 -1
- data/spree_api.gemspec +1 -2
- metadata +6 -88
- data/spec/controllers/spree/api/base_controller_spec.rb +0 -96
- data/spec/controllers/spree/api/v1/addresses_controller_spec.rb +0 -56
- data/spec/controllers/spree/api/v1/checkouts_controller_spec.rb +0 -363
- data/spec/controllers/spree/api/v1/classifications_controller_spec.rb +0 -48
- data/spec/controllers/spree/api/v1/countries_controller_spec.rb +0 -48
- data/spec/controllers/spree/api/v1/credit_cards_controller_spec.rb +0 -80
- data/spec/controllers/spree/api/v1/images_controller_spec.rb +0 -115
- data/spec/controllers/spree/api/v1/inventory_units_controller_spec.rb +0 -49
- data/spec/controllers/spree/api/v1/line_items_controller_spec.rb +0 -184
- data/spec/controllers/spree/api/v1/option_types_controller_spec.rb +0 -122
- data/spec/controllers/spree/api/v1/option_values_controller_spec.rb +0 -141
- data/spec/controllers/spree/api/v1/orders_controller_spec.rb +0 -735
- data/spec/controllers/spree/api/v1/payments_controller_spec.rb +0 -234
- data/spec/controllers/spree/api/v1/product_properties_controller_spec.rb +0 -116
- data/spec/controllers/spree/api/v1/products_controller_spec.rb +0 -409
- data/spec/controllers/spree/api/v1/promotion_application_spec.rb +0 -50
- data/spec/controllers/spree/api/v1/promotions_controller_spec.rb +0 -64
- data/spec/controllers/spree/api/v1/properties_controller_spec.rb +0 -102
- data/spec/controllers/spree/api/v1/return_authorizations_controller_spec.rb +0 -161
- data/spec/controllers/spree/api/v1/shipments_controller_spec.rb +0 -187
- data/spec/controllers/spree/api/v1/states_controller_spec.rb +0 -86
- data/spec/controllers/spree/api/v1/stock_items_controller_spec.rb +0 -143
- data/spec/controllers/spree/api/v1/stock_locations_controller_spec.rb +0 -113
- data/spec/controllers/spree/api/v1/stock_movements_controller_spec.rb +0 -84
- data/spec/controllers/spree/api/v1/stores_controller_spec.rb +0 -133
- data/spec/controllers/spree/api/v1/taxonomies_controller_spec.rb +0 -114
- data/spec/controllers/spree/api/v1/taxons_controller_spec.rb +0 -177
- data/spec/controllers/spree/api/v1/unauthenticated_products_controller_spec.rb +0 -26
- data/spec/controllers/spree/api/v1/users_controller_spec.rb +0 -153
- data/spec/controllers/spree/api/v1/variants_controller_spec.rb +0 -205
- data/spec/controllers/spree/api/v1/zones_controller_spec.rb +0 -91
- data/spec/fixtures/thinking-cat.jpg +0 -0
- data/spec/models/spree/legacy_user_spec.rb +0 -19
- data/spec/requests/rabl_cache_spec.rb +0 -32
- data/spec/requests/ransackable_attributes_spec.rb +0 -79
- data/spec/requests/version_spec.rb +0 -19
- data/spec/shared_examples/protect_product_actions.rb +0 -17
- data/spec/spec_helper.rb +0 -55
- data/spec/support/controller_hacks.rb +0 -33
- data/spec/support/database_cleaner.rb +0 -14
- data/spec/support/have_attributes_matcher.rb +0 -13
@@ -1,234 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Spree
|
4
|
-
describe Api::V1::PaymentsController, :type => :controller do
|
5
|
-
render_views
|
6
|
-
let!(:order) { create(:order) }
|
7
|
-
let!(:payment) { create(:payment, :order => order) }
|
8
|
-
let!(:attributes) { [:id, :source_type, :source_id, :amount, :display_amount,
|
9
|
-
:payment_method_id, :state, :avs_response,
|
10
|
-
:created_at, :updated_at, :number] }
|
11
|
-
|
12
|
-
let(:resource_scoping) { { :order_id => order.to_param } }
|
13
|
-
|
14
|
-
before do
|
15
|
-
stub_authentication!
|
16
|
-
end
|
17
|
-
|
18
|
-
context "as a user" do
|
19
|
-
context "when the order belongs to the user" do
|
20
|
-
before do
|
21
|
-
allow_any_instance_of(Order).to receive_messages :user => current_api_user
|
22
|
-
end
|
23
|
-
|
24
|
-
it "can view the payments for their order" do
|
25
|
-
api_get :index
|
26
|
-
expect(json_response["payments"].first).to have_attributes(attributes)
|
27
|
-
end
|
28
|
-
|
29
|
-
it "can learn how to create a new payment" do
|
30
|
-
api_get :new
|
31
|
-
expect(json_response["attributes"]).to eq(attributes.map(&:to_s))
|
32
|
-
expect(json_response["payment_methods"]).not_to be_empty
|
33
|
-
expect(json_response["payment_methods"].first).to have_attributes([:id, :name, :description])
|
34
|
-
end
|
35
|
-
|
36
|
-
it "can create a new payment" do
|
37
|
-
api_post :create, :payment => { :payment_method_id => PaymentMethod.first.id, :amount => 50 }
|
38
|
-
expect(response.status).to eq(201)
|
39
|
-
expect(json_response).to have_attributes(attributes)
|
40
|
-
end
|
41
|
-
|
42
|
-
it "can view a pre-existing payment's details" do
|
43
|
-
api_get :show, :id => payment.to_param
|
44
|
-
expect(json_response).to have_attributes(attributes)
|
45
|
-
end
|
46
|
-
|
47
|
-
it "cannot update a payment" do
|
48
|
-
api_put :update, :id => payment.to_param, :payment => { :amount => 2.01 }
|
49
|
-
assert_unauthorized!
|
50
|
-
end
|
51
|
-
|
52
|
-
it "cannot authorize a payment" do
|
53
|
-
api_put :authorize, :id => payment.to_param
|
54
|
-
assert_unauthorized!
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
context "when the order does not belong to the user" do
|
59
|
-
before do
|
60
|
-
allow_any_instance_of(Order).to receive_messages :user => stub_model(LegacyUser)
|
61
|
-
end
|
62
|
-
|
63
|
-
it "cannot view payments for somebody else's order" do
|
64
|
-
api_get :index, :order_id => order.to_param
|
65
|
-
assert_unauthorized!
|
66
|
-
end
|
67
|
-
|
68
|
-
it "can view the payments for an order given the order token" do
|
69
|
-
api_get :index, :order_id => order.to_param, :order_token => order.guest_token
|
70
|
-
expect(json_response["payments"].first).to have_attributes(attributes)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
context "as an admin" do
|
76
|
-
sign_in_as_admin!
|
77
|
-
|
78
|
-
it "can view the payments on any order" do
|
79
|
-
api_get :index
|
80
|
-
expect(response.status).to eq(200)
|
81
|
-
expect(json_response["payments"].first).to have_attributes(attributes)
|
82
|
-
end
|
83
|
-
|
84
|
-
context "multiple payments" do
|
85
|
-
before { @payment = create(:payment, :order => order) }
|
86
|
-
|
87
|
-
it "can view all payments on an order" do
|
88
|
-
api_get :index
|
89
|
-
expect(json_response["count"]).to eq(2)
|
90
|
-
end
|
91
|
-
|
92
|
-
it 'can control the page size through a parameter' do
|
93
|
-
api_get :index, :per_page => 1
|
94
|
-
expect(json_response['count']).to eq(1)
|
95
|
-
expect(json_response['current_page']).to eq(1)
|
96
|
-
expect(json_response['pages']).to eq(2)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
context "for a given payment" do
|
101
|
-
context "updating" do
|
102
|
-
context "when the state is checkout" do
|
103
|
-
it "can update" do
|
104
|
-
payment.update_attributes(state: 'checkout')
|
105
|
-
api_put(:update, id: payment.to_param, payment: { amount: 2.01 })
|
106
|
-
expect(response.status).to be(200)
|
107
|
-
expect(payment.reload.amount).to eq(2.01)
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
context "when the state is pending" do
|
112
|
-
it "can update" do
|
113
|
-
payment.update_attributes(state: 'pending')
|
114
|
-
api_put(:update, id: payment.to_param, payment: { amount: 2.01 })
|
115
|
-
expect(response.status).to be(200)
|
116
|
-
expect(payment.reload.amount).to eq(2.01)
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
context "update fails" do
|
121
|
-
it "returns a 422 status when the amount is invalid" do
|
122
|
-
payment.update_attributes(state: 'pending')
|
123
|
-
api_put(:update, id: payment.to_param, payment: { amount: 'invalid' })
|
124
|
-
expect(response.status).to be(422)
|
125
|
-
expect(json_response['error']).to eql('Invalid resource. Please fix errors and try again.')
|
126
|
-
end
|
127
|
-
|
128
|
-
it "returns a 403 status when the payment is not pending" do
|
129
|
-
payment.update_attributes(state: 'completed')
|
130
|
-
api_put(:update, id: payment.to_param, payment: { amount: 2.01 })
|
131
|
-
expect(response.status).to be(403)
|
132
|
-
expect(json_response['error']).to eql('This payment cannot be updated because it is completed.')
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
context "authorizing" do
|
138
|
-
it "can authorize" do
|
139
|
-
api_put :authorize, :id => payment.to_param
|
140
|
-
expect(response.status).to eq(200)
|
141
|
-
expect(payment.reload.state).to eq("pending")
|
142
|
-
end
|
143
|
-
|
144
|
-
context "authorization fails" do
|
145
|
-
before do
|
146
|
-
fake_response = double(:success? => false, :to_s => "Could not authorize card")
|
147
|
-
expect_any_instance_of(Spree::Gateway::Bogus).to receive(:authorize).and_return(fake_response)
|
148
|
-
api_put :authorize, :id => payment.to_param
|
149
|
-
end
|
150
|
-
|
151
|
-
it "returns a 422 status" do
|
152
|
-
expect(response.status).to eq(422)
|
153
|
-
expect(json_response["error"]).to eq "Invalid resource. Please fix errors and try again."
|
154
|
-
expect(json_response["errors"]["base"][0]).to eq "Could not authorize card"
|
155
|
-
end
|
156
|
-
|
157
|
-
it "does not raise a stack level error" do
|
158
|
-
skip "Investigate why a payment.reload after the request raises 'stack level too deep'"
|
159
|
-
expect(payment.reload.state).to eq("failed")
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
context "capturing" do
|
165
|
-
it "can capture" do
|
166
|
-
api_put :capture, :id => payment.to_param
|
167
|
-
expect(response.status).to eq(200)
|
168
|
-
expect(payment.reload.state).to eq("completed")
|
169
|
-
end
|
170
|
-
|
171
|
-
context "capturing fails" do
|
172
|
-
before do
|
173
|
-
fake_response = double(:success? => false, :to_s => "Insufficient funds")
|
174
|
-
expect_any_instance_of(Spree::Gateway::Bogus).to receive(:capture).and_return(fake_response)
|
175
|
-
end
|
176
|
-
|
177
|
-
it "returns a 422 status" do
|
178
|
-
api_put :capture, :id => payment.to_param
|
179
|
-
expect(response.status).to eq(422)
|
180
|
-
expect(json_response["error"]).to eq "Invalid resource. Please fix errors and try again."
|
181
|
-
expect(json_response["errors"]["base"][0]).to eq "Insufficient funds"
|
182
|
-
end
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
context "purchasing" do
|
187
|
-
it "can purchase" do
|
188
|
-
api_put :purchase, :id => payment.to_param
|
189
|
-
expect(response.status).to eq(200)
|
190
|
-
expect(payment.reload.state).to eq("completed")
|
191
|
-
end
|
192
|
-
|
193
|
-
context "purchasing fails" do
|
194
|
-
before do
|
195
|
-
fake_response = double(:success? => false, :to_s => "Insufficient funds")
|
196
|
-
expect_any_instance_of(Spree::Gateway::Bogus).to receive(:purchase).and_return(fake_response)
|
197
|
-
end
|
198
|
-
|
199
|
-
it "returns a 422 status" do
|
200
|
-
api_put :purchase, :id => payment.to_param
|
201
|
-
expect(response.status).to eq(422)
|
202
|
-
expect(json_response["error"]).to eq "Invalid resource. Please fix errors and try again."
|
203
|
-
expect(json_response["errors"]["base"][0]).to eq "Insufficient funds"
|
204
|
-
end
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
context "voiding" do
|
209
|
-
it "can void" do
|
210
|
-
api_put :void, id: payment.to_param
|
211
|
-
expect(response.status).to eq 200
|
212
|
-
expect(payment.reload.state).to eq "void"
|
213
|
-
end
|
214
|
-
|
215
|
-
context "voiding fails" do
|
216
|
-
before do
|
217
|
-
fake_response = double(success?: false, to_s: "NO REFUNDS")
|
218
|
-
expect_any_instance_of(Spree::Gateway::Bogus).to receive(:void).and_return(fake_response)
|
219
|
-
end
|
220
|
-
|
221
|
-
it "returns a 422 status" do
|
222
|
-
api_put :void, id: payment.to_param
|
223
|
-
expect(response.status).to eq 422
|
224
|
-
expect(json_response["error"]).to eq "Invalid resource. Please fix errors and try again."
|
225
|
-
expect(json_response["errors"]["base"][0]).to eq "NO REFUNDS"
|
226
|
-
expect(payment.reload.state).to eq "checkout"
|
227
|
-
end
|
228
|
-
end
|
229
|
-
end
|
230
|
-
|
231
|
-
end
|
232
|
-
end
|
233
|
-
end
|
234
|
-
end
|
@@ -1,116 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'shared_examples/protect_product_actions'
|
3
|
-
|
4
|
-
module Spree
|
5
|
-
describe Api::V1::ProductPropertiesController, :type => :controller do
|
6
|
-
render_views
|
7
|
-
|
8
|
-
let!(:product) { create(:product) }
|
9
|
-
let!(:property_1) {product.product_properties.create(:property_name => "My Property 1", :value => "my value 1", :position => 0)}
|
10
|
-
let!(:property_2) {product.product_properties.create(:property_name => "My Property 2", :value => "my value 2", :position => 1)}
|
11
|
-
|
12
|
-
let(:attributes) { [:id, :product_id, :property_id, :value, :property_name] }
|
13
|
-
let(:resource_scoping) { { :product_id => product.to_param } }
|
14
|
-
|
15
|
-
before do
|
16
|
-
stub_authentication!
|
17
|
-
end
|
18
|
-
|
19
|
-
context "if product is deleted" do
|
20
|
-
before do
|
21
|
-
product.update_column(:deleted_at, 1.day.ago)
|
22
|
-
end
|
23
|
-
|
24
|
-
it "can not see a list of product properties" do
|
25
|
-
api_get :index
|
26
|
-
expect(response.status).to eq(404)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
it "can see a list of all product properties" do
|
31
|
-
api_get :index
|
32
|
-
expect(json_response["product_properties"].count).to eq 2
|
33
|
-
expect(json_response["product_properties"].first).to have_attributes(attributes)
|
34
|
-
end
|
35
|
-
|
36
|
-
it "can control the page size through a parameter" do
|
37
|
-
api_get :index, :per_page => 1
|
38
|
-
expect(json_response['product_properties'].count).to eq(1)
|
39
|
-
expect(json_response['current_page']).to eq(1)
|
40
|
-
expect(json_response['pages']).to eq(2)
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'can query the results through a parameter' do
|
44
|
-
Spree::ProductProperty.last.update_attribute(:value, 'loose')
|
45
|
-
property = Spree::ProductProperty.last
|
46
|
-
api_get :index, :q => { :value_cont => 'loose' }
|
47
|
-
expect(json_response['count']).to eq(1)
|
48
|
-
expect(json_response['product_properties'].first['value']).to eq property.value
|
49
|
-
end
|
50
|
-
|
51
|
-
it "can see a single product_property" do
|
52
|
-
api_get :show, :id => property_1.property_name
|
53
|
-
expect(json_response).to have_attributes(attributes)
|
54
|
-
end
|
55
|
-
|
56
|
-
it "can learn how to create a new product property" do
|
57
|
-
api_get :new
|
58
|
-
expect(json_response["attributes"]).to eq(attributes.map(&:to_s))
|
59
|
-
expect(json_response["required_attributes"]).to be_empty
|
60
|
-
end
|
61
|
-
|
62
|
-
it "cannot create a new product property if not an admin" do
|
63
|
-
api_post :create, :product_property => { :property_name => "My Property 3" }
|
64
|
-
assert_unauthorized!
|
65
|
-
end
|
66
|
-
|
67
|
-
it "cannot update a product property" do
|
68
|
-
api_put :update, :id => property_1.property_name, :product_property => { :value => "my value 456" }
|
69
|
-
assert_unauthorized!
|
70
|
-
end
|
71
|
-
|
72
|
-
it "cannot delete a product property" do
|
73
|
-
api_delete :destroy, id: property_1.to_param, :property_name => property_1.property_name
|
74
|
-
assert_unauthorized!
|
75
|
-
expect { property_1.reload }.not_to raise_error
|
76
|
-
end
|
77
|
-
|
78
|
-
context "as an admin" do
|
79
|
-
sign_in_as_admin!
|
80
|
-
|
81
|
-
it "can create a new product property" do
|
82
|
-
expect do
|
83
|
-
api_post :create, :product_property => { :property_name => "My Property 3", :value => "my value 3" }
|
84
|
-
end.to change(product.product_properties, :count).by(1)
|
85
|
-
expect(json_response).to have_attributes(attributes)
|
86
|
-
expect(response.status).to eq(201)
|
87
|
-
end
|
88
|
-
|
89
|
-
it "can update a product property" do
|
90
|
-
api_put :update, :id => property_1.property_name, :product_property => { :value => "my value 456" }
|
91
|
-
expect(response.status).to eq(200)
|
92
|
-
end
|
93
|
-
|
94
|
-
it "can delete a product property" do
|
95
|
-
api_delete :destroy, :id => property_1.property_name
|
96
|
-
expect(response.status).to eq(204)
|
97
|
-
expect { property_1.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
context "with product identified by id" do
|
102
|
-
let(:resource_scoping) { { :product_id => product.id } }
|
103
|
-
it "can see a list of all product properties" do
|
104
|
-
api_get :index
|
105
|
-
expect(json_response["product_properties"].count).to eq 2
|
106
|
-
expect(json_response["product_properties"].first).to have_attributes(attributes)
|
107
|
-
end
|
108
|
-
|
109
|
-
it "can see a single product_property by id" do
|
110
|
-
api_get :show, :id => property_1.id
|
111
|
-
expect(json_response).to have_attributes(attributes)
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
end
|
116
|
-
end
|
@@ -1,409 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'shared_examples/protect_product_actions'
|
3
|
-
|
4
|
-
module Spree
|
5
|
-
describe Api::V1::ProductsController, :type => :controller do
|
6
|
-
render_views
|
7
|
-
|
8
|
-
let!(:product) { create(:product) }
|
9
|
-
let!(:inactive_product) { create(:product, available_on: Time.current.tomorrow, name: "inactive") }
|
10
|
-
let(:base_attributes) { Api::ApiHelpers.product_attributes }
|
11
|
-
let(:show_attributes) { base_attributes.dup.push(:has_variants) }
|
12
|
-
let(:new_attributes) { base_attributes }
|
13
|
-
|
14
|
-
let(:product_data) do
|
15
|
-
{ name: "The Other Product",
|
16
|
-
price: 19.99,
|
17
|
-
shipping_category_id: create(:shipping_category).id }
|
18
|
-
end
|
19
|
-
let(:attributes_for_variant) do
|
20
|
-
h = attributes_for(:variant).except(:option_values, :product)
|
21
|
-
h.merge({
|
22
|
-
options: [
|
23
|
-
{ name: "size", value: "small" },
|
24
|
-
{ name: "color", value: "black" }
|
25
|
-
]
|
26
|
-
})
|
27
|
-
end
|
28
|
-
|
29
|
-
before do
|
30
|
-
stub_authentication!
|
31
|
-
end
|
32
|
-
|
33
|
-
context "as a normal user" do
|
34
|
-
context "with caching enabled" do
|
35
|
-
let!(:product_2) { create(:product) }
|
36
|
-
|
37
|
-
before do
|
38
|
-
ActionController::Base.perform_caching = true
|
39
|
-
end
|
40
|
-
|
41
|
-
it "returns unique products" do
|
42
|
-
api_get :index
|
43
|
-
product_ids = json_response["products"].map { |p| p["id"] }
|
44
|
-
expect(product_ids.uniq.count).to eq(product_ids.count)
|
45
|
-
end
|
46
|
-
|
47
|
-
after do
|
48
|
-
ActionController::Base.perform_caching = false
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
it "retrieves a list of products" do
|
53
|
-
api_get :index
|
54
|
-
expect(json_response["products"].first).to have_attributes(show_attributes)
|
55
|
-
expect(json_response["total_count"]).to eq(1)
|
56
|
-
expect(json_response["current_page"]).to eq(1)
|
57
|
-
expect(json_response["pages"]).to eq(1)
|
58
|
-
expect(json_response["per_page"]).to eq(Kaminari.config.default_per_page)
|
59
|
-
end
|
60
|
-
|
61
|
-
it "retrieves a list of products by id" do
|
62
|
-
api_get :index, :ids => [product.id]
|
63
|
-
expect(json_response["products"].first).to have_attributes(show_attributes)
|
64
|
-
expect(json_response["total_count"]).to eq(1)
|
65
|
-
expect(json_response["current_page"]).to eq(1)
|
66
|
-
expect(json_response["pages"]).to eq(1)
|
67
|
-
expect(json_response["per_page"]).to eq(Kaminari.config.default_per_page)
|
68
|
-
end
|
69
|
-
|
70
|
-
context "product has more than one price" do
|
71
|
-
before { product.master.prices.create currency: "EUR", amount: 22 }
|
72
|
-
|
73
|
-
it "returns distinct products only" do
|
74
|
-
api_get :index
|
75
|
-
expect(assigns(:products).map(&:id).uniq).to eq assigns(:products).map(&:id)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
it "retrieves a list of products by ids string" do
|
80
|
-
second_product = create(:product)
|
81
|
-
api_get :index, :ids => [product.id, second_product.id].join(",")
|
82
|
-
expect(json_response["products"].first).to have_attributes(show_attributes)
|
83
|
-
expect(json_response["products"][1]).to have_attributes(show_attributes)
|
84
|
-
expect(json_response["total_count"]).to eq(2)
|
85
|
-
expect(json_response["current_page"]).to eq(1)
|
86
|
-
expect(json_response["pages"]).to eq(1)
|
87
|
-
expect(json_response["per_page"]).to eq(Kaminari.config.default_per_page)
|
88
|
-
end
|
89
|
-
|
90
|
-
it "does not return inactive products when queried by ids" do
|
91
|
-
api_get :index, :ids => [inactive_product.id]
|
92
|
-
expect(json_response["count"]).to eq(0)
|
93
|
-
end
|
94
|
-
|
95
|
-
it "does not list unavailable products" do
|
96
|
-
api_get :index
|
97
|
-
expect(json_response["products"].first["name"]).not_to eq("inactive")
|
98
|
-
end
|
99
|
-
|
100
|
-
context "pagination" do
|
101
|
-
it "can select the next page of products" do
|
102
|
-
second_product = create(:product)
|
103
|
-
api_get :index, :page => 2, :per_page => 1
|
104
|
-
expect(json_response["products"].first).to have_attributes(show_attributes)
|
105
|
-
expect(json_response["total_count"]).to eq(2)
|
106
|
-
expect(json_response["current_page"]).to eq(2)
|
107
|
-
expect(json_response["pages"]).to eq(2)
|
108
|
-
end
|
109
|
-
|
110
|
-
it 'can control the page size through a parameter' do
|
111
|
-
create(:product)
|
112
|
-
api_get :index, :per_page => 1
|
113
|
-
expect(json_response['count']).to eq(1)
|
114
|
-
expect(json_response['total_count']).to eq(2)
|
115
|
-
expect(json_response['current_page']).to eq(1)
|
116
|
-
expect(json_response['pages']).to eq(2)
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
it "can search for products" do
|
121
|
-
create(:product, :name => "The best product in the world")
|
122
|
-
api_get :index, :q => { :name_cont => "best" }
|
123
|
-
expect(json_response["products"].first).to have_attributes(show_attributes)
|
124
|
-
expect(json_response["count"]).to eq(1)
|
125
|
-
end
|
126
|
-
|
127
|
-
it "gets a single product" do
|
128
|
-
product.master.images.create!(:attachment => image("thinking-cat.jpg"))
|
129
|
-
create(:variant, product: product)
|
130
|
-
product.variants.first.images.create!(:attachment => image("thinking-cat.jpg"))
|
131
|
-
product.set_property("spree", "rocks")
|
132
|
-
product.taxons << create(:taxon)
|
133
|
-
|
134
|
-
api_get :show, :id => product.to_param
|
135
|
-
|
136
|
-
expect(json_response).to have_attributes(show_attributes)
|
137
|
-
expect(json_response['variants'].first).to have_attributes([:name,
|
138
|
-
:is_master,
|
139
|
-
:price,
|
140
|
-
:images,
|
141
|
-
:in_stock])
|
142
|
-
|
143
|
-
expect(json_response['variants'].first['images'].first).to have_attributes([:attachment_file_name,
|
144
|
-
:attachment_width,
|
145
|
-
:attachment_height,
|
146
|
-
:attachment_content_type,
|
147
|
-
:mini_url,
|
148
|
-
:small_url,
|
149
|
-
:product_url,
|
150
|
-
:large_url])
|
151
|
-
|
152
|
-
expect(json_response["product_properties"].first).to have_attributes([:value,
|
153
|
-
:product_id,
|
154
|
-
:property_name])
|
155
|
-
|
156
|
-
expect(json_response["classifications"].first).to have_attributes([:taxon_id, :position, :taxon])
|
157
|
-
expect(json_response["classifications"].first['taxon']).to have_attributes([:id, :name, :pretty_name, :permalink, :taxonomy_id, :parent_id])
|
158
|
-
end
|
159
|
-
|
160
|
-
context "tracking is disabled" do
|
161
|
-
before { Config.track_inventory_levels = false }
|
162
|
-
|
163
|
-
it "still displays valid json with total_on_hand Float::INFINITY" do
|
164
|
-
api_get :show, :id => product.to_param
|
165
|
-
expect(response).to be_ok
|
166
|
-
expect(json_response[:total_on_hand]).to eq nil
|
167
|
-
end
|
168
|
-
|
169
|
-
after { Config.track_inventory_levels = true }
|
170
|
-
end
|
171
|
-
|
172
|
-
context "finds a product by slug first then by id" do
|
173
|
-
let!(:other_product) { create(:product, :slug => "these-are-not-the-droids-you-are-looking-for") }
|
174
|
-
|
175
|
-
before do
|
176
|
-
product.update_column(:slug, "#{other_product.id}-and-1-ways")
|
177
|
-
end
|
178
|
-
|
179
|
-
specify do
|
180
|
-
api_get :show, :id => product.to_param
|
181
|
-
expect(json_response["slug"]).to match(/and-1-ways/)
|
182
|
-
product.destroy
|
183
|
-
|
184
|
-
api_get :show, :id => other_product.id
|
185
|
-
expect(json_response["slug"]).to match(/droids/)
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
it "cannot see inactive products" do
|
190
|
-
api_get :show, :id => inactive_product.to_param
|
191
|
-
assert_not_found!
|
192
|
-
end
|
193
|
-
|
194
|
-
it "returns a 404 error when it cannot find a product" do
|
195
|
-
api_get :show, :id => "non-existant"
|
196
|
-
assert_not_found!
|
197
|
-
end
|
198
|
-
|
199
|
-
it "can learn how to create a new product" do
|
200
|
-
api_get :new
|
201
|
-
expect(json_response["attributes"]).to eq(new_attributes.map(&:to_s))
|
202
|
-
required_attributes = json_response["required_attributes"]
|
203
|
-
expect(required_attributes).to include("name")
|
204
|
-
expect(required_attributes).to include("price")
|
205
|
-
expect(required_attributes).to include("shipping_category")
|
206
|
-
end
|
207
|
-
|
208
|
-
it_behaves_like "modifying product actions are restricted"
|
209
|
-
end
|
210
|
-
|
211
|
-
context "as an admin" do
|
212
|
-
let(:taxon_1) { create(:taxon) }
|
213
|
-
let(:taxon_2) { create(:taxon) }
|
214
|
-
|
215
|
-
sign_in_as_admin!
|
216
|
-
|
217
|
-
it "can see all products" do
|
218
|
-
api_get :index
|
219
|
-
expect(json_response["products"].count).to eq(2)
|
220
|
-
expect(json_response["count"]).to eq(2)
|
221
|
-
expect(json_response["current_page"]).to eq(1)
|
222
|
-
expect(json_response["pages"]).to eq(1)
|
223
|
-
end
|
224
|
-
|
225
|
-
# Regression test for #1626
|
226
|
-
context "deleted products" do
|
227
|
-
before do
|
228
|
-
create(:product, :deleted_at => 1.day.ago)
|
229
|
-
end
|
230
|
-
|
231
|
-
it "does not include deleted products" do
|
232
|
-
api_get :index
|
233
|
-
expect(json_response["products"].count).to eq(2)
|
234
|
-
end
|
235
|
-
|
236
|
-
it "can include deleted products" do
|
237
|
-
api_get :index, :show_deleted => 1
|
238
|
-
expect(json_response["products"].count).to eq(3)
|
239
|
-
end
|
240
|
-
end
|
241
|
-
|
242
|
-
describe "creating a product" do
|
243
|
-
it "can create a new product" do
|
244
|
-
api_post :create, :product => { :name => "The Other Product",
|
245
|
-
:price => 19.99,
|
246
|
-
:shipping_category_id => create(:shipping_category).id }
|
247
|
-
expect(json_response).to have_attributes(base_attributes)
|
248
|
-
expect(response.status).to eq(201)
|
249
|
-
end
|
250
|
-
|
251
|
-
it "creates with embedded variants" do
|
252
|
-
product_data.merge!({
|
253
|
-
variants: [attributes_for_variant, attributes_for_variant]
|
254
|
-
})
|
255
|
-
|
256
|
-
api_post :create, :product => product_data
|
257
|
-
expect(response.status).to eq 201
|
258
|
-
|
259
|
-
variants = json_response['variants']
|
260
|
-
expect(variants.count).to eq(2)
|
261
|
-
expect(variants.last['option_values'][0]['name']).to eq('small')
|
262
|
-
expect(variants.last['option_values'][0]['option_type_name']).to eq('size')
|
263
|
-
|
264
|
-
expect(json_response['option_types'].count).to eq(2) # size, color
|
265
|
-
end
|
266
|
-
|
267
|
-
it "can create a new product with embedded product_properties" do
|
268
|
-
product_data.merge!({
|
269
|
-
product_properties_attributes: [{
|
270
|
-
property_name: "fabric",
|
271
|
-
value: "cotton"
|
272
|
-
}]
|
273
|
-
})
|
274
|
-
|
275
|
-
api_post :create, :product => product_data
|
276
|
-
|
277
|
-
expect(json_response['product_properties'][0]['property_name']).to eq('fabric')
|
278
|
-
expect(json_response['product_properties'][0]['value']).to eq('cotton')
|
279
|
-
end
|
280
|
-
|
281
|
-
it "can create a new product with option_types" do
|
282
|
-
product_data.merge!({
|
283
|
-
option_types: ['size', 'color']
|
284
|
-
})
|
285
|
-
|
286
|
-
api_post :create, :product => product_data
|
287
|
-
expect(json_response['option_types'].count).to eq(2)
|
288
|
-
end
|
289
|
-
|
290
|
-
it "creates product with option_types ids" do
|
291
|
-
option_type = create(:option_type)
|
292
|
-
product_data.merge!(option_type_ids: [option_type.id])
|
293
|
-
api_post :create, product: product_data
|
294
|
-
expect(json_response['option_types'].first['id']).to eq option_type.id
|
295
|
-
end
|
296
|
-
|
297
|
-
it "creates with shipping categories" do
|
298
|
-
hash = { :name => "The Other Product",
|
299
|
-
:price => 19.99,
|
300
|
-
:shipping_category => "Free Ships" }
|
301
|
-
|
302
|
-
api_post :create, :product => hash
|
303
|
-
expect(response.status).to eq 201
|
304
|
-
|
305
|
-
shipping_id = ShippingCategory.find_by_name("Free Ships").id
|
306
|
-
expect(json_response['shipping_category_id']).to eq shipping_id
|
307
|
-
end
|
308
|
-
|
309
|
-
it "puts the created product in the given taxons" do
|
310
|
-
product_data[:taxon_ids] = [taxon_1.id, taxon_2.id]
|
311
|
-
api_post :create, product: product_data
|
312
|
-
expect(json_response["taxon_ids"]).to eq([taxon_1.id, taxon_2.id])
|
313
|
-
end
|
314
|
-
|
315
|
-
# Regression test for #2140
|
316
|
-
context "with authentication_required set to false" do
|
317
|
-
before do
|
318
|
-
Spree::Api::Config.requires_authentication = false
|
319
|
-
end
|
320
|
-
|
321
|
-
after do
|
322
|
-
Spree::Api::Config.requires_authentication = true
|
323
|
-
end
|
324
|
-
|
325
|
-
it "can still create a product" do
|
326
|
-
api_post :create, :product => product_data, :token => "fake"
|
327
|
-
expect(json_response).to have_attributes(show_attributes)
|
328
|
-
expect(response.status).to eq(201)
|
329
|
-
end
|
330
|
-
end
|
331
|
-
|
332
|
-
it "cannot create a new product with invalid attributes" do
|
333
|
-
api_post :create, product: {}
|
334
|
-
expect(response.status).to eq(422)
|
335
|
-
expect(json_response["error"]).to eq("Invalid resource. Please fix errors and try again.")
|
336
|
-
errors = json_response["errors"]
|
337
|
-
errors.delete("slug") # Don't care about this one.
|
338
|
-
expect(errors.keys).to match_array(["name", "price", "shipping_category"])
|
339
|
-
end
|
340
|
-
end
|
341
|
-
|
342
|
-
context 'updating a product' do
|
343
|
-
it "can update a product" do
|
344
|
-
api_put :update, :id => product.to_param, :product => { :name => "New and Improved Product!" }
|
345
|
-
expect(response.status).to eq(200)
|
346
|
-
end
|
347
|
-
|
348
|
-
it "can create new option types on a product" do
|
349
|
-
api_put :update, :id => product.to_param, :product => { :option_types => ['shape', 'color'] }
|
350
|
-
expect(json_response['option_types'].count).to eq(2)
|
351
|
-
end
|
352
|
-
|
353
|
-
it "can create new variants on a product" do
|
354
|
-
api_put :update, :id => product.to_param, :product => { :variants => [attributes_for_variant, attributes_for_variant.merge(sku: "ABC-#{Kernel.rand(9999)}")] }
|
355
|
-
expect(response.status).to eq 200
|
356
|
-
expect(json_response['variants'].count).to eq(2) # 2 variants
|
357
|
-
|
358
|
-
variants = json_response['variants'].select { |v| !v['is_master'] }
|
359
|
-
expect(variants.last['option_values'][0]['name']).to eq('small')
|
360
|
-
expect(variants.last['option_values'][0]['option_type_name']).to eq('size')
|
361
|
-
|
362
|
-
expect(json_response['option_types'].count).to eq(2) # size, color
|
363
|
-
end
|
364
|
-
|
365
|
-
it "can update an existing variant on a product" do
|
366
|
-
variant_hash = {
|
367
|
-
:sku => '123', :price => 19.99, :options => [{:name => "size", :value => "small"}]
|
368
|
-
}
|
369
|
-
variant_id = product.variants.create!({ product: product }.merge(variant_hash)).id
|
370
|
-
|
371
|
-
api_put :update, :id => product.to_param, :product => {
|
372
|
-
:variants => [
|
373
|
-
variant_hash.merge(
|
374
|
-
:id => variant_id.to_s,
|
375
|
-
:sku => '456',
|
376
|
-
:options => [{:name => "size", :value => "large" }]
|
377
|
-
)
|
378
|
-
]
|
379
|
-
}
|
380
|
-
|
381
|
-
expect(json_response['variants'].count).to eq(1)
|
382
|
-
variants = json_response['variants'].select { |v| !v['is_master'] }
|
383
|
-
expect(variants.last['option_values'][0]['name']).to eq('large')
|
384
|
-
expect(variants.last['sku']).to eq('456')
|
385
|
-
expect(variants.count).to eq(1)
|
386
|
-
end
|
387
|
-
|
388
|
-
it "cannot update a product with an invalid attribute" do
|
389
|
-
api_put :update, :id => product.to_param, :product => { :name => "" }
|
390
|
-
expect(response.status).to eq(422)
|
391
|
-
expect(json_response["error"]).to eq("Invalid resource. Please fix errors and try again.")
|
392
|
-
expect(json_response["errors"]["name"]).to eq(["can't be blank"])
|
393
|
-
end
|
394
|
-
|
395
|
-
it "puts the updated product in the given taxons" do
|
396
|
-
api_put :update, id: product.to_param, product: { taxon_ids: [taxon_1.id, taxon_2.id] }
|
397
|
-
expect(json_response["taxon_ids"].to_set).to eql([taxon_1.id, taxon_2.id].to_set)
|
398
|
-
end
|
399
|
-
end
|
400
|
-
|
401
|
-
it "can delete a product" do
|
402
|
-
expect(product.deleted_at).to be_nil
|
403
|
-
api_delete :destroy, :id => product.to_param
|
404
|
-
expect(response.status).to eq(204)
|
405
|
-
expect(product.reload.deleted_at).not_to be_nil
|
406
|
-
end
|
407
|
-
end
|
408
|
-
end
|
409
|
-
end
|