braintree 4.34.0 → 4.36.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.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/lib/braintree/apple_pay_card.rb +7 -0
  3. data/lib/braintree/apple_pay_gateway.rb +43 -0
  4. data/lib/braintree/base_module.rb +9 -0
  5. data/lib/braintree/credit_card_verification.rb +2 -0
  6. data/lib/braintree/customer.rb +2 -2
  7. data/lib/braintree/customer_gateway.rb +2 -0
  8. data/lib/braintree/error_codes.rb +20 -0
  9. data/lib/braintree/gateway.rb +4 -0
  10. data/lib/braintree/graphql/inputs/billing_address_input.rb +34 -0
  11. data/lib/braintree/graphql/inputs/create_local_payment_context_input.rb +44 -0
  12. data/lib/braintree/graphql/inputs/payer_info_input.rb +38 -0
  13. data/lib/braintree/graphql/inputs/shipping_address_input.rb +34 -0
  14. data/lib/braintree/local_payment_context.rb +108 -0
  15. data/lib/braintree/local_payment_context_gateway.rb +132 -0
  16. data/lib/braintree/local_payment_type.rb +6 -0
  17. data/lib/braintree/merchant_gateway.rb +16 -16
  18. data/lib/braintree/monetary_amount.rb +24 -0
  19. data/lib/braintree/payment_instrument_type.rb +1 -0
  20. data/lib/braintree/payment_method_parser.rb +1 -0
  21. data/lib/braintree/successful_result.rb +1 -0
  22. data/lib/braintree/test/nonce.rb +1 -0
  23. data/lib/braintree/test/transaction_amounts.rb +1 -0
  24. data/lib/braintree/transaction/visa_checkout_card_details.rb +2 -0
  25. data/lib/braintree/transaction.rb +8 -2
  26. data/lib/braintree/transaction_gateway.rb +12 -5
  27. data/lib/braintree/transaction_search.rb +1 -0
  28. data/lib/braintree/validation_error_collection.rb +1 -1
  29. data/lib/braintree/version.rb +1 -1
  30. data/lib/braintree/visa_checkout_card.rb +2 -0
  31. data/lib/braintree.rb +20 -3
  32. data/spec/integration/braintree/customer_spec.rb +550 -16
  33. data/spec/integration/braintree/http_spec.rb +1 -1
  34. data/spec/integration/braintree/local_payment_context_spec.rb +168 -0
  35. data/spec/integration/braintree/merchant_spec.rb +5 -169
  36. data/spec/integration/braintree/payment_method_spec.rb +174 -1
  37. data/spec/integration/braintree/payment_method_us_bank_account_spec.rb +1 -1
  38. data/spec/integration/braintree/test_transaction_spec.rb +6 -6
  39. data/spec/integration/braintree/transaction_idempotency_spec.rb +320 -0
  40. data/spec/integration/braintree/transaction_search_spec.rb +3 -2
  41. data/spec/integration/braintree/transaction_spec.rb +91 -0
  42. data/spec/integration/braintree/transaction_us_bank_account_spec.rb +42 -0
  43. data/spec/integration/braintree/visa_checkout_card_spec.rb +4 -100
  44. data/spec/spec_helper.rb +2 -0
  45. data/spec/unit/braintree/credit_card_verification_spec.rb +1 -1
  46. data/spec/unit/braintree/customer_spec.rb +67 -1
  47. data/spec/unit/braintree/graphql/billing_address_input_spec.rb +68 -0
  48. data/spec/unit/braintree/graphql/create_local_payment_context_input_spec.rb +63 -0
  49. data/spec/unit/braintree/graphql/monetary_amount_input_spec.rb +55 -0
  50. data/spec/unit/braintree/graphql/payer_info_input_spec.rb +92 -0
  51. data/spec/unit/braintree/local_payment_context_gateway_spec.rb +149 -0
  52. data/spec/unit/braintree/local_payment_context_spec.rb +141 -0
  53. data/spec/unit/braintree/monetary_amount_spec.rb +34 -0
  54. data/spec/unit/braintree/three_d_secure_info_spec.rb +3 -1
  55. data/spec/unit/braintree/transaction/apple_pay_details_spec.rb +7 -7
  56. data/spec/unit/braintree/transaction/google_pay_details_spec.rb +7 -7
  57. data/spec/unit/braintree/transaction/meta_checkout_card_details_spec.rb +6 -6
  58. data/spec/unit/braintree/transaction/meta_checkout_token_details_spec.rb +6 -6
  59. data/spec/unit/braintree/transaction/payment_receipt_spec.rb +4 -4
  60. data/spec/unit/braintree/transaction/visa_checkout_card_details_spec.rb +6 -6
  61. data/spec/unit/braintree/transaction_gateway_spec.rb +5 -3
  62. data/spec/unit/braintree/transaction_spec.rb +31 -0
  63. data/spec/unit/braintree/visa_checkout_card_spec.rb +1 -0
  64. data/spec/unit/credit_card_details_spec.rb +6 -6
  65. data/spec/unit/spec_helper.rb +9 -0
  66. metadata +23 -6
