{"action":"created","comment":{"url":"https://api.github.com/repos/masschallenge/impact-api/pulls/comments/124329126","pull_request_review_id":46545600,"id":124329126,"diff_hunk":"@@ -0,0 +1,61 @@\n+# MIT License\n+# Copyright (c) 2017 MassChallenge, Inc.\n+\n+from django.urls import reverse\n+\n+from impact.tests.contexts import UserContext\n+from impact.tests.api_test_case import APITestCase\n+from django.contrib.auth import get_user_model\n+\n+\n+EXAMPLE_USER = {\n+    \"first_name\": \"First\",\n+    \"last_name\": \"Last\",\n+    \"email\": \"test@example.com\",\n+    \"gender\": \"o\",\n+}\n+User = get_user_model()\n+\n+\n+class TestUserListView(APITestCase):\n+\n+    def test_get(self):\n+        user1 = UserContext().user\n+        user2 = UserContext().user\n+        with self.login(username=self.basic_user().username):\n+            url = reverse(\"user\")\n+            response = self.client.get(url)\n+            emails = [result[\"email\"] for result in response.data[\"results\"]]\n+            assert user1.email in emails\n+            assert user2.email in emails\n+\n+    def test_post(self):\n+        with self.login(username=self.basic_user().username):\n+            url = reverse(\"user\")\n+            response = self.client.post(url, EXAMPLE_USER)\n+            id = response.data[\"id\"]\n+            user = User.objects.get(id=id)\n+            assert user.email == EXAMPLE_USER[\"email\"]\n+\n+    def test_post_required_missing(self):\n+        with self.login(username=self.basic_user().username):\n+            url = reverse(\"user\")\n+            response = self.client.post(url, {})\n+            assert response.status_code == 403\n+\n+    def test_post_bad_key(self):\n+        with self.login(username=self.basic_user().username):\n+            url = reverse(\"user\")\n+            bad_key = \"bad key\"\n+            response = self.client.post(url, {bad_key: True})\n+            assert response.status_code == 403\n+            assert any([bad_key in error for error in response.data])\n+\n+    def test_post_existing(self):\n+        user = UserContext().user\n+        data = EXAMPLE_USER.copy()\n+        data[\"email\"] = user.email\n+        with self.login(username=self.basic_user().username):\n+            url = reverse(\"user\")\n+            response = self.client.post(url, data)\n+            assert response.status_code == 403","path":"web/impact/impact/tests/test_user_list_view.py","position":61,"original_position":61,"commit_id":"ba1ead3f77c7898c4fe5a39578ffcd2f6aaa5605","original_commit_id":"ba1ead3f77c7898c4fe5a39578ffcd2f6aaa5605","user":{"login":"yotammanor","id":5147457,"avatar_url":"https://avatars1.githubusercontent.com/u/5147457?v=3","gravatar_id":"","url":"https://api.github.com/users/yotammanor","html_url":"https://github.com/yotammanor","followers_url":"https://api.github.com/users/yotammanor/followers","following_url":"https://api.github.com/users/yotammanor/following{/other_user}","gists_url":"https://api.github.com/users/yotammanor/gists{/gist_id}","starred_url":"https://api.github.com/users/yotammanor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yotammanor/subscriptions","organizations_url":"https://api.github.com/users/yotammanor/orgs","repos_url":"https://api.github.com/users/yotammanor/repos","events_url":"https://api.github.com/users/yotammanor/events{/privacy}","received_events_url":"https://api.github.com/users/yotammanor/received_events","type":"User","site_admin":false},"body":"Is there a way to assert that the reason of the 403 is the existence of the user?","created_at":"2017-06-27T16:38:22Z","updated_at":"2017-06-27T16:51:38Z","html_url":"https://github.com/masschallenge/impact-api/pull/4#discussion_r124329126","pull_request_url":"https://api.github.com/repos/masschallenge/impact-api/pulls/4","_links":{"self":{"href":"https://api.github.com/repos/masschallenge/impact-api/pulls/comments/124329126"},"html":{"href":"https://github.com/masschallenge/impact-api/pull/4#discussion_r124329126"},"pull_request":{"href":"https://api.github.com/repos/masschallenge/impact-api/pulls/4"}}},"pull_request":{"url":"https://api.github.com/repos/masschallenge/impact-api/pulls/4","id":127568991,"html_url":"https://github.com/masschallenge/impact-api/pull/4","diff_url":"https://github.com/masschallenge/impact-api/pull/4.diff","patch_url":"https://github.com/masschallenge/impact-api/pull/4.patch","issue_url":"https://api.github.com/repos/masschallenge/impact-api/issues/4","number":4,"state":"open","locked":false,"title":"AC-4501: Add v1 API to support RESTful user calls","user":{"login":"mc-nathan","id":9534003,"avatar_url":"https://avatars2.githubusercontent.com/u/9534003?v=3","gravatar_id":"","url":"https://api.github.com/users/mc-nathan","html_url":"https://github.com/mc-nathan","followers_url":"https://api.github.com/users/mc-nathan/followers","following_url":"https://api.github.com/users/mc-nathan/following{/other_user}","gists_url":"https://api.github.com/users/mc-nathan/gists{/gist_id}","starred_url":"https://api.github.com/users/mc-nathan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mc-nathan/subscriptions","organizations_url":"https://api.github.com/users/mc-nathan/orgs","repos_url":"https://api.github.com/users/mc-nathan/repos","events_url":"https://api.github.com/users/mc-nathan/events{/privacy}","received_events_url":"https://api.github.com/users/mc-nathan/received_events","type":"User","site_admin":false},"body":"To test:\r\n\r\n1) Get the branch.\r\n2) make dev\r\n3) `make dbload GZ_FILE=../accelerate/test_data/initial_schema.sql.gz`\r\n4) Grant v1_clients permission to a user without any existing permissions and answer 'y' when/if it asks.  E.g.,\r\n```\r\n$ make grant-permissions PERMISSION_USER=37891-user@example.com PERMISSION_CLASSES=v1_clients\r\nCreate group name v1_clients? y\r\ngranting 37891-user@example.com add to group v1_clients\r\n```\r\n5) Login to the local impact-api server as the given user.\r\n6) Create and application for the user.  Provide name, select Client type => Public, Authorization grant type => Resource owner password-based, click 'Save'.\r\n7) In Postman load the [collection](https://www.getpostman.com/collections/85194e59d55e7358722f):  File => Import => Import from Link\r\n8) Set the Environment variables for the user and the client id (<eye> => Edit)\r\n9) Send 'oauth token' API from Postman\r\n10)   Send 'v1 user list get' (should see a list of user info in the results).\r\n11) You can test the next and previous links by pasting the URL into the url box next to 'GET V'.  This should behave the same way that they do for more generic DRF API calls like 'startup list'.  Running 'v1 user list get' should set the Postman `variable random_user_id` which is used by the other 'v1 user get' and 'v1 user patch'. **Yotam: As far as I can see the script that sets `random_user_id` is at \"simple user list\". I had to add it manually to \"v1 user list get\", and then it worked as described.**\r\n12) You should now be able to test 'v1 user get' and 'v1 user patch'.  Note if you check off items in 'v1 user patch' it should succeed and only update the appropriate fields when you then run 'v1 user get'.\r\n13) POST should work as well and again will set the `random_user_id` appropriately.  If you send the same args more than once you should get an error since the email is already in use.  If you are missing requirement arguments it should complain.  `is_active` is the only optional argument.\r\n\r\nThere currently is not a good way to test that the users created using the API works as users on accelerate or impact-api.  We're working on providing that functionality.  The problem with accelerate is needing to either load a dump from impact-api into accelerate (but there is a version incompatibility) or have impact-api point directly to an existing accelerate database (which is currently not documented).  Trying to run from the impact-api has the problem that there is no way to set/reset the password for a newly created user.\r\n","created_at":"2017-06-26T21:35:13Z","updated_at":"2017-06-27T16:51:38Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f29f40ec217a119e701b73a2b31a9c8def61b8fb","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/masschallenge/impact-api/pulls/4/commits","review_comments_url":"https://api.github.com/repos/masschallenge/impact-api/pulls/4/comments","review_comment_url":"https://api.github.com/repos/masschallenge/impact-api/pulls/comments{/number}","comments_url":"https://api.github.com/repos/masschallenge/impact-api/issues/4/comments","statuses_url":"https://api.github.com/repos/masschallenge/impact-api/statuses/ba1ead3f77c7898c4fe5a39578ffcd2f6aaa5605","head":{"label":"masschallenge:AC-4501","ref":"AC-4501","sha":"ba1ead3f77c7898c4fe5a39578ffcd2f6aaa5605","user":{"login":"masschallenge","id":1440552,"avatar_url":"https://avatars2.githubusercontent.com/u/1440552?v=3","gravatar_id":"","url":"https://api.github.com/users/masschallenge","html_url":"https://github.com/masschallenge","followers_url":"https://api.github.com/users/masschallenge/followers","following_url":"https://api.github.com/users/masschallenge/following{/other_user}","gists_url":"https://api.github.com/users/masschallenge/gists{/gist_id}","starred_url":"https://api.github.com/users/masschallenge/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/masschallenge/subscriptions","organizations_url":"https://api.github.com/users/masschallenge/orgs","repos_url":"https://api.github.com/users/masschallenge/repos","events_url":"https://api.github.com/users/masschallenge/events{/privacy}","received_events_url":"https://api.github.com/users/masschallenge/received_events","type":"Organization","site_admin":false},"repo":{"id":95133025,"name":"impact-api","full_name":"masschallenge/impact-api","owner":{"login":"masschallenge","id":1440552,"avatar_url":"https://avatars2.githubusercontent.com/u/1440552?v=3","gravatar_id":"","url":"https://api.github.com/users/masschallenge","html_url":"https://github.com/masschallenge","followers_url":"https://api.github.com/users/masschallenge/followers","following_url":"https://api.github.com/users/masschallenge/following{/other_user}","gists_url":"https://api.github.com/users/masschallenge/gists{/gist_id}","starred_url":"https://api.github.com/users/masschallenge/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/masschallenge/subscriptions","organizations_url":"https://api.github.com/users/masschallenge/orgs","repos_url":"https://api.github.com/users/masschallenge/repos","events_url":"https://api.github.com/users/masschallenge/events{/privacy}","received_events_url":"https://api.github.com/users/masschallenge/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/masschallenge/impact-api","description":null,"fork":false,"url":"https://api.github.com/repos/masschallenge/impact-api","forks_url":"https://api.github.com/repos/masschallenge/impact-api/forks","keys_url":"https://api.github.com/repos/masschallenge/impact-api/keys{/key_id}","collaborators_url":"https://api.github.com/repos/masschallenge/impact-api/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/masschallenge/impact-api/teams","hooks_url":"https://api.github.com/repos/masschallenge/impact-api/hooks","issue_events_url":"https://api.github.com/repos/masschallenge/impact-api/issues/events{/number}","events_url":"https://api.github.com/repos/masschallenge/impact-api/events","assignees_url":"https://api.github.com/repos/masschallenge/impact-api/assignees{/user}","branches_url":"https://api.github.com/repos/masschallenge/impact-api/branches{/branch}","tags_url":"https://api.github.com/repos/masschallenge/impact-api/tags","blobs_url":"https://api.github.com/repos/masschallenge/impact-api/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/masschallenge/impact-api/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/masschallenge/impact-api/git/refs{/sha}","trees_url":"https://api.github.com/repos/masschallenge/impact-api/git/trees{/sha}","statuses_url":"https://api.github.com/repos/masschallenge/impact-api/statuses/{sha}","languages_url":"https://api.github.com/repos/masschallenge/impact-api/languages","stargazers_url":"https://api.github.com/repos/masschallenge/impact-api/stargazers","contributors_url":"https://api.github.com/repos/masschallenge/impact-api/contributors","subscribers_url":"https://api.github.com/repos/masschallenge/impact-api/subscribers","subscription_url":"https://api.github.com/repos/masschallenge/impact-api/subscription","commits_url":"https://api.github.com/repos/masschallenge/impact-api/commits{/sha}","git_commits_url":"https://api.github.com/repos/masschallenge/impact-api/git/commits{/sha}","comments_url":"https://api.github.com/repos/masschallenge/impact-api/comments{/number}","issue_comment_url":"https://api.github.com/repos/masschallenge/impact-api/issues/comments{/number}","contents_url":"https://api.github.com/repos/masschallenge/impact-api/contents/{+path}","compare_url":"https://api.github.com/repos/masschallenge/impact-api/compare/{base}...{head}","merges_url":"https://api.github.com/repos/masschallenge/impact-api/merges","archive_url":"https://api.github.com/repos/masschallenge/impact-api/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/masschallenge/impact-api/downloads","issues_url":"https://api.github.com/repos/masschallenge/impact-api/issues{/number}","pulls_url":"https://api.github.com/repos/masschallenge/impact-api/pulls{/number}","milestones_url":"https://api.github.com/repos/masschallenge/impact-api/milestones{/number}","notifications_url":"https://api.github.com/repos/masschallenge/impact-api/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/masschallenge/impact-api/labels{/name}","releases_url":"https://api.github.com/repos/masschallenge/impact-api/releases{/id}","deployments_url":"https://api.github.com/repos/masschallenge/impact-api/deployments","created_at":"2017-06-22T16:02:26Z","updated_at":"2017-06-22T16:05:25Z","pushed_at":"2017-06-26T21:44:46Z","git_url":"git://github.com/masschallenge/impact-api.git","ssh_url":"git@github.com:masschallenge/impact-api.git","clone_url":"https://github.com/masschallenge/impact-api.git","svn_url":"https://github.com/masschallenge/impact-api","homepage":null,"size":229,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":true,"has_projects":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":0,"default_branch":"development"}},"base":{"label":"masschallenge:development","ref":"development","sha":"101513aed751c14b273c59a162cbdaea88f405b8","user":{"login":"masschallenge","id":1440552,"avatar_url":"https://avatars2.githubusercontent.com/u/1440552?v=3","gravatar_id":"","url":"https://api.github.com/users/masschallenge","html_url":"https://github.com/masschallenge","followers_url":"https://api.github.com/users/masschallenge/followers","following_url":"https://api.github.com/users/masschallenge/following{/other_user}","gists_url":"https://api.github.com/users/masschallenge/gists{/gist_id}","starred_url":"https://api.github.com/users/masschallenge/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/masschallenge/subscriptions","organizations_url":"https://api.github.com/users/masschallenge/orgs","repos_url":"https://api.github.com/users/masschallenge/repos","events_url":"https://api.github.com/users/masschallenge/events{/privacy}","received_events_url":"https://api.github.com/users/masschallenge/received_events","type":"Organization","site_admin":false},"repo":{"id":95133025,"name":"impact-api","full_name":"masschallenge/impact-api","owner":{"login":"masschallenge","id":1440552,"avatar_url":"https://avatars2.githubusercontent.com/u/1440552?v=3","gravatar_id":"","url":"https://api.github.com/users/masschallenge","html_url":"https://github.com/masschallenge","followers_url":"https://api.github.com/users/masschallenge/followers","following_url":"https://api.github.com/users/masschallenge/following{/other_user}","gists_url":"https://api.github.com/users/masschallenge/gists{/gist_id}","starred_url":"https://api.github.com/users/masschallenge/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/masschallenge/subscriptions","organizations_url":"https://api.github.com/users/masschallenge/orgs","repos_url":"https://api.github.com/users/masschallenge/repos","events_url":"https://api.github.com/users/masschallenge/events{/privacy}","received_events_url":"https://api.github.com/users/masschallenge/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/masschallenge/impact-api","description":null,"fork":false,"url":"https://api.github.com/repos/masschallenge/impact-api","forks_url":"https://api.github.com/repos/masschallenge/impact-api/forks","keys_url":"https://api.github.com/repos/masschallenge/impact-api/keys{/key_id}","collaborators_url":"https://api.github.com/repos/masschallenge/impact-api/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/masschallenge/impact-api/teams","hooks_url":"https://api.github.com/repos/masschallenge/impact-api/hooks","issue_events_url":"https://api.github.com/repos/masschallenge/impact-api/issues/events{/number}","events_url":"https://api.github.com/repos/masschallenge/impact-api/events","assignees_url":"https://api.github.com/repos/masschallenge/impact-api/assignees{/user}","branches_url":"https://api.github.com/repos/masschallenge/impact-api/branches{/branch}","tags_url":"https://api.github.com/repos/masschallenge/impact-api/tags","blobs_url":"https://api.github.com/repos/masschallenge/impact-api/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/masschallenge/impact-api/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/masschallenge/impact-api/git/refs{/sha}","trees_url":"https://api.github.com/repos/masschallenge/impact-api/git/trees{/sha}","statuses_url":"https://api.github.com/repos/masschallenge/impact-api/statuses/{sha}","languages_url":"https://api.github.com/repos/masschallenge/impact-api/languages","stargazers_url":"https://api.github.com/repos/masschallenge/impact-api/stargazers","contributors_url":"https://api.github.com/repos/masschallenge/impact-api/contributors","subscribers_url":"https://api.github.com/repos/masschallenge/impact-api/subscribers","subscription_url":"https://api.github.com/repos/masschallenge/impact-api/subscription","commits_url":"https://api.github.com/repos/masschallenge/impact-api/commits{/sha}","git_commits_url":"https://api.github.com/repos/masschallenge/impact-api/git/commits{/sha}","comments_url":"https://api.github.com/repos/masschallenge/impact-api/comments{/number}","issue_comment_url":"https://api.github.com/repos/masschallenge/impact-api/issues/comments{/number}","contents_url":"https://api.github.com/repos/masschallenge/impact-api/contents/{+path}","compare_url":"https://api.github.com/repos/masschallenge/impact-api/compare/{base}...{head}","merges_url":"https://api.github.com/repos/masschallenge/impact-api/merges","archive_url":"https://api.github.com/repos/masschallenge/impact-api/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/masschallenge/impact-api/downloads","issues_url":"https://api.github.com/repos/masschallenge/impact-api/issues{/number}","pulls_url":"https://api.github.com/repos/masschallenge/impact-api/pulls{/number}","milestones_url":"https://api.github.com/repos/masschallenge/impact-api/milestones{/number}","notifications_url":"https://api.github.com/repos/masschallenge/impact-api/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/masschallenge/impact-api/labels{/name}","releases_url":"https://api.github.com/repos/masschallenge/impact-api/releases{/id}","deployments_url":"https://api.github.com/repos/masschallenge/impact-api/deployments","created_at":"2017-06-22T16:02:26Z","updated_at":"2017-06-22T16:05:25Z","pushed_at":"2017-06-26T21:44:46Z","git_url":"git://github.com/masschallenge/impact-api.git","ssh_url":"git@github.com:masschallenge/impact-api.git","clone_url":"https://github.com/masschallenge/impact-api.git","svn_url":"https://github.com/masschallenge/impact-api","homepage":null,"size":229,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":true,"has_projects":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":0,"default_branch":"development"}},"_links":{"self":{"href":"https://api.github.com/repos/masschallenge/impact-api/pulls/4"},"html":{"href":"https://github.com/masschallenge/impact-api/pull/4"},"issue":{"href":"https://api.github.com/repos/masschallenge/impact-api/issues/4"},"comments":{"href":"https://api.github.com/repos/masschallenge/impact-api/issues/4/comments"},"review_comments":{"href":"https://api.github.com/repos/masschallenge/impact-api/pulls/4/comments"},"review_comment":{"href":"https://api.github.com/repos/masschallenge/impact-api/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/masschallenge/impact-api/pulls/4/commits"},"statuses":{"href":"https://api.github.com/repos/masschallenge/impact-api/statuses/ba1ead3f77c7898c4fe5a39578ffcd2f6aaa5605"}}}}
{"actor":{"display_login":"yotammanor"}}