{"action":"created","comment":{"url":"https://api.github.com/repos/edx/edx-platform/pulls/comments/26802690","id":26802690,"diff_hunk":"@@ -1518,6 +1525,136 @@ def _assert_reg_field(self, extra_fields_setting, expected_field):\n         self.assertIn(expected_field, form_desc[\"fields\"])\n \n \n+@httpretty.activate\n+@ddt.ddt\n+class ThirdPartyRegistrationTestMixin(ThirdPartyOAuthTestMixin):\n+    \"\"\"\n+    Tests for the User API registration endpoint with 3rd party authentication.\n+    \"\"\"\n+    def setUp(self):\n+        super(ThirdPartyRegistrationTestMixin, self).setUp(create_user=False)\n+        self.url = reverse('user_api_registration')\n+\n+    def data(self, user=None):\n+        \"\"\"Returns the request data for the endpoint.\"\"\"\n+        return {\n+            \"provider\": self.BACKEND,\n+            \"access_token\": self.access_token,\n+            \"client_id\": self.client_id,\n+            \"honor_code\": \"true\",\n+            \"country\": \"US\",\n+            \"username\": user.username if user else \"test_username\",\n+            \"name\": user.first_name if user else \"test name\",\n+            \"email\": user.email if user else \"test@test.com\",\n+        }\n+\n+    def _assert_existing_user_error(self, response):\n+        \"\"\"Assert that the given response was an error with the given status_code and error code\"\"\"\n+        self.assertEqual(response.status_code, 409)\n+        errors = json.loads(response.content)\n+        for conflict_attribute in [\"username\", \"email\"]:\n+            self.assertIn(conflict_attribute, errors)\n+            self.assertIn(\"belongs to an existing account\", errors[conflict_attribute][0][\"user_message\"])\n+        self.assertNotIn(\"partial_pipeline\", self.client.session)\n+\n+    def _assert_access_token_error(self, response, expected_error_message):\n+        self.assertEqual(response.status_code, 400)\n+        response_json = json.loads(response.content)\n+        self.assertEqual(\n+            response_json,\n+            {\"access_token\": [{\"user_message\": expected_error_message}]}\n+        )\n+        self.assertNotIn(\"partial_pipeline\", self.client.session)\n+        self._verify_user_existence(user_exists=False, social_link_exists=False)\n+\n+    def _verify_user_existence(self, user_exists, social_link_exists, user_is_active=None, username=None):\n+        \"\"\"Verifies whether the user object exists.\"\"\"\n+        users = User.objects.filter(username=(username if username else \"test_username\"))\n+        self.assertEquals(len(users), 1 if user_exists else 0)\n+        if user_exists:\n+            self.assertEquals(users[0].is_active, user_is_active)\n+        if social_link_exists:\n+            social_users = UserSocialAuth.objects.filter(user=users[0], provider=self.BACKEND)\n+            self.assertEquals(len(social_users), 1)\n+        else:\n+            self.assertEquals(UserSocialAuth.objects.count(), 0)\n+\n+    def test_success(self):\n+        self._verify_user_existence(user_exists=False, social_link_exists=False)\n+\n+        self._setup_provider_response(success=True)\n+        response = self.client.post(self.url, self.data())\n+        self.assertEqual(response.status_code, 200)\n+\n+        self._verify_user_existence(user_exists=True, social_link_exists=True, user_is_active=False)\n+\n+    def test_user_conflict(self):\n+        self._setup_provider_response(success=True)\n+        user = UserFactory()\n+        UserSocialAuth.objects.create(user=user, provider=self.BACKEND, uid=self.social_uid)\n+        response = self.client.post(self.url, self.data(user))\n+        self._assert_existing_user_error(response)\n+        self._verify_user_existence(\n+            user_exists=True, social_link_exists=True, user_is_active=True, username=user.username\n+        )\n+\n+    def test_unlinked_active_user(self):\n+        user = UserFactory()\n+        response = self.client.post(self.url, self.data(user))\n+        self._assert_existing_user_error(response)\n+        self._verify_user_existence(\n+            user_exists=True, social_link_exists=False, user_is_active=True, username=user.username\n+        )\n+\n+    def test_unlinked_inactive_user(self):\n+        user = UserFactory(is_active=False)\n+        response = self.client.post(self.url, self.data(user))\n+        self._assert_existing_user_error(response)\n+        self._verify_user_existence(\n+            user_exists=True, social_link_exists=False, user_is_active=False, username=user.username\n+        )\n+\n+    def test_invalid_token(self):\n+        self._setup_provider_response(success=False)\n+\n+        # temporarily enable transactions in test code to verify the transaction gets aborted.\n+        restore_transaction_methods()\n+        response = self.client.post(self.url, self.data())\n+        disable_transaction_methods()\n+\n+        self._assert_access_token_error(response, \"The provided access_token is not valid.\")\n+\n+    def test_missing_token(self):\n+        data = self.data()\n+        data.pop(\"access_token\")\n+\n+        # temporarily enable transactions in test code to verify the transaction gets aborted.\n+        restore_transaction_methods()\n+        response = self.client.post(self.url, data)\n+        disable_transaction_methods()\n+\n+        self._assert_access_token_error(\n+            response,\n+            \"An access_token is required when passing value ({}) for provider.\".format(self.BACKEND)\n+        )\n+","path":"openedx/core/djangoapps/user_api/tests/test_views.py","position":160,"original_position":160,"commit_id":"52f29ba329dfab2a16480522766ce9c1e3e26588","original_commit_id":"dba743314bb96466100966a904918b7979fa91aa","user":{"login":"nasthagiri","id":6772826,"avatar_url":"https://avatars.githubusercontent.com/u/6772826?v=3","gravatar_id":"","url":"https://api.github.com/users/nasthagiri","html_url":"https://github.com/nasthagiri","followers_url":"https://api.github.com/users/nasthagiri/followers","following_url":"https://api.github.com/users/nasthagiri/following{/other_user}","gists_url":"https://api.github.com/users/nasthagiri/gists{/gist_id}","starred_url":"https://api.github.com/users/nasthagiri/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nasthagiri/subscriptions","organizations_url":"https://api.github.com/users/nasthagiri/orgs","repos_url":"https://api.github.com/users/nasthagiri/repos","events_url":"https://api.github.com/users/nasthagiri/events{/privacy}","received_events_url":"https://api.github.com/users/nasthagiri/received_events","type":"User","site_admin":false},"body":"User non-existence is verified in `_assert_access_token_error`.","created_at":"2015-03-19T22:06:31Z","updated_at":"2015-03-19T22:06:31Z","html_url":"https://github.com/edx/edx-platform/pull/7353#discussion_r26802690","pull_request_url":"https://api.github.com/repos/edx/edx-platform/pulls/7353","_links":{"self":{"href":"https://api.github.com/repos/edx/edx-platform/pulls/comments/26802690"},"html":{"href":"https://github.com/edx/edx-platform/pull/7353#discussion_r26802690"},"pull_request":{"href":"https://api.github.com/repos/edx/edx-platform/pulls/7353"}}},"pull_request":{"url":"https://api.github.com/repos/edx/edx-platform/pulls/7353","id":31180652,"html_url":"https://github.com/edx/edx-platform/pull/7353","diff_url":"https://github.com/edx/edx-platform/pull/7353.diff","patch_url":"https://github.com/edx/edx-platform/pull/7353.patch","issue_url":"https://api.github.com/repos/edx/edx-platform/issues/7353","number":7353,"state":"open","locked":false,"title":"Mobile registration with Google/FB","user":{"login":"nasthagiri","id":6772826,"avatar_url":"https://avatars.githubusercontent.com/u/6772826?v=3","gravatar_id":"","url":"https://api.github.com/users/nasthagiri","html_url":"https://github.com/nasthagiri","followers_url":"https://api.github.com/users/nasthagiri/followers","following_url":"https://api.github.com/users/nasthagiri/following{/other_user}","gists_url":"https://api.github.com/users/nasthagiri/gists{/gist_id}","starred_url":"https://api.github.com/users/nasthagiri/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nasthagiri/subscriptions","organizations_url":"https://api.github.com/users/nasthagiri/orgs","repos_url":"https://api.github.com/users/nasthagiri/repos","events_url":"https://api.github.com/users/nasthagiri/events{/privacy}","received_events_url":"https://api.github.com/users/nasthagiri/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-03-14T08:59:09Z","updated_at":"2015-03-19T22:06:31Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c5a00a9d0626506b21edd9e73cf9392b6f0fa4b8","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/edx/edx-platform/pulls/7353/commits","review_comments_url":"https://api.github.com/repos/edx/edx-platform/pulls/7353/comments","review_comment_url":"https://api.github.com/repos/edx/edx-platform/pulls/comments{/number}","comments_url":"https://api.github.com/repos/edx/edx-platform/issues/7353/comments","statuses_url":"https://api.github.com/repos/edx/edx-platform/statuses/52f29ba329dfab2a16480522766ce9c1e3e26588","head":{"label":"edx:mobile/third-party-oauth-reg","ref":"mobile/third-party-oauth-reg","sha":"52f29ba329dfab2a16480522766ce9c1e3e26588","user":{"login":"edx","id":3179841,"avatar_url":"https://avatars.githubusercontent.com/u/3179841?v=3","gravatar_id":"","url":"https://api.github.com/users/edx","html_url":"https://github.com/edx","followers_url":"https://api.github.com/users/edx/followers","following_url":"https://api.github.com/users/edx/following{/other_user}","gists_url":"https://api.github.com/users/edx/gists{/gist_id}","starred_url":"https://api.github.com/users/edx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edx/subscriptions","organizations_url":"https://api.github.com/users/edx/orgs","repos_url":"https://api.github.com/users/edx/repos","events_url":"https://api.github.com/users/edx/events{/privacy}","received_events_url":"https://api.github.com/users/edx/received_events","type":"Organization","site_admin":false},"repo":{"id":10391073,"name":"edx-platform","full_name":"edx/edx-platform","owner":{"login":"edx","id":3179841,"avatar_url":"https://avatars.githubusercontent.com/u/3179841?v=3","gravatar_id":"","url":"https://api.github.com/users/edx","html_url":"https://github.com/edx","followers_url":"https://api.github.com/users/edx/followers","following_url":"https://api.github.com/users/edx/following{/other_user}","gists_url":"https://api.github.com/users/edx/gists{/gist_id}","starred_url":"https://api.github.com/users/edx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edx/subscriptions","organizations_url":"https://api.github.com/users/edx/orgs","repos_url":"https://api.github.com/users/edx/repos","events_url":"https://api.github.com/users/edx/events{/privacy}","received_events_url":"https://api.github.com/users/edx/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/edx/edx-platform","description":"Open edX, the edX platform that powers http://edx.org","fork":false,"url":"https://api.github.com/repos/edx/edx-platform","forks_url":"https://api.github.com/repos/edx/edx-platform/forks","keys_url":"https://api.github.com/repos/edx/edx-platform/keys{/key_id}","collaborators_url":"https://api.github.com/repos/edx/edx-platform/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/edx/edx-platform/teams","hooks_url":"https://api.github.com/repos/edx/edx-platform/hooks","issue_events_url":"https://api.github.com/repos/edx/edx-platform/issues/events{/number}","events_url":"https://api.github.com/repos/edx/edx-platform/events","assignees_url":"https://api.github.com/repos/edx/edx-platform/assignees{/user}","branches_url":"https://api.github.com/repos/edx/edx-platform/branches{/branch}","tags_url":"https://api.github.com/repos/edx/edx-platform/tags","blobs_url":"https://api.github.com/repos/edx/edx-platform/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/edx/edx-platform/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/edx/edx-platform/git/refs{/sha}","trees_url":"https://api.github.com/repos/edx/edx-platform/git/trees{/sha}","statuses_url":"https://api.github.com/repos/edx/edx-platform/statuses/{sha}","languages_url":"https://api.github.com/repos/edx/edx-platform/languages","stargazers_url":"https://api.github.com/repos/edx/edx-platform/stargazers","contributors_url":"https://api.github.com/repos/edx/edx-platform/contributors","subscribers_url":"https://api.github.com/repos/edx/edx-platform/subscribers","subscription_url":"https://api.github.com/repos/edx/edx-platform/subscription","commits_url":"https://api.github.com/repos/edx/edx-platform/commits{/sha}","git_commits_url":"https://api.github.com/repos/edx/edx-platform/git/commits{/sha}","comments_url":"https://api.github.com/repos/edx/edx-platform/comments{/number}","issue_comment_url":"https://api.github.com/repos/edx/edx-platform/issues/comments{/number}","contents_url":"https://api.github.com/repos/edx/edx-platform/contents/{+path}","compare_url":"https://api.github.com/repos/edx/edx-platform/compare/{base}...{head}","merges_url":"https://api.github.com/repos/edx/edx-platform/merges","archive_url":"https://api.github.com/repos/edx/edx-platform/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/edx/edx-platform/downloads","issues_url":"https://api.github.com/repos/edx/edx-platform/issues{/number}","pulls_url":"https://api.github.com/repos/edx/edx-platform/pulls{/number}","milestones_url":"https://api.github.com/repos/edx/edx-platform/milestones{/number}","notifications_url":"https://api.github.com/repos/edx/edx-platform/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/edx/edx-platform/labels{/name}","releases_url":"https://api.github.com/repos/edx/edx-platform/releases{/id}","created_at":"2013-05-30T20:20:38Z","updated_at":"2015-03-19T18:51:21Z","pushed_at":"2015-03-19T22:03:23Z","git_url":"git://github.com/edx/edx-platform.git","ssh_url":"git@github.com:edx/edx-platform.git","clone_url":"https://github.com/edx/edx-platform.git","svn_url":"https://github.com/edx/edx-platform","homepage":"http://openedx.org/","size":1826973,"stargazers_count":1803,"watchers_count":1803,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":1025,"mirror_url":null,"open_issues_count":136,"forks":1025,"open_issues":136,"watchers":1803,"default_branch":"master"}},"base":{"label":"edx:master","ref":"master","sha":"d182b8db99ec52f11e844829a3e8d6c8c3e26b18","user":{"login":"edx","id":3179841,"avatar_url":"https://avatars.githubusercontent.com/u/3179841?v=3","gravatar_id":"","url":"https://api.github.com/users/edx","html_url":"https://github.com/edx","followers_url":"https://api.github.com/users/edx/followers","following_url":"https://api.github.com/users/edx/following{/other_user}","gists_url":"https://api.github.com/users/edx/gists{/gist_id}","starred_url":"https://api.github.com/users/edx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edx/subscriptions","organizations_url":"https://api.github.com/users/edx/orgs","repos_url":"https://api.github.com/users/edx/repos","events_url":"https://api.github.com/users/edx/events{/privacy}","received_events_url":"https://api.github.com/users/edx/received_events","type":"Organization","site_admin":false},"repo":{"id":10391073,"name":"edx-platform","full_name":"edx/edx-platform","owner":{"login":"edx","id":3179841,"avatar_url":"https://avatars.githubusercontent.com/u/3179841?v=3","gravatar_id":"","url":"https://api.github.com/users/edx","html_url":"https://github.com/edx","followers_url":"https://api.github.com/users/edx/followers","following_url":"https://api.github.com/users/edx/following{/other_user}","gists_url":"https://api.github.com/users/edx/gists{/gist_id}","starred_url":"https://api.github.com/users/edx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edx/subscriptions","organizations_url":"https://api.github.com/users/edx/orgs","repos_url":"https://api.github.com/users/edx/repos","events_url":"https://api.github.com/users/edx/events{/privacy}","received_events_url":"https://api.github.com/users/edx/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/edx/edx-platform","description":"Open edX, the edX platform that powers http://edx.org","fork":false,"url":"https://api.github.com/repos/edx/edx-platform","forks_url":"https://api.github.com/repos/edx/edx-platform/forks","keys_url":"https://api.github.com/repos/edx/edx-platform/keys{/key_id}","collaborators_url":"https://api.github.com/repos/edx/edx-platform/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/edx/edx-platform/teams","hooks_url":"https://api.github.com/repos/edx/edx-platform/hooks","issue_events_url":"https://api.github.com/repos/edx/edx-platform/issues/events{/number}","events_url":"https://api.github.com/repos/edx/edx-platform/events","assignees_url":"https://api.github.com/repos/edx/edx-platform/assignees{/user}","branches_url":"https://api.github.com/repos/edx/edx-platform/branches{/branch}","tags_url":"https://api.github.com/repos/edx/edx-platform/tags","blobs_url":"https://api.github.com/repos/edx/edx-platform/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/edx/edx-platform/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/edx/edx-platform/git/refs{/sha}","trees_url":"https://api.github.com/repos/edx/edx-platform/git/trees{/sha}","statuses_url":"https://api.github.com/repos/edx/edx-platform/statuses/{sha}","languages_url":"https://api.github.com/repos/edx/edx-platform/languages","stargazers_url":"https://api.github.com/repos/edx/edx-platform/stargazers","contributors_url":"https://api.github.com/repos/edx/edx-platform/contributors","subscribers_url":"https://api.github.com/repos/edx/edx-platform/subscribers","subscription_url":"https://api.github.com/repos/edx/edx-platform/subscription","commits_url":"https://api.github.com/repos/edx/edx-platform/commits{/sha}","git_commits_url":"https://api.github.com/repos/edx/edx-platform/git/commits{/sha}","comments_url":"https://api.github.com/repos/edx/edx-platform/comments{/number}","issue_comment_url":"https://api.github.com/repos/edx/edx-platform/issues/comments{/number}","contents_url":"https://api.github.com/repos/edx/edx-platform/contents/{+path}","compare_url":"https://api.github.com/repos/edx/edx-platform/compare/{base}...{head}","merges_url":"https://api.github.com/repos/edx/edx-platform/merges","archive_url":"https://api.github.com/repos/edx/edx-platform/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/edx/edx-platform/downloads","issues_url":"https://api.github.com/repos/edx/edx-platform/issues{/number}","pulls_url":"https://api.github.com/repos/edx/edx-platform/pulls{/number}","milestones_url":"https://api.github.com/repos/edx/edx-platform/milestones{/number}","notifications_url":"https://api.github.com/repos/edx/edx-platform/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/edx/edx-platform/labels{/name}","releases_url":"https://api.github.com/repos/edx/edx-platform/releases{/id}","created_at":"2013-05-30T20:20:38Z","updated_at":"2015-03-19T18:51:21Z","pushed_at":"2015-03-19T22:03:23Z","git_url":"git://github.com/edx/edx-platform.git","ssh_url":"git@github.com:edx/edx-platform.git","clone_url":"https://github.com/edx/edx-platform.git","svn_url":"https://github.com/edx/edx-platform","homepage":"http://openedx.org/","size":1826973,"stargazers_count":1803,"watchers_count":1803,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":1025,"mirror_url":null,"open_issues_count":136,"forks":1025,"open_issues":136,"watchers":1803,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/edx/edx-platform/pulls/7353"},"html":{"href":"https://github.com/edx/edx-platform/pull/7353"},"issue":{"href":"https://api.github.com/repos/edx/edx-platform/issues/7353"},"comments":{"href":"https://api.github.com/repos/edx/edx-platform/issues/7353/comments"},"review_comments":{"href":"https://api.github.com/repos/edx/edx-platform/pulls/7353/comments"},"review_comment":{"href":"https://api.github.com/repos/edx/edx-platform/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/edx/edx-platform/pulls/7353/commits"},"statuses":{"href":"https://api.github.com/repos/edx/edx-platform/statuses/52f29ba329dfab2a16480522766ce9c1e3e26588"}}}}