@@ -28,7 +28,8 @@ describe Braintree::Customer do
28
28
  expect(output).to include(%q(first_name: "Patrick"))
29
29
  expect(output).to include(%q(last_name: "Smith"))
30
30
  expect(output).to include(%q(phone: "802-483-5932"))
31
- expect(output).to include(%q(international_phone: {:country_code=>"1", :national_number=>"3121234567"}))
31
+ international_phone_hash = {:country_code => "1", :national_number => "3121234567"}.inspect
32
+ expect(output).to include("international_phone: #{international_phone_hash}")
32
33
  expect(output).to include(%q(website: "patrick.smith.com"))
33
34
  expect(output).to include(%q(addresses: []))
34
35
  expect(output).to include(%q(credit_cards: []))
@@ -91,6 +92,38 @@ describe Braintree::Customer do
91
92
  :device_data,
92
93
  :payment_method_nonce,
93
94
  {:risk_data => [:customer_browser, :customer_ip]},
95
+ {:apple_pay_card => [
96
+ :cardholder_name,
97
+ :cryptogram,
98
+ :eci_indicator,
99
+ :expiration_month,
100
+ :expiration_year,
101
+ :network_transaction_id,
102
+ :number,
103
+ :token,
104
+ {:billing_address => [
105
+ :company,
106
+ :country_code_alpha2,
107
+ :country_code_alpha3,
108
+ :country_code_numeric,
109
+ :country_name,
110
+ :extended_address,
111
+ :first_name,
112
+ {:international_phone=>[:country_code, :national_number]},
113
+ :last_name,
114
+ :locality,
115
+ :phone_number,
116
+ :postal_code,
117
+ :region,
118
+ :street_address
119
+ ]},
120
+ {:options => match_array([
121
+ :verification_account_type,
122
+ :verification_amount,
123
+ :verification_merchant_account_id,
124
+ :verify_card
125
+ ])},
126
+ ]},
94
127
  {:credit_card => [
95
128
  :billing_address_id,
96
129
  :cardholder_name,
@@ -188,6 +221,39 @@ describe Braintree::Customer do
188
221
  :device_data,
189
222
  :payment_method_nonce,
190
223
  :default_payment_method_token,
224
+ {:apple_pay_card => [
225
+ :cardholder_name,
226
+ :cryptogram,
227
+ :eci_indicator,
228
+ :expiration_month,
229
+ :expiration_year,
230
+ :network_transaction_id,
231
+ :number,
232
+ :token,
233
+ {:billing_address => [
234
+ :company,
235
+ :country_code_alpha2,
236
+ :country_code_alpha3,
237
+ :country_code_numeric,
238
+ :country_name,
239
+ :extended_address,
240
+ :first_name,
241
+ {:international_phone=>[:country_code, :national_number]},
242
+ :last_name,
243
+ :locality,
244
+ :phone_number,
245
+ :postal_code,
246
+ :region,
247
+ :street_address
248
+ ]},
249
+ {:options => match_array([
250
+ :make_default,
251
+ :verification_account_type,
252
+ :verification_amount,
253
+ :verification_merchant_account_id,
254
+ :verify_card
255
+ ])},
256
+ ]},
191
257
  {:credit_card => [
192
258
  :billing_address_id,
193
259
  :cardholder_name,
@@ -0,0 +1,68 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../../spec_helper")
2
+
3
+ describe Braintree::BillingAddressInput do
4
+ describe "#initialize" do
5
+ it "initializes with all attributes" do
6
+ attributes = {
7
+ street_address: "123 Main St",
8
+ extended_address: "Apt 4B",
9
+ locality: "Mexico City",
10
+ region: "CDMX",
11
+ postal_code: "01000",
12
+ country_code_alpha2: "MX"
13
+ }
14
+ input = Braintree::BillingAddressInput.new(attributes)
15
+
16
+ expect(input.street_address).to eq("123 Main St")
17
+ expect(input.extended_address).to eq("Apt 4B")
18
+ expect(input.locality).to eq("Mexico City")
19
+ expect(input.region).to eq("CDMX")
20
+ expect(input.postal_code).to eq("01000")
21
+ expect(input.country_code_alpha2).to eq("MX")
22
+ end
23
+ end
24
+
25
+ describe "#to_graphql_variables" do
26
+ it "converts to graphql variables with camelCase keys" do
27
+ attributes = {
28
+ street_address: "123 Main St",
29
+ locality: "Mexico City",
30
+ postal_code: "01000",
31
+ country_code_alpha2: "MX"
32
+ }
33
+ input = Braintree::BillingAddressInput.new(attributes)
34
+ expected_variables = {
35
+ "streetAddress" => "123 Main St",
36
+ "locality" => "Mexico City",
37
+ "postalCode" => "01000",
38
+ "countryCode" => "MX"
39
+ }
40
+
41
+ expect(input.to_graphql_variables).to eq(expected_variables)
42
+ end
43
+
44
+ it "omits nil values" do
45
+ attributes = {street_address: "123 Main St"}
46
+ input = Braintree::BillingAddressInput.new(attributes)
47
+ expected_variables = {"streetAddress" => "123 Main St"}
48
+
49
+ expect(input.to_graphql_variables).to eq(expected_variables)
50
+ end
51
+ end
52
+
53
+ describe "#inspect" do
54
+ it "returns formatted string" do
55
+ attributes = {
56
+ street_address: "123 Main St",
57
+ locality: "Mexico City",
58
+ postal_code: "01000"
59
+ }
60
+ input = Braintree::BillingAddressInput.new(attributes)
61
+ result = input.inspect
62
+
63
+ expect(result).to include("BillingAddressInput")
64
+ expect(result).to include("street_address:")
65
+ expect(result).to include("locality:")
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,63 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../../spec_helper")
2
+
3
+ describe Braintree::CreateLocalPaymentContextInput do
4
+ let(:input_data) do
5
+ {
6
+ amount: {value: "10.00", currency_code: "EUR"},
7
+ type: Braintree::LocalPaymentType::MBWAY,
8
+ payer_info: {
9
+ given_name: "John",
10
+ surname: "Doe"
11
+ },
12
+ order_id: "order-123"
13
+ }
14
+ end
15
+
16
+ describe "#initialize" do
17
+ it "initializes with attributes" do
18
+ input = Braintree::CreateLocalPaymentContextInput.new(input_data)
19
+
20
+ expect(input.attrs).to eq(input_data.keys)
21
+ expect(input.type).to eq(Braintree::LocalPaymentType::MBWAY)
22
+ expect(input.order_id).to eq("order-123")
23
+ expect(input.amount).to be_a(Braintree::MonetaryAmountInput)
24
+ expect(input.payer_info).to be_a(Braintree::PayerInfoInput)
25
+ end
26
+
27
+ it "handles nil payer_info" do
28
+ attributes = {amount: {value: "10.00", currency_code: "EUR"}, type: "OXXO"}
29
+ input = Braintree::CreateLocalPaymentContextInput.new(attributes)
30
+ expect(input.payer_info).to be_nil
31
+ end
32
+ end
33
+
34
+ describe "#to_graphql_variables" do
35
+ it "converts to graphql variables with camelCase keys" do
36
+ input = Braintree::CreateLocalPaymentContextInput.new(input_data)
37
+ expected_variables = {
38
+ "paymentContext" => {
39
+ "amount" => {"value" => "10.00", "currencyCode" => "EUR"},
40
+ "orderId" => "order-123",
41
+ "payerInfo" => {
42
+ "givenName" => "John",
43
+ "surname" => "Doe"
44
+ },
45
+ "type" => Braintree::LocalPaymentType::MBWAY
46
+ }
47
+ }
48
+
49
+ expect(input.to_graphql_variables).to eq(expected_variables)
50
+ end
51
+ end
52
+
53
+ describe "#inspect" do
54
+ it "returns formatted string" do
55
+ input = Braintree::CreateLocalPaymentContextInput.new(input_data)
56
+ result = input.inspect
57
+
58
+ expect(result).to include("CreateLocalPaymentContextInput")
59
+ expect(result).to include("amount:")
60
+ expect(result).to include("type:")
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,55 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../../spec_helper")
2
+
3
+ describe Braintree::MonetaryAmountInput do
4
+ describe "#initialize" do
5
+ it "initializes with all attributes" do
6
+ attributes = {
7
+ value: "10.00",
8
+ currency_code: "USD"
9
+ }
10
+ input = Braintree::MonetaryAmountInput.new(attributes)
11
+
12
+ expect(input.value).to eq("10.00")
13
+ expect(input.currency_code).to eq("USD")
14
+ end
15
+ end
16
+
17
+ describe "#to_graphql_variables" do
18
+ it "converts to graphql variables with camelCase keys" do
19
+ attributes = {
20
+ value: "25.50",
21
+ currency_code: "EUR"
22
+ }
23
+ input = Braintree::MonetaryAmountInput.new(attributes)
24
+ expected_variables = {
25
+ "value" => "25.50",
26
+ "currencyCode" => "EUR"
27
+ }
28
+
29
+ expect(input.to_graphql_variables).to eq(expected_variables)
30
+ end
31
+
32
+ it "omits nil values" do
33
+ attributes = {value: "10.00"}
34
+ input = Braintree::MonetaryAmountInput.new(attributes)
35
+ expected_variables = {"value" => "10.00"}
36
+
37
+ expect(input.to_graphql_variables).to eq(expected_variables)
38
+ end
39
+ end
40
+
41
+ describe "#inspect" do
42
+ it "returns formatted string" do
43
+ attributes = {
44
+ value: "25.50",
45
+ currency_code: "EUR"
46
+ }
47
+ input = Braintree::MonetaryAmountInput.new(attributes)
48
+ result = input.inspect
49
+
50
+ expect(result).to include("MonetaryAmountInput")
51
+ expect(result).to include("value:")
52
+ expect(result).to include("currency_code:")
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,92 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../../spec_helper")
2
+
3
+ describe Braintree::PayerInfoInput do
4
+ describe "#initialize" do
5
+ it "initializes with all attributes" do
6
+ attributes = {
7
+ given_name: "John",
8
+ surname: "Doe",
9
+ phone_country_code: "+351",
10
+ phone_number: "912345678",
11
+ billing_address: {
12
+ street_address: "123 Main St",
13
+ locality: "Lisbon"
14
+ }
15
+ }
16
+ input = Braintree::PayerInfoInput.new(attributes)
17
+
18
+ expect(input.given_name).to eq("John")
19
+ expect(input.surname).to eq("Doe")
20
+ expect(input.phone_country_code).to eq("+351")
21
+ expect(input.phone_number).to eq("912345678")
22
+ expect(input.billing_address).to be_a(Braintree::BillingAddressInput)
23
+ end
24
+
25
+ it "handles nil billing_address" do
26
+ attributes = {given_name: "John", surname: "Doe"}
27
+ input = Braintree::PayerInfoInput.new(attributes)
28
+ expect(input.billing_address).to be_nil
29
+ end
30
+ end
31
+
32
+ describe "#to_graphql_variables" do
33
+ it "converts to graphql variables with camelCase keys" do
34
+ attributes = {
35
+ given_name: "John",
36
+ surname: "Doe",
37
+ phone_country_code: "+351",
38
+ phone_number: "912345678"
39
+ }
40
+ input = Braintree::PayerInfoInput.new(attributes)
41
+ expected_variables = {
42
+ "givenName" => "John",
43
+ "phoneCountryCode" => "+351",
44
+ "phoneNumber" => "912345678",
45
+ "surname" => "Doe"
46
+ }
47
+
48
+ expect(input.to_graphql_variables).to eq(expected_variables)
49
+ end
50
+
51
+ it "includes nested billing_address" do
52
+ attributes = {
53
+ given_name: "John",
54
+ surname: "Doe",
55
+ billing_address: {
56
+ street_address: "123 Main St",
57
+ postal_code: "1000-001"
58
+ }
59
+ }
60
+ input = Braintree::PayerInfoInput.new(attributes)
61
+ variables = input.to_graphql_variables
62
+
63
+ expect(variables["billingAddress"]).to be_a(Hash)
64
+ expect(variables["billingAddress"]["streetAddress"]).to eq("123 Main St")
65
+ expect(variables["billingAddress"]["postalCode"]).to eq("1000-001")
66
+ end
67
+
68
+ it "omits nil values" do
69
+ attributes = {given_name: "John"}
70
+ input = Braintree::PayerInfoInput.new(attributes)
71
+ expected_variables = {"givenName" => "John"}
72
+
73
+ expect(input.to_graphql_variables).to eq(expected_variables)
74
+ end
75
+ end
76
+
77
+ describe "#inspect" do
78
+ it "returns formatted string" do
79
+ attributes = {
80
+ given_name: "John",
81
+ surname: "Doe",
82
+ email: "john@example.com"
83
+ }
84
+ input = Braintree::PayerInfoInput.new(attributes)
85
+ result = input.inspect
86
+
87
+ expect(result).to include("PayerInfoInput")
88
+ expect(result).to include("given_name:")
89
+ expect(result).to include("surname:")
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,149 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
2
+
3
+ describe Braintree::LocalPaymentContextGateway do
4
+ let(:gateway) { double(:gateway) }
5
+ let(:graphql_client) { double(:graphql_client) }
6
+ let(:local_payment_gateway) { Braintree::LocalPaymentContextGateway.new(gateway, graphql_client) }
7
+
8
+ describe "#create" do
9
+ let(:input) do
10
+ {
11
+ amount: {value: "10.00", currency_code: "EUR"},
12
+ type: Braintree::LocalPaymentType::MBWAY,
13
+ payer_info: {
14
+ given_name: "John",
15
+ surname: "Doe"
16
+ }
17
+ }
18
+ end
19
+
20
+ let(:response) do
21
+ {
22
+ data: {
23
+ createLocalPaymentContext: {
24
+ paymentContext: {
25
+ id: "context-id-123",
26
+ type: "MBWAY",
27
+ paymentId: "payment-123",
28
+ approvalUrl: "https://approval.url",
29
+ merchantAccountId: "merchant-123",
30
+ orderId: "order-456",
31
+ createdAt: "2025-01-15T10:00:00Z",
32
+ transactedAt: nil,
33
+ approvedAt: nil,
34
+ amount: {
35
+ value: "10.00",
36
+ currencyCode: "EUR"
37
+ }
38
+ }
39
+ }
40
+ }
41
+ }
42
+ end
43
+
44
+ it "executes the createLocalPaymentContext mutation" do
45
+ create_input = Braintree::CreateLocalPaymentContextInput.new(input)
46
+ expect(graphql_client).to receive(:query).with(
47
+ Braintree::LocalPaymentContextGateway::CREATE_LOCAL_PAYMENT_CONTEXT,
48
+ {"input" => create_input.to_graphql_variables},
49
+ ).and_return(response)
50
+
51
+ expect(Braintree::GraphQLClient).to receive(:get_validation_errors)
52
+ .with(response).and_return(nil)
53
+
54
+ result = local_payment_gateway.create(create_input)
55
+ expect(result).to be_a(Braintree::SuccessfulResult)
56
+ expect(result.payment_context).to be_a(Braintree::LocalPaymentContext)
57
+ expect(result.payment_context.id).to eq("context-id-123")
58
+ expect(result.payment_context.approval_url).to eq("https://approval.url")
59
+ expect(result.payment_context.order_id).to eq("order-456")
60
+ expect(result.payment_context.amount.value).to eq("10.00")
61
+ expect(result.payment_context.amount.currency_code).to eq("EUR")
62
+ end
63
+
64
+ it "returns an error result if there are validation errors" do
65
+ create_input = Braintree::CreateLocalPaymentContextInput.new(input)
66
+ errors = {:errors =>
67
+ [ {:attribute => "", :code => "123", :message => "Invalid amount"} ]}
68
+
69
+ expect(graphql_client).to receive(:query).and_return(response)
70
+ expect(Braintree::GraphQLClient).to receive(:get_validation_errors)
71
+ .with(response).and_return(errors)
72
+
73
+ result = local_payment_gateway.create(create_input)
74
+ expect(result).to be_a(Braintree::ErrorResult)
75
+ expect(result.errors.first.message).to eq("Invalid amount")
76
+ end
77
+
78
+ it "raises an UnexpectedError if response is malformed" do
79
+ create_input = Braintree::CreateLocalPaymentContextInput.new(input)
80
+ bad_response = {:data => {}}
81
+
82
+ expect(graphql_client).to receive(:query).and_return(bad_response)
83
+ expect(Braintree::GraphQLClient).to receive(:get_validation_errors)
84
+ .with(bad_response).and_return(nil)
85
+
86
+ expect {
87
+ local_payment_gateway.create(create_input)
88
+ }.to raise_error(Braintree::UnexpectedError)
89
+ end
90
+ end
91
+
92
+ describe "#find" do
93
+ let(:find_response) do
94
+ {
95
+ data: {
96
+ node: {
97
+ id: "context-id-123",
98
+ legacyId: "legacy-123",
99
+ type: "MBWAY",
100
+ paymentId: "payment-123",
101
+ orderId: "order-456",
102
+ approvalUrl: "https://approval.url",
103
+ merchantAccountId: "merchant-123",
104
+ createdAt: "2025-01-15T10:00:00Z",
105
+ updatedAt: "2025-01-15T10:05:00Z",
106
+ transactedAt: nil,
107
+ approvedAt: nil,
108
+ expiredAt: nil,
109
+ amount: {
110
+ value: "10.00",
111
+ currencyIsoCode: "EUR"
112
+ }
113
+ }
114
+ }
115
+ }
116
+ end
117
+
118
+ it "finds a payment context by ID" do
119
+ expect(graphql_client).to receive(:query).with(
120
+ Braintree::LocalPaymentContextGateway::FIND_LOCAL_PAYMENT_CONTEXT,
121
+ {"id" => "context-id-123"},
122
+ ).and_return(find_response)
123
+
124
+ expect(Braintree::GraphQLClient).to receive(:get_validation_errors)
125
+ .with(find_response).and_return(nil)
126
+
127
+ result = local_payment_gateway.find("context-id-123")
128
+ expect(result).to be_a(Braintree::SuccessfulResult)
129
+ expect(result.payment_context).to be_a(Braintree::LocalPaymentContext)
130
+ expect(result.payment_context.id).to eq("context-id-123")
131
+ expect(result.payment_context.legacy_id).to eq("legacy-123")
132
+ expect(result.payment_context.type).to eq("MBWAY")
133
+ expect(result.payment_context.order_id).to eq("order-456")
134
+ expect(result.payment_context.updated_at).to eq("2025-01-15T10:05:00Z")
135
+ end
136
+
137
+ it "raises NotFoundError when payment context does not exist" do
138
+ not_found_response = {data: {node: nil}}
139
+
140
+ expect(graphql_client).to receive(:query).and_return(not_found_response)
141
+ expect(Braintree::GraphQLClient).to receive(:get_validation_errors)
142
+ .with(not_found_response).and_return(nil)
143
+
144
+ expect {
145
+ local_payment_gateway.find("non-existent-id")
146
+ }.to raise_error(Braintree::NotFoundError, "Payment context not found")
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,141 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Braintree::LocalPaymentContext do
4
+ describe "#initialize" do
5
+ it "initializes from response hash" do
6
+ response = {
7
+ response: {
8
+ "paymentContext" => {
9
+ "id" => "context-123",
10
+ "legacyId" => "legacy-456",
11
+ "type" => "MBWAY",
12
+ "paymentId" => "payment-789",
13
+ "orderId" => "order-abc",
14
+ "approvalUrl" => "https://example.com/approve",
15
+ "merchantAccountId" => "merchant-xyz",
16
+ "createdAt" => "2025-01-15T10:00:00Z",
17
+ "updatedAt" => "2025-01-15T11:00:00Z",
18
+ "transactedAt" => "2025-01-15T12:00:00Z",
19
+ "approvedAt" => "2025-01-15T11:30:00Z",
20
+ "expiredAt" => nil,
21
+ "amount" => {
22
+ "value" => "10.00",
23
+ "currencyCode" => "EUR"
24
+ }
25
+ }
26
+ }
27
+ }
28
+
29
+ context = Braintree::LocalPaymentContext._new(response)
30
+
31
+ expect(context.id).to eq("context-123")
32
+ expect(context.legacy_id).to eq("legacy-456")
33
+ expect(context.type).to eq("MBWAY")
34
+ expect(context.payment_id).to eq("payment-789")
35
+ expect(context.order_id).to eq("order-abc")
36
+ expect(context.approval_url).to eq("https://example.com/approve")
37
+ expect(context.merchant_account_id).to eq("merchant-xyz")
38
+ expect(context.created_at).to eq("2025-01-15T10:00:00Z")
39
+ expect(context.updated_at).to eq("2025-01-15T11:00:00Z")
40
+ expect(context.transacted_at).to eq("2025-01-15T12:00:00Z")
41
+ expect(context.approved_at).to eq("2025-01-15T11:30:00Z")
42
+ expect(context.expired_at).to be_nil
43
+ expect(context.amount).to be_a(Braintree::MonetaryAmount)
44
+ expect(context.amount.value).to eq("10.00")
45
+ expect(context.amount.currency_code).to eq("EUR")
46
+ end
47
+
48
+ it "initializes from attributes hash" do
49
+ attributes = {
50
+ id: "context-123",
51
+ type: "OXXO",
52
+ approval_url: "https://example.com/approve"
53
+ }
54
+
55
+ context = Braintree::LocalPaymentContext._new(attributes)
56
+
57
+ expect(context.id).to eq("context-123")
58
+ expect(context.type).to eq("OXXO")
59
+ expect(context.approval_url).to eq("https://example.com/approve")
60
+ end
61
+
62
+ it "handles symbol keys in amount hash" do
63
+ response = {
64
+ response: {
65
+ paymentContext: {
66
+ id: "context-123",
67
+ type: "MBWAY",
68
+ amount: {
69
+ value: "15.00",
70
+ currencyCode: "USD"
71
+ }
72
+ }
73
+ }
74
+ }
75
+
76
+ context = Braintree::LocalPaymentContext._new(response)
77
+
78
+ expect(context.amount.value).to eq("15.00")
79
+ expect(context.amount.currency_code).to eq("USD")
80
+ end
81
+
82
+ it "handles currencyIsoCode in amount hash" do
83
+ response = {
84
+ response: {
85
+ paymentContext: {
86
+ id: "context-123",
87
+ type: "MBWAY",
88
+ amount: {
89
+ value: "20.00",
90
+ currencyIsoCode: "GBP"
91
+ }
92
+ }
93
+ }
94
+ }
95
+
96
+ context = Braintree::LocalPaymentContext._new(response)
97
+
98
+ expect(context.amount.currency_code).to eq("GBP")
99
+ end
100
+
101
+ it "returns nil for amount when not present" do
102
+ response = {
103
+ response: {
104
+ paymentContext: {
105
+ id: "context-123",
106
+ type: "MBWAY"
107
+ }
108
+ }
109
+ }
110
+
111
+ context = Braintree::LocalPaymentContext._new(response)
112
+
113
+ expect(context.amount).to be_nil
114
+ end
115
+ end
116
+
117
+ describe "#inspect" do
118
+ it "returns formatted string representation" do
119
+ attributes = {
120
+ id: "context-123",
121
+ type: "OXXO",
122
+ approval_url: "https://example.com/approve"
123
+ }
124
+
125
+ context = Braintree::LocalPaymentContext._new(attributes)
126
+
127
+ expect(context.inspect).to include("LocalPaymentContext")
128
+ expect(context.inspect).to include("id:")
129
+ expect(context.inspect).to include("type:")
130
+ expect(context.inspect).to include("approval_url:")
131
+ end
132
+ end
133
+
134
+ describe "self.new" do
135
+ it "is protected" do
136
+ expect do
137
+ Braintree::LocalPaymentContext.new
138
+ end.to raise_error(NoMethodError, /protected method .new/)
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,34 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Braintree::MonetaryAmount do
4
+ describe "#initialize" do
5
+ it "initializes with value and currency_code" do
6
+ amount = Braintree::MonetaryAmount._new(
7
+ value: "10.00",
8
+ currency_code: "USD",
9
+ )
10
+
11
+ expect(amount.value).to eq("10.00")
12
+ expect(amount.currency_code).to eq("USD")
13
+ end
14
+ end
15
+
16
+ describe "#inspect" do
17
+ it "returns formatted string representation" do
18
+ amount = Braintree::MonetaryAmount._new(
19
+ value: "25.50",
20
+ currency_code: "EUR",
21
+ )
22
+
23
+ expect(amount.inspect).to eq('#<MonetaryAmount currency_code:"EUR" value:"25.50">')
24
+ end
25
+ end
26
+
27
+ describe "self.new" do
28
+ it "is protected" do
29
+ expect do
30
+ Braintree::MonetaryAmount.new
31
+ end.to raise_error(NoMethodError, /protected method .new/)
32
+ end
33
+ end
34
+ end