omise 0.4.0 → 0.5.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 +9 -0
- data/bin/console +9 -0
- data/bin/rake +17 -0
- data/lib/omise/all.rb +3 -0
- data/lib/omise/attributes.rb +12 -3
- data/lib/omise/card_list.rb +1 -6
- data/lib/omise/charge.rb +5 -0
- data/lib/omise/charge_list.rb +10 -0
- data/lib/omise/customer.rb +12 -2
- data/lib/omise/dispute.rb +10 -0
- data/lib/omise/document.rb +15 -0
- data/lib/omise/document_list.rb +15 -0
- data/lib/omise/error.rb +3 -5
- data/lib/omise/link.rb +37 -0
- data/lib/omise/list.rb +53 -2
- data/lib/omise/recipient.rb +5 -0
- data/lib/omise/refund.rb +4 -0
- data/lib/omise/refund_list.rb +0 -5
- data/lib/omise/resource.rb +27 -13
- data/lib/omise/search.rb +9 -0
- data/lib/omise/search_scope.rb +59 -0
- data/lib/omise/testing/resource.rb +1 -1
- data/lib/omise/transfer.rb +4 -0
- data/lib/omise/util.rb +44 -1
- data/lib/omise/version.rb +1 -1
- data/omise.gemspec +2 -1
- data/test/fixtures/api.omise.co/charges-get-limit-20-offset-0.json +59 -0
- data/test/fixtures/api.omise.co/charges-get-limit-20-offset-20.json +59 -0
- data/test/fixtures/api.omise.co/disputes/dspt_test_5089off452g5m5te7xs/documents-get.json +19 -0
- data/test/fixtures/api.omise.co/disputes/dspt_test_5089off452g5m5te7xs/documents-post.json +7 -0
- data/test/fixtures/api.omise.co/disputes/dspt_test_5089off452g5m5te7xs/documents/docu_test_55869onwfm2g3bsw8d8-delete.json +6 -0
- data/test/fixtures/api.omise.co/disputes/dspt_test_5089off452g5m5te7xs/documents/docu_test_55869onwfm2g3bsw8d8-get.json +7 -0
- data/test/fixtures/api.omise.co/links-get.json +94 -0
- data/test/fixtures/api.omise.co/links-post.json +82 -0
- data/test/fixtures/api.omise.co/links/link_test_55pcclmznvrv9lc7r9s-get.json +82 -0
- data/test/fixtures/api.omise.co/search-get-scope-charge.json +62 -0
- data/test/omise/test_attributes.rb +79 -0
- data/test/omise/test_charge.rb +5 -0
- data/test/omise/test_customer.rb +11 -0
- data/test/omise/test_dispute.rb +9 -0
- data/test/omise/test_document.rb +33 -0
- data/test/omise/test_link.rb +36 -0
- data/test/omise/test_list.rb +101 -0
- data/test/omise/test_recipient.rb +5 -0
- data/test/omise/test_resource.rb +2 -1
- data/test/omise/test_search.rb +10 -0
- data/test/omise/test_search_scope.rb +138 -0
- data/test/omise/test_transfer.rb +1 -1
- data/test/omise/test_util.rb +65 -0
- data/test/support.rb +2 -2
- metadata +59 -4
@@ -0,0 +1,82 @@
|
|
1
|
+
{
|
2
|
+
"object": "link",
|
3
|
+
"id": "link_test_55pcclmznvrv9lc7r9s",
|
4
|
+
"livemode": false,
|
5
|
+
"location": "/links/link_test_55pcclmznvrv9lc7r9s",
|
6
|
+
"amount": 10000,
|
7
|
+
"currency": "thb",
|
8
|
+
"used": true,
|
9
|
+
"multiple": false,
|
10
|
+
"title": "Lunch",
|
11
|
+
"description": "Pay me back for lunch",
|
12
|
+
"charges": {
|
13
|
+
"object": "list",
|
14
|
+
"from": "1970-01-01T00:00:00+00:00",
|
15
|
+
"to": "2016-11-09T03:28:42+00:00",
|
16
|
+
"offset": 0,
|
17
|
+
"limit": 20,
|
18
|
+
"total": 1,
|
19
|
+
"order": null,
|
20
|
+
"location": "/links/link_test_55pcclmznvrv9lc7r9s/charges",
|
21
|
+
"data": [
|
22
|
+
{
|
23
|
+
"object": "charge",
|
24
|
+
"id": "chrg_test_55pcd9rn4dz1r8rtokz",
|
25
|
+
"livemode": false,
|
26
|
+
"location": "/charges/chrg_test_55pcd9rn4dz1r8rtokz",
|
27
|
+
"amount": 10000,
|
28
|
+
"currency": "thb",
|
29
|
+
"description": "Lunch\n\nPay me back for lunch",
|
30
|
+
"status": "successful",
|
31
|
+
"capture": true,
|
32
|
+
"authorized": true,
|
33
|
+
"reversed": false,
|
34
|
+
"paid": true,
|
35
|
+
"transaction": "trxn_test_55pcd9t5vh5m7rflo7x",
|
36
|
+
"refunded": 0,
|
37
|
+
"refunds": {
|
38
|
+
"object": "list",
|
39
|
+
"from": "1970-01-01T00:00:00+00:00",
|
40
|
+
"to": "2016-11-09T03:28:42+00:00",
|
41
|
+
"offset": 0,
|
42
|
+
"limit": 20,
|
43
|
+
"total": 0,
|
44
|
+
"order": null,
|
45
|
+
"location": "/charges/chrg_test_55pcd9rn4dz1r8rtokz/refunds",
|
46
|
+
"data": [
|
47
|
+
|
48
|
+
]
|
49
|
+
},
|
50
|
+
"return_uri": "https://link.omise.co/AC6BD2FD/complete",
|
51
|
+
"reference": "paym_test_55pcd9rzzt5hsko5loq",
|
52
|
+
"authorize_uri": "http://api.omise.co/payments/paym_test_55pcd9rzzt5hsko5loq/authorize",
|
53
|
+
"failure_code": null,
|
54
|
+
"failure_message": null,
|
55
|
+
"card": {
|
56
|
+
"object": "card",
|
57
|
+
"id": "card_test_55pcd8si7fqp1zuihwk",
|
58
|
+
"livemode": false,
|
59
|
+
"country": "us",
|
60
|
+
"city": null,
|
61
|
+
"postal_code": null,
|
62
|
+
"financing": "",
|
63
|
+
"bank": "",
|
64
|
+
"last_digits": "4242",
|
65
|
+
"brand": "Visa",
|
66
|
+
"expiration_month": 7,
|
67
|
+
"expiration_year": 2019,
|
68
|
+
"fingerprint": "hdEymlzWwHtOipbRxVUp3Ek7q13+1KUtwIvkkwz2cqE=",
|
69
|
+
"name": "sanjeev",
|
70
|
+
"security_code_check": true,
|
71
|
+
"created": "2016-10-18T06:56:47Z"
|
72
|
+
},
|
73
|
+
"customer": null,
|
74
|
+
"ip": "101.127.195.82",
|
75
|
+
"dispute": null,
|
76
|
+
"created": "2016-10-18T06:56:51Z"
|
77
|
+
}
|
78
|
+
]
|
79
|
+
},
|
80
|
+
"payment_uri": "https://link.omise.co/AC6BD2FD",
|
81
|
+
"created": "2016-10-18T06:54:57Z"
|
82
|
+
}
|
@@ -0,0 +1,62 @@
|
|
1
|
+
{
|
2
|
+
"object": "search",
|
3
|
+
"order": "chronological",
|
4
|
+
"scope": "charge",
|
5
|
+
"query": "",
|
6
|
+
"filters": {
|
7
|
+
},
|
8
|
+
"page": 1,
|
9
|
+
"total_pages": 1,
|
10
|
+
"total": 1,
|
11
|
+
"data": [
|
12
|
+
{
|
13
|
+
"object": "charge",
|
14
|
+
"id": "chrg_test_4yq7duw15p9hdrjp8oq",
|
15
|
+
"livemode": false,
|
16
|
+
"location": "/charges/chrg_test_4yq7duw15p9hdrjp8oq",
|
17
|
+
"amount": 100000,
|
18
|
+
"currency": "thb",
|
19
|
+
"description": "Charge for order 3947",
|
20
|
+
"capture": true,
|
21
|
+
"authorized": true,
|
22
|
+
"captured": true,
|
23
|
+
"transaction": "trxn_test_4yq7duwb9jts1vxgqua",
|
24
|
+
"refunded": 0,
|
25
|
+
"refunds": {
|
26
|
+
"object": "list",
|
27
|
+
"from": "1970-01-01T00:00:00+00:00",
|
28
|
+
"to": "2015-01-15T05:04:30+00:00",
|
29
|
+
"offset": 0,
|
30
|
+
"limit": 20,
|
31
|
+
"total": 0,
|
32
|
+
"data": [
|
33
|
+
|
34
|
+
],
|
35
|
+
"location": "/charges/chrg_test_4yq7duw15p9hdrjp8oq/refunds"
|
36
|
+
},
|
37
|
+
"failure_code": null,
|
38
|
+
"failure_message": null,
|
39
|
+
"card": {
|
40
|
+
"object": "card",
|
41
|
+
"id": "card_test_4yq6tuucl9h4erukfl0",
|
42
|
+
"livemode": false,
|
43
|
+
"location": "/customers/cust_test_4yq6txdpfadhbaqnwp3/cards/card_test_4yq6tuucl9h4erukfl0",
|
44
|
+
"country": "",
|
45
|
+
"city": "Bangkok",
|
46
|
+
"postal_code": "10320",
|
47
|
+
"financing": "",
|
48
|
+
"last_digits": "4242",
|
49
|
+
"brand": "Visa",
|
50
|
+
"expiration_month": 1,
|
51
|
+
"expiration_year": 2017,
|
52
|
+
"fingerprint": "sRF/oMw2UQJJp/WbU+2/ZbVzwROjpMf1lyhOHhOqziw=",
|
53
|
+
"name": "JOHN DOE",
|
54
|
+
"security_code_check": true,
|
55
|
+
"created": "2015-01-15T04:03:40Z"
|
56
|
+
},
|
57
|
+
"customer": "cust_test_4yq6txdpfadhbaqnwp3",
|
58
|
+
"ip": null,
|
59
|
+
"created": "2015-01-15T05:00:29Z"
|
60
|
+
}
|
61
|
+
]
|
62
|
+
}
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require "support"
|
2
|
+
|
3
|
+
module Omise
|
4
|
+
class Teapot
|
5
|
+
include Attributes
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class TestAttributes < Omise::Test
|
10
|
+
setup do
|
11
|
+
@attributes = JSON.load(JSON.dump({
|
12
|
+
object: "teapot",
|
13
|
+
name: "Potts",
|
14
|
+
location: "/teapots/teap_1",
|
15
|
+
deleted: false,
|
16
|
+
child: {
|
17
|
+
object: "teapot",
|
18
|
+
name: "Chip Potts",
|
19
|
+
location: "/teapots/teap_2",
|
20
|
+
deleted: false,
|
21
|
+
}
|
22
|
+
}))
|
23
|
+
|
24
|
+
@teapot = Omise::Teapot.new(@attributes)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_that_we_can_create_a_teapot
|
28
|
+
assert_instance_of Omise::Teapot, @teapot
|
29
|
+
assert_equal "teapot", @teapot.object
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_that_the_child_of_a_teapot_is_still_a_teapot
|
33
|
+
assert_instance_of Omise::Teapot, @teapot.child
|
34
|
+
assert_equal "teapot", @teapot.child.object
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_that_we_can_get_the_attributes_of_the_teapot
|
38
|
+
assert_equal @attributes, @teapot.attributes
|
39
|
+
assert_equal @attributes, @teapot.as_json
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_that_we_can_update_the_teapot_attributes
|
43
|
+
@teapot.attributes.taint
|
44
|
+
@teapot.assign_attributes({})
|
45
|
+
|
46
|
+
refute @teapot.attributes.tainted?
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_that_we_can_tell_if_a_teapot_has_not_been_destroyed
|
50
|
+
refute @teapot.destroyed?
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_that_we_can_tell_if_a_teapot_has_been_destroyed
|
54
|
+
@teapot.assign_attributes(@attributes.merge("deleted" => true))
|
55
|
+
|
56
|
+
assert @teapot.destroyed?
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_that_we_get_the_location_of_the_teapot
|
60
|
+
assert_equal "/teapots/teap_1", @teapot.location
|
61
|
+
assert_equal "/teapots/teap_1/child", @teapot.location("child")
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_that_we_can_access_an_attributes_value_with_the_square_bracket_accessor
|
65
|
+
assert_equal "Potts", @teapot["name"]
|
66
|
+
assert_nil @teapot["color"]
|
67
|
+
assert_instance_of Omise::Teapot, @teapot["child"]
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_that_we_can_tell_if_a_key_is_present_in_the_attributes
|
71
|
+
assert @teapot.key?("name")
|
72
|
+
refute @teapot.key?("color")
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_that_a_teapot_respond_correctly_to_dynamic_method_names
|
76
|
+
assert @teapot.respond_to?("name")
|
77
|
+
refute @teapot.respond_to?("color")
|
78
|
+
end
|
79
|
+
end
|
data/test/omise/test_charge.rb
CHANGED
@@ -101,4 +101,9 @@ class TestCharge < Omise::Test
|
|
101
101
|
def test_that_we_can_send_a_reverse_request
|
102
102
|
assert @charge.reverse
|
103
103
|
end
|
104
|
+
|
105
|
+
def test_that_search_returns_a_scoped_search
|
106
|
+
assert_instance_of Omise::SearchScope, Omise::Charge.search
|
107
|
+
assert_equal "charge", Omise::Charge.search.scope
|
108
|
+
end
|
104
109
|
end
|
data/test/omise/test_customer.rb
CHANGED
@@ -43,6 +43,12 @@ class TestCustomer < Omise::Test
|
|
43
43
|
refute @customer.attributes.tainted?
|
44
44
|
end
|
45
45
|
|
46
|
+
def test_that_we_can_charge_a_customer
|
47
|
+
charge = @customer.charge(amount: 100000, currency: "THB")
|
48
|
+
|
49
|
+
assert_instance_of Omise::Charge, charge
|
50
|
+
end
|
51
|
+
|
46
52
|
def test_that_retrieveing_a_non_existing_customer_will_raise_an_error
|
47
53
|
assert_raises Omise::Error do
|
48
54
|
Omise::Customer.retrieve("404")
|
@@ -61,4 +67,9 @@ class TestCustomer < Omise::Test
|
|
61
67
|
def test_that_a_customer_has_a_default_card
|
62
68
|
assert_instance_of Omise::Card, @customer.default_card
|
63
69
|
end
|
70
|
+
|
71
|
+
def test_that_search_returns_a_scoped_search
|
72
|
+
assert_instance_of Omise::SearchScope, Omise::Customer.search
|
73
|
+
assert_equal "customer", Omise::Customer.search.scope
|
74
|
+
end
|
64
75
|
end
|
data/test/omise/test_dispute.rb
CHANGED
@@ -39,4 +39,13 @@ class TestDispute < Omise::Test
|
|
39
39
|
|
40
40
|
assert_equal @dispute.message, "Your dispute message"
|
41
41
|
end
|
42
|
+
|
43
|
+
def test_that_we_can_retrieve_a_list_of_documents
|
44
|
+
assert_instance_of Omise::DocumentList, @dispute.documents
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_that_search_returns_a_scoped_search
|
48
|
+
assert_instance_of Omise::SearchScope, Omise::Dispute.search
|
49
|
+
assert_equal "dispute", Omise::Dispute.search.scope
|
50
|
+
end
|
42
51
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "support"
|
2
|
+
|
3
|
+
class TestDocument < Omise::Test
|
4
|
+
setup do
|
5
|
+
@documents = Omise::Dispute.retrieve("dspt_test_5089off452g5m5te7xs").documents
|
6
|
+
@document = @documents.retrieve("docu_test_55869onwfm2g3bsw8d8")
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_that_we_can_retrieve_a_document
|
10
|
+
assert_instance_of Omise::Document, @document
|
11
|
+
assert_equal "docu_test_55869onwfm2g3bsw8d8", @document.id
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_that_we_can_upload_a_new_document
|
15
|
+
document = @documents.upload(StringIO.new)
|
16
|
+
|
17
|
+
assert_instance_of Omise::Document, document
|
18
|
+
assert_equal "docu_test_55869onwfm2g3bsw8d8", document.id
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_that_a_document_can_be_reloaded
|
22
|
+
@document.attributes.taint
|
23
|
+
@document.reload
|
24
|
+
|
25
|
+
refute @document.attributes.tainted?
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_that_we_can_destroy_a_document
|
29
|
+
@document.destroy
|
30
|
+
|
31
|
+
assert @document.deleted
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require "support"
|
2
|
+
|
3
|
+
class TestLink < Omise::Test
|
4
|
+
setup do
|
5
|
+
@link = Omise::Link.retrieve("link_test_55pcclmznvrv9lc7r9s")
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_that_we_can_create_a_link
|
9
|
+
link = Omise::Link.create
|
10
|
+
|
11
|
+
assert_instance_of Omise::Link, link
|
12
|
+
assert_equal "link_test_55pcclmznvrv9lc7r9s", link.id
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_that_we_can_retrieve_a_link
|
16
|
+
assert_instance_of Omise::Link, @link
|
17
|
+
assert_equal "link_test_55pcclmznvrv9lc7r9s", @link.id
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_that_we_can_list_all_links
|
21
|
+
links = Omise::Link.list
|
22
|
+
|
23
|
+
assert_instance_of Omise::List, links
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_that_we_can_reload_a_link
|
27
|
+
@link.attributes.taint
|
28
|
+
@link.reload
|
29
|
+
|
30
|
+
refute @link.attributes.tainted?
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_that_a_link_has_a_list_of_charges
|
34
|
+
assert_instance_of Omise::ChargeList, @link.charges
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require "support"
|
2
|
+
|
3
|
+
class TestList < Omise::Test
|
4
|
+
setup do
|
5
|
+
attributes = JSON.parse(JSON.generate({
|
6
|
+
object: "list",
|
7
|
+
location: "/charges",
|
8
|
+
offset: 0,
|
9
|
+
limit: 20,
|
10
|
+
total: 40,
|
11
|
+
data: 20.times.map { |i| { object: "charge", id: "chrg_#{i}" } },
|
12
|
+
}))
|
13
|
+
|
14
|
+
@parent = Object.new
|
15
|
+
@list = Omise::List.new(attributes, parent: @parent)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_that_we_can_initialize_a_list
|
19
|
+
assert_instance_of Omise::List, @list
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_that_we_can_reload_a_list
|
23
|
+
assert @list.reload
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_that_we_can_get_the_parent
|
27
|
+
assert_equal @parent, @list.parent
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_that_we_know_if_we_are_on_the_first_page
|
31
|
+
assert make_paginated_list(00, 20, 60).first_page?
|
32
|
+
refute make_paginated_list(20, 20, 60).first_page?
|
33
|
+
refute make_paginated_list(40, 20, 60).first_page?
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_that_we_know_if_we_are_on_the_last_page
|
37
|
+
refute make_paginated_list(00, 20, 60).last_page?
|
38
|
+
refute make_paginated_list(20, 20, 60).last_page?
|
39
|
+
assert make_paginated_list(40, 20, 60).last_page?
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_that_we_know_on_which_page_we_are
|
43
|
+
assert_equal 1, make_paginated_list(00, 20, 60).page
|
44
|
+
assert_equal 2, make_paginated_list(20, 20, 60).page
|
45
|
+
assert_equal 3, make_paginated_list(40, 20, 60).page
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_that_we_know_how_many_page_there_is
|
49
|
+
assert_equal 0, make_paginated_list(00, 20, 00).total_pages
|
50
|
+
assert_equal 1, make_paginated_list(00, 20, 10).total_pages
|
51
|
+
assert_equal 1, make_paginated_list(00, 20, 20).total_pages
|
52
|
+
assert_equal 2, make_paginated_list(00, 20, 30).total_pages
|
53
|
+
assert_equal 2, make_paginated_list(00, 20, 40).total_pages
|
54
|
+
assert_equal 3, make_paginated_list(00, 20, 50).total_pages
|
55
|
+
assert_equal 3, make_paginated_list(00, 20, 60).total_pages
|
56
|
+
assert_equal 4, make_paginated_list(00, 20, 70).total_pages
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_that_we_can_go_to_the_next_page
|
60
|
+
assert_nil make_paginated_list(0, 20, 10).next_page
|
61
|
+
assert_instance_of Omise::List, make_paginated_list(0, 20, 30).next_page
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_that_we_can_go_to_the_previous_page
|
65
|
+
assert_nil make_paginated_list(0, 20, 30).previous_page
|
66
|
+
assert_instance_of Omise::List, make_paginated_list(20, 20, 30).previous_page
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_that_we_can_go_to_a_specific_page
|
70
|
+
assert_nil make_paginated_list(0, 20, 100).jump_to_page(6)
|
71
|
+
assert_instance_of Omise::List, make_paginated_list(0, 20, 100).jump_to_page(2)
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_we_can_get_enumerate_a_list
|
75
|
+
assert_instance_of Enumerator, @list.each
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_we_can_get_the_array
|
79
|
+
assert_instance_of Array, @list.to_a
|
80
|
+
assert_instance_of Omise::Charge, @list.to_a.first
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_that_we_can_get_the_last_element_of_the_array
|
84
|
+
assert_equal "chrg_19", @list.last.id
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def make_paginated_list(offset, limit, total)
|
90
|
+
attributes = JSON.parse(JSON.generate({
|
91
|
+
object: "list",
|
92
|
+
location: "/charges",
|
93
|
+
offset: offset,
|
94
|
+
limit: limit,
|
95
|
+
total: total,
|
96
|
+
data: limit.times.map { { object: "charge" } },
|
97
|
+
}))
|
98
|
+
|
99
|
+
Omise::List.new(attributes)
|
100
|
+
end
|
101
|
+
end
|