braintree 2.76.0 → 2.77.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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/lib/braintree.rb +12 -0
  3. data/lib/braintree/apple_pay.rb +29 -0
  4. data/lib/braintree/apple_pay_card.rb +1 -1
  5. data/lib/braintree/apple_pay_gateway.rb +37 -0
  6. data/lib/braintree/apple_pay_options.rb +19 -0
  7. data/lib/braintree/authorization_adjustment.rb +20 -0
  8. data/lib/braintree/dispute.rb +78 -9
  9. data/lib/braintree/dispute/evidence.rb +18 -0
  10. data/lib/braintree/dispute/history_event.rb +14 -0
  11. data/lib/braintree/dispute/transaction.rb +18 -0
  12. data/lib/braintree/dispute_gateway.rb +118 -0
  13. data/lib/braintree/dispute_search.rb +30 -0
  14. data/lib/braintree/document_upload.rb +34 -0
  15. data/lib/braintree/document_upload_gateway.rb +32 -0
  16. data/lib/braintree/error_codes.rb +17 -0
  17. data/lib/braintree/facilitated_details.rb +19 -0
  18. data/lib/braintree/gateway.rb +12 -0
  19. data/lib/braintree/http.rb +60 -12
  20. data/lib/braintree/successful_result.rb +1 -1
  21. data/lib/braintree/test/credit_card.rb +6 -0
  22. data/lib/braintree/transaction.rb +4 -0
  23. data/lib/braintree/version.rb +1 -1
  24. data/lib/braintree/webhook_testing_gateway.rb +196 -19
  25. data/spec/fixtures/files/bt_logo.png +0 -0
  26. data/spec/fixtures/files/gif_extension_bt_logo.gif +0 -0
  27. data/spec/fixtures/files/malformed_pdf.pdf +1 -0
  28. data/spec/httpsd.pid +1 -1
  29. data/spec/integration/braintree/apple_pay_spec.rb +92 -0
  30. data/spec/integration/braintree/coinbase_spec.rb +15 -12
  31. data/spec/integration/braintree/dispute_search_spec.rb +49 -0
  32. data/spec/integration/braintree/dispute_spec.rb +216 -0
  33. data/spec/integration/braintree/document_upload_spec.rb +55 -0
  34. data/spec/integration/braintree/http_spec.rb +8 -0
  35. data/spec/integration/braintree/payment_method_spec.rb +5 -16
  36. data/spec/integration/braintree/transaction_spec.rb +21 -4
  37. data/spec/spec_helper.rb +3 -2
  38. data/spec/unit/braintree/apple_pay_card_spec.rb +6 -0
  39. data/spec/unit/braintree/dispute_search_spec.rb +59 -0
  40. data/spec/unit/braintree/dispute_spec.rb +331 -8
  41. data/spec/unit/braintree/document_upload_spec.rb +35 -0
  42. data/spec/unit/braintree/http_spec.rb +21 -0
  43. data/spec/unit/braintree/transaction_spec.rb +17 -0
  44. data/spec/unit/braintree/webhook_notification_spec.rb +74 -51
  45. metadata +24 -3
