spree_api 2.2.14 → 2.3.0
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/CHANGELOG.md +43 -1
- data/app/controllers/spree/api/base_controller.rb +8 -12
- data/app/controllers/spree/api/checkouts_controller.rb +4 -58
- data/app/controllers/spree/api/inventory_units_controller.rb +0 -1
- data/app/controllers/spree/api/line_items_controller.rb +3 -3
- data/app/controllers/spree/api/option_types_controller.rb +2 -2
- data/app/controllers/spree/api/orders_controller.rb +11 -36
- data/app/controllers/spree/api/payments_controller.rb +2 -2
- data/app/controllers/spree/api/products_controller.rb +6 -36
- data/app/controllers/spree/api/shipments_controller.rb +6 -25
- data/app/controllers/spree/api/taxonomies_controller.rb +8 -6
- data/app/controllers/spree/api/taxons_controller.rb +1 -1
- data/app/controllers/spree/api/variants_controller.rb +16 -19
- data/app/helpers/spree/api/api_helpers.rb +6 -1
- data/app/views/spree/api/errors/invalid_resource.v1.rabl +1 -1
- data/app/views/spree/api/orders/could_not_transition.v1.rabl +1 -1
- data/app/views/spree/api/orders/order.v1.rabl +1 -1
- data/app/views/spree/api/orders/show.v1.rabl +10 -4
- data/app/views/spree/api/shipments/small.v1.rabl +33 -0
- data/app/views/spree/api/taxonomies/show.v1.rabl +2 -2
- data/app/views/spree/api/users/show.v1.rabl +7 -0
- data/config/routes.rb +19 -28
- data/lib/spree/api/engine.rb +3 -3
- data/lib/spree/api/responders/rabl_template.rb +1 -1
- data/lib/spree/api/testing_support/helpers.rb +8 -3
- data/spec/controllers/spree/api/base_controller_spec.rb +15 -12
- data/spec/controllers/spree/api/checkouts_controller_spec.rb +78 -90
- data/spec/controllers/spree/api/line_items_controller_spec.rb +13 -9
- data/spec/controllers/spree/api/orders_controller_spec.rb +53 -31
- data/spec/controllers/spree/api/payments_controller_spec.rb +9 -8
- data/spec/controllers/spree/api/products_controller_spec.rb +1 -1
- data/spec/controllers/spree/api/promotion_application_spec.rb +5 -5
- data/spec/controllers/spree/api/shipments_controller_spec.rb +1 -11
- data/spec/controllers/spree/api/taxonomies_controller_spec.rb +2 -2
- data/spec/controllers/spree/api/users_controller_spec.rb +23 -23
- data/spec/controllers/spree/api/zones_controller_spec.rb +22 -0
- data/spec/requests/rabl_cache_spec.rb +2 -2
- data/spec/spec_helper.rb +0 -1
- data/spec/support/controller_hacks.rb +1 -1
- data/spree_api.gemspec +2 -2
- metadata +12 -15
- data/app/views/spree/api/orders/delivery.v1.rabl +0 -3
- data/lib/spree/api/version.rb +0 -5
- data/spec/requests/ransackable_attributes_spec.rb +0 -79
@@ -10,7 +10,7 @@ module Spree::Api
|
|
10
10
|
|
11
11
|
context "with an available promotion" do
|
12
12
|
let!(:order) { create(:order_with_line_items, :line_items_count => 1) }
|
13
|
-
let!(:promotion) do
|
13
|
+
let!(:promotion) do
|
14
14
|
promotion = Spree::Promotion.create(name: "10% off", code: "10off")
|
15
15
|
calculator = Spree::Calculator::FlatPercentItemTotal.create(preferred_flat_percent: "10")
|
16
16
|
action = Spree::Promotion::Actions::CreateItemAdjustments.create(calculator: calculator)
|
@@ -20,12 +20,12 @@ module Spree::Api
|
|
20
20
|
|
21
21
|
it "can apply a coupon code to the order" do
|
22
22
|
order.total.should == 110.00
|
23
|
-
api_put :apply_coupon_code, :id => order.to_param, :coupon_code => "10off", :order_token => order.
|
23
|
+
api_put :apply_coupon_code, :id => order.to_param, :coupon_code => "10off", :order_token => order.guest_token
|
24
24
|
response.status.should == 200
|
25
25
|
order.reload.total.should == 109.00
|
26
26
|
json_response["success"].should == "The coupon code was successfully applied to your order."
|
27
27
|
json_response["error"].should be_blank
|
28
|
-
json_response["successful"].should
|
28
|
+
json_response["successful"].should be_true
|
29
29
|
end
|
30
30
|
|
31
31
|
context "with an expired promotion" do
|
@@ -36,11 +36,11 @@ module Spree::Api
|
|
36
36
|
end
|
37
37
|
|
38
38
|
it "fails to apply" do
|
39
|
-
api_put :apply_coupon_code, :id => order.to_param, :coupon_code => "10off", :order_token => order.
|
39
|
+
api_put :apply_coupon_code, :id => order.to_param, :coupon_code => "10off", :order_token => order.guest_token
|
40
40
|
response.status.should == 422
|
41
41
|
json_response["success"].should be_blank
|
42
42
|
json_response["error"].should == "The coupon code is expired"
|
43
|
-
json_response["successful"].should
|
43
|
+
json_response["successful"].should be_false
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
@@ -52,7 +52,7 @@ describe Spree::Api::ShipmentsController do
|
|
52
52
|
response.status.should == 200
|
53
53
|
json_response['stock_location_name'].should == stock_location.name
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
it "can make a shipment ready" do
|
57
57
|
Spree::Order.any_instance.stub(:paid? => true, :complete? => true)
|
58
58
|
api_put :ready
|
@@ -105,16 +105,6 @@ describe Spree::Api::ShipmentsController do
|
|
105
105
|
json_response["state"].should == "shipped"
|
106
106
|
end
|
107
107
|
|
108
|
-
context 'DEPRECATED:' do
|
109
|
-
it "can transition a shipment from ready to ship" do
|
110
|
-
ActiveSupport::Deprecation.should_receive(:warn).once
|
111
|
-
shipment.reload
|
112
|
-
api_put :ship, order_id: shipment.order.to_param, id: shipment.to_param, shipment: { tracking: "123123" }
|
113
|
-
json_response.should have_attributes(attributes)
|
114
|
-
json_response["state"].should == "shipped"
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
108
|
end
|
119
109
|
end
|
120
110
|
end
|
@@ -47,7 +47,7 @@ module Spree
|
|
47
47
|
children = json_response['root']['taxons']
|
48
48
|
children.count.should eq 1
|
49
49
|
children.first['name'].should eq taxon.name
|
50
|
-
children.first.key?('taxons').should
|
50
|
+
children.first.key?('taxons').should be_false
|
51
51
|
end
|
52
52
|
|
53
53
|
it "gets a single taxonomy with set=nested" do
|
@@ -56,7 +56,7 @@ module Spree
|
|
56
56
|
json_response['name'].should eq taxonomy.name
|
57
57
|
|
58
58
|
children = json_response['root']['taxons']
|
59
|
-
children.first.key?('taxons').should
|
59
|
+
children.first.key?('taxons').should be_true
|
60
60
|
end
|
61
61
|
|
62
62
|
it "gets the jstree-friendly version of a taxonomy" do
|
@@ -4,68 +4,70 @@ module Spree
|
|
4
4
|
describe Api::UsersController do
|
5
5
|
render_views
|
6
6
|
|
7
|
-
let(:user) { create(:user
|
7
|
+
let(:user) { create(:user) }
|
8
8
|
let(:stranger) { create(:user, :email => 'stranger@example.com') }
|
9
9
|
let(:attributes) { [:id, :email, :created_at, :updated_at] }
|
10
10
|
|
11
|
+
before { stub_authentication! }
|
12
|
+
|
11
13
|
context "as a normal user" do
|
14
|
+
before do
|
15
|
+
controller.stub :try_spree_current_user => user
|
16
|
+
end
|
17
|
+
|
12
18
|
it "can get own details" do
|
13
|
-
api_get :show,
|
19
|
+
api_get :show, :id => user.id
|
14
20
|
|
15
|
-
|
21
|
+
json_response['email'].should eq user.email
|
16
22
|
end
|
17
23
|
|
18
24
|
it "cannot get other users details" do
|
19
|
-
api_get :show, id
|
25
|
+
api_get :show, :id => stranger.id
|
20
26
|
|
21
27
|
assert_not_found!
|
22
28
|
end
|
23
29
|
|
24
30
|
it "can learn how to create a new user" do
|
25
|
-
api_get :new
|
26
|
-
|
31
|
+
api_get :new
|
32
|
+
json_response["attributes"].should == attributes.map(&:to_s)
|
27
33
|
end
|
28
34
|
|
29
35
|
it "can create a new user" do
|
30
|
-
|
31
|
-
|
32
|
-
}
|
33
|
-
|
34
|
-
api_post :create, :user => user_params, token: user.spree_api_key
|
35
|
-
expect(json_response['email']).to eq 'new@example.com'
|
36
|
+
api_post :create, :user => { :email => 'new@example.com', :password => 'spree123', :password_confirmation => 'spree123' }
|
37
|
+
json_response['email'].should eq 'new@example.com'
|
36
38
|
end
|
37
39
|
|
38
40
|
# there's no validations on LegacyUser?
|
39
41
|
xit "cannot create a new user with invalid attributes" do
|
40
|
-
api_post :create, :user => {}
|
41
|
-
|
42
|
-
|
42
|
+
api_post :create, :user => {}
|
43
|
+
response.status.should == 422
|
44
|
+
json_response["error"].should == "Invalid resource. Please fix errors and try again."
|
43
45
|
errors = json_response["errors"]
|
44
46
|
end
|
45
47
|
|
46
48
|
it "can update own details" do
|
47
|
-
api_put :update, id
|
49
|
+
api_put :update, :id => user.id, :user => { :email => "mine@example.com" }
|
48
50
|
json_response['email'].should eq 'mine@example.com'
|
49
51
|
end
|
50
52
|
|
51
53
|
it "cannot update other users details" do
|
52
|
-
api_put :update, id
|
54
|
+
api_put :update, :id => stranger.id, :user => { :email => "mine@example.com" }
|
53
55
|
assert_not_found!
|
54
56
|
end
|
55
57
|
|
56
58
|
it "can delete itself" do
|
57
|
-
api_delete :destroy,
|
58
|
-
|
59
|
+
api_delete :destroy, :id => user.id
|
60
|
+
response.status.should == 204
|
59
61
|
end
|
60
62
|
|
61
63
|
it "cannot delete other user" do
|
62
|
-
api_delete :destroy, id
|
64
|
+
api_delete :destroy, :id => stranger.id
|
63
65
|
assert_not_found!
|
64
66
|
end
|
65
67
|
|
66
68
|
it "should only get own details on index" do
|
67
69
|
2.times { create(:user) }
|
68
|
-
api_get :index
|
70
|
+
api_get :index
|
69
71
|
|
70
72
|
Spree.user_class.count.should eq 3
|
71
73
|
json_response['count'].should eq 1
|
@@ -74,8 +76,6 @@ module Spree
|
|
74
76
|
end
|
75
77
|
|
76
78
|
context "as an admin" do
|
77
|
-
before { stub_authentication! }
|
78
|
-
|
79
79
|
sign_in_as_admin!
|
80
80
|
|
81
81
|
it "gets all users" do
|
@@ -38,6 +38,28 @@ module Spree
|
|
38
38
|
json_response['zone_members'].size.should eq @zone.zone_members.count
|
39
39
|
end
|
40
40
|
|
41
|
+
context "specifying a rabl template to use" do
|
42
|
+
before do
|
43
|
+
Spree::Api::ZonesController.class_eval do
|
44
|
+
def custom_show
|
45
|
+
respond_with(zone)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
it "uses the specified template" do
|
51
|
+
request.headers['X-Spree-Template'] = 'show'
|
52
|
+
api_get :custom_show, :id => @zone.id
|
53
|
+
response.should render_template('spree/api/zones/show')
|
54
|
+
end
|
55
|
+
|
56
|
+
it "falls back to the default template if the specified template does not exist" do
|
57
|
+
request.headers['X-Spree-Template'] = 'invoice'
|
58
|
+
api_get :show, :id => @zone.id
|
59
|
+
response.should render_template('spree/api/zones/show')
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
41
63
|
context "as an admin" do
|
42
64
|
sign_in_as_admin!
|
43
65
|
|
@@ -18,13 +18,13 @@ describe "Rabl Cache", :caching => true do
|
|
18
18
|
!v['is_master']
|
19
19
|
end.first
|
20
20
|
|
21
|
-
variant_a['is_master'].should
|
21
|
+
variant_a['is_master'].should be_false
|
22
22
|
variant_a['stock_items'].should_not be_nil
|
23
23
|
|
24
24
|
get "/api/products/#{Spree::Product.first.id}", :token => user.spree_api_key
|
25
25
|
response.status.should == 200
|
26
26
|
variant_b = JSON.parse(response.body)['variants'].last
|
27
|
-
variant_b['is_master'].should
|
27
|
+
variant_b['is_master'].should be_false
|
28
28
|
|
29
29
|
variant_a['id'].should == variant_b['id']
|
30
30
|
variant_b['stock_items'].should be_nil
|
data/spec/spec_helper.rb
CHANGED
@@ -39,7 +39,6 @@ require 'spree/api/testing_support/setup'
|
|
39
39
|
RSpec.configure do |config|
|
40
40
|
config.backtrace_exclusion_patterns = [/gems\/activesupport/, /gems\/actionpack/, /gems\/rspec/]
|
41
41
|
config.color = true
|
42
|
-
config.infer_spec_type_from_file_location!
|
43
42
|
|
44
43
|
config.include FactoryGirl::Syntax::Methods
|
45
44
|
config.include Spree::Api::TestingSupport::Helpers, :type => :controller
|
data/spree_api.gemspec
CHANGED
@@ -16,6 +16,6 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.version = version
|
17
17
|
|
18
18
|
gem.add_dependency 'spree_core', version
|
19
|
-
gem.add_dependency 'rabl', '0.9.
|
20
|
-
gem.add_dependency 'versioncake', '~>
|
19
|
+
gem.add_dependency 'rabl', '~> 0.9.4.pre1'
|
20
|
+
gem.add_dependency 'versioncake', '~> 2.3.1'
|
21
21
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spree_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Bigg
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-06-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: spree_core
|
@@ -16,42 +16,42 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 2.
|
19
|
+
version: 2.3.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 2.
|
26
|
+
version: 2.3.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rabl
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.9.
|
33
|
+
version: 0.9.4.pre1
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.9.
|
40
|
+
version: 0.9.4.pre1
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: versioncake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 2.3.1
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 2.3.1
|
55
55
|
description: Spree's API
|
56
56
|
email:
|
57
57
|
- ryan@spreecommerce.com
|
@@ -121,7 +121,6 @@ files:
|
|
121
121
|
- app/views/spree/api/orders/complete.v1.rabl
|
122
122
|
- app/views/spree/api/orders/could_not_apply_coupon.v1.rabl
|
123
123
|
- app/views/spree/api/orders/could_not_transition.v1.rabl
|
124
|
-
- app/views/spree/api/orders/delivery.v1.rabl
|
125
124
|
- app/views/spree/api/orders/index.v1.rabl
|
126
125
|
- app/views/spree/api/orders/invalid_shipping_method.v1.rabl
|
127
126
|
- app/views/spree/api/orders/mine.v1.rabl
|
@@ -150,6 +149,7 @@ files:
|
|
150
149
|
- app/views/spree/api/shared/stock_location_required.v1.rabl
|
151
150
|
- app/views/spree/api/shipments/cannot_ready_shipment.v1.rabl
|
152
151
|
- app/views/spree/api/shipments/show.v1.rabl
|
152
|
+
- app/views/spree/api/shipments/small.v1.rabl
|
153
153
|
- app/views/spree/api/shipping_rates/show.v1.rabl
|
154
154
|
- app/views/spree/api/states/index.v1.rabl
|
155
155
|
- app/views/spree/api/states/show.v1.rabl
|
@@ -194,7 +194,6 @@ files:
|
|
194
194
|
- lib/spree/api/testing_support/caching.rb
|
195
195
|
- lib/spree/api/testing_support/helpers.rb
|
196
196
|
- lib/spree/api/testing_support/setup.rb
|
197
|
-
- lib/spree/api/version.rb
|
198
197
|
- lib/spree_api.rb
|
199
198
|
- script/rails
|
200
199
|
- spec/controllers/spree/api/addresses_controller_spec.rb
|
@@ -229,7 +228,6 @@ files:
|
|
229
228
|
- spec/fixtures/thinking-cat.jpg
|
230
229
|
- spec/models/spree/legacy_user_spec.rb
|
231
230
|
- spec/requests/rabl_cache_spec.rb
|
232
|
-
- spec/requests/ransackable_attributes_spec.rb
|
233
231
|
- spec/shared_examples/protect_product_actions.rb
|
234
232
|
- spec/spec_helper.rb
|
235
233
|
- spec/support/controller_hacks.rb
|
@@ -255,7 +253,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
255
253
|
version: '0'
|
256
254
|
requirements: []
|
257
255
|
rubyforge_project:
|
258
|
-
rubygems_version: 2.
|
256
|
+
rubygems_version: 2.2.2
|
259
257
|
signing_key:
|
260
258
|
specification_version: 4
|
261
259
|
summary: Spree's API
|
@@ -292,7 +290,6 @@ test_files:
|
|
292
290
|
- spec/fixtures/thinking-cat.jpg
|
293
291
|
- spec/models/spree/legacy_user_spec.rb
|
294
292
|
- spec/requests/rabl_cache_spec.rb
|
295
|
-
- spec/requests/ransackable_attributes_spec.rb
|
296
293
|
- spec/shared_examples/protect_product_actions.rb
|
297
294
|
- spec/spec_helper.rb
|
298
295
|
- spec/support/controller_hacks.rb
|
data/lib/spree/api/version.rb
DELETED
@@ -1,79 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe "Ransackable Attributes" do
|
4
|
-
let(:user) { create(:user).tap(&:generate_spree_api_key!) }
|
5
|
-
let(:order) { create(:order_with_line_items, user: user) }
|
6
|
-
context "filtering by attributes one association away" do
|
7
|
-
it "does not allow the filtering of variants by order attributes" do
|
8
|
-
2.times { create(:variant) }
|
9
|
-
|
10
|
-
get "/api/variants?q[orders_email_start]=#{order.email}", token: user.spree_api_key
|
11
|
-
|
12
|
-
variants_response = JSON.parse(response.body)
|
13
|
-
expect(variants_response['total_count']).to eq(Spree::Variant.count)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
context "filtering by attributes two associations away" do
|
18
|
-
it "does not allow the filtering of variants by user attributes" do
|
19
|
-
2.times { create(:variant) }
|
20
|
-
|
21
|
-
get "/api/variants?q[orders_user_email_start]=#{order.user.email}", token: user.spree_api_key
|
22
|
-
|
23
|
-
variants_response = JSON.parse(response.body)
|
24
|
-
expect(variants_response['total_count']).to eq(Spree::Variant.count)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
context "it maintains desired association behavior" do
|
29
|
-
it "allows filtering of variants product name" do
|
30
|
-
product = create(:product, name: "Fritos")
|
31
|
-
variant = create(:variant, product: product)
|
32
|
-
other_variant = create(:variant)
|
33
|
-
|
34
|
-
get "/api/variants?q[product_name_or_sku_cont]=fritos", token: user.spree_api_key
|
35
|
-
|
36
|
-
skus = JSON.parse(response.body)['variants'].map { |variant| variant['sku'] }
|
37
|
-
expect(skus).to include variant.sku
|
38
|
-
expect(skus).not_to include other_variant.sku
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
context "filtering by attributes" do
|
43
|
-
it "most attributes are not filterable by default" do
|
44
|
-
product = create(:product, description: "special product")
|
45
|
-
other_product = create(:product)
|
46
|
-
|
47
|
-
get "/api/products?q[description_cont]=special", token: user.spree_api_key
|
48
|
-
|
49
|
-
products_response = JSON.parse(response.body)
|
50
|
-
expect(products_response['total_count']).to eq(Spree::Product.count)
|
51
|
-
end
|
52
|
-
|
53
|
-
it "id is filterable by default" do
|
54
|
-
product = create(:product)
|
55
|
-
other_product = create(:product)
|
56
|
-
|
57
|
-
get "/api/products?q[id_eq]=#{product.id}", token: user.spree_api_key
|
58
|
-
|
59
|
-
product_names = JSON.parse(response.body)['products'].map { |product| product['name'] }
|
60
|
-
expect(product_names).to include product.name
|
61
|
-
expect(product_names).not_to include other_product.name
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
context "filtering by whitelisted attributes" do
|
66
|
-
it "filtering is supported for whitelisted attributes" do
|
67
|
-
product = create(:product, name: "Fritos")
|
68
|
-
other_product = create(:product)
|
69
|
-
|
70
|
-
get "/api/products?q[name_cont]=fritos", token: user.spree_api_key
|
71
|
-
|
72
|
-
product_names = JSON.parse(response.body)['products'].map { |product| product['name'] }
|
73
|
-
expect(product_names).to include product.name
|
74
|
-
expect(product_names).not_to include other_product.name
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
|
79
|
-
end
|