{"action":"created","comment":{"url":"https://api.github.com/repos/Captricity/mocurly/pulls/comments/31973733","id":31973733,"diff_hunk":"@@ -141,53 +158,202 @@ def test_transaction_void(self):\n         mocurly.backend.transactions_backend.add_object('1234', self.base_transaction_data)\n \n         transaction = recurly.Transaction.get('1234')\n-        transaction.refund()\n+        with self.assertRaises(recurly.NotFoundError):\n+            transaction.refund()\n \n-        self.assertEqual(len(mocurly.backend.transactions_backend.datastore), 1)\n-        voided_transaction = mocurly.backend.transactions_backend.get_object('1234')\n-        for k, v in self.base_transaction_data.items():\n-            if k in ['voidable', 'refundable']:\n-                self.assertEqual(voided_transaction[k], False) # already refunded\n-            elif k == 'status':\n-                self.assertEqual(voided_transaction[k], 'void') # is now voided\n+    def test_transaction_refund_via_invoice(self):\n+        \"\"\"Uses the invoice refund system to refund a transaction.\"\"\"\n+        self.assertEqual(len(mocurly.backend.transactions_backend.datastore), 0)\n+\n+        self.base_transaction_data['uuid'] = '1234'\n+        self.base_transaction_data['account'] = self.base_account_data['uuid']\n+        self.base_transaction_data['invoice'] = self.base_invoice_data['invoice_number']\n+        self.base_transaction_data['test'] = True\n+        self.base_transaction_data['voidable'] = False\n+        self.base_transaction_data['refundable'] = True\n+        self.base_transaction_data['tax_in_cents'] = 0\n+        self.base_transaction_data['action'] = 'purchase'\n+        self.base_transaction_data['status'] = 'success'\n+        self.base_transaction_data['created_at'] = '2014-08-11'\n+        mocurly.backend.transactions_backend.add_object('1234', self.base_transaction_data)\n+        mocurly.backend.invoices_backend.add_object('1234', self.base_invoice_data)\n+        mocurly.backend.adjustments_backend.add_object('abcd1234', self.base_line_item)\n+\n+        transaction = recurly.Transaction.get('1234')\n+        invoice = transaction.invoice()\n+        line_items = invoice.line_items\n+        adjustments_to_refund = []\n+        for line_item in line_items:\n+            adjustments_to_refund.append({\n+                'adjustment': line_item,\n+                'quantity': line_item.quantity,\n+                'prorate': False \n+            })\n+        new_invoice = invoice.refund(adjustments_to_refund)\n+\n+        # Verify behavior of invoice line item refund\n+        # - Creates a new invoice with adjustments that cancel out original invoice\n+        # - Creates a new transaction object to be REFUND\n+        self.assertEqual(len(mocurly.backend.transactions_backend.datastore), 2)\n+        self.assertEqual(len(mocurly.backend.invoices_backend.datastore), 2)\n+        self.assertEqual(len(mocurly.backend.adjustments_backend.datastore), 2)\n+\n+        for invoice_number, invoice in mocurly.backend.invoices_backend.datastore.items():\n+            self.assertEqual(len(invoice['transactions']), 1)\n+            if invoice_number == '1234':\n+                original_invoice = invoice\n+                self.assertEqual(invoice['transactions'][0], '1234')\n+            else:\n+                refund_invoice = invoice\n+                self.assertNotEqual(invoice['transactions'][0], '1234')\n+        self.assertEqual(original_invoice['total_in_cents'], -refund_invoice['total_in_cents'])\n+\n+        for adjustment_uuid, adjustment in mocurly.backend.adjustments_backend.datastore.items():\n+            if adjustment['invoice'] == '1234':\n+                original_adjustment = adjustment\n+            else:\n+                refund_adjustment = adjustment\n+        self.assertEqual(original_adjustment['total_in_cents'], -refund_adjustment['total_in_cents'])\n+        self.assertEqual(int(original_adjustment['quantity']), -int(refund_adjustment['quantity']))\n+\n+        for transaction_uuid, transaction in mocurly.backend.transactions_backend.datastore.items():\n+            if transaction_uuid == '1234':\n+                original_transaction = transaction\n             else:\n-                self.assertEqual(voided_transaction[k], v)\n+                refund_transaction = transaction\n+        self.assertEqual(original_transaction['action'], 'purchase')\n+        self.assertEqual(original_transaction['status'], 'success')\n+        self.assertEqual(original_transaction['voidable'], False)\n+        self.assertEqual(original_transaction['refundable'], False)\n+        self.assertEqual(refund_transaction['action'], 'refund')\n+        self.assertEqual(refund_transaction['status'], 'success')\n+        self.assertEqual(refund_transaction['voidable'], True)\n+        self.assertEqual(refund_transaction['refundable'], False)\n+\n+        self.assertEqual(new_invoice.original_invoice().invoice_number, 1234)\n \n-    def test_transaction_refund(self):\n+\n+    def test_transaction_void_via_invoice(self):\n+        \"\"\"Uses the invoice refund system to void a transaction.\"\"\"\n         self.assertEqual(len(mocurly.backend.transactions_backend.datastore), 0)\n \n+        self.base_transaction_data['uuid'] = '1234'\n+        self.base_transaction_data['account'] = self.base_account_data['uuid']\n+        self.base_transaction_data['invoice'] = self.base_invoice_data['invoice_number']\n+        self.base_transaction_data['test'] = True\n+        self.base_transaction_data['voidable'] = True\n+        self.base_transaction_data['refundable'] = True\n+        self.base_transaction_data['tax_in_cents'] = 0\n+        self.base_transaction_data['action'] = 'purchase'\n+        self.base_transaction_data['status'] = 'success'\n+        self.base_transaction_data['created_at'] = '2014-08-11'\n+        mocurly.backend.transactions_backend.add_object('1234', self.base_transaction_data)\n         mocurly.backend.invoices_backend.add_object('1234', self.base_invoice_data)\n+        mocurly.backend.adjustments_backend.add_object('abcd1234', self.base_line_item)\n+\n+        transaction = recurly.Transaction.get('1234')\n+        invoice = transaction.invoice()\n+        line_items = invoice.line_items\n+        adjustments_to_refund = []\n+        for line_item in line_items:\n+            adjustments_to_refund.append({\n+                'adjustment': line_item,\n+                'quantity': line_item.quantity,\n+                'prorate': False \n+            })\n+        new_invoice = invoice.refund(adjustments_to_refund)\n+\n+        # Verify behavior of invoice line item refund\n+        # - Creates a new invoice with adjustments that cancel out original invoice\n+        # - Updates associated transaction object to be VOID\n+        self.assertEqual(len(mocurly.backend.transactions_backend.datastore), 1)\n+        self.assertEqual(len(mocurly.backend.invoices_backend.datastore), 2)\n+        self.assertEqual(len(mocurly.backend.adjustments_backend.datastore), 2)\n+\n+        for invoice_number, invoice in mocurly.backend.invoices_backend.datastore.items():","path":"tests/test_transaction.py","position":161,"original_position":161,"commit_id":"3ce22652f30556057503ed8629e9ac3e19117360","original_commit_id":"024e3bbe788808a57cfedd30f3f49e7d967e4f3d","user":{"login":"yorinasub17","id":430092,"avatar_url":"https://avatars.githubusercontent.com/u/430092?v=3","gravatar_id":"","url":"https://api.github.com/users/yorinasub17","html_url":"https://github.com/yorinasub17","followers_url":"https://api.github.com/users/yorinasub17/followers","following_url":"https://api.github.com/users/yorinasub17/following{/other_user}","gists_url":"https://api.github.com/users/yorinasub17/gists{/gist_id}","starred_url":"https://api.github.com/users/yorinasub17/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yorinasub17/subscriptions","organizations_url":"https://api.github.com/users/yorinasub17/orgs","repos_url":"https://api.github.com/users/yorinasub17/repos","events_url":"https://api.github.com/users/yorinasub17/events{/privacy}","received_events_url":"https://api.github.com/users/yorinasub17/received_events","type":"User","site_admin":false},"body":"No not really...","created_at":"2015-06-09T00:27:26Z","updated_at":"2015-06-09T00:27:26Z","html_url":"https://github.com/Captricity/mocurly/pull/1#discussion_r31973733","pull_request_url":"https://api.github.com/repos/Captricity/mocurly/pulls/1","_links":{"self":{"href":"https://api.github.com/repos/Captricity/mocurly/pulls/comments/31973733"},"html":{"href":"https://github.com/Captricity/mocurly/pull/1#discussion_r31973733"},"pull_request":{"href":"https://api.github.com/repos/Captricity/mocurly/pulls/1"}}},"pull_request":{"url":"https://api.github.com/repos/Captricity/mocurly/pulls/1","id":37063702,"html_url":"https://github.com/Captricity/mocurly/pull/1","diff_url":"https://github.com/Captricity/mocurly/pull/1.diff","patch_url":"https://github.com/Captricity/mocurly/pull/1.patch","issue_url":"https://api.github.com/repos/Captricity/mocurly/issues/1","number":1,"state":"open","locked":false,"title":"Deprecated transaction refund","user":{"login":"yorinasub17","id":430092,"avatar_url":"https://avatars.githubusercontent.com/u/430092?v=3","gravatar_id":"","url":"https://api.github.com/users/yorinasub17","html_url":"https://github.com/yorinasub17","followers_url":"https://api.github.com/users/yorinasub17/followers","following_url":"https://api.github.com/users/yorinasub17/following{/other_user}","gists_url":"https://api.github.com/users/yorinasub17/gists{/gist_id}","starred_url":"https://api.github.com/users/yorinasub17/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yorinasub17/subscriptions","organizations_url":"https://api.github.com/users/yorinasub17/orgs","repos_url":"https://api.github.com/users/yorinasub17/repos","events_url":"https://api.github.com/users/yorinasub17/events{/privacy}","received_events_url":"https://api.github.com/users/yorinasub17/received_events","type":"User","site_admin":false},"body":"This implements the new [invoice refund APIs](https://docs.recurly.com/api/invoices#line-item-refund) in recurly, while deprecating the old transaction refund API.\r\n\r\nTest:\r\n`python setup.py test`\r\n\r\nBuild Info:\r\n[Travis](https://travis-ci.org/Captricity/mocurly/branches)\r\n[Coverage](https://coveralls.io/r/Captricity/mocurly?branch=yori-deprecated-transaction-refund)","created_at":"2015-06-05T19:46:03Z","updated_at":"2015-06-09T00:27:26Z","closed_at":null,"merged_at":null,"merge_commit_sha":"3b0144582453cbcbf3acfa8fac2d8466409fa170","assignee":{"login":"raphaelmerx","id":5139869,"avatar_url":"https://avatars.githubusercontent.com/u/5139869?v=3","gravatar_id":"","url":"https://api.github.com/users/raphaelmerx","html_url":"https://github.com/raphaelmerx","followers_url":"https://api.github.com/users/raphaelmerx/followers","following_url":"https://api.github.com/users/raphaelmerx/following{/other_user}","gists_url":"https://api.github.com/users/raphaelmerx/gists{/gist_id}","starred_url":"https://api.github.com/users/raphaelmerx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/raphaelmerx/subscriptions","organizations_url":"https://api.github.com/users/raphaelmerx/orgs","repos_url":"https://api.github.com/users/raphaelmerx/repos","events_url":"https://api.github.com/users/raphaelmerx/events{/privacy}","received_events_url":"https://api.github.com/users/raphaelmerx/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/Captricity/mocurly/pulls/1/commits","review_comments_url":"https://api.github.com/repos/Captricity/mocurly/pulls/1/comments","review_comment_url":"https://api.github.com/repos/Captricity/mocurly/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Captricity/mocurly/issues/1/comments","statuses_url":"https://api.github.com/repos/Captricity/mocurly/statuses/3ce22652f30556057503ed8629e9ac3e19117360","head":{"label":"Captricity:yori-deprecated-transaction-refund","ref":"yori-deprecated-transaction-refund","sha":"3ce22652f30556057503ed8629e9ac3e19117360","user":{"login":"Captricity","id":769390,"avatar_url":"https://avatars.githubusercontent.com/u/769390?v=3","gravatar_id":"","url":"https://api.github.com/users/Captricity","html_url":"https://github.com/Captricity","followers_url":"https://api.github.com/users/Captricity/followers","following_url":"https://api.github.com/users/Captricity/following{/other_user}","gists_url":"https://api.github.com/users/Captricity/gists{/gist_id}","starred_url":"https://api.github.com/users/Captricity/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Captricity/subscriptions","organizations_url":"https://api.github.com/users/Captricity/orgs","repos_url":"https://api.github.com/users/Captricity/repos","events_url":"https://api.github.com/users/Captricity/events{/privacy}","received_events_url":"https://api.github.com/users/Captricity/received_events","type":"Organization","site_admin":false},"repo":{"id":22734055,"name":"mocurly","full_name":"Captricity/mocurly","owner":{"login":"Captricity","id":769390,"avatar_url":"https://avatars.githubusercontent.com/u/769390?v=3","gravatar_id":"","url":"https://api.github.com/users/Captricity","html_url":"https://github.com/Captricity","followers_url":"https://api.github.com/users/Captricity/followers","following_url":"https://api.github.com/users/Captricity/following{/other_user}","gists_url":"https://api.github.com/users/Captricity/gists{/gist_id}","starred_url":"https://api.github.com/users/Captricity/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Captricity/subscriptions","organizations_url":"https://api.github.com/users/Captricity/orgs","repos_url":"https://api.github.com/users/Captricity/repos","events_url":"https://api.github.com/users/Captricity/events{/privacy}","received_events_url":"https://api.github.com/users/Captricity/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Captricity/mocurly","description":"Mocurly is a library that mocks the recurly python client","fork":false,"url":"https://api.github.com/repos/Captricity/mocurly","forks_url":"https://api.github.com/repos/Captricity/mocurly/forks","keys_url":"https://api.github.com/repos/Captricity/mocurly/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Captricity/mocurly/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Captricity/mocurly/teams","hooks_url":"https://api.github.com/repos/Captricity/mocurly/hooks","issue_events_url":"https://api.github.com/repos/Captricity/mocurly/issues/events{/number}","events_url":"https://api.github.com/repos/Captricity/mocurly/events","assignees_url":"https://api.github.com/repos/Captricity/mocurly/assignees{/user}","branches_url":"https://api.github.com/repos/Captricity/mocurly/branches{/branch}","tags_url":"https://api.github.com/repos/Captricity/mocurly/tags","blobs_url":"https://api.github.com/repos/Captricity/mocurly/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Captricity/mocurly/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Captricity/mocurly/git/refs{/sha}","trees_url":"https://api.github.com/repos/Captricity/mocurly/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Captricity/mocurly/statuses/{sha}","languages_url":"https://api.github.com/repos/Captricity/mocurly/languages","stargazers_url":"https://api.github.com/repos/Captricity/mocurly/stargazers","contributors_url":"https://api.github.com/repos/Captricity/mocurly/contributors","subscribers_url":"https://api.github.com/repos/Captricity/mocurly/subscribers","subscription_url":"https://api.github.com/repos/Captricity/mocurly/subscription","commits_url":"https://api.github.com/repos/Captricity/mocurly/commits{/sha}","git_commits_url":"https://api.github.com/repos/Captricity/mocurly/git/commits{/sha}","comments_url":"https://api.github.com/repos/Captricity/mocurly/comments{/number}","issue_comment_url":"https://api.github.com/repos/Captricity/mocurly/issues/comments{/number}","contents_url":"https://api.github.com/repos/Captricity/mocurly/contents/{+path}","compare_url":"https://api.github.com/repos/Captricity/mocurly/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Captricity/mocurly/merges","archive_url":"https://api.github.com/repos/Captricity/mocurly/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Captricity/mocurly/downloads","issues_url":"https://api.github.com/repos/Captricity/mocurly/issues{/number}","pulls_url":"https://api.github.com/repos/Captricity/mocurly/pulls{/number}","milestones_url":"https://api.github.com/repos/Captricity/mocurly/milestones{/number}","notifications_url":"https://api.github.com/repos/Captricity/mocurly/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Captricity/mocurly/labels{/name}","releases_url":"https://api.github.com/repos/Captricity/mocurly/releases{/id}","created_at":"2014-08-07T19:34:51Z","updated_at":"2014-09-23T18:58:23Z","pushed_at":"2015-06-08T02:54:52Z","git_url":"git://github.com/Captricity/mocurly.git","ssh_url":"git@github.com:Captricity/mocurly.git","clone_url":"https://github.com/Captricity/mocurly.git","svn_url":"https://github.com/Captricity/mocurly","homepage":null,"size":743,"stargazers_count":3,"watchers_count":3,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":3,"default_branch":"master"}},"base":{"label":"Captricity:master","ref":"master","sha":"a9dd4b6a643b84aa69a23c9156ae4a5975a4ebe6","user":{"login":"Captricity","id":769390,"avatar_url":"https://avatars.githubusercontent.com/u/769390?v=3","gravatar_id":"","url":"https://api.github.com/users/Captricity","html_url":"https://github.com/Captricity","followers_url":"https://api.github.com/users/Captricity/followers","following_url":"https://api.github.com/users/Captricity/following{/other_user}","gists_url":"https://api.github.com/users/Captricity/gists{/gist_id}","starred_url":"https://api.github.com/users/Captricity/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Captricity/subscriptions","organizations_url":"https://api.github.com/users/Captricity/orgs","repos_url":"https://api.github.com/users/Captricity/repos","events_url":"https://api.github.com/users/Captricity/events{/privacy}","received_events_url":"https://api.github.com/users/Captricity/received_events","type":"Organization","site_admin":false},"repo":{"id":22734055,"name":"mocurly","full_name":"Captricity/mocurly","owner":{"login":"Captricity","id":769390,"avatar_url":"https://avatars.githubusercontent.com/u/769390?v=3","gravatar_id":"","url":"https://api.github.com/users/Captricity","html_url":"https://github.com/Captricity","followers_url":"https://api.github.com/users/Captricity/followers","following_url":"https://api.github.com/users/Captricity/following{/other_user}","gists_url":"https://api.github.com/users/Captricity/gists{/gist_id}","starred_url":"https://api.github.com/users/Captricity/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Captricity/subscriptions","organizations_url":"https://api.github.com/users/Captricity/orgs","repos_url":"https://api.github.com/users/Captricity/repos","events_url":"https://api.github.com/users/Captricity/events{/privacy}","received_events_url":"https://api.github.com/users/Captricity/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Captricity/mocurly","description":"Mocurly is a library that mocks the recurly python client","fork":false,"url":"https://api.github.com/repos/Captricity/mocurly","forks_url":"https://api.github.com/repos/Captricity/mocurly/forks","keys_url":"https://api.github.com/repos/Captricity/mocurly/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Captricity/mocurly/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Captricity/mocurly/teams","hooks_url":"https://api.github.com/repos/Captricity/mocurly/hooks","issue_events_url":"https://api.github.com/repos/Captricity/mocurly/issues/events{/number}","events_url":"https://api.github.com/repos/Captricity/mocurly/events","assignees_url":"https://api.github.com/repos/Captricity/mocurly/assignees{/user}","branches_url":"https://api.github.com/repos/Captricity/mocurly/branches{/branch}","tags_url":"https://api.github.com/repos/Captricity/mocurly/tags","blobs_url":"https://api.github.com/repos/Captricity/mocurly/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Captricity/mocurly/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Captricity/mocurly/git/refs{/sha}","trees_url":"https://api.github.com/repos/Captricity/mocurly/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Captricity/mocurly/statuses/{sha}","languages_url":"https://api.github.com/repos/Captricity/mocurly/languages","stargazers_url":"https://api.github.com/repos/Captricity/mocurly/stargazers","contributors_url":"https://api.github.com/repos/Captricity/mocurly/contributors","subscribers_url":"https://api.github.com/repos/Captricity/mocurly/subscribers","subscription_url":"https://api.github.com/repos/Captricity/mocurly/subscription","commits_url":"https://api.github.com/repos/Captricity/mocurly/commits{/sha}","git_commits_url":"https://api.github.com/repos/Captricity/mocurly/git/commits{/sha}","comments_url":"https://api.github.com/repos/Captricity/mocurly/comments{/number}","issue_comment_url":"https://api.github.com/repos/Captricity/mocurly/issues/comments{/number}","contents_url":"https://api.github.com/repos/Captricity/mocurly/contents/{+path}","compare_url":"https://api.github.com/repos/Captricity/mocurly/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Captricity/mocurly/merges","archive_url":"https://api.github.com/repos/Captricity/mocurly/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Captricity/mocurly/downloads","issues_url":"https://api.github.com/repos/Captricity/mocurly/issues{/number}","pulls_url":"https://api.github.com/repos/Captricity/mocurly/pulls{/number}","milestones_url":"https://api.github.com/repos/Captricity/mocurly/milestones{/number}","notifications_url":"https://api.github.com/repos/Captricity/mocurly/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Captricity/mocurly/labels{/name}","releases_url":"https://api.github.com/repos/Captricity/mocurly/releases{/id}","created_at":"2014-08-07T19:34:51Z","updated_at":"2014-09-23T18:58:23Z","pushed_at":"2015-06-08T02:54:52Z","git_url":"git://github.com/Captricity/mocurly.git","ssh_url":"git@github.com:Captricity/mocurly.git","clone_url":"https://github.com/Captricity/mocurly.git","svn_url":"https://github.com/Captricity/mocurly","homepage":null,"size":743,"stargazers_count":3,"watchers_count":3,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":3,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Captricity/mocurly/pulls/1"},"html":{"href":"https://github.com/Captricity/mocurly/pull/1"},"issue":{"href":"https://api.github.com/repos/Captricity/mocurly/issues/1"},"comments":{"href":"https://api.github.com/repos/Captricity/mocurly/issues/1/comments"},"review_comments":{"href":"https://api.github.com/repos/Captricity/mocurly/pulls/1/comments"},"review_comment":{"href":"https://api.github.com/repos/Captricity/mocurly/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Captricity/mocurly/pulls/1/commits"},"statuses":{"href":"https://api.github.com/repos/Captricity/mocurly/statuses/3ce22652f30556057503ed8629e9ac3e19117360"}}}}