{"action":"created","comment":{"url":"https://api.github.com/repos/raccoongang/edx-platform/pulls/comments/129534477","pull_request_review_id":52312676,"id":129534477,"diff_hunk":"@@ -0,0 +1,173 @@\n+\"\"\"\n+Tests acceptor API usage by edx global analytics application functions aka utils.\n+\"\"\"\n+\n+import uuid\n+import unittest\n+\n+from mock import patch\n+\n+from openedx.core.djangoapps.edx_global_analytics.utils import send_instance_statistics_to_acceptor\n+from openedx.core.djangoapps.edx_global_analytics.token_utils import (\n+    access_token_authorization,\n+    access_token_registration,\n+    get_acceptor_api_access_token,\n+)\n+\n+\n+@patch('openedx.core.djangoapps.edx_global_analytics.utils.requests.post')\n+class TestAcceptorApiUsage(unittest.TestCase):\n+    \"\"\"\n+    Test acceptor API usage by edx global analytics application functions aka utils.\n+    \"\"\"\n+\n+    def test_token_registration(self, mock_request):\n+        \"\"\"\n+        Verify that access_token_registration sends request to acceptor API for token registration.\n+        \"\"\"\n+        access_token_registration('https://mock-url.com')\n+\n+        mock_request.assert_called_once_with('https://mock-url.com' + '/api/token/registration/')\n+\n+    @patch('openedx.core.djangoapps.edx_global_analytics.models.AccessTokensStorage.objects.create')\n+    def test_saving_token(self, mock_access_tokens_storage_model_objects_create_method, mock_request):\n+        \"\"\"\n+        Verify that access_token_registration gets access token after registration request to acceptor and\n+        save it to AccessTokensStorage model in database.\n+        \"\"\"\n+        mock_access_token = uuid.uuid4().hex\n+\n+        mock_request.return_value.json.return_value = {\n+            'access_token': mock_access_token\n+        }\n+\n+        access_token_registration('https://mock-url.com')\n+\n+        mock_access_tokens_storage_model_objects_create_method.assert_called_with(access_token=mock_access_token)\n+\n+    def test_token_authorization(self, mock_request):\n+        \"\"\"\n+        Verify that access_token_authorization sends request to acceptor API for token authorization.\n+        \"\"\"\n+        mock_access_token = uuid.uuid4().hex\n+\n+        access_token_authorization(mock_access_token, 'https://mock-url.com')\n+\n+        mock_request.assert_called_once_with(\n+            'https://mock-url.com' + '/api/token/authorization/', data={'access_token': mock_access_token, }\n+        )\n+\n+    @patch('openedx.core.djangoapps.edx_global_analytics.models.AccessTokensStorage.objects.first')\n+    def test_refreshing_token(self, mock_access_tokens_storage_model_objects_first, mock_request):\n+        \"\"\"\n+        Verify that access_token_authorization method gets refreshed access token after authorization request to\n+        acceptor if Acceptor for any reason does not has a token from edX installation in own database.\n+        \"\"\"\n+        mock_access_token = uuid.uuid4().hex\n+        mock_refreshed_access_token = uuid.uuid4().hex\n+\n+        mock_request.status_code = 401\n+\n+        mock_request.return_value.json.return_value = {\n+            'refreshed_access_token': mock_refreshed_access_token\n+        }\n+\n+        access_token_authorization(mock_access_token, 'https://mock-url.com')\n+\n+        mock_access_tokens_storage_model_objects_first.access_token = mock_refreshed_access_token\n+\n+        self.assertEqual(mock_refreshed_access_token, mock_access_tokens_storage_model_objects_first.access_token)\n+        mock_access_tokens_storage_model_objects_first.save.assert_called_once()\n+\n+    def test_sending_statistics(self, mock_request):\n+        \"\"\"\n+        Verify that send_instance_statistics_to_acceptor sends request to acceptor API for token dispatch statistics.\n+        \"\"\"\n+        send_instance_statistics_to_acceptor('https://mock-url.com', {'mock_data': 'mock_data', })\n+\n+        mock_request.assert_called_once_with(\n+            'https://mock-url.com' + '/api/installation/statistics/', {'mock_data': 'mock_data', }\n+        )\n+\n+    @patch('openedx.core.djangoapps.edx_global_analytics.utils.logging.Logger.info')\n+    def test_successfully_sent_statistics(self, mock_logging, mock_request):\n+        \"\"\"\n+        Verify that send_instance_statistics_to_acceptor successfully dispatches\n+        installation_statistics to acceptor API.\n+        \"\"\"\n+        mock_request.return_value.status_code = 201\n+\n+        send_instance_statistics_to_acceptor('https://mock-url.com', {'mock_data': 'mock_data', })\n+\n+        mock_logging.assert_called_with('Data were successfully transferred to OLGA acceptor. Status code is 201.')\n+\n+    @patch('openedx.core.djangoapps.edx_global_analytics.utils.logging.Logger.info')\n+    def test_unsuccessfully_sent_statistics(self, mock_logging, mock_request):\n+        \"\"\"\n+        Verify that send_instance_statistics_to_acceptor unsuccessfully dispatches\n+        installation_statistics to acceptor API.\n+        \"\"\"\n+        mock_request.return_value.status_code = 400\n+\n+        send_instance_statistics_to_acceptor('https://mock-url.com', {'mock_data': 'mock_data', })\n+\n+        mock_logging.assert_called_with(\n+            'Data were not successfully transferred to OLGA acceptor. Status code is {0}.'.format(\n+                mock_request.return_value.status_code\n+            )\n+        )","path":"openedx/core/djangoapps/edx_global_analytics/tests/test_acceptor_api_usage.py","position":118,"original_position":118,"commit_id":"ebe709feef8f9cb0e1e94891fe5d3ab3d1639c1d","original_commit_id":"ebe709feef8f9cb0e1e94891fe5d3ab3d1639c1d","user":{"login":"auraz","id":67241,"avatar_url":"https://avatars2.githubusercontent.com/u/67241?v=4","gravatar_id":"","url":"https://api.github.com/users/auraz","html_url":"https://github.com/auraz","followers_url":"https://api.github.com/users/auraz/followers","following_url":"https://api.github.com/users/auraz/following{/other_user}","gists_url":"https://api.github.com/users/auraz/gists{/gist_id}","starred_url":"https://api.github.com/users/auraz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/auraz/subscriptions","organizations_url":"https://api.github.com/users/auraz/orgs","repos_url":"https://api.github.com/users/auraz/repos","events_url":"https://api.github.com/users/auraz/events{/privacy}","received_events_url":"https://api.github.com/users/auraz/received_events","type":"User","site_admin":false},"body":"Use ddt please for this and previous test","created_at":"2017-07-26T10:20:40Z","updated_at":"2017-07-26T10:33:08Z","html_url":"https://github.com/raccoongang/edx-platform/pull/83#discussion_r129534477","pull_request_url":"https://api.github.com/repos/raccoongang/edx-platform/pulls/83","_links":{"self":{"href":"https://api.github.com/repos/raccoongang/edx-platform/pulls/comments/129534477"},"html":{"href":"https://github.com/raccoongang/edx-platform/pull/83#discussion_r129534477"},"pull_request":{"href":"https://api.github.com/repos/raccoongang/edx-platform/pulls/83"}}},"pull_request":{"url":"https://api.github.com/repos/raccoongang/edx-platform/pulls/83","id":127278759,"html_url":"https://github.com/raccoongang/edx-platform/pull/83","diff_url":"https://github.com/raccoongang/edx-platform/pull/83.diff","patch_url":"https://github.com/raccoongang/edx-platform/pull/83.patch","issue_url":"https://api.github.com/repos/raccoongang/edx-platform/issues/83","number":83,"state":"open","locked":false,"title":"Token authentication flow, documentation","user":{"login":"DmytryiStriletskyi","id":22666467,"avatar_url":"https://avatars2.githubusercontent.com/u/22666467?v=4","gravatar_id":"","url":"https://api.github.com/users/DmytryiStriletskyi","html_url":"https://github.com/DmytryiStriletskyi","followers_url":"https://api.github.com/users/DmytryiStriletskyi/followers","following_url":"https://api.github.com/users/DmytryiStriletskyi/following{/other_user}","gists_url":"https://api.github.com/users/DmytryiStriletskyi/gists{/gist_id}","starred_url":"https://api.github.com/users/DmytryiStriletskyi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DmytryiStriletskyi/subscriptions","organizations_url":"https://api.github.com/users/DmytryiStriletskyi/orgs","repos_url":"https://api.github.com/users/DmytryiStriletskyi/repos","events_url":"https://api.github.com/users/DmytryiStriletskyi/events{/privacy}","received_events_url":"https://api.github.com/users/DmytryiStriletskyi/received_events","type":"User","site_admin":false},"body":"## Features \r\n`openedx/core/djangoapps/edx_global_analytics/models.py` — change table and field model.\r\nI think `secret_token` is a bit useless name, `access_token` shows cleaner intention.\r\n\r\nAll functionality, that works with acceptor API I moved to `utils.py` (at the end of the file) from main `tasks.py` — `openedx/core/djangoapps/edx_global_analytics/utils.py`.\r\n\r\nI removed unnecessary workflow with registration token return via post-request (from acceptor to edX):\r\n1. `openedx/core/djangoapps/edx_global_analytics/urls.py`\r\n2. `openedx/core/djangoapps/edx_global_analytics/views.py`\r\n\r\nIt just works now only in one way (from edX to acceptor) and regulates by `http status codes`.\r\n\r\n## Tests \r\nI added corresponding tests for `token authentication flow`, that connected with acceptor API usage:\r\n1. `openedx/core/djangoapps/edx_global_analytics/tests/test_acceptor_api_usage.py` — tests for directly API (requests, flow).\r\n2. `openedx/core/djangoapps/edx_global_analytics/tests/test_acceptor_api_usage_helpers.py` - test for API usage helpers.\r\n\r\nI separated `test_utils.py` to:  \r\n1. `openedx/core/djangoapps/edx_global_analytics/tests/test_cache_instance_data.py` — tests for cache instance data.\r\n2. and other test for instance student amount (rename `test_utils` to `test_instance_students_amount`).\r\n\r\nAlso I added tests for `statistics bunches` and tried to cover all code lines. ","created_at":"2017-06-23T20:02:59Z","updated_at":"2017-07-26T10:33:08Z","closed_at":null,"merged_at":null,"merge_commit_sha":"8659d2203e0e456d82a0a902c439c536b7a3b832","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/raccoongang/edx-platform/pulls/83/commits","review_comments_url":"https://api.github.com/repos/raccoongang/edx-platform/pulls/83/comments","review_comment_url":"https://api.github.com/repos/raccoongang/edx-platform/pulls/comments{/number}","comments_url":"https://api.github.com/repos/raccoongang/edx-platform/issues/83/comments","statuses_url":"https://api.github.com/repos/raccoongang/edx-platform/statuses/ebe709feef8f9cb0e1e94891fe5d3ab3d1639c1d","head":{"label":"raccoongang:edx_global_analytics","ref":"edx_global_analytics","sha":"ebe709feef8f9cb0e1e94891fe5d3ab3d1639c1d","user":{"login":"raccoongang","id":11388447,"avatar_url":"https://avatars0.githubusercontent.com/u/11388447?v=4","gravatar_id":"","url":"https://api.github.com/users/raccoongang","html_url":"https://github.com/raccoongang","followers_url":"https://api.github.com/users/raccoongang/followers","following_url":"https://api.github.com/users/raccoongang/following{/other_user}","gists_url":"https://api.github.com/users/raccoongang/gists{/gist_id}","starred_url":"https://api.github.com/users/raccoongang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/raccoongang/subscriptions","organizations_url":"https://api.github.com/users/raccoongang/orgs","repos_url":"https://api.github.com/users/raccoongang/repos","events_url":"https://api.github.com/users/raccoongang/events{/privacy}","received_events_url":"https://api.github.com/users/raccoongang/received_events","type":"Organization","site_admin":false},"repo":{"id":26811891,"name":"edx-platform","full_name":"raccoongang/edx-platform","owner":{"login":"raccoongang","id":11388447,"avatar_url":"https://avatars0.githubusercontent.com/u/11388447?v=4","gravatar_id":"","url":"https://api.github.com/users/raccoongang","html_url":"https://github.com/raccoongang","followers_url":"https://api.github.com/users/raccoongang/followers","following_url":"https://api.github.com/users/raccoongang/following{/other_user}","gists_url":"https://api.github.com/users/raccoongang/gists{/gist_id}","starred_url":"https://api.github.com/users/raccoongang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/raccoongang/subscriptions","organizations_url":"https://api.github.com/users/raccoongang/orgs","repos_url":"https://api.github.com/users/raccoongang/repos","events_url":"https://api.github.com/users/raccoongang/events{/privacy}","received_events_url":"https://api.github.com/users/raccoongang/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/raccoongang/edx-platform","description":"Open edX, the edX platform that powers http://edx.org","fork":true,"url":"https://api.github.com/repos/raccoongang/edx-platform","forks_url":"https://api.github.com/repos/raccoongang/edx-platform/forks","keys_url":"https://api.github.com/repos/raccoongang/edx-platform/keys{/key_id}","collaborators_url":"https://api.github.com/repos/raccoongang/edx-platform/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/raccoongang/edx-platform/teams","hooks_url":"https://api.github.com/repos/raccoongang/edx-platform/hooks","issue_events_url":"https://api.github.com/repos/raccoongang/edx-platform/issues/events{/number}","events_url":"https://api.github.com/repos/raccoongang/edx-platform/events","assignees_url":"https://api.github.com/repos/raccoongang/edx-platform/assignees{/user}","branches_url":"https://api.github.com/repos/raccoongang/edx-platform/branches{/branch}","tags_url":"https://api.github.com/repos/raccoongang/edx-platform/tags","blobs_url":"https://api.github.com/repos/raccoongang/edx-platform/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/raccoongang/edx-platform/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/raccoongang/edx-platform/git/refs{/sha}","trees_url":"https://api.github.com/repos/raccoongang/edx-platform/git/trees{/sha}","statuses_url":"https://api.github.com/repos/raccoongang/edx-platform/statuses/{sha}","languages_url":"https://api.github.com/repos/raccoongang/edx-platform/languages","stargazers_url":"https://api.github.com/repos/raccoongang/edx-platform/stargazers","contributors_url":"https://api.github.com/repos/raccoongang/edx-platform/contributors","subscribers_url":"https://api.github.com/repos/raccoongang/edx-platform/subscribers","subscription_url":"https://api.github.com/repos/raccoongang/edx-platform/subscription","commits_url":"https://api.github.com/repos/raccoongang/edx-platform/commits{/sha}","git_commits_url":"https://api.github.com/repos/raccoongang/edx-platform/git/commits{/sha}","comments_url":"https://api.github.com/repos/raccoongang/edx-platform/comments{/number}","issue_comment_url":"https://api.github.com/repos/raccoongang/edx-platform/issues/comments{/number}","contents_url":"https://api.github.com/repos/raccoongang/edx-platform/contents/{+path}","compare_url":"https://api.github.com/repos/raccoongang/edx-platform/compare/{base}...{head}","merges_url":"https://api.github.com/repos/raccoongang/edx-platform/merges","archive_url":"https://api.github.com/repos/raccoongang/edx-platform/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/raccoongang/edx-platform/downloads","issues_url":"https://api.github.com/repos/raccoongang/edx-platform/issues{/number}","pulls_url":"https://api.github.com/repos/raccoongang/edx-platform/pulls{/number}","milestones_url":"https://api.github.com/repos/raccoongang/edx-platform/milestones{/number}","notifications_url":"https://api.github.com/repos/raccoongang/edx-platform/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/raccoongang/edx-platform/labels{/name}","releases_url":"https://api.github.com/repos/raccoongang/edx-platform/releases{/id}","deployments_url":"https://api.github.com/repos/raccoongang/edx-platform/deployments","created_at":"2014-11-18T14:05:58Z","updated_at":"2017-02-02T15:29:38Z","pushed_at":"2017-07-26T10:10:34Z","git_url":"git://github.com/raccoongang/edx-platform.git","ssh_url":"git@github.com:raccoongang/edx-platform.git","clone_url":"https://github.com/raccoongang/edx-platform.git","svn_url":"https://github.com/raccoongang/edx-platform","homepage":"http://openedx.org/","size":893311,"stargazers_count":3,"watchers_count":3,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":8,"mirror_url":null,"open_issues_count":4,"forks":8,"open_issues":4,"watchers":3,"default_branch":"master"}},"base":{"label":"raccoongang:master_olga","ref":"master_olga","sha":"e7013d0bcbe6139472eeea0fbf13838b93ce48bc","user":{"login":"raccoongang","id":11388447,"avatar_url":"https://avatars0.githubusercontent.com/u/11388447?v=4","gravatar_id":"","url":"https://api.github.com/users/raccoongang","html_url":"https://github.com/raccoongang","followers_url":"https://api.github.com/users/raccoongang/followers","following_url":"https://api.github.com/users/raccoongang/following{/other_user}","gists_url":"https://api.github.com/users/raccoongang/gists{/gist_id}","starred_url":"https://api.github.com/users/raccoongang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/raccoongang/subscriptions","organizations_url":"https://api.github.com/users/raccoongang/orgs","repos_url":"https://api.github.com/users/raccoongang/repos","events_url":"https://api.github.com/users/raccoongang/events{/privacy}","received_events_url":"https://api.github.com/users/raccoongang/received_events","type":"Organization","site_admin":false},"repo":{"id":26811891,"name":"edx-platform","full_name":"raccoongang/edx-platform","owner":{"login":"raccoongang","id":11388447,"avatar_url":"https://avatars0.githubusercontent.com/u/11388447?v=4","gravatar_id":"","url":"https://api.github.com/users/raccoongang","html_url":"https://github.com/raccoongang","followers_url":"https://api.github.com/users/raccoongang/followers","following_url":"https://api.github.com/users/raccoongang/following{/other_user}","gists_url":"https://api.github.com/users/raccoongang/gists{/gist_id}","starred_url":"https://api.github.com/users/raccoongang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/raccoongang/subscriptions","organizations_url":"https://api.github.com/users/raccoongang/orgs","repos_url":"https://api.github.com/users/raccoongang/repos","events_url":"https://api.github.com/users/raccoongang/events{/privacy}","received_events_url":"https://api.github.com/users/raccoongang/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/raccoongang/edx-platform","description":"Open edX, the edX platform that powers http://edx.org","fork":true,"url":"https://api.github.com/repos/raccoongang/edx-platform","forks_url":"https://api.github.com/repos/raccoongang/edx-platform/forks","keys_url":"https://api.github.com/repos/raccoongang/edx-platform/keys{/key_id}","collaborators_url":"https://api.github.com/repos/raccoongang/edx-platform/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/raccoongang/edx-platform/teams","hooks_url":"https://api.github.com/repos/raccoongang/edx-platform/hooks","issue_events_url":"https://api.github.com/repos/raccoongang/edx-platform/issues/events{/number}","events_url":"https://api.github.com/repos/raccoongang/edx-platform/events","assignees_url":"https://api.github.com/repos/raccoongang/edx-platform/assignees{/user}","branches_url":"https://api.github.com/repos/raccoongang/edx-platform/branches{/branch}","tags_url":"https://api.github.com/repos/raccoongang/edx-platform/tags","blobs_url":"https://api.github.com/repos/raccoongang/edx-platform/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/raccoongang/edx-platform/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/raccoongang/edx-platform/git/refs{/sha}","trees_url":"https://api.github.com/repos/raccoongang/edx-platform/git/trees{/sha}","statuses_url":"https://api.github.com/repos/raccoongang/edx-platform/statuses/{sha}","languages_url":"https://api.github.com/repos/raccoongang/edx-platform/languages","stargazers_url":"https://api.github.com/repos/raccoongang/edx-platform/stargazers","contributors_url":"https://api.github.com/repos/raccoongang/edx-platform/contributors","subscribers_url":"https://api.github.com/repos/raccoongang/edx-platform/subscribers","subscription_url":"https://api.github.com/repos/raccoongang/edx-platform/subscription","commits_url":"https://api.github.com/repos/raccoongang/edx-platform/commits{/sha}","git_commits_url":"https://api.github.com/repos/raccoongang/edx-platform/git/commits{/sha}","comments_url":"https://api.github.com/repos/raccoongang/edx-platform/comments{/number}","issue_comment_url":"https://api.github.com/repos/raccoongang/edx-platform/issues/comments{/number}","contents_url":"https://api.github.com/repos/raccoongang/edx-platform/contents/{+path}","compare_url":"https://api.github.com/repos/raccoongang/edx-platform/compare/{base}...{head}","merges_url":"https://api.github.com/repos/raccoongang/edx-platform/merges","archive_url":"https://api.github.com/repos/raccoongang/edx-platform/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/raccoongang/edx-platform/downloads","issues_url":"https://api.github.com/repos/raccoongang/edx-platform/issues{/number}","pulls_url":"https://api.github.com/repos/raccoongang/edx-platform/pulls{/number}","milestones_url":"https://api.github.com/repos/raccoongang/edx-platform/milestones{/number}","notifications_url":"https://api.github.com/repos/raccoongang/edx-platform/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/raccoongang/edx-platform/labels{/name}","releases_url":"https://api.github.com/repos/raccoongang/edx-platform/releases{/id}","deployments_url":"https://api.github.com/repos/raccoongang/edx-platform/deployments","created_at":"2014-11-18T14:05:58Z","updated_at":"2017-02-02T15:29:38Z","pushed_at":"2017-07-26T10:10:34Z","git_url":"git://github.com/raccoongang/edx-platform.git","ssh_url":"git@github.com:raccoongang/edx-platform.git","clone_url":"https://github.com/raccoongang/edx-platform.git","svn_url":"https://github.com/raccoongang/edx-platform","homepage":"http://openedx.org/","size":893311,"stargazers_count":3,"watchers_count":3,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":8,"mirror_url":null,"open_issues_count":4,"forks":8,"open_issues":4,"watchers":3,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/raccoongang/edx-platform/pulls/83"},"html":{"href":"https://github.com/raccoongang/edx-platform/pull/83"},"issue":{"href":"https://api.github.com/repos/raccoongang/edx-platform/issues/83"},"comments":{"href":"https://api.github.com/repos/raccoongang/edx-platform/issues/83/comments"},"review_comments":{"href":"https://api.github.com/repos/raccoongang/edx-platform/pulls/83/comments"},"review_comment":{"href":"https://api.github.com/repos/raccoongang/edx-platform/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/raccoongang/edx-platform/pulls/83/commits"},"statuses":{"href":"https://api.github.com/repos/raccoongang/edx-platform/statuses/ebe709feef8f9cb0e1e94891fe5d3ab3d1639c1d"}}}}
{"actor":{"display_login":"auraz"}}