spree_api 1.0.7 → 1.1.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.
- data/.gitignore +17 -0
- data/Gemfile +6 -0
- data/LICENSE +19 -23
- data/README.md +22 -10
- data/Rakefile +30 -0
- data/app/controllers/spree/api/v1/base_controller.rb +71 -0
- data/app/controllers/spree/api/v1/images_controller.rb +46 -0
- data/app/controllers/spree/api/v1/line_items_controller.rb +40 -0
- data/app/controllers/spree/api/v1/orders_controller.rb +53 -0
- data/app/controllers/spree/api/v1/products_controller.rb +46 -0
- data/app/controllers/spree/api/v1/variants_controller.rb +56 -0
- data/app/helpers/spree/api/api_helpers.rb +44 -0
- data/app/models/spree/line_item_decorator.rb +3 -0
- data/app/models/spree/option_value_decorator.rb +5 -0
- data/app/models/spree/order_decorator.rb +12 -0
- data/app/models/spree/user_decorator.rb +11 -0
- data/app/views/spree/api/v1/errors/invalid_api_key.rabl +2 -0
- data/app/views/spree/api/v1/errors/invalid_resource.rabl +3 -0
- data/app/views/spree/api/v1/errors/must_specify_api_key.rabl +2 -0
- data/app/views/spree/api/v1/errors/not_found.rabl +2 -0
- data/app/views/spree/api/v1/errors/unauthorized.rabl +2 -0
- data/app/views/spree/api/v1/images/show.rabl +2 -0
- data/app/views/spree/api/v1/line_items/new.rabl +3 -0
- data/app/views/spree/api/v1/line_items/show.rabl +5 -0
- data/app/views/spree/api/v1/orders/address.rabl +0 -0
- data/app/views/spree/api/v1/orders/cart.rabl +0 -0
- data/app/views/spree/api/v1/orders/complete.rabl +0 -0
- data/app/views/spree/api/v1/orders/could_not_transition.rabl +3 -0
- data/app/views/spree/api/v1/orders/delivery.rabl +3 -0
- data/app/views/spree/api/v1/orders/index.rabl +7 -0
- data/app/views/spree/api/v1/orders/invalid_shipping_method.rabl +2 -0
- data/app/views/spree/api/v1/orders/payment.rabl +0 -0
- data/app/views/spree/api/v1/orders/show.rabl +3 -0
- data/app/views/spree/api/v1/products/index.rabl +8 -0
- data/app/views/spree/api/v1/products/new.rabl +3 -0
- data/app/views/spree/api/v1/products/product.rabl +1 -0
- data/app/views/spree/api/v1/products/show.rabl +21 -0
- data/app/views/spree/api/v1/variants/index.rabl +3 -0
- data/app/views/spree/api/v1/variants/new.rabl +2 -0
- data/app/views/spree/api/v1/variants/show.rabl +3 -0
- data/app/views/spree/api/v1/variants/variant.rabl +1 -0
- data/config/locales/en.yml +11 -15
- data/config/routes.rb +14 -28
- data/db/migrate/{20100107141738_add_api_key_to_users.rb → 20100107141738_add_api_key_to_spree_users.rb} +1 -1
- data/lib/spree/api.rb +7 -4
- data/lib/spree/api/controller_setup.rb +27 -0
- data/lib/spree/api/engine.rb +3 -13
- data/lib/spree/api/version.rb +5 -0
- data/lib/spree_api.rb +0 -2
- data/script/rails +5 -0
- data/spec/controllers/spree/api/v1/base_controller_spec.rb +29 -0
- data/spec/controllers/spree/api/v1/images_controller_spec.rb +50 -0
- data/spec/controllers/spree/api/v1/line_items_controller_spec.rb +77 -0
- data/spec/controllers/spree/api/v1/orders_controller_spec.rb +148 -0
- data/spec/controllers/spree/api/v1/products_controller_spec.rb +159 -0
- data/spec/controllers/spree/api/v1/variants_controller_spec.rb +90 -0
- data/spec/fixtures/thinking-cat.jpg +0 -0
- data/spec/models/spree/order_spec.rb +18 -0
- data/spec/models/spree/user_spec.rb +19 -0
- data/spec/spec_helper.rb +28 -0
- data/spec/support/api_helpers.rb +68 -0
- data/spec/support/controller_hacks.rb +27 -0
- data/spree_api.gemspec +24 -0
- metadata +123 -56
- data/app/assets/javascripts/admin/spree.js +0 -4
- data/app/assets/javascripts/admin/spree_api.js +0 -2
- data/app/assets/javascripts/store/spree.js +0 -4
- data/app/assets/javascripts/store/spree_api.js +0 -2
- data/app/assets/stylesheets/admin/spree.css +0 -6
- data/app/assets/stylesheets/admin/spree_api.css +0 -4
- data/app/assets/stylesheets/store/spree.css +0 -6
- data/app/assets/stylesheets/store/spree_api.css +0 -4
- data/app/controllers/spree/admin/users_controller_decorator.rb +0 -17
- data/app/controllers/spree/api/base_controller.rb +0 -172
- data/app/controllers/spree/api/countries_controller.rb +0 -3
- data/app/controllers/spree/api/inventory_units_controller.rb +0 -18
- data/app/controllers/spree/api/line_items_controller.rb +0 -20
- data/app/controllers/spree/api/orders_controller.rb +0 -19
- data/app/controllers/spree/api/products_controller.rb +0 -14
- data/app/controllers/spree/api/shipments_controller.rb +0 -35
- data/app/controllers/spree/api/states_controller.rb +0 -8
- data/app/models/line_item_decorator.rb +0 -7
- data/app/models/order_decorator.rb +0 -9
- data/app/models/shipment_decorator.rb +0 -9
- data/app/models/user_decorator.rb +0 -19
- data/app/overrides/api_admin_user_edit_form.rb +0 -6
- data/app/views/spree/admin/users/_api_fields.html.erb +0 -16
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
describe Api::V1::LineItemsController do
|
|
5
|
+
render_views
|
|
6
|
+
|
|
7
|
+
let!(:order) do
|
|
8
|
+
order = Factory(:order)
|
|
9
|
+
order.line_items << Factory(:line_item)
|
|
10
|
+
order
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
let(:product) { Factory(:product) }
|
|
14
|
+
let(:attributes) { [:quantity, :price, :variant] }
|
|
15
|
+
let(:resource_scoping) { { :order_id => order.to_param } }
|
|
16
|
+
|
|
17
|
+
before do
|
|
18
|
+
stub_authentication!
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "can learn how to create a new line item" do
|
|
22
|
+
api_get :new
|
|
23
|
+
json_response["attributes"].should == ["quantity", "price", "variant_id"]
|
|
24
|
+
required_attributes = json_response["required_attributes"]
|
|
25
|
+
required_attributes.should include("quantity", "variant_id")
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
context "as the order owner" do
|
|
29
|
+
before do
|
|
30
|
+
Order.any_instance.stub :user => current_api_user
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "can add a new line item to an existing order" do
|
|
34
|
+
api_post :create, :line_item => { :variant_id => product.master.to_param, :quantity => 1 }
|
|
35
|
+
response.status.should == 201
|
|
36
|
+
json_response.should have_attributes(attributes)
|
|
37
|
+
json_response["line_item"]["variant"]["name"].should_not be_blank
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "can update a line item on the order" do
|
|
41
|
+
line_item = order.line_items.first
|
|
42
|
+
api_put :update, :id => line_item.id, :line_item => { :quantity => 1000 }
|
|
43
|
+
response.status.should == 200
|
|
44
|
+
json_response.should have_attributes(attributes)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "can delete a line item on the order" do
|
|
48
|
+
line_item = order.line_items.first
|
|
49
|
+
api_delete :destroy, :id => line_item.id
|
|
50
|
+
response.status.should == 200
|
|
51
|
+
lambda { line_item.reload }.should raise_error(ActiveRecord::RecordNotFound)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
context "as just another user" do
|
|
56
|
+
it "cannot add a new line item to the order" do
|
|
57
|
+
api_post :create, :line_item => { :variant_id => product.master.to_param, :quantity => 1 }
|
|
58
|
+
assert_unauthorized!
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "cannot update a line item on the order" do
|
|
62
|
+
line_item = order.line_items.first
|
|
63
|
+
api_put :update, :id => line_item.id, :line_item => { :quantity => 1000 }
|
|
64
|
+
assert_unauthorized!
|
|
65
|
+
line_item.reload.quantity.should_not == 1000
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "cannot delete a line item on the order" do
|
|
69
|
+
line_item = order.line_items.first
|
|
70
|
+
api_delete :destroy, :id => line_item.id
|
|
71
|
+
assert_unauthorized!
|
|
72
|
+
lambda { line_item.reload }.should_not raise_error(ActiveRecord::RecordNotFound)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
describe Api::V1::OrdersController do
|
|
5
|
+
render_views
|
|
6
|
+
|
|
7
|
+
let!(:order) { Factory(:order) }
|
|
8
|
+
let(:attributes) { [:number, :item_total, :total,
|
|
9
|
+
:state, :adjustment_total, :credit_total,
|
|
10
|
+
:user_id, :created_at, :updated_at,
|
|
11
|
+
:completed_at, :payment_total, :shipment_state,
|
|
12
|
+
:payment_state, :email, :special_instructions] }
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
before do
|
|
16
|
+
stub_authentication!
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "cannot view all orders" do
|
|
20
|
+
api_get :index
|
|
21
|
+
assert_unauthorized!
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "can view their own order" do
|
|
25
|
+
Order.any_instance.stub :user => current_api_user
|
|
26
|
+
api_get :show, :id => order.to_param
|
|
27
|
+
response.status.should == 200
|
|
28
|
+
json_response.should have_attributes(attributes)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "can not view someone else's order" do
|
|
32
|
+
Order.any_instance.stub :user => stub_model(User)
|
|
33
|
+
api_get :show, :id => order.to_param
|
|
34
|
+
assert_unauthorized!
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "can create an order" do
|
|
38
|
+
variant = Factory(:variant)
|
|
39
|
+
api_post :create, :order => { :line_items => { variant.to_param => 5 } }
|
|
40
|
+
response.status.should == 200
|
|
41
|
+
order = Order.last
|
|
42
|
+
order.line_items.count.should == 1
|
|
43
|
+
order.line_items.first.variant.should == variant
|
|
44
|
+
order.line_items.first.quantity.should == 5
|
|
45
|
+
json_response["order"]["state"].should == "address"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
context "working with an order" do
|
|
49
|
+
before do
|
|
50
|
+
Factory(:payment_method)
|
|
51
|
+
order.next # Switch from cart to address
|
|
52
|
+
order.ship_address.should be_nil
|
|
53
|
+
order.state.should == "address"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def clean_address(address)
|
|
57
|
+
address.delete(:state)
|
|
58
|
+
address.delete(:country)
|
|
59
|
+
address
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
let(:address_params) { { :country_id => Country.first.id, :state_id => State.first.id } }
|
|
63
|
+
let(:shipping_address) { clean_address(Factory.attributes_for(:address).merge!(address_params)) }
|
|
64
|
+
let(:billing_address) { clean_address(Factory.attributes_for(:address).merge!(address_params)) }
|
|
65
|
+
let!(:shipping_method) { Factory(:shipping_method) }
|
|
66
|
+
let!(:payment_method) { Factory(:payment_method) }
|
|
67
|
+
|
|
68
|
+
it "can add address information to an order" do
|
|
69
|
+
api_put :address, :id => order.to_param, :shipping_address => shipping_address, :billing_address => billing_address
|
|
70
|
+
|
|
71
|
+
response.status.should == 200
|
|
72
|
+
order.reload
|
|
73
|
+
order.shipping_address.reload
|
|
74
|
+
order.billing_address.reload
|
|
75
|
+
# We can assume the rest of the parameters are set if these two are
|
|
76
|
+
order.shipping_address.firstname.should == shipping_address[:firstname]
|
|
77
|
+
order.billing_address.firstname.should == billing_address[:firstname]
|
|
78
|
+
order.state.should == "delivery"
|
|
79
|
+
json_response["order"]["shipping_methods"].should_not be_empty
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "cannot use an address that has no valid shipping methods" do
|
|
83
|
+
shipping_method.destroy
|
|
84
|
+
api_put :address, :id => order.to_param, :shipping_address => shipping_address, :billing_address => billing_address
|
|
85
|
+
response.status.should == 422
|
|
86
|
+
json_response["errors"]["base"].should == ["No shipping methods available for selected location, please change your address and try again."]
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it "can not add invalid ship address information to an order" do
|
|
90
|
+
shipping_address[:firstname] = ""
|
|
91
|
+
api_put :address, :id => order.to_param, :shipping_address => shipping_address, :billing_address => billing_address
|
|
92
|
+
|
|
93
|
+
response.status.should == 422
|
|
94
|
+
json_response["errors"]["ship_address.firstname"].should_not be_blank
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "can not add invalid ship address information to an order" do
|
|
98
|
+
billing_address[:firstname] = ""
|
|
99
|
+
api_put :address, :id => order.to_param, :shipping_address => shipping_address, :billing_address => billing_address
|
|
100
|
+
|
|
101
|
+
response.status.should == 422
|
|
102
|
+
json_response["errors"]["bill_address.firstname"].should_not be_blank
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
context "with a line item" do
|
|
106
|
+
before do
|
|
107
|
+
order.line_items << Factory(:line_item)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
context "for delivery" do
|
|
111
|
+
before do
|
|
112
|
+
order.update_attribute(:state, "delivery")
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it "can select a shipping method for an order" do
|
|
116
|
+
order.shipping_method.should be_nil
|
|
117
|
+
api_put :delivery, :id => order.to_param, :shipping_method_id => shipping_method.id
|
|
118
|
+
response.status.should == 200
|
|
119
|
+
order.reload
|
|
120
|
+
order.state.should == "payment"
|
|
121
|
+
order.shipping_method.should == shipping_method
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it "cannot select an invalid shipping method for an order" do
|
|
125
|
+
order.shipping_method.should be_nil
|
|
126
|
+
api_put :delivery, :id => order.to_param, :shipping_method_id => '1234567890'
|
|
127
|
+
response.status.should == 422
|
|
128
|
+
json_response["errors"].should include("Invalid shipping method specified.")
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
context "as an admin" do
|
|
137
|
+
sign_in_as_admin!
|
|
138
|
+
|
|
139
|
+
it "can view all orders" do
|
|
140
|
+
api_get :index
|
|
141
|
+
json_response["orders"].first.should have_attributes(attributes)
|
|
142
|
+
json_response["count"].should == 1
|
|
143
|
+
json_response["current_page"].should == 1
|
|
144
|
+
json_response["pages"].should == 1
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
describe Spree::Api::V1::ProductsController do
|
|
5
|
+
render_views
|
|
6
|
+
|
|
7
|
+
let!(:product) { Factory(:product) }
|
|
8
|
+
let!(:inactive_product) { Factory(:product, :available_on => Time.now.tomorrow, :name => "inactive") }
|
|
9
|
+
let(:attributes) { [:id, :name, :description, :price, :available_on, :permalink, :count_on_hand, :meta_description, :meta_keywords] }
|
|
10
|
+
|
|
11
|
+
before do
|
|
12
|
+
stub_authentication!
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
context "as a normal user" do
|
|
16
|
+
it "retrieves a list of products" do
|
|
17
|
+
api_get :index
|
|
18
|
+
json_response["products"].first.should have_attributes(attributes)
|
|
19
|
+
json_response["count"].should == 1
|
|
20
|
+
json_response["current_page"].should == 1
|
|
21
|
+
json_response["pages"].should == 1
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "does not list unavailable products" do
|
|
25
|
+
api_get :index
|
|
26
|
+
json_response["products"].first["name"].should_not eq("inactive")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context "pagination" do
|
|
30
|
+
default_per_page(1)
|
|
31
|
+
|
|
32
|
+
it "can select the next page of products" do
|
|
33
|
+
second_product = Factory(:product)
|
|
34
|
+
api_get :index, :page => 2
|
|
35
|
+
json_response["products"].first.should have_attributes(attributes)
|
|
36
|
+
json_response["count"].should == 2
|
|
37
|
+
json_response["current_page"].should == 2
|
|
38
|
+
json_response["pages"].should == 2
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "gets a single product" do
|
|
43
|
+
product.master.images.create!(:attachment => image("thinking-cat.jpg"))
|
|
44
|
+
api_get :show, :id => product.to_param
|
|
45
|
+
json_response.should have_attributes(attributes)
|
|
46
|
+
product_json = json_response["product"]
|
|
47
|
+
product_json["variants"].first.should have_attributes([:name,
|
|
48
|
+
:is_master,
|
|
49
|
+
:count_on_hand,
|
|
50
|
+
:price])
|
|
51
|
+
|
|
52
|
+
product_json["images"].first.should have_attributes([:attachment_file_name,
|
|
53
|
+
:attachment_width,
|
|
54
|
+
:attachment_height,
|
|
55
|
+
:attachment_content_type])
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
context "finds a product by permalink first then by id" do
|
|
60
|
+
let!(:other_product) { Factory(:product, :permalink => "these-are-not-the-droids-you-are-looking-for") }
|
|
61
|
+
|
|
62
|
+
before do
|
|
63
|
+
product.update_attribute(:permalink, "#{other_product.id}-and-1-ways")
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
specify do
|
|
67
|
+
api_get :show, :id => product.to_param
|
|
68
|
+
json_response["product"]["permalink"].should =~ /and-1-ways/
|
|
69
|
+
product.destroy
|
|
70
|
+
|
|
71
|
+
api_get :show, :id => other_product.id
|
|
72
|
+
json_response["product"]["permalink"].should =~ /droids/
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "cannot see inactive products" do
|
|
77
|
+
api_get :show, :id => inactive_product.to_param
|
|
78
|
+
json_response["error"].should == "The resource you were looking for could not be found."
|
|
79
|
+
response.status.should == 404
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "returns a 404 error when it cannot find a product" do
|
|
83
|
+
api_get :show, :id => "non-existant"
|
|
84
|
+
json_response["error"].should == "The resource you were looking for could not be found."
|
|
85
|
+
response.status.should == 404
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it "can learn how to create a new product" do
|
|
89
|
+
api_get :new
|
|
90
|
+
json_response["attributes"].should == attributes.map(&:to_s)
|
|
91
|
+
required_attributes = json_response["required_attributes"]
|
|
92
|
+
required_attributes.should include("name")
|
|
93
|
+
required_attributes.should include("price")
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it "cannot create a new product if not an admin" do
|
|
97
|
+
api_post :create, :product => { :name => "Brand new product!" }
|
|
98
|
+
assert_unauthorized!
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it "cannot update a product" do
|
|
102
|
+
api_put :update, :id => product.to_param, :product => { :name => "I hacked your store!" }
|
|
103
|
+
assert_unauthorized!
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it "cannot delete a product" do
|
|
107
|
+
api_delete :destroy, :id => product.to_param
|
|
108
|
+
assert_unauthorized!
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
context "as an admin" do
|
|
113
|
+
sign_in_as_admin!
|
|
114
|
+
|
|
115
|
+
it "can see all products" do
|
|
116
|
+
api_get :index
|
|
117
|
+
json_response["products"].count.should == 2
|
|
118
|
+
json_response["count"].should == 2
|
|
119
|
+
json_response["current_page"].should == 1
|
|
120
|
+
json_response["pages"].should == 1
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "can create a new product" do
|
|
124
|
+
api_post :create, :product => { :name => "The Other Product",
|
|
125
|
+
:price => 19.99 }
|
|
126
|
+
json_response.should have_attributes(attributes)
|
|
127
|
+
response.status.should == 201
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it "cannot create a new product with invalid attributes" do
|
|
131
|
+
api_post :create, :product => {}
|
|
132
|
+
response.status.should == 422
|
|
133
|
+
json_response["error"].should == "Invalid resource. Please fix errors and try again."
|
|
134
|
+
errors = json_response["errors"]
|
|
135
|
+
errors.delete("permalink") # Don't care about this one.
|
|
136
|
+
errors.keys.should =~ ["name", "price"]
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it "can update a product" do
|
|
140
|
+
api_put :update, :id => product.to_param, :product => { :name => "New and Improved Product!" }
|
|
141
|
+
response.status.should == 200
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it "cannot update a product with an invalid attribute" do
|
|
145
|
+
api_put :update, :id => product.to_param, :product => { :name => "" }
|
|
146
|
+
response.status.should == 422
|
|
147
|
+
json_response["error"].should == "Invalid resource. Please fix errors and try again."
|
|
148
|
+
json_response["errors"]["name"].should == ["can't be blank"]
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it "can delete a product" do
|
|
152
|
+
product.deleted_at.should be_nil
|
|
153
|
+
api_delete :destroy, :id => product.to_param
|
|
154
|
+
response.status.should == 200
|
|
155
|
+
product.reload.deleted_at.should_not be_nil
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
describe Api::V1::VariantsController do
|
|
5
|
+
render_views
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
let!(:product) { Factory(:product) }
|
|
9
|
+
let!(:variant) do
|
|
10
|
+
variant = product.master
|
|
11
|
+
variant.option_values << Factory(:option_value)
|
|
12
|
+
variant
|
|
13
|
+
end
|
|
14
|
+
let!(:attributes) { [:id, :name, :count_on_hand,
|
|
15
|
+
:sku, :price, :weight, :height,
|
|
16
|
+
:width, :depth, :is_master, :cost_price] }
|
|
17
|
+
|
|
18
|
+
before do
|
|
19
|
+
stub_authentication!
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "can see a list of all variants" do
|
|
23
|
+
api_get :index
|
|
24
|
+
json_response.first.should have_attributes(attributes)
|
|
25
|
+
option_values = json_response.last["variant"]["option_values"]
|
|
26
|
+
option_values.first.should have_attributes([:name,
|
|
27
|
+
:presentation,
|
|
28
|
+
:option_type_name,
|
|
29
|
+
:option_type_id])
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "can see a single variant" do
|
|
33
|
+
api_get :show, :id => variant.to_param
|
|
34
|
+
json_response.should have_attributes(attributes)
|
|
35
|
+
option_values = json_response["variant"]["option_values"]
|
|
36
|
+
option_values.first.should have_attributes([:name,
|
|
37
|
+
:presentation,
|
|
38
|
+
:option_type_name,
|
|
39
|
+
:option_type_id])
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "can learn how to create a new variant" do
|
|
43
|
+
api_get :new
|
|
44
|
+
json_response["attributes"].should == attributes.map(&:to_s)
|
|
45
|
+
json_response["required_attributes"].should be_empty
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "cannot create a new variant if not an admin" do
|
|
49
|
+
api_post :create, :variant => { :sku => "12345" }
|
|
50
|
+
assert_unauthorized!
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it "cannot update a variant" do
|
|
54
|
+
api_put :update, :id => variant.to_param, :variant => { :sku => "12345" }
|
|
55
|
+
assert_unauthorized!
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "cannot delete a variant" do
|
|
59
|
+
api_delete :destroy, :id => variant.to_param
|
|
60
|
+
assert_unauthorized!
|
|
61
|
+
lambda { variant.reload }.should_not raise_error
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
context "as an admin" do
|
|
65
|
+
sign_in_as_admin!
|
|
66
|
+
let(:resource_scoping) { { :product_id => variant.product.to_param } }
|
|
67
|
+
|
|
68
|
+
it "can create a new variant" do
|
|
69
|
+
api_post :create, :variant => { :sku => "12345" }
|
|
70
|
+
json_response.should have_attributes(attributes)
|
|
71
|
+
response.status.should == 201
|
|
72
|
+
|
|
73
|
+
variant.product.variants.count.should == 1
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "can update a variant" do
|
|
77
|
+
api_put :update, :id => variant.to_param, :variant => { :sku => "12345" }
|
|
78
|
+
response.status.should == 200
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it "can delete a variant" do
|
|
82
|
+
api_delete :destroy, :id => variant.to_param
|
|
83
|
+
response.status.should == 200
|
|
84
|
+
lambda { variant.reload }.should raise_error(ActiveRecord::RecordNotFound)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
end
|
|
90
|
+
end
|