DisputeTest.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. <?php
  2. namespace Test\Integration;
  3. require_once dirname(__DIR__) . '/Setup.php';
  4. use Test\Setup;
  5. use Braintree;
  6. class DisputeTest extends Setup
  7. {
  8. private $gateway;
  9. public function __construct() {
  10. $this->gateway = new Braintree\Gateway([
  11. 'environment' => 'development',
  12. 'merchantId' => 'integration_merchant_id',
  13. 'publicKey' => 'integration_public_key',
  14. 'privateKey' => 'integration_private_key'
  15. ]);
  16. }
  17. public function createSampleDocument()
  18. {
  19. $pngFile = fopen(dirname(__DIR__) . '/fixtures/bt_logo.png', 'rb');
  20. $result = Braintree\DocumentUpload::create([
  21. "kind" => Braintree\DocumentUpload::EVIDENCE_DOCUMENT,
  22. "file" => $pngFile
  23. ]);
  24. return $result->documentUpload;
  25. }
  26. public function createSampleDispute()
  27. {
  28. $result = Braintree\Transaction::sale([
  29. 'amount' => '100.00',
  30. 'creditCard' => [
  31. 'number' => Braintree\Test\CreditCardNumbers::$disputes['Chargeback'],
  32. 'expirationDate' => '12/2019',
  33. ]
  34. ]);
  35. return $result->transaction->disputes[0];
  36. }
  37. public function testAccept_changesDisputeStatusToAccepted()
  38. {
  39. $dispute = $this->createSampleDispute();
  40. $result = $this->gateway->dispute()->accept($dispute->id);
  41. $this->assertTrue($result->success);
  42. $updatedDispute = $this->gateway->dispute()->find($dispute->id);
  43. $this->assertEquals(Braintree\Dispute::ACCEPTED, $updatedDispute->status);
  44. }
  45. public function testAccept_errors_whenDisputeNotOpen()
  46. {
  47. $result = $this->gateway->dispute()->accept("wells_dispute");
  48. $error = $result->errors->forKey('dispute')->errors[0];
  49. $this->assertFalse($result->success);
  50. $this->assertEquals(Braintree\Error\Codes::DISPUTE_CAN_ONLY_ACCEPT_OPEN_DISPUTE, $error->code);
  51. $this->assertEquals("Disputes can only be accepted when they are in an Open state", $error->message);
  52. }
  53. public function testAccept_raisesError_whenDisputeNotFound()
  54. {
  55. $this->setExpectedException('Braintree\Exception\NotFound', 'dispute with id "invalid-id" not found');
  56. $this->gateway->dispute()->accept("invalid-id");
  57. }
  58. public function testAddFileEvidence_addsEvidence()
  59. {
  60. $disputeId = $this->createSampleDispute()->id;
  61. $documentId = $this->createSampleDocument()->id;
  62. $result = $this->gateway->dispute()->addFileEvidence($disputeId, $documentId);
  63. $this->assertTrue($result->success);
  64. $updatedDispute = $this->gateway->dispute()->find($disputeId);
  65. $this->assertEquals($result->evidence->id, $updatedDispute->evidence[0]->id);
  66. }
  67. public function testAddFileEvidence_addsEvidence_withCategory()
  68. {
  69. $disputeId = $this->createSampleDispute()->id;
  70. $documentId = $this->createSampleDocument()->id;
  71. $result = Braintree\Dispute::addFileEvidence($disputeId,
  72. [
  73. 'category' => 'GENERAL',
  74. 'documentId' => $documentId,
  75. ]
  76. );
  77. $this->assertTrue($result->success);
  78. $this->assertEquals('GENERAL', $result->evidence->category);
  79. }
  80. public function testAddFileEvidence_raisesError_whenDisputeNotFound()
  81. {
  82. $this->setExpectedException('Braintree\Exception\NotFound', 'dispute with id "unknown_dispute_id" not found');
  83. $this->gateway->dispute()->addFileEvidence("unknown_dispute_id", "unknown_file_id");
  84. }
  85. public function testAddFileEvidence_raisesError_whenDisputeNotOpen()
  86. {
  87. $disputeId = $this->createSampleDispute()->id;
  88. $documentId = $this->createSampleDocument()->id;
  89. $this->gateway->dispute()->accept($disputeId);
  90. $result = $this->gateway->dispute()->addFileEvidence($disputeId, $documentId);
  91. $error = $result->errors->forKey('dispute')->errors[0];
  92. $this->assertFalse($result->success);
  93. $this->assertEquals(Braintree\Error\Codes::DISPUTE_CAN_ONLY_ADD_EVIDENCE_TO_OPEN_DISPUTE, $error->code);
  94. $this->assertEquals("Evidence can only be attached to disputes that are in an Open state", $error->message);
  95. }
  96. public function testAddTextEvidence_addsTextEvidence()
  97. {
  98. $disputeId = $this->createSampleDispute()->id;
  99. $result = $this->gateway->dispute()->addTextEvidence($disputeId, "text evidence");
  100. $evidence = $result->evidence;
  101. $this->assertTrue($result->success);
  102. $this->assertEquals("text evidence", $evidence->comment);
  103. $this->assertNotNull($evidence->createdAt);
  104. $this->assertRegExp('/^\w{16,}$/', $evidence->id);
  105. $this->assertNull($evidence->sentToProcessorAt);
  106. $this->assertNull($evidence->url);
  107. $this->assertNull($evidence->tag);
  108. $this->assertNull($evidence->sequenceNumber);
  109. }
  110. public function testAddTaggedTextEvidence_addsTextEvidence()
  111. {
  112. $disputeId = $this->createSampleDispute()->id;
  113. $result = $this->gateway->dispute()->addTextEvidence($disputeId,
  114. [
  115. 'content' => "UPS",
  116. 'category' => "CARRIER_NAME",
  117. 'sequenceNumber' => "1"
  118. ]
  119. );
  120. $evidence = $result->evidence;
  121. $this->assertTrue($result->success);
  122. $this->assertEquals("UPS", $evidence->comment);
  123. $this->assertNotNull($evidence->createdAt);
  124. $this->assertRegExp('/^\w{16,}$/', $evidence->id);
  125. $this->assertNull($evidence->sentToProcessorAt);
  126. $this->assertNull($evidence->url);
  127. $this->assertEquals("CARRIER_NAME", $evidence->category);
  128. $this->assertEquals("CARRIER_NAME", $evidence->tag);
  129. $this->assertEquals("1", $evidence->sequenceNumber);
  130. }
  131. public function testAddTextEvidence_raisesError_whenDisputeNotFound()
  132. {
  133. $this->setExpectedException('Braintree\Exception\NotFound', 'dispute with id "unknown_dispute_id" not found');
  134. $dispute = $this->gateway->dispute()->addTextEvidence("unknown_dispute_id", "text evidence");
  135. }
  136. public function testAddTextEvidence_raisesError_whenDisputeNotOpen()
  137. {
  138. $disputeId = $this->createSampleDispute()->id;
  139. $this->gateway->dispute()->accept($disputeId);
  140. $result = $this->gateway->dispute()->addTextEvidence($disputeId, "text evidence");
  141. $error = $result->errors->forKey('dispute')->errors[0];
  142. $this->assertFalse($result->success);
  143. $this->assertEquals(Braintree\Error\Codes::DISPUTE_CAN_ONLY_ADD_EVIDENCE_TO_OPEN_DISPUTE, $error->code);
  144. $this->assertEquals("Evidence can only be attached to disputes that are in an Open state", $error->message);
  145. }
  146. public function testAddTextEvidence_showsNewRecord_inFind()
  147. {
  148. $disputeId = $this->createSampleDispute()->id;
  149. $evidence = $this->gateway->dispute()->addTextEvidence($disputeId, "text evidence")->evidence;
  150. $refreshedDispute = $this->gateway->dispute()->find($disputeId);
  151. $refreshedEvidence = $refreshedDispute->evidence[0];
  152. $this->assertEquals($evidence->id, $refreshedEvidence->id);
  153. $this->assertEquals($evidence->comment, $refreshedEvidence->comment);
  154. }
  155. public function testFinalize_changesDisputeStatus_toDisputed()
  156. {
  157. $disputeId = $this->createSampleDispute()->id;
  158. $result = $this->gateway->dispute()->finalize($disputeId);
  159. $this->assertTrue($result->success);
  160. $updatedDispute = $this->gateway->dispute()->find($disputeId);
  161. $this->assertEquals(Braintree\Dispute::DISPUTED, $updatedDispute->status);
  162. }
  163. public function testFinalize_errors_whenDisputeNotOpen()
  164. {
  165. $result = $this->gateway->dispute()->finalize("wells_dispute");
  166. $error = $result->errors->forKey('dispute')->errors[0];
  167. $this->assertFalse($result->success);
  168. $this->assertEquals(Braintree\Error\Codes::DISPUTE_CAN_ONLY_FINALIZE_OPEN_DISPUTE, $error->code);
  169. $this->assertEquals("Disputes can only be finalized when they are in an Open state", $error->message);
  170. }
  171. public function testFinalize_raisesError_whenDisputeNotFound()
  172. {
  173. $this->setExpectedException('Braintree\Exception\NotFound', 'dispute with id "invalid-id" not found');
  174. $result = $this->gateway->dispute()->finalize("invalid-id");
  175. }
  176. public function testFind_returnsDispute_withGivenId()
  177. {
  178. $dispute = $this->gateway->dispute()->find("open_dispute");
  179. $this->assertEquals("31.0", $dispute->amountDisputed);
  180. $this->assertEquals("0.0", $dispute->amountWon);
  181. $this->assertEquals("open_dispute", $dispute->id);
  182. $this->assertEquals(Braintree\Dispute::OPEN, $dispute->status);
  183. $this->assertEquals("open_disputed_transaction", $dispute->transaction->id);
  184. }
  185. public function testFind_raisesError_whenDisputeNotFound()
  186. {
  187. $this->setExpectedException('Braintree\Exception\NotFound', 'dispute with id "invalid-id" not found');
  188. $this->gateway->dispute()->find("invalid-id");
  189. }
  190. public function testRemoveEvidence_removesEvidenceFromTheDisupute()
  191. {
  192. $disputeId = $this->createSampleDispute()->id;
  193. $evidenceId = $this->gateway->dispute()->addTextEvidence($disputeId, "text evidence")->evidence->id;
  194. $result = $this->gateway->dispute()->removeEvidence($disputeId, $evidenceId);
  195. $this->assertTrue($result->success);
  196. }
  197. public function testRemoveEvidence_raisesError_whenDisputeOrEvidenceNotFound()
  198. {
  199. $this->setExpectedException('Braintree\Exception\NotFound', "evidence with id \"unknown_evidence_id\" for dispute with id \"unknown_dispute_id\" not found");
  200. $this->gateway->dispute()->removeEvidence("unknown_dispute_id", "unknown_evidence_id");
  201. }
  202. public function testRemoveEvidence_errors_whenDisputeNotOpen()
  203. {
  204. $disputeId = $this->createSampleDispute()->id;
  205. $evidenceId = $this->gateway->dispute()->addTextEvidence($disputeId, "text evidence")->evidence->id;
  206. $this->gateway->dispute()->accept($disputeId);
  207. $result = $this->gateway->dispute()->removeEvidence($disputeId, $evidenceId);
  208. $error = $result->errors->forKey('dispute')->errors[0];
  209. $this->assertFalse($result->success);
  210. $this->assertEquals(Braintree\Error\Codes::DISPUTE_CAN_ONLY_REMOVE_EVIDENCE_FROM_OPEN_DISPUTE, $error->code);
  211. $this->assertEquals("Evidence can only be removed from disputes that are in an Open state", $error->message);
  212. }
  213. public function testCategorizedEvidence_fileForTextOnlyCategory()
  214. {
  215. $disputeId = $this->createSampleDispute()->id;
  216. $documentId = $this->createSampleDocument()->id;
  217. $result = Braintree\Dispute::addFileEvidence($disputeId,
  218. [
  219. 'category' => 'DEVICE_ID',
  220. 'documentId' => $documentId,
  221. ]
  222. );
  223. $error = $result->errors->forKey('dispute')->errors[0];
  224. $this->assertFalse($result->success);
  225. $this->assertEquals(Braintree\Error\Codes::DISPUTE_EVIDENCE_CATEGORY_TEXT_ONLY, $error->code);
  226. }
  227. public function testCategorizedEvidence_withFile_invalidCategoryProvided()
  228. {
  229. $disputeId = $this->createSampleDispute()->id;
  230. $documentId = $this->createSampleDocument()->id;
  231. $result = Braintree\Dispute::addFileEvidence($disputeId,
  232. [
  233. 'category' => 'NOTREALCATEGORY',
  234. 'documentId' => $documentId,
  235. ]
  236. );
  237. $error = $result->errors->forKey('dispute')->errors[0];
  238. $this->assertFalse($result->success);
  239. $this->assertEquals(Braintree\Error\Codes::DISPUTE_CAN_ONLY_CREATE_EVIDENCE_WITH_VALID_CATEGORY, $error->code);
  240. }
  241. public function testCategorizedEvidence_withText_invalidCategoryProvided()
  242. {
  243. $disputeId = $this->createSampleDispute()->id;
  244. $result = Braintree\Dispute::addTextEvidence($disputeId,
  245. [
  246. 'category' => 'NOTREALCATEGORY',
  247. 'content' => 'evidence',
  248. ]
  249. );
  250. $error = $result->errors->forKey('dispute')->errors[0];
  251. $this->assertFalse($result->success);
  252. $this->assertEquals(Braintree\Error\Codes::DISPUTE_CAN_ONLY_CREATE_EVIDENCE_WITH_VALID_CATEGORY, $error->code);
  253. }
  254. public function testCategorizedEvidence_textForFileOnlyCategory()
  255. {
  256. $disputeId = $this->createSampleDispute()->id;
  257. $result = Braintree\Dispute::addTextEvidence($disputeId,
  258. [
  259. 'category' => 'MERCHANT_WEBSITE_OR_APP_ACCESS',
  260. 'content' => 'evidence',
  261. ]
  262. );
  263. $error = $result->errors->forKey('dispute')->errors[0];
  264. $this->assertFalse($result->success);
  265. $this->assertEquals(Braintree\Error\Codes::DISPUTE_EVIDENCE_CATEGORY_DOCUMENT_ONLY, $error->code);
  266. }
  267. public function testCategorizedEvidence_invalidDateTimeFormatFails()
  268. {
  269. $disputeId = $this->createSampleDispute()->id;
  270. $result = Braintree\Dispute::addTextEvidence($disputeId,
  271. [
  272. 'category' => 'DOWNLOAD_DATE_TIME',
  273. 'content' => 'baddate',
  274. ]
  275. );
  276. $error = $result->errors->forKey('dispute')->errors[0];
  277. $this->assertFalse($result->success);
  278. $this->assertEquals(Braintree\Error\Codes::DISPUTE_EVIDENCE_CONTENT_DATE_INVALID, $error->code);
  279. }
  280. public function testCategorizedEvidence_validDateTimeFormatSuccess()
  281. {
  282. $disputeId = $this->createSampleDispute()->id;
  283. $result = Braintree\Dispute::addTextEvidence($disputeId,
  284. [
  285. 'category' => 'DOWNLOAD_DATE_TIME',
  286. 'content' => '2018-10-20T18:00:00-0500',
  287. ]
  288. );
  289. $this->assertTrue($result->success);
  290. }
  291. public function testCategorizedEvidence_finalizeFail_DigitalGoodsPartialEvidence()
  292. {
  293. $disputeId = $this->createSampleDispute()->id;
  294. Braintree\Dispute::addTextEvidence($disputeId,
  295. [
  296. 'category' => 'DEVICE_ID',
  297. 'content' => 'iphone_id',
  298. ]
  299. );
  300. $result = Braintree\Dispute::finalize($disputeId);
  301. $this->assertFalse($result->success);
  302. $errors = $result->errors->forKey('dispute')->errors;
  303. $this->assertEquals(Braintree\Error\Codes::DISPUTE_DIGITAL_GOODS_MISSING_EVIDENCE, $errors[0]->code);
  304. $this->assertEquals(Braintree\Error\Codes::DISPUTE_DIGITAL_GOODS_MISSING_DOWNLOAD_DATE, $errors[1]->code);
  305. }
  306. public function testCategorizedEvidence_finalizeFail_PartialNonDisputeTransInfo()
  307. {
  308. $disputeId = $this->createSampleDispute()->id;
  309. Braintree\Dispute::addTextEvidence($disputeId,
  310. [
  311. 'category' => 'PRIOR_NON_DISPUTED_TRANSACTION_ARN',
  312. 'content' => '123',
  313. ]
  314. );
  315. $result = Braintree\Dispute::finalize($disputeId);
  316. $this->assertFalse($result->success);
  317. $error = $result->errors->forKey('dispute')->errors[0];
  318. $this->assertEquals(Braintree\Error\Codes::DISPUTE_PRIOR_NON_DISPUTED_TRANSACTION_MISSING_DATE, $error->code);
  319. }
  320. }