solidus_api 1.0.0.pre
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 +7 -0
- data/.gitignore +17 -0
- data/CHANGELOG.md +1 -0
- data/Gemfile +5 -0
- data/LICENSE +27 -0
- data/Rakefile +16 -0
- data/app/controllers/spree/api/addresses_controller.rb +43 -0
- data/app/controllers/spree/api/base_controller.rb +189 -0
- data/app/controllers/spree/api/checkouts_controller.rb +133 -0
- data/app/controllers/spree/api/classifications_controller.rb +18 -0
- data/app/controllers/spree/api/config_controller.rb +6 -0
- data/app/controllers/spree/api/countries_controller.rb +23 -0
- data/app/controllers/spree/api/credit_cards_controller.rb +25 -0
- data/app/controllers/spree/api/images_controller.rb +47 -0
- data/app/controllers/spree/api/inventory_units_controller.rb +52 -0
- data/app/controllers/spree/api/line_items_controller.rb +74 -0
- data/app/controllers/spree/api/option_types_controller.rb +49 -0
- data/app/controllers/spree/api/option_values_controller.rb +58 -0
- data/app/controllers/spree/api/orders_controller.rb +155 -0
- data/app/controllers/spree/api/payments_controller.rb +81 -0
- data/app/controllers/spree/api/product_properties_controller.rb +72 -0
- data/app/controllers/spree/api/products_controller.rb +129 -0
- data/app/controllers/spree/api/promotions_controller.rb +26 -0
- data/app/controllers/spree/api/properties_controller.rb +71 -0
- data/app/controllers/spree/api/return_authorizations_controller.rb +71 -0
- data/app/controllers/spree/api/shipments_controller.rb +172 -0
- data/app/controllers/spree/api/states_controller.rb +35 -0
- data/app/controllers/spree/api/stock_items_controller.rb +84 -0
- data/app/controllers/spree/api/stock_locations_controller.rb +50 -0
- data/app/controllers/spree/api/stock_movements_controller.rb +42 -0
- data/app/controllers/spree/api/stock_transfers_controller.rb +19 -0
- data/app/controllers/spree/api/store_credit_events_controller.rb +9 -0
- data/app/controllers/spree/api/stores_controller.rb +55 -0
- data/app/controllers/spree/api/taxonomies_controller.rb +64 -0
- data/app/controllers/spree/api/taxons_controller.rb +93 -0
- data/app/controllers/spree/api/transfer_items_controller.rb +42 -0
- data/app/controllers/spree/api/users_controller.rb +56 -0
- data/app/controllers/spree/api/variants_controller.rb +75 -0
- data/app/controllers/spree/api/zones_controller.rb +50 -0
- data/app/helpers/spree/api/api_helpers.rb +190 -0
- data/app/models/spree/api_configuration.rb +5 -0
- data/app/models/spree/option_value_decorator.rb +9 -0
- data/app/views/spree/api/addresses/show.v1.rabl +10 -0
- data/app/views/spree/api/adjustments/show.v1.rabl +4 -0
- data/app/views/spree/api/config/money.v1.rabl +2 -0
- data/app/views/spree/api/config/show.v1.rabl +2 -0
- data/app/views/spree/api/countries/index.v1.rabl +7 -0
- data/app/views/spree/api/countries/show.v1.rabl +5 -0
- data/app/views/spree/api/credit_cards/index.v1.rabl +7 -0
- data/app/views/spree/api/credit_cards/show.v1.rabl +3 -0
- data/app/views/spree/api/errors/gateway_error.v1.rabl +2 -0
- data/app/views/spree/api/errors/invalid_api_key.v1.rabl +2 -0
- data/app/views/spree/api/errors/invalid_resource.v1.rabl +3 -0
- data/app/views/spree/api/errors/must_specify_api_key.v1.rabl +2 -0
- data/app/views/spree/api/errors/not_found.v1.rabl +2 -0
- data/app/views/spree/api/errors/unauthorized.v1.rabl +2 -0
- data/app/views/spree/api/errors/variant_not_in_stock_transfer.v1.rabl +2 -0
- data/app/views/spree/api/images/index.v1.rabl +4 -0
- data/app/views/spree/api/images/show.v1.rabl +6 -0
- data/app/views/spree/api/inventory_units/show.rabl +2 -0
- data/app/views/spree/api/line_items/new.v1.rabl +3 -0
- data/app/views/spree/api/line_items/show.v1.rabl +15 -0
- data/app/views/spree/api/option_types/index.v1.rabl +3 -0
- data/app/views/spree/api/option_types/show.v1.rabl +5 -0
- data/app/views/spree/api/option_values/index.v1.rabl +3 -0
- data/app/views/spree/api/option_values/show.v1.rabl +2 -0
- data/app/views/spree/api/orders/address.v1.rabl +0 -0
- data/app/views/spree/api/orders/canceled.v1.rabl +0 -0
- data/app/views/spree/api/orders/cart.v1.rabl +0 -0
- data/app/views/spree/api/orders/complete.v1.rabl +0 -0
- data/app/views/spree/api/orders/could_not_apply_coupon.v1.rabl +2 -0
- data/app/views/spree/api/orders/could_not_transition.v1.rabl +3 -0
- data/app/views/spree/api/orders/expected_total_mismatch.v1.rabl +2 -0
- data/app/views/spree/api/orders/index.v1.rabl +7 -0
- data/app/views/spree/api/orders/invalid_shipping_method.v1.rabl +2 -0
- data/app/views/spree/api/orders/mine.v1.rabl +9 -0
- data/app/views/spree/api/orders/order.v1.rabl +9 -0
- data/app/views/spree/api/orders/payment.v1.rabl +3 -0
- data/app/views/spree/api/orders/show.v1.rabl +52 -0
- data/app/views/spree/api/payments/credit_over_limit.v1.rabl +2 -0
- data/app/views/spree/api/payments/index.v1.rabl +7 -0
- data/app/views/spree/api/payments/new.v1.rabl +5 -0
- data/app/views/spree/api/payments/show.v1.rabl +2 -0
- data/app/views/spree/api/payments/update_forbidden.v1.rabl +2 -0
- data/app/views/spree/api/product_properties/index.v1.rabl +7 -0
- data/app/views/spree/api/product_properties/new.v1.rabl +2 -0
- data/app/views/spree/api/product_properties/show.v1.rabl +2 -0
- data/app/views/spree/api/products/index.v1.rabl +9 -0
- data/app/views/spree/api/products/new.v1.rabl +3 -0
- data/app/views/spree/api/products/product.v1.rabl +1 -0
- data/app/views/spree/api/products/show.v1.rabl +31 -0
- data/app/views/spree/api/promotions/handler.v1.rabl +5 -0
- data/app/views/spree/api/promotions/show.v1.rabl +2 -0
- data/app/views/spree/api/properties/index.v1.rabl +7 -0
- data/app/views/spree/api/properties/new.v1.rabl +2 -0
- data/app/views/spree/api/properties/show.v1.rabl +2 -0
- data/app/views/spree/api/return_authorizations/index.v1.rabl +7 -0
- data/app/views/spree/api/return_authorizations/new.v1.rabl +3 -0
- data/app/views/spree/api/return_authorizations/show.v1.rabl +2 -0
- data/app/views/spree/api/shared/stock_location_required.v1.rabl +2 -0
- data/app/views/spree/api/shipments/big.v1.rabl +48 -0
- data/app/views/spree/api/shipments/cannot_ready_shipment.v1.rabl +2 -0
- data/app/views/spree/api/shipments/mine.v1.rabl +9 -0
- data/app/views/spree/api/shipments/show.v1.rabl +32 -0
- data/app/views/spree/api/shipments/small.v1.rabl +37 -0
- data/app/views/spree/api/shipping_rates/show.v1.rabl +2 -0
- data/app/views/spree/api/states/index.v1.rabl +14 -0
- data/app/views/spree/api/states/show.v1.rabl +2 -0
- data/app/views/spree/api/stock_items/index.v1.rabl +7 -0
- data/app/views/spree/api/stock_items/show.v1.rabl +5 -0
- data/app/views/spree/api/stock_locations/index.v1.rabl +7 -0
- data/app/views/spree/api/stock_locations/show.v1.rabl +8 -0
- data/app/views/spree/api/stock_movements/index.v1.rabl +7 -0
- data/app/views/spree/api/stock_movements/show.v1.rabl +5 -0
- data/app/views/spree/api/stock_transfers/receive.v1.rabl +5 -0
- data/app/views/spree/api/store_credit_events/mine.v1.rabl +10 -0
- data/app/views/spree/api/stores/index.v1.rabl +4 -0
- data/app/views/spree/api/stores/show.v1.rabl +2 -0
- data/app/views/spree/api/taxonomies/index.v1.rabl +7 -0
- data/app/views/spree/api/taxonomies/jstree.rabl +8 -0
- data/app/views/spree/api/taxonomies/nested.v1.rabl +11 -0
- data/app/views/spree/api/taxonomies/new.v1.rabl +3 -0
- data/app/views/spree/api/taxonomies/show.v1.rabl +15 -0
- data/app/views/spree/api/taxons/index.v1.rabl +12 -0
- data/app/views/spree/api/taxons/jstree.rabl +8 -0
- data/app/views/spree/api/taxons/new.v1.rabl +3 -0
- data/app/views/spree/api/taxons/show.v1.rabl +6 -0
- data/app/views/spree/api/taxons/taxons.v1.rabl +5 -0
- data/app/views/spree/api/transfer_items/show.v1.rabl +6 -0
- data/app/views/spree/api/users/index.v1.rabl +7 -0
- data/app/views/spree/api/users/new.v1.rabl +3 -0
- data/app/views/spree/api/users/show.v1.rabl +10 -0
- data/app/views/spree/api/variants/big.v1.rabl +17 -0
- data/app/views/spree/api/variants/index.v1.rabl +9 -0
- data/app/views/spree/api/variants/new.v1.rabl +2 -0
- data/app/views/spree/api/variants/show.v1.rabl +3 -0
- data/app/views/spree/api/variants/small.v1.rabl +17 -0
- data/app/views/spree/api/zones/index.v1.rabl +7 -0
- data/app/views/spree/api/zones/show.v1.rabl +6 -0
- data/config/initializers/metal_load_paths.rb +1 -0
- data/config/locales/en.yml +29 -0
- data/config/routes.rb +139 -0
- data/db/migrate/20100107141738_add_api_key_to_spree_users.rb +7 -0
- data/db/migrate/20120411123334_resize_api_key_field.rb +7 -0
- data/db/migrate/20120530054546_rename_api_key_to_spree_api_key.rb +7 -0
- data/db/migrate/20131017162334_add_index_to_user_spree_api_key.rb +7 -0
- data/lib/solidus_api.rb +1 -0
- data/lib/spree/api/engine.rb +38 -0
- data/lib/spree/api/responders/rabl_template.rb +31 -0
- data/lib/spree/api/responders.rb +11 -0
- data/lib/spree/api/testing_support/caching.rb +10 -0
- data/lib/spree/api/testing_support/helpers.rb +44 -0
- data/lib/spree/api/testing_support/setup.rb +16 -0
- data/lib/spree/api.rb +10 -0
- data/lib/spree_api.rb +3 -0
- data/script/rails +9 -0
- data/solidus_api.gemspec +21 -0
- data/spec/controllers/spree/api/addresses_controller_spec.rb +56 -0
- data/spec/controllers/spree/api/base_controller_spec.rb +164 -0
- data/spec/controllers/spree/api/checkouts_controller_spec.rb +386 -0
- data/spec/controllers/spree/api/classifications_controller_spec.rb +48 -0
- data/spec/controllers/spree/api/config_controller_spec.rb +23 -0
- data/spec/controllers/spree/api/countries_controller_spec.rb +48 -0
- data/spec/controllers/spree/api/credit_cards_controller_spec.rb +80 -0
- data/spec/controllers/spree/api/images_controller_spec.rb +93 -0
- data/spec/controllers/spree/api/inventory_units_controller_spec.rb +50 -0
- data/spec/controllers/spree/api/line_items_controller_spec.rb +186 -0
- data/spec/controllers/spree/api/option_types_controller_spec.rb +116 -0
- data/spec/controllers/spree/api/option_values_controller_spec.rb +135 -0
- data/spec/controllers/spree/api/orders_controller_spec.rb +759 -0
- data/spec/controllers/spree/api/payments_controller_spec.rb +254 -0
- data/spec/controllers/spree/api/product_properties_controller_spec.rb +116 -0
- data/spec/controllers/spree/api/products_controller_spec.rb +454 -0
- data/spec/controllers/spree/api/promotion_application_spec.rb +50 -0
- data/spec/controllers/spree/api/promotions_controller_spec.rb +64 -0
- data/spec/controllers/spree/api/properties_controller_spec.rb +102 -0
- data/spec/controllers/spree/api/return_authorizations_controller_spec.rb +173 -0
- data/spec/controllers/spree/api/shipments_controller_spec.rb +252 -0
- data/spec/controllers/spree/api/states_controller_spec.rb +82 -0
- data/spec/controllers/spree/api/stock_items_controller_spec.rb +307 -0
- data/spec/controllers/spree/api/stock_locations_controller_spec.rb +172 -0
- data/spec/controllers/spree/api/stock_movements_controller_spec.rb +84 -0
- data/spec/controllers/spree/api/stock_transfers_controller_spec.rb +83 -0
- data/spec/controllers/spree/api/store_credit_events_controller_spec.rb +68 -0
- data/spec/controllers/spree/api/stores_controller_spec.rb +133 -0
- data/spec/controllers/spree/api/taxonomies_controller_spec.rb +114 -0
- data/spec/controllers/spree/api/taxons_controller_spec.rb +177 -0
- data/spec/controllers/spree/api/transfer_items_controller_spec.rb +152 -0
- data/spec/controllers/spree/api/unauthenticated_products_controller_spec.rb +26 -0
- data/spec/controllers/spree/api/users_controller_spec.rb +153 -0
- data/spec/controllers/spree/api/variants_controller_spec.rb +235 -0
- data/spec/controllers/spree/api/zones_controller_spec.rb +115 -0
- data/spec/features/checkout_spec.rb +187 -0
- data/spec/fixtures/thinking-cat.jpg +0 -0
- data/spec/models/spree/legacy_user_spec.rb +45 -0
- data/spec/requests/rabl_cache_spec.rb +32 -0
- data/spec/shared_examples/protect_product_actions.rb +17 -0
- data/spec/spec_helper.rb +60 -0
- data/spec/support/controller_hacks.rb +38 -0
- data/spec/support/database_cleaner.rb +14 -0
- data/spec/support/have_attributes_matcher.rb +13 -0
- metadata +334 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
class FakesController < Spree::Api::BaseController
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
describe Spree::Api::BaseController, :type => :controller do
|
|
7
|
+
render_views
|
|
8
|
+
controller(Spree::Api::BaseController) do
|
|
9
|
+
def index
|
|
10
|
+
render :text => { "products" => [] }.to_json
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
before do
|
|
15
|
+
@routes = ActionDispatch::Routing::RouteSet.new.tap do |r|
|
|
16
|
+
r.draw { get 'index', to: 'spree/api/base#index' }
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context "when validating based on an order token" do
|
|
21
|
+
let!(:order) { create :order }
|
|
22
|
+
|
|
23
|
+
context "with a correct order token" do
|
|
24
|
+
it "succeeds" do
|
|
25
|
+
api_get :index, order_token: order.guest_token, order_id: order.number
|
|
26
|
+
expect(response.status).to eq(200)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "succeeds with an order_number parameter" do
|
|
30
|
+
api_get :index, order_token: order.guest_token, order_number: order.number
|
|
31
|
+
expect(response.status).to eq(200)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
context "with an incorrect order token" do
|
|
36
|
+
it "returns unauthorized" do
|
|
37
|
+
api_get :index, order_token: "NOT_A_TOKEN", order_id: order.number
|
|
38
|
+
expect(response.status).to eq(401)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
context "cannot make a request to the API" do
|
|
44
|
+
it "without an API key" do
|
|
45
|
+
api_get :index
|
|
46
|
+
expect(json_response).to eq({ "error" => "You must specify an API key." })
|
|
47
|
+
expect(response.status).to eq(401)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "with an invalid API key" do
|
|
51
|
+
request.headers["X-Spree-Token"] = "fake_key"
|
|
52
|
+
get :index, {}
|
|
53
|
+
expect(json_response).to eq({ "error" => "Invalid API key (fake_key) specified." })
|
|
54
|
+
expect(response.status).to eq(401)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it "using an invalid token param" do
|
|
58
|
+
get :index, :token => "fake_key"
|
|
59
|
+
expect(json_response).to eq({ "error" => "Invalid API key (fake_key) specified." })
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it 'chatches StandardError' do
|
|
64
|
+
expect(subject).to receive(:authenticate_user).and_return(true)
|
|
65
|
+
expect(subject).to receive(:load_user_roles).and_return(true)
|
|
66
|
+
expect(subject).to receive(:index).and_raise("no joy")
|
|
67
|
+
get :index, :token => "fake_key"
|
|
68
|
+
expect(json_response).to eq({ "exception" => "no joy" })
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it 'raises Exception' do
|
|
72
|
+
expect(subject).to receive(:authenticate_user).and_return(true)
|
|
73
|
+
expect(subject).to receive(:load_user_roles).and_return(true)
|
|
74
|
+
expect(subject).to receive(:index).and_raise(Exception.new("no joy"))
|
|
75
|
+
expect {
|
|
76
|
+
get :index, :token => "fake_key"
|
|
77
|
+
}.to raise_error(Exception, "no joy")
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "maps semantic keys to nested_attributes keys" do
|
|
81
|
+
klass = double(:nested_attributes_options => { :line_items => {},
|
|
82
|
+
:bill_address => {} })
|
|
83
|
+
attributes = { 'line_items' => { :id => 1 },
|
|
84
|
+
'bill_address' => { :id => 2 },
|
|
85
|
+
'name' => 'test order' }
|
|
86
|
+
|
|
87
|
+
mapped = subject.map_nested_attributes_keys(klass, attributes)
|
|
88
|
+
expect(mapped.has_key?('line_items_attributes')).to be true
|
|
89
|
+
expect(mapped.has_key?('name')).to be true
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "lets a subclass override the product associations that are eager-loaded" do
|
|
93
|
+
expect(controller.respond_to?(:product_includes, true)).to be
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
describe '#error_during_processing' do
|
|
97
|
+
controller(FakesController) do
|
|
98
|
+
# GET /foo
|
|
99
|
+
# Simulates a failed API call.
|
|
100
|
+
def foo
|
|
101
|
+
raise StandardError
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# What would be placed in config/initializers/spree.rb
|
|
106
|
+
Spree::Api::BaseController.error_notifier = Proc.new do |e, controller|
|
|
107
|
+
MockHoneybadger.notify_or_ignore(e, rack_env: controller.request.env)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
##
|
|
111
|
+
# Fake HB alert class
|
|
112
|
+
class MockHoneybadger
|
|
113
|
+
# https://github.com/honeybadger-io/honeybadger-ruby/blob/master/lib/honeybadger.rb#L136
|
|
114
|
+
def self.notify_or_ignore(exception, opts = {})
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
before do
|
|
119
|
+
user = double(email: "spree@example.com")
|
|
120
|
+
allow(user).to receive_message_chain :spree_roles, pluck: []
|
|
121
|
+
allow(Spree.user_class).to receive_messages find_by: user
|
|
122
|
+
@routes = ActionDispatch::Routing::RouteSet.new.tap do |r|
|
|
123
|
+
r.draw { get 'foo' => 'fakes#foo' }
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
it 'should notify notify_error_during_processing' do
|
|
128
|
+
expect(MockHoneybadger).to receive(:notify_or_ignore).once.with(kind_of(Exception), rack_env: kind_of(Hash))
|
|
129
|
+
api_get :foo, token: 123
|
|
130
|
+
expect(response.status).to eq(422)
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
context 'lock_order' do
|
|
135
|
+
let!(:order) { create :order }
|
|
136
|
+
|
|
137
|
+
controller(Spree::Api::BaseController) do
|
|
138
|
+
around_filter :lock_order
|
|
139
|
+
|
|
140
|
+
def index
|
|
141
|
+
render :text => { "products" => [] }.to_json
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
context 'without an existing lock' do
|
|
146
|
+
it 'succeeds' do
|
|
147
|
+
api_get :index, order_token: order.guest_token, order_id: order.number
|
|
148
|
+
response.status.should == 200
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
context 'with an existing lock' do
|
|
153
|
+
around do |example|
|
|
154
|
+
Spree::OrderMutex.with_lock!(order) { example.run }
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
it 'returns a 409 conflict' do
|
|
158
|
+
api_get :index, order_token: order.guest_token, order_id: order.number
|
|
159
|
+
response.status.should == 409
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
end
|
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
describe Api::CheckoutsController, type: :controller do
|
|
5
|
+
render_views
|
|
6
|
+
|
|
7
|
+
before(:each) do
|
|
8
|
+
stub_authentication!
|
|
9
|
+
Spree::Config[:track_inventory_levels] = false
|
|
10
|
+
country_zone = create(:zone, name: 'CountryZone')
|
|
11
|
+
@state = create(:state)
|
|
12
|
+
@country = @state.country
|
|
13
|
+
country_zone.members.create(zoneable: @country)
|
|
14
|
+
create(:stock_location)
|
|
15
|
+
|
|
16
|
+
@shipping_method = create(:shipping_method, zones: [country_zone])
|
|
17
|
+
@payment_method = create(:credit_card_payment_method)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
after do
|
|
21
|
+
Spree::Config[:track_inventory_levels] = true
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
context "PUT 'update'" do
|
|
25
|
+
let(:order) do
|
|
26
|
+
order = create(:order_with_line_items)
|
|
27
|
+
# Order should be in a pristine state
|
|
28
|
+
# Without doing this, the order may transition from 'cart' straight to 'delivery'
|
|
29
|
+
order.shipments.delete_all
|
|
30
|
+
order
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
before(:each) do
|
|
34
|
+
allow_any_instance_of(Order).to receive_messages(confirmation_required?: true)
|
|
35
|
+
allow_any_instance_of(Order).to receive_messages(payment_required?: true)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "should transition a recently created order from cart to address" do
|
|
39
|
+
expect(order.state).to eq "cart"
|
|
40
|
+
expect(order.email).not_to be_nil
|
|
41
|
+
api_put :update, id: order.to_param, order_token: order.guest_token
|
|
42
|
+
expect(order.reload.state).to eq "address"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "should transition a recently created order from cart to address with order token in header" do
|
|
46
|
+
expect(order.state).to eq "cart"
|
|
47
|
+
expect(order.email).not_to be_nil
|
|
48
|
+
request.headers["X-Spree-Order-Token"] = order.guest_token
|
|
49
|
+
api_put :update, :id => order.to_param
|
|
50
|
+
expect(order.reload.state).to eq "address"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it "can take line_items_attributes as a parameter" do
|
|
54
|
+
line_item = order.line_items.first
|
|
55
|
+
api_put :update, id: order.to_param, order_token: order.guest_token,
|
|
56
|
+
order: { line_items_attributes: { 0 => { id: line_item.id, quantity: 1 } } }
|
|
57
|
+
expect(response.status).to eq(200)
|
|
58
|
+
expect(order.reload.state).to eq "address"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "can take line_items as a parameter" do
|
|
62
|
+
line_item = order.line_items.first
|
|
63
|
+
api_put :update, id: order.to_param, order_token: order.guest_token,
|
|
64
|
+
order: { line_items: { 0 => { id: line_item.id, quantity: 1 } } }
|
|
65
|
+
expect(response.status).to eq(200)
|
|
66
|
+
expect(order.reload.state).to eq "address"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it "will return an error if the order cannot transition" do
|
|
70
|
+
skip "not sure if this test is valid"
|
|
71
|
+
order.bill_address = nil
|
|
72
|
+
order.save
|
|
73
|
+
order.update_column(:state, "address")
|
|
74
|
+
api_put :update, id: order.to_param, order_token: order.guest_token
|
|
75
|
+
# Order has not transitioned
|
|
76
|
+
expect(response.status).to eq(422)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
context "transitioning to delivery" do
|
|
80
|
+
before do
|
|
81
|
+
order.update_column(:state, "address")
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
let(:address) do
|
|
85
|
+
{
|
|
86
|
+
firstname: 'John',
|
|
87
|
+
lastname: 'Doe',
|
|
88
|
+
address1: '7735 Old Georgetown Road',
|
|
89
|
+
city: 'Bethesda',
|
|
90
|
+
phone: '3014445002',
|
|
91
|
+
zipcode: '20814',
|
|
92
|
+
state_id: @state.id,
|
|
93
|
+
country_id: @country.id
|
|
94
|
+
}
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "can update addresses and transition from address to delivery" do
|
|
98
|
+
api_put :update,
|
|
99
|
+
id: order.to_param, order_token: order.guest_token,
|
|
100
|
+
order: {
|
|
101
|
+
bill_address_attributes: address,
|
|
102
|
+
ship_address_attributes: address
|
|
103
|
+
}
|
|
104
|
+
expect(json_response['state']).to eq('delivery')
|
|
105
|
+
expect(json_response['bill_address']['firstname']).to eq('John')
|
|
106
|
+
expect(json_response['ship_address']['firstname']).to eq('John')
|
|
107
|
+
expect(response.status).to eq(200)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Regression Spec for #5389 & #5880
|
|
111
|
+
it "can update addresses but not transition to delivery w/o shipping setup" do
|
|
112
|
+
Spree::ShippingMethod.destroy_all
|
|
113
|
+
api_put :update,
|
|
114
|
+
id: order.to_param, order_token: order.guest_token,
|
|
115
|
+
order: {
|
|
116
|
+
bill_address_attributes: address,
|
|
117
|
+
ship_address_attributes: address
|
|
118
|
+
}
|
|
119
|
+
expect(json_response['error']).to eq(I18n.t(:could_not_transition, scope: "spree.api.order"))
|
|
120
|
+
expect(response.status).to eq(422)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Regression test for #4498
|
|
124
|
+
it "does not contain duplicate variant data in delivery return" do
|
|
125
|
+
api_put :update,
|
|
126
|
+
id: order.to_param, order_token: order.guest_token,
|
|
127
|
+
order: {
|
|
128
|
+
bill_address_attributes: address,
|
|
129
|
+
ship_address_attributes: address
|
|
130
|
+
}
|
|
131
|
+
# Shipments manifests should not return the ENTIRE variant
|
|
132
|
+
# This information is already present within the order's line items
|
|
133
|
+
expect(json_response['shipments'].first['manifest'].first['variant']).to be_nil
|
|
134
|
+
expect(json_response['shipments'].first['manifest'].first['variant_id']).to_not be_nil
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it "can update shipping method and transition from delivery to payment" do
|
|
139
|
+
order.update_column(:state, "delivery")
|
|
140
|
+
shipment = create(:shipment, order: order)
|
|
141
|
+
shipment.refresh_rates
|
|
142
|
+
shipping_rate = shipment.shipping_rates.where(selected: false).first
|
|
143
|
+
api_put :update, id: order.to_param, order_token: order.guest_token,
|
|
144
|
+
order: { shipments_attributes: { "0" => { selected_shipping_rate_id: shipping_rate.id, id: shipment.id } } }
|
|
145
|
+
expect(response.status).to eq(200)
|
|
146
|
+
# Find the correct shipment...
|
|
147
|
+
json_shipment = json_response['shipments'].detect { |s| s["id"] == shipment.id }
|
|
148
|
+
# Find the correct shipping rate for that shipment...
|
|
149
|
+
json_shipping_rate = json_shipment['shipping_rates'].detect { |sr| sr["id"] == shipping_rate.id }
|
|
150
|
+
# ... And finally ensure that it's selected
|
|
151
|
+
expect(json_shipping_rate['selected']).to be true
|
|
152
|
+
# Order should automatically transfer to payment because all criteria are met
|
|
153
|
+
expect(json_response['state']).to eq('payment')
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
it "can update payment method and transition from payment to confirm" do
|
|
157
|
+
order.update_column(:state, "payment")
|
|
158
|
+
Spree::Gateway::Bogus.any_instance.stub(:source_required?).and_return(false)
|
|
159
|
+
api_put :update, id: order.to_param, order_token: order.guest_token,
|
|
160
|
+
order: { payments_attributes: [{ payment_method_id: @payment_method.id }] }
|
|
161
|
+
expect(json_response['state']).to eq('confirm')
|
|
162
|
+
expect(json_response['payments'][0]['payment_method']['name']).to eq(@payment_method.name)
|
|
163
|
+
expect(json_response['payments'][0]['amount']).to eq(order.total.to_s)
|
|
164
|
+
expect(response.status).to eq(200)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
it "returns errors when source is required and missing" do
|
|
168
|
+
order.update_column(:state, "payment")
|
|
169
|
+
api_put :update, :id => order.to_param, :order_token => order.guest_token,
|
|
170
|
+
:order => { :payments_attributes => [{ :payment_method_id => @payment_method.id }] }
|
|
171
|
+
response.status.should == 422
|
|
172
|
+
source_errors = json_response['errors']['payments.source']
|
|
173
|
+
source_errors.should include("can't be blank")
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
it "can update payment method with source and transition from payment to confirm" do
|
|
177
|
+
order.update_column(:state, "payment")
|
|
178
|
+
source_attributes = {
|
|
179
|
+
number: "4111111111111111",
|
|
180
|
+
month: 1.month.from_now.month,
|
|
181
|
+
year: 1.month.from_now.year,
|
|
182
|
+
verification_value: "123",
|
|
183
|
+
name: "Spree Commerce"
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
api_put :update, id: order.to_param, order_token: order.guest_token,
|
|
187
|
+
order: { payments_attributes: [{ payment_method_id: @payment_method.id.to_s }]},
|
|
188
|
+
payment_source: { @payment_method.id.to_s => source_attributes }
|
|
189
|
+
expect(json_response['payments'][0]['payment_method']['name']).to eq(@payment_method.name)
|
|
190
|
+
expect(json_response['payments'][0]['amount']).to eq(order.total.to_s)
|
|
191
|
+
expect(response.status).to eq(200)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
it "returns errors when source is missing attributes" do
|
|
195
|
+
order.update_column(:state, "payment")
|
|
196
|
+
api_put :update, id: order.to_param, order_token: order.guest_token,
|
|
197
|
+
order: {
|
|
198
|
+
payments_attributes: [{ payment_method_id: @payment_method.id }]
|
|
199
|
+
},
|
|
200
|
+
payment_source: {
|
|
201
|
+
@payment_method.id.to_s => { name: "Spree" }
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
expect(response.status).to eq(422)
|
|
205
|
+
cc_errors = json_response['errors']['payments.Credit Card']
|
|
206
|
+
expect(cc_errors).to include("Number can't be blank")
|
|
207
|
+
expect(cc_errors).to include("Month is not a number")
|
|
208
|
+
expect(cc_errors).to include("Year is not a number")
|
|
209
|
+
expect(cc_errors).to include("Verification Value can't be blank")
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
it "allow users to reuse a credit card" do
|
|
213
|
+
order.update_column(:state, "payment")
|
|
214
|
+
credit_card = create(:credit_card, user_id: order.user_id, payment_method_id: @payment_method.id)
|
|
215
|
+
|
|
216
|
+
api_put :update, id: order.to_param, order_token: order.guest_token,
|
|
217
|
+
order: { existing_card: credit_card.id }
|
|
218
|
+
|
|
219
|
+
expect(response.status).to eq 200
|
|
220
|
+
expect(order.credit_cards).to match_array [credit_card]
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
it "can transition from confirm to complete" do
|
|
224
|
+
order.update_columns(completed_at: Time.now, state: 'complete')
|
|
225
|
+
allow_any_instance_of(Spree::Order).to receive_messages(payment_required?: false)
|
|
226
|
+
api_put :update, id: order.to_param, order_token: order.guest_token
|
|
227
|
+
expect(json_response['state']).to eq('complete')
|
|
228
|
+
expect(response.status).to eq(200)
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
it "returns the order if the order is already complete" do
|
|
232
|
+
order.update_columns(completed_at: Time.now, state: 'complete')
|
|
233
|
+
api_put :update, id: order.to_param, order_token: order.guest_token
|
|
234
|
+
expect(json_response['number']).to eq(order.number)
|
|
235
|
+
expect(response.status).to eq(200)
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
# Regression test for #3784
|
|
239
|
+
it "can update the special instructions for an order" do
|
|
240
|
+
instructions = "Don't drop it. (Please)"
|
|
241
|
+
api_put :update, id: order.to_param, order_token: order.guest_token,
|
|
242
|
+
order: { special_instructions: instructions }
|
|
243
|
+
expect(json_response['special_instructions']).to eql(instructions)
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
context "as an admin" do
|
|
247
|
+
sign_in_as_admin!
|
|
248
|
+
it "can assign a user to the order" do
|
|
249
|
+
user = create(:user)
|
|
250
|
+
# Need to pass email as well so that validations succeed
|
|
251
|
+
api_put :update, id: order.to_param, order_token: order.guest_token,
|
|
252
|
+
order: { user_id: user.id, email: "guest@spreecommerce.com" }
|
|
253
|
+
expect(response.status).to eq(200)
|
|
254
|
+
expect(json_response['user_id']).to eq(user.id)
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
it "can assign an email to the order" do
|
|
259
|
+
api_put :update, id: order.to_param, order_token: order.guest_token,
|
|
260
|
+
order: { email: "guest@spreecommerce.com" }
|
|
261
|
+
expect(json_response['email']).to eq("guest@spreecommerce.com")
|
|
262
|
+
expect(response.status).to eq(200)
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
it "can apply a coupon code to an order" do
|
|
266
|
+
skip "ensure that the order totals are properly updated, see frontend orders_controller or checkout_controller as example"
|
|
267
|
+
|
|
268
|
+
order.update_column(:state, "payment")
|
|
269
|
+
expect(PromotionHandler::Coupon).to receive(:new).with(order).and_call_original
|
|
270
|
+
expect_any_instance_of(PromotionHandler::Coupon).to receive(:apply).and_return({ coupon_applied?: true })
|
|
271
|
+
api_put :update, :id => order.to_param, order_token: order.guest_token, order: { coupon_code: "foobar" }
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
context "PUT 'next'" do
|
|
276
|
+
let!(:order) { create(:order_with_line_items) }
|
|
277
|
+
it "cannot transition to address without a line item" do
|
|
278
|
+
order.line_items.delete_all
|
|
279
|
+
order.update_column(:email, "spree@example.com")
|
|
280
|
+
api_put :next, id: order.to_param, order_token: order.guest_token
|
|
281
|
+
expect(response.status).to eq(422)
|
|
282
|
+
expect(json_response["errors"]["base"]).to include(Spree.t(:there_are_no_items_for_this_order))
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
it "can transition an order to the next state" do
|
|
286
|
+
order.update_column(:email, "spree@example.com")
|
|
287
|
+
|
|
288
|
+
api_put :next, id: order.to_param, order_token: order.guest_token
|
|
289
|
+
expect(response.status).to eq(200)
|
|
290
|
+
expect(json_response['state']).to eq('address')
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
it "cannot transition if order email is blank" do
|
|
294
|
+
order.update_columns(
|
|
295
|
+
state: 'address',
|
|
296
|
+
email: nil
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
api_put :next, :id => order.to_param, :order_token => order.guest_token
|
|
300
|
+
expect(response.status).to eq(422)
|
|
301
|
+
expect(json_response['error']).to match(/could not be transitioned/)
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
# NOTE: Temporarily making "next" behave just like "complete" when order is in confirm state
|
|
306
|
+
# Using "next" this way is deprecated.
|
|
307
|
+
[:next, :complete].each do |action|
|
|
308
|
+
context "#{action}" do
|
|
309
|
+
context "with order in confirm state" do
|
|
310
|
+
subject do
|
|
311
|
+
api_put action, params
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
let(:params) { {id: order.to_param, order_token: order.guest_token} }
|
|
315
|
+
let(:order) { create(:order_with_line_items) }
|
|
316
|
+
|
|
317
|
+
before do
|
|
318
|
+
order.update_column(:state, "confirm")
|
|
319
|
+
|
|
320
|
+
if action == :next
|
|
321
|
+
#ActiveSupport::Deprecation.should_receive(:warn).once
|
|
322
|
+
end
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
it "can transition from confirm to complete" do
|
|
326
|
+
Spree::Order.any_instance.stub(:payment_required? => false)
|
|
327
|
+
subject
|
|
328
|
+
json_response['state'].should == 'complete'
|
|
329
|
+
response.status.should == 200
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
it "returns a sensible error when no payment method is specified" do
|
|
333
|
+
# api_put :complete, :id => order.to_param, :order_token => order.token, :order => {}
|
|
334
|
+
subject
|
|
335
|
+
json_response["errors"]["base"].should include(Spree.t(:no_payment_found))
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
context "with mismatched expected_total" do
|
|
339
|
+
let(:params) { super().merge(expected_total: order.total + 1) }
|
|
340
|
+
|
|
341
|
+
it "returns an error if expected_total is present and does not match actual total" do
|
|
342
|
+
# api_put :complete, :id => order.to_param, :order_token => order.token, :expected_total => order.total + 1
|
|
343
|
+
subject
|
|
344
|
+
response.status.should == 400
|
|
345
|
+
json_response['errors']['expected_total'].should include(Spree.t(:expected_total_mismatch, :scope => 'api.order'))
|
|
346
|
+
end
|
|
347
|
+
end
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
context 'insufficient stock' do
|
|
352
|
+
let(:order) { create(:order_with_line_items) }
|
|
353
|
+
before do
|
|
354
|
+
expect_any_instance_of(Spree::Order).to receive(:next!).and_raise(Spree::Order::InsufficientStock)
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
subject { api_put :next, :id => order.to_param, :order_token => order.guest_token }
|
|
358
|
+
|
|
359
|
+
it "should return a 422" do
|
|
360
|
+
expect(subject.status).to eq(422)
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
it "returns an error message" do
|
|
364
|
+
subject
|
|
365
|
+
expect(JSON.parse(response.body)).to eq(
|
|
366
|
+
{"errors" => ["Quantity is not available for items in your order"], "type" => "insufficient_stock"}
|
|
367
|
+
)
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
context "PUT 'advance'" do
|
|
373
|
+
let!(:order) { create(:order_with_line_items) }
|
|
374
|
+
|
|
375
|
+
it 'continues to advance advances an order while it can move forward' do
|
|
376
|
+
expect_any_instance_of(Spree::Order).to receive(:next).exactly(3).times.and_return(true, true, false)
|
|
377
|
+
api_put :advance, id: order.to_param, order_token: order.guest_token
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
it 'returns the order' do
|
|
381
|
+
api_put :advance, id: order.to_param, order_token: order.guest_token
|
|
382
|
+
expect(json_response['id']).to eq(order.id)
|
|
383
|
+
end
|
|
384
|
+
end
|
|
385
|
+
end
|
|
386
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
describe Api::ClassificationsController, type: :controller do
|
|
5
|
+
let(:taxon) do
|
|
6
|
+
taxon = create(:taxon)
|
|
7
|
+
|
|
8
|
+
3.times do
|
|
9
|
+
product = create(:product)
|
|
10
|
+
product.taxons << taxon
|
|
11
|
+
end
|
|
12
|
+
taxon
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
before do
|
|
16
|
+
stub_authentication!
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
context "as a user" do
|
|
20
|
+
it "cannot change the order of a product" do
|
|
21
|
+
api_put :update, taxon_id: taxon, product_id: taxon.products.first, position: 1
|
|
22
|
+
expect(response.status).to eq(401)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
context "as an admin" do
|
|
27
|
+
sign_in_as_admin!
|
|
28
|
+
|
|
29
|
+
let(:last_product) { taxon.products.last }
|
|
30
|
+
|
|
31
|
+
it "can change the order a product" do
|
|
32
|
+
classification = taxon.classifications.find_by(product_id: last_product.id)
|
|
33
|
+
expect(classification.position).to eq(3)
|
|
34
|
+
api_put :update, taxon_id: taxon, product_id: last_product, position: 0
|
|
35
|
+
expect(response.status).to eq(200)
|
|
36
|
+
expect(classification.reload.position).to eq(1)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "should touch the taxon" do
|
|
40
|
+
taxon.update_attributes(updated_at: Time.now - 10.seconds)
|
|
41
|
+
taxon_last_updated_at = taxon.updated_at
|
|
42
|
+
api_put :update, taxon_id: taxon, product_id: last_product, position: 0
|
|
43
|
+
taxon.reload
|
|
44
|
+
expect(taxon_last_updated_at.to_i).to_not eq(taxon.updated_at.to_i)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
describe Api::ConfigController, :type => :controller do
|
|
5
|
+
render_views
|
|
6
|
+
|
|
7
|
+
before do
|
|
8
|
+
stub_authentication!
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "returns Spree::Money settings" do
|
|
12
|
+
api_get :money
|
|
13
|
+
expect(response).to be_success
|
|
14
|
+
expect(json_response["symbol"]).to eq("$")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "returns some configuration settings" do
|
|
18
|
+
api_get :show
|
|
19
|
+
expect(response).to be_success
|
|
20
|
+
expect(json_response["default_country_id"]).to eq(Spree::Config[:default_country_id])
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
describe Api::CountriesController, :type => :controller do
|
|
5
|
+
render_views
|
|
6
|
+
|
|
7
|
+
before do
|
|
8
|
+
stub_authentication!
|
|
9
|
+
@state = create(:state)
|
|
10
|
+
@country = @state.country
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "gets all countries" do
|
|
14
|
+
api_get :index
|
|
15
|
+
expect(json_response['countries'].first['iso3']).to 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
|
+
expect(json_response['count']).to eq(2)
|
|
24
|
+
expect(json_response['current_page']).to eq(1)
|
|
25
|
+
expect(json_response['pages']).to eq(1)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'can query the results through a paramter' do
|
|
29
|
+
api_get :index, :q => { :name_cont => 'zam' }
|
|
30
|
+
expect(json_response['count']).to eq(1)
|
|
31
|
+
expect(json_response['countries'].first['name']).to 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
|
+
expect(json_response['count']).to eq(1)
|
|
37
|
+
expect(json_response['current_page']).to eq(1)
|
|
38
|
+
expect(json_response['pages']).to eq(2)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "includes states" do
|
|
43
|
+
api_get :show, :id => @country.id
|
|
44
|
+
states = json_response['states']
|
|
45
|
+
expect(states.first['name']).to eq @state.name
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|