spree_api 3.2.9 → 3.3.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.
- checksums.yaml +4 -4
- data/app/controllers/spree/api/base_controller.rb +11 -12
- data/app/controllers/spree/api/v1/checkouts_controller.rb +5 -8
- data/app/controllers/spree/api/v1/customer_returns_controller.rb +24 -0
- data/app/controllers/spree/api/v1/orders_controller.rb +13 -24
- data/app/controllers/spree/api/v1/payments_controller.rb +2 -3
- data/app/controllers/spree/api/v1/reimbursements_controller.rb +24 -0
- data/app/controllers/spree/api/v1/shipments_controller.rb +4 -4
- data/app/controllers/spree/api/v1/zones_controller.rb +8 -3
- data/app/helpers/spree/api/api_helpers.rb +13 -1
- data/app/models/concerns/spree/user_api_authentication.rb +19 -0
- data/app/models/concerns/spree/user_api_methods.rb +7 -0
- data/app/views/spree/api/v1/customer_returns/index.v1.rabl +7 -0
- data/app/views/spree/api/v1/line_items/show.v1.rabl +0 -1
- data/app/views/spree/api/v1/reimbursements/index.v1.rabl +7 -0
- data/config/initializers/user_class_extensions.rb +7 -0
- data/config/routes.rb +3 -0
- data/spec/controllers/spree/api/base_controller_spec.rb +84 -0
- data/spec/controllers/spree/api/v1/addresses_controller_spec.rb +56 -0
- data/spec/controllers/spree/api/v1/checkouts_controller_spec.rb +361 -0
- data/spec/controllers/spree/api/v1/classifications_controller_spec.rb +48 -0
- data/spec/controllers/spree/api/v1/countries_controller_spec.rb +48 -0
- data/spec/controllers/spree/api/v1/credit_cards_controller_spec.rb +80 -0
- data/spec/controllers/spree/api/v1/customer_returns_controller_spec.rb +27 -0
- data/spec/controllers/spree/api/v1/images_controller_spec.rb +114 -0
- data/spec/controllers/spree/api/v1/inventory_units_controller_spec.rb +48 -0
- data/spec/controllers/spree/api/v1/line_items_controller_spec.rb +210 -0
- data/spec/controllers/spree/api/v1/option_types_controller_spec.rb +122 -0
- data/spec/controllers/spree/api/v1/option_values_controller_spec.rb +141 -0
- data/spec/controllers/spree/api/v1/orders_controller_spec.rb +735 -0
- data/spec/controllers/spree/api/v1/payments_controller_spec.rb +234 -0
- data/spec/controllers/spree/api/v1/product_properties_controller_spec.rb +156 -0
- data/spec/controllers/spree/api/v1/products_controller_spec.rb +409 -0
- data/spec/controllers/spree/api/v1/promotion_application_spec.rb +50 -0
- data/spec/controllers/spree/api/v1/promotions_controller_spec.rb +64 -0
- data/spec/controllers/spree/api/v1/properties_controller_spec.rb +102 -0
- data/spec/controllers/spree/api/v1/reimbursements_controller_spec.rb +24 -0
- data/spec/controllers/spree/api/v1/return_authorizations_controller_spec.rb +161 -0
- data/spec/controllers/spree/api/v1/shipments_controller_spec.rb +187 -0
- data/spec/controllers/spree/api/v1/states_controller_spec.rb +86 -0
- data/spec/controllers/spree/api/v1/stock_items_controller_spec.rb +151 -0
- data/spec/controllers/spree/api/v1/stock_locations_controller_spec.rb +113 -0
- data/spec/controllers/spree/api/v1/stock_movements_controller_spec.rb +84 -0
- data/spec/controllers/spree/api/v1/stores_controller_spec.rb +133 -0
- data/spec/controllers/spree/api/v1/tags_controller_spec.rb +102 -0
- data/spec/controllers/spree/api/v1/taxonomies_controller_spec.rb +114 -0
- data/spec/controllers/spree/api/v1/taxons_controller_spec.rb +177 -0
- data/spec/controllers/spree/api/v1/unauthenticated_products_controller_spec.rb +26 -0
- data/spec/controllers/spree/api/v1/users_controller_spec.rb +153 -0
- data/spec/controllers/spree/api/v1/variants_controller_spec.rb +205 -0
- data/spec/controllers/spree/api/v1/zones_controller_spec.rb +91 -0
- data/spec/models/spree/legacy_user_spec.rb +19 -0
- data/spec/requests/rabl_cache_spec.rb +32 -0
- data/spec/requests/ransackable_attributes_spec.rb +79 -0
- data/spec/requests/version_spec.rb +19 -0
- data/spec/shared_examples/protect_product_actions.rb +17 -0
- data/spec/spec_helper.rb +63 -0
- data/spec/support/controller_hacks.rb +40 -0
- data/spec/support/database_cleaner.rb +14 -0
- data/spec/support/have_attributes_matcher.rb +13 -0
- data/spree_api.gemspec +4 -3
- metadata +105 -13
- data/app/views/spree/api/v1/config/money.v1.rabl +0 -2
- data/app/views/spree/api/v1/config/show.v1.rabl +0 -2
@@ -0,0 +1,234 @@
|
|
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
|
@@ -0,0 +1,156 @@
|
|
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 search for product properties" do
|
52
|
+
product.product_properties.create(property_name: "Shirt Size")
|
53
|
+
product.product_properties.create(property_name: "Shirt Weight")
|
54
|
+
api_get :index, q: { property_name_cont: "size" }
|
55
|
+
expect(json_response["product_properties"].first['property_name']).to eq('Shirt Size')
|
56
|
+
expect(json_response["product_properties"].first).to have_attributes(attributes)
|
57
|
+
expect(json_response["count"]).to eq(1)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "can see a single product_property" do
|
61
|
+
api_get :show, id: property_1.property_name
|
62
|
+
expect(json_response).to have_attributes(attributes)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "can learn how to create a new product property" do
|
66
|
+
api_get :new
|
67
|
+
expect(json_response["attributes"]).to eq(attributes.map(&:to_s))
|
68
|
+
expect(json_response["required_attributes"]).to be_empty
|
69
|
+
end
|
70
|
+
|
71
|
+
it "cannot create a new product property if not an admin" do
|
72
|
+
api_post :create, product_property: { property_name: "My Property 3" }
|
73
|
+
assert_unauthorized!
|
74
|
+
end
|
75
|
+
|
76
|
+
it "cannot update a product property" do
|
77
|
+
api_put :update, id: property_1.property_name, product_property: { value: "my value 456" }
|
78
|
+
assert_unauthorized!
|
79
|
+
end
|
80
|
+
|
81
|
+
it "cannot delete a product property" do
|
82
|
+
api_delete :destroy, id: property_1.to_param, property_name: property_1.property_name
|
83
|
+
assert_unauthorized!
|
84
|
+
expect { property_1.reload }.not_to raise_error
|
85
|
+
end
|
86
|
+
|
87
|
+
context "as an admin" do
|
88
|
+
sign_in_as_admin!
|
89
|
+
|
90
|
+
it "can create a new product property" do
|
91
|
+
expect do
|
92
|
+
api_post :create, product_property: { property_name: "My Property 3", value: "my value 3" }
|
93
|
+
end.to change(product.product_properties, :count).by(1)
|
94
|
+
expect(json_response).to have_attributes(attributes)
|
95
|
+
expect(response.status).to eq(201)
|
96
|
+
end
|
97
|
+
|
98
|
+
context 'when product property does not exist' do
|
99
|
+
it 'cannot update product property and responds 404' do
|
100
|
+
api_put :update, id: 'does not exist', product_property: { value: 'new value' }
|
101
|
+
expect(response.status).to eq(404)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context 'when product property exists' do
|
106
|
+
context 'when product property is valid' do
|
107
|
+
it 'responds 200' do
|
108
|
+
api_put :update, id: property_1.property_name, product_property: { value: "my value 456" }
|
109
|
+
expect(response.status).to eq(200)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context 'when product property is invalid' do
|
114
|
+
before(:each) do
|
115
|
+
expect_any_instance_of(Spree::ProductProperty).to receive(:update_attributes).and_return false
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'responds 422' do
|
119
|
+
api_put :update, id: property_1.property_name, product_property: { value: 'hello' }
|
120
|
+
expect(response.status).to eq(422)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'when product property does not exist' do
|
126
|
+
it 'cannot delete product property and responds 404' do
|
127
|
+
api_delete :destroy, id: 'does not exist'
|
128
|
+
expect(response.status).to eq(404)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context 'when product property exists' do
|
133
|
+
it "can delete a product property" do
|
134
|
+
api_delete :destroy, id: property_1.property_name
|
135
|
+
expect(response.status).to eq(204)
|
136
|
+
expect { property_1.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
context "with product identified by id" do
|
142
|
+
let(:resource_scoping) { { product_id: product.id } }
|
143
|
+
it "can see a list of all product properties" do
|
144
|
+
api_get :index
|
145
|
+
expect(json_response["product_properties"].count).to eq 2
|
146
|
+
expect(json_response["product_properties"].first).to have_attributes(attributes)
|
147
|
+
end
|
148
|
+
|
149
|
+
it "can see a single product_property by id" do
|
150
|
+
api_get :show, id: property_1.id
|
151
|
+
expect(json_response).to have_attributes(attributes)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
end
|