spree_api 1.0.7 → 1.1.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|