@@ -0,0 +1 @@
1
+ XXXXXXXXXXX¾?^gfkbfu¶šÙú”¼Åxc¯ÄÖñ•:x„BºS·É=] óqçÅÒÐwî+= x wÁ¼/7ú7ÀݛeÀÅA¿8?À­‹6Á2[î(†¤Ö@+3[ß}
@@ -1 +1 @@
1
- 13345
1
+ 3946
@@ -0,0 +1,92 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
2
+
3
+ describe Braintree::ApplePayGateway do
4
+ before(:each) do
5
+ gateway = Braintree::Gateway.new(
6
+ :client_id => "client_id$#{Braintree::Configuration.environment}$integration_client_id",
7
+ :client_secret => "client_secret$#{Braintree::Configuration.environment}$integration_client_secret",
8
+ :logger => Logger.new("/dev/null")
9
+ )
10
+
11
+ result = gateway.merchant.create(
12
+ :email => "name@email.com",
13
+ :country_code_alpha3 => "USA",
14
+ :payment_methods => ["credit_card", "paypal"]
15
+ )
16
+
17
+ @gateway = Braintree::Gateway.new(
18
+ :access_token => result.credentials.access_token,
19
+ :logger => Logger.new("/dev/null")
20
+ )
21
+ end
22
+
23
+ describe "register_domain" do
24
+ it "registers an apple pay domain" do
25
+ result = @gateway.apple_pay.register_domain("www.example.com")
26
+ result.should be_success
27
+ end
28
+
29
+ it "gets a validation error when attempting to register no domains" do
30
+ result = @gateway.apple_pay.register_domain("")
31
+ result.should_not be_success
32
+ result.errors.for(:apple_pay)[0].message.should eq("Domain name is required.")
33
+ end
34
+ end
35
+
36
+ describe "unregister_domain" do
37
+ it "unregisters an apple pay domain" do
38
+ domain = "example.org"
39
+ result = @gateway.apple_pay.register_domain(domain)
40
+ result.should be_success
41
+
42
+ result = @gateway.apple_pay.unregister_domain(domain)
43
+ result.should be_success
44
+ @gateway.apple_pay.registered_domains.apple_pay_options.domains.should be_empty
45
+ end
46
+
47
+ it "unregisters an apple pay domain with scheme in url" do
48
+ domain = "http://example.org"
49
+ result = @gateway.apple_pay.register_domain(domain)
50
+ result.should be_success
51
+
52
+ result = @gateway.apple_pay.unregister_domain(domain)
53
+ result.should be_success
54
+ @gateway.apple_pay.registered_domains.apple_pay_options.domains.should be_empty
55
+ end
56
+
57
+ it "does not fail when unregistering a non-registered domain" do
58
+ result = @gateway.apple_pay.unregister_domain("unregistered.com")
59
+ result.should be_success
60
+ end
61
+
62
+ it "escapes the unregistered domain query parameter" do
63
+ domain = "ex&mple.org"
64
+ result = @gateway.apple_pay.register_domain(domain)
65
+ result.should be_success
66
+ @gateway.apple_pay.registered_domains.apple_pay_options.domains.should_not be_empty
67
+
68
+ result = @gateway.apple_pay.unregister_domain(domain)
69
+ result.should be_success
70
+ @gateway.apple_pay.registered_domains.apple_pay_options.domains.should be_empty
71
+ end
72
+ end
73
+
74
+ describe "registered_domains" do
75
+ it "returns registered domains" do
76
+ result = @gateway.apple_pay.register_domain("www.example.com")
77
+ result.should be_success
78
+ result = @gateway.apple_pay.register_domain("www.example.org")
79
+ result.should be_success
80
+
81
+ result = @gateway.apple_pay.registered_domains
82
+ result.should be_success
83
+ result.apple_pay_options.domains.should =~ ["www.example.org", "www.example.com"]
84
+ end
85
+
86
+ it "returns an empty list if no domains are registered" do
87
+ result = @gateway.apple_pay.registered_domains
88
+ result.should be_success
89
+ result.apple_pay_options.domains.should == []
90
+ end
91
+ end
92
+ end
@@ -8,24 +8,27 @@ describe "Coinbase" do
8
8
  end
9
9
  end
10
10
 
11
- it "works for transaction#create" do
11
+ it "is no longer supported with transaction#create" do
12
12
  result = Braintree::Transaction.sale(:payment_method_nonce => Braintree::Test::Nonce::Coinbase, :amount => "0.02")
13
- result.should be_success
14
- assert_valid_coinbase_attrs(result.transaction.coinbase_details)
13
+ result.should_not be_success
14
+
15
+ result.errors.for(:transaction).first.code.should == Braintree::ErrorCodes::PaymentMethod::PaymentMethodNoLongerSupported
15
16
  end
16
17
 
17
- it "works for vaulting" do
18
+ it "is no longer supported for vaulting" do
18
19
  customer = Braintree::Customer.create!
19
- vaulted = Braintree::PaymentMethod.create(:customer_id => customer.id, :payment_method_nonce => Braintree::Test::Nonce::Coinbase).payment_method
20
- assert_valid_coinbase_attrs(vaulted)
20
+ result = Braintree::PaymentMethod.create(:customer_id => customer.id, :payment_method_nonce => Braintree::Test::Nonce::Coinbase)
21
+ result.should_not be_success
21
22
 
22
- found = Braintree::PaymentMethod.find(vaulted.token).payment_method
23
- assert_valid_coinbase_attrs(found)
23
+ result.errors.for(:coinbase_account).first.code.should == Braintree::ErrorCodes::PaymentMethod::PaymentMethodNoLongerSupported
24
24
  end
25
25
 
26
- it "is returned on Customers" do
27
- customer = Braintree::Customer.create!(:payment_method_nonce => Braintree::Test::Nonce::Coinbase)
28
- customer.payment_methods.should == customer.coinbase_accounts
29
- assert_valid_coinbase_attrs(customer.coinbase_accounts[0])
26
+ it "is no longer supported when creating a Customer with a Coinbase payment method nonce" do
27
+ expect do
28
+ Braintree::Customer.create!(:payment_method_nonce => Braintree::Test::Nonce::Coinbase)
29
+ end.to raise_error { |error|
30
+ error.should be_a(Braintree::ValidationsFailed)
31
+ error.error_result.errors.for(:coinbase_account).first.code.should == Braintree::ErrorCodes::PaymentMethod::PaymentMethodNoLongerSupported
32
+ }
30
33
  end
31
34
  end
@@ -0,0 +1,49 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+ require File.expand_path(File.dirname(__FILE__) + "/client_api/spec_helper")
3
+
4
+ describe Braintree::Dispute, "search" do
5
+ context "advanced" do
6
+ it "correctly returns a result with no matches" do
7
+ collection = Braintree::Dispute.search do |search|
8
+ search.id.is "non_existent_dispute"
9
+ end
10
+
11
+ expect(collection.disputes.count).to eq(0)
12
+ end
13
+
14
+ it "correctly returns a single dispute by id" do
15
+ collection = Braintree::Dispute.search do |search|
16
+ search.id.is "open_dispute"
17
+ end
18
+
19
+ expect(collection.disputes.count).to eq(1)
20
+ dispute = collection.disputes.first
21
+
22
+ expect(dispute.id).to eq("open_dispute")
23
+ expect(dispute.status).to eq(Braintree::Dispute::Status::Open)
24
+ end
25
+
26
+ it "correctly returns disputes by multiple reasons" do
27
+ collection = Braintree::Dispute.search do |search|
28
+ search.reason.in [
29
+ Braintree::Dispute::Reason::ProductUnsatisfactory,
30
+ Braintree::Dispute::Reason::Retrieval
31
+ ]
32
+ end
33
+
34
+ expect(collection.disputes.count).to eq(2)
35
+ dispute = collection.disputes.first
36
+ end
37
+
38
+ it "correctly returns disputes by received_date range" do
39
+ collection = Braintree::Dispute.search do |search|
40
+ search.received_date.between("03/03/2014", "03/05/2014")
41
+ end
42
+
43
+ expect(collection.disputes.count).to eq(1)
44
+ dispute = collection.disputes.first
45
+
46
+ expect(dispute.received_date).to eq(Date.new(2014, 3, 4))
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,216 @@
1
+ # encoding: utf-8
2
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
3
+ require File.expand_path(File.dirname(__FILE__) + "/client_api/spec_helper")
4
+
5
+ describe Braintree::Dispute do
6
+ let(:transaction) do
7
+ result = Braintree::Transaction.sale(
8
+ :amount => '10.00',
9
+ :credit_card => {
10
+ :expiration_date => '01/2020',
11
+ :number => Braintree::Test::CreditCardNumbers::Disputes::Chargeback
12
+ },
13
+ :options => {
14
+ :submit_for_settlement => true
15
+ }
16
+ )
17
+
18
+ result.transaction
19
+ end
20
+
21
+ let(:dispute) { transaction.disputes.first }
22
+
23
+ describe "self.accept" do
24
+ it "changes the dispute status to accepted" do
25
+ result = Braintree::Dispute.accept(dispute.id)
26
+
27
+ result.success?.should == true
28
+
29
+ refreshed_dispute = Braintree::Dispute.find(dispute.id)
30
+ refreshed_dispute.status.should == Braintree::Dispute::Status::Accepted
31
+ end
32
+
33
+ it "returns an error response if the dispute is not in open status" do
34
+ result = Braintree::Dispute.accept("wells_dispute")
35
+
36
+ result.success?.should == false
37
+ result.errors.for(:dispute)[0].code.should == Braintree::ErrorCodes::Dispute::CanOnlyAcceptOpenDispute
38
+ result.errors.for(:dispute)[0].message.should == "Disputes can only be accepted when they are in an Open state"
39
+ end
40
+
41
+ it "raises a NotFound exception if the dispute cannot be found" do
42
+ expect do
43
+ Braintree::Dispute.accept("invalid-id")
44
+ end.to raise_error(Braintree::NotFoundError, 'dispute with id invalid-id not found')
45
+ end
46
+ end
47
+
48
+ describe "self.add_file_evidence" do
49
+ let(:document_upload) do
50
+ file = File.new("#{File.dirname(__FILE__)}/../../fixtures/files/bt_logo.png", "r")
51
+ response = Braintree::DocumentUpload.create({:kind => Braintree::DocumentUpload::Kind::EvidenceDocument, :file => file})
52
+ document_upload = response.document_upload
53
+ end
54
+
55
+ it "creates text evidence for the dispute" do
56
+ result = Braintree::Dispute.add_file_evidence(dispute.id, document_upload.id)
57
+
58
+ result.success?.should == true
59
+ result.evidence.comment.should be_nil
60
+ result.evidence.created_at.between?(Time.now - 10, Time.now).should == true
61
+ result.evidence.id.should =~ /^\w{16,}$/
62
+ result.evidence.sent_to_processor_at.should == nil
63
+ result.evidence.url.should include("bt_logo.png")
64
+ end
65
+
66
+ it "returns a NotFoundError if the dispute doesn't exist" do
67
+ expect do
68
+ Braintree::Dispute.add_file_evidence("unknown_dispute_id", "b51927a6-4ed7-4a32-8404-df8ef892e1a3")
69
+ end.to raise_error(Braintree::NotFoundError)
70
+ end
71
+
72
+ it "returns an error response if the dispute is not in open status" do
73
+ Braintree::Dispute.accept(dispute.id)
74
+
75
+ result = Braintree::Dispute.add_file_evidence(dispute.id, document_upload.id)
76
+ result.success?.should == false
77
+ result.errors.for(:dispute)[0].code.should == Braintree::ErrorCodes::Dispute::CanOnlyAddEvidenceToOpenDispute
78
+ result.errors.for(:dispute)[0].message.should == "Evidence can only be attached to disputes that are in an Open state"
79
+ end
80
+
81
+ it "returns the new evidence record in subsequent dispute finds" do
82
+ result = Braintree::Dispute.add_file_evidence(dispute.id, document_upload.id)
83
+ refreshed_dispute = Braintree::Dispute.find(dispute.id)
84
+
85
+ expected_evidence = refreshed_dispute.evidence.find { |e| e.id == result.evidence.id }
86
+ expected_evidence.should_not == nil
87
+ expected_evidence.comment.should be_nil
88
+ expected_evidence.url.should include("bt_logo.png")
89
+ end
90
+ end
91
+
92
+ describe "self.add_text_evidence" do
93
+ it "creates text evidence for the dispute" do
94
+ result = Braintree::Dispute.add_text_evidence(dispute.id, "text evidence")
95
+
96
+ result.success?.should == true
97
+ result.evidence.comment.should == "text evidence"
98
+ result.evidence.created_at.between?(Time.now - 10, Time.now).should == true
99
+ result.evidence.id.should =~ /^\w{16,}$/
100
+ result.evidence.sent_to_processor_at.should == nil
101
+ result.evidence.url.should == nil
102
+ end
103
+
104
+ it "returns a NotFoundError if the dispute doesn't exist" do
105
+ expect do
106
+ Braintree::Dispute.add_text_evidence("unknown_dispute_id", "text evidence")
107
+ end.to raise_error(Braintree::NotFoundError)
108
+ end
109
+
110
+ it "returns an error response if the dispute is not in open status" do
111
+ Braintree::Dispute.accept(dispute.id)
112
+
113
+ result = Braintree::Dispute.add_text_evidence(dispute.id, "text evidence")
114
+ result.success?.should == false
115
+ result.errors.for(:dispute)[0].code.should == Braintree::ErrorCodes::Dispute::CanOnlyAddEvidenceToOpenDispute
116
+ result.errors.for(:dispute)[0].message.should == "Evidence can only be attached to disputes that are in an Open state"
117
+ end
118
+
119
+ it "returns the new evidence record in subsequent dispute finds" do
120
+ result = Braintree::Dispute.add_text_evidence(dispute.id, "text evidence")
121
+ refreshed_dispute = Braintree::Dispute.find(dispute.id)
122
+
123
+ expected_evidence = refreshed_dispute.evidence.find { |e| e.id == result.evidence.id }
124
+ expected_evidence.should_not == nil
125
+ expected_evidence.comment.should == "text evidence"
126
+ end
127
+ end
128
+
129
+ describe "self.finalize" do
130
+ it "changes the dispute status to disputed" do
131
+ result = Braintree::Dispute.finalize(dispute.id)
132
+
133
+ result.success?.should == true
134
+
135
+ refreshed_dispute = Braintree::Dispute.find(dispute.id)
136
+ refreshed_dispute.status.should == Braintree::Dispute::Status::Disputed
137
+ end
138
+
139
+ it "returns an error response if the dispute is not in open status" do
140
+ result = Braintree::Dispute.finalize("wells_dispute")
141
+
142
+ result.success?.should == false
143
+ result.errors.for(:dispute)[0].code.should == Braintree::ErrorCodes::Dispute::CanOnlyFinalizeOpenDispute
144
+ result.errors.for(:dispute)[0].message.should == "Disputes can only be finalized when they are in an Open state"
145
+ end
146
+
147
+ it "raises a NotFound exception if the dispute cannot be found" do
148
+ expect do
149
+ Braintree::Dispute.finalize("invalid-id")
150
+ end.to raise_error(Braintree::NotFoundError, 'dispute with id invalid-id not found')
151
+ end
152
+ end
153
+
154
+ describe "self.find" do
155
+ it "finds the dispute with the given id" do
156
+ dispute = Braintree::Dispute.find("open_dispute")
157
+
158
+ dispute.amount_disputed.should == 31.0
159
+ dispute.amount_won.should == 0.0
160
+ dispute.id.should == "open_dispute"
161
+ dispute.status.should == Braintree::Dispute::Status::Open
162
+ dispute.transaction.amount.should == 31.0
163
+ dispute.transaction.id.should == "open_disputed_transaction"
164
+ end
165
+
166
+ it "raises an ArgumentError if dispute_id is not a string" do
167
+ expect do
168
+ Braintree::Dispute.find(Object.new)
169
+ end.to raise_error(ArgumentError, "dispute_id contains invalid characters")
170
+ end
171
+
172
+ it "raises an ArgumentError if dispute_id is blank" do
173
+ expect do
174
+ Braintree::Dispute.find("")
175
+ end.to raise_error(ArgumentError, "dispute_id contains invalid characters")
176
+ end
177
+
178
+ it "raises a NotFoundError exception if the dispute cannot be found" do
179
+ expect do
180
+ Braintree::Dispute.find("invalid-id")
181
+ end.to raise_error(Braintree::NotFoundError, "dispute with id invalid-id not found")
182
+ end
183
+ end
184
+
185
+ describe "self.remove_evidence" do
186
+ let(:evidence) { Braintree::Dispute.add_text_evidence(dispute.id, "text evidence").evidence }
187
+
188
+ it "removes evidence from the dispute" do
189
+ result = Braintree::Dispute.remove_evidence(dispute.id, evidence.id)
190
+
191
+ result.success?.should == true
192
+ end
193
+
194
+ it "returns a NotFoundError if the dispute doesn't exist" do
195
+ expect do
196
+ Braintree::Dispute.remove_evidence("unknown_dispute_id", evidence.id)
197
+ end.to raise_error(Braintree::NotFoundError, "evidence with id #{evidence.id} for dispute with id unknown_dispute_id not found")
198
+ end
199
+
200
+ it "returns a NotFoundError if the dispute doesn't exist" do
201
+ expect do
202
+ Braintree::Dispute.remove_evidence(dispute.id, "unknown_evidence_id")
203
+ end.to raise_error(Braintree::NotFoundError, "evidence with id unknown_evidence_id for dispute with id #{dispute.id} not found")
204
+ end
205
+
206
+ it "returns an error response if the dispute is not in open status" do
207
+ evidence = Braintree::Dispute.add_text_evidence(dispute.id, "text evidence").evidence
208
+ Braintree::Dispute.accept(dispute.id)
209
+
210
+ result = Braintree::Dispute.remove_evidence(dispute.id, evidence.id)
211
+ result.success?.should == false
212
+ result.errors.for(:dispute)[0].code.should == Braintree::ErrorCodes::Dispute::CanOnlyRemoveEvidenceFromOpenDispute
213
+ result.errors.for(:dispute)[0].message.should == "Evidence can only be removed from disputes that are in an Open state"
214
+ end
215
+ end
216
+ end
@@ -0,0 +1,55 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Braintree::DocumentUploadGateway do
4
+ describe "create" do
5
+ it "returns successful with valid request" do
6
+ file = File.new("#{File.dirname(__FILE__)}/../../fixtures/files/bt_logo.png", "r")
7
+ response = Braintree::DocumentUpload.create({:kind => Braintree::DocumentUpload::Kind::EvidenceDocument, :file => file})
8
+ document_upload = response.document_upload
9
+
10
+ response.success?.should == true
11
+ document_upload.id.should_not be_nil
12
+ document_upload.content_type.should == "image/png"
13
+ document_upload.kind.should == Braintree::DocumentUpload::Kind::EvidenceDocument
14
+ document_upload.name.should == "bt_logo.png"
15
+ document_upload.size.should == 2443
16
+ end
17
+
18
+ it "returns file type error with unsupported file type" do
19
+ file = File.new("#{File.dirname(__FILE__)}/../../fixtures/files/gif_extension_bt_logo.gif", "r")
20
+ response = Braintree::DocumentUpload.create({:kind => Braintree::DocumentUpload::Kind::EvidenceDocument, :file => file})
21
+ response.errors.for(:document_upload).first.code.should == Braintree::ErrorCodes::DocumentUpload::FileTypeIsInvalid
22
+ end
23
+
24
+ it "returns malformed error with malformed file" do
25
+ file = File.new("#{File.dirname(__FILE__)}/../../fixtures/files/malformed_pdf.pdf", "r")
26
+ response = Braintree::DocumentUpload.create({:kind => Braintree::DocumentUpload::Kind::EvidenceDocument, :file => file})
27
+ response.errors.for(:document_upload).first.code.should == Braintree::ErrorCodes::DocumentUpload::FileIsMalformedOrEncrypted
28
+ end
29
+
30
+ it "returns invalid kind error with invalid kind" do
31
+ file = File.new("#{File.dirname(__FILE__)}/../../fixtures/files/bt_logo.png", "r")
32
+ response = Braintree::DocumentUpload.create({:kind => "invalid_kind", :file => file})
33
+ response.errors.for(:document_upload).first.code.should == Braintree::ErrorCodes::DocumentUpload::KindIsInvalid
34
+ end
35
+
36
+ it "returns file too large error with file over 4mb" do
37
+ filename = "#{File.dirname(__FILE__)}/../../fixtures/files/large_file.png"
38
+ begin
39
+ write_times = 1048577 * 4
40
+ File.open(filename, "w+") { |f| write_times.times { f.write "a" } }
41
+ file = File.new(filename, "r")
42
+ response = Braintree::DocumentUpload.create({:kind => Braintree::DocumentUpload::Kind::EvidenceDocument, :file => file})
43
+ response.errors.for(:document_upload).first.code.should == Braintree::ErrorCodes::DocumentUpload::FileIsTooLarge
44
+ ensure
45
+ File.delete(filename)
46
+ end
47
+ end
48
+
49
+ it "returns invalid keys error if signature is invalid" do
50
+ expect do
51
+ response = Braintree::DocumentUpload.create({:invalid_key => "do not add", :kind => Braintree::DocumentUpload::Kind::EvidenceDocument})
52
+ end.to raise_error(ArgumentError, "invalid keys: invalid_key")
53
+ end
54
+ end
55
+ end