Skip to content

Commit

Permalink
test login with github
Browse files Browse the repository at this point in the history
  • Loading branch information
SalmanAsh committed Jul 24, 2024
1 parent 463eb78 commit e1d3b28
Show file tree
Hide file tree
Showing 2 changed files with 309 additions and 43 deletions.
7 changes: 6 additions & 1 deletion api/views/contributor.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ class ContributorViewSet(ModelViewSet[User, Contributor]):
@action(detail=False, methods=["get"])
def log_into_github(self, request: Request):
"""Users can login using their existing github account"""
# Get code from login request
code = request.GET.get("code")
if not code:
return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)

# Get user access Token
access_token_request = requests.post(
url="https://github.com/login/oauth/access_token",
Expand Down Expand Up @@ -68,7 +73,7 @@ def log_into_github(self, request: Request):
status=status.HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS,
)

# Check if user is already a contributor
# Check if user is already a contributor (TODO: Update user info)
gh_id = user_data["id"]
if Contributor.objects.filter(pk=gh_id):
return Response(status=status.HTTP_409_CONFLICT)
Expand Down
345 changes: 303 additions & 42 deletions api/views/contributor_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
Created on 16/07/2024 at 14:54:09(+01:00).
"""

import json
from unittest.mock import patch

import requests
from codeforlife.request import Request
from codeforlife.tests import ModelViewSetTestCase
from codeforlife.user.models import User
from rest_framework import status
Expand Down Expand Up @@ -49,44 +49,305 @@ def test_create(self):
}
)

# def test_log_into_github__no_code(self):
# """Login API call does not return a code."""
# code = "3e074f3e12656707cf7f"
# request = Request
# # request.GET= {"code": code}

# with patch.object(Request, "GET", return_value=request):
# self.client.get(
# self.reverse_action(
# "log_into_github",
# ),
# status_code_assertion=status.HTTP_500_INTERNAL_SERVER_ERROR,
# )

# def test_log_into_github__no_access_token(self):
# """POST API call did not return an access token"""
# code = "3e074f3e12656707cf7f"
# response = requests.Response()
# response.status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
# request = Request
# request.GET = {"code": code}
# with patch.object(
# requests, "post", return_value=response
# ) as requests_get:
# self.client.get(
# self.reverse_action(
# "log_into_github",
# ),
# status_code_assertion=status.HTTP_500_INTERNAL_SERVER_ERROR,
# )

# requests_get.assert_called_once_with(
# url="https://github.com/login/oauth/access_token",
# headers={"Accept": "application/json"},
# params={
# "client_id": settings.GITHUB_CLIENT_ID,
# "client_secret": settings.GITHUB_CLIENT_SECRET,
# "code": code,
# },
# timeout=5,
# )
def test_log_into_github__no_code(self):
"""Login API call does not return a code."""
code = ""
self.client.get(
self.reverse_action(
"log_into_github",
),
{"code": code},
status_code_assertion=status.HTTP_500_INTERNAL_SERVER_ERROR,
)

def test_log_into_github__no_access_token(self):
"""POST API call did not return an access token"""
code = "3e074f3e12656707cf7f"

response = requests.Response()
response.status_code = status.HTTP_500_INTERNAL_SERVER_ERROR

with patch.object(
requests, "post", return_value=response
) as requests_post:
self.client.get(
self.reverse_action(
"log_into_github",
),
{"code": code},
status_code_assertion=status.HTTP_500_INTERNAL_SERVER_ERROR,
)

requests_post.assert_called_once_with(
url="https://github.com/login/oauth/access_token",
headers={"Accept": "application/json"},
params={
"client_id": settings.GITHUB_CLIENT_ID,
"client_secret": settings.GITHUB_CLIENT_SECRET,
"code": code,
},
timeout=5,
)

def test_log_into_github__code_expired(self):
"""POST API call failed due to expired code."""
code = "3e074f3e12656707cf7f"

response = requests.Response()
response.status_code = status.HTTP_200_OK
response.encoding = "utf-8"
# pylint: disable-next=protected-access
response._content = json.dumps({}).encode("utf-8")

with patch.object(
requests, "post", return_value=response
) as requests_post:
self.client.get(
self.reverse_action(
"log_into_github",
),
{"code": code},
status_code_assertion=status.HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS,
)

requests_post.assert_called_once_with(
url="https://github.com/login/oauth/access_token",
headers={"Accept": "application/json"},
params={
"client_id": settings.GITHUB_CLIENT_ID,
"client_secret": settings.GITHUB_CLIENT_SECRET,
"code": code,
},
timeout=5,
)

def test_log_into_github__null_email(self):
"""User must have their email public on github"""
code = "3e074f3e12656707cf7f"

response_post = requests.Response()
response_post.status_code = status.HTTP_200_OK
response_post.encoding = "utf-8"
# pylint: disable-next=protected-access
response_post._content = json.dumps(
{"access_token": "123254", "token_type": "Bearer"}
).encode("utf-8")

response_get = requests.Response()
response_get.status_code = status.HTTP_200_OK
response_get.encoding = "utf-8"
# pylint: disable-next=protected-access
response_get._content = json.dumps({"email": ""}).encode("utf-8")

with patch.object(
requests, "post", return_value=response_post
) as requests_post:
with patch.object(
requests, "get", return_value=response_get
) as requests_get:
self.client.get(
self.reverse_action(
"log_into_github",
),
{"code": code},
status_code_assertion=status.HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS,
)

requests_post.assert_called_once_with(
url="https://github.com/login/oauth/access_token",
headers={"Accept": "application/json"},
params={
"client_id": settings.GITHUB_CLIENT_ID,
"client_secret": settings.GITHUB_CLIENT_SECRET,
"code": code,
},
timeout=5,
)
requests_get.assert_called_once_with(
url="https://api.github.com/user",
headers={
"Accept": "application/json",
"Authorization": "Bearer 123254",
},
timeout=5,
)

def test_log_into_github__existing_contributor(self):
"""User already exists as a contributor"""
# TODO: update the user info
code = "3e074f3e12656707cf7f"

response_post = requests.Response()
response_post.status_code = status.HTTP_200_OK
response_post.encoding = "utf-8"
# pylint: disable-next=protected-access
response_post._content = json.dumps(
{"access_token": "123254", "token_type": "Bearer"}
).encode("utf-8")

response_get = requests.Response()
response_get.status_code = status.HTTP_200_OK
response_get.encoding = "utf-8"
# pylint: disable-next=protected-access
response_get._content = json.dumps(
{
"id": 1,
"email": "[email protected]",
"name": "contributor one",
"location": "London",
"html_url": "https://github.com/contributor1",
"avatar_url": "https://contributor1.github.io/",
}
).encode("utf-8")

with patch.object(
requests, "post", return_value=response_post
) as requests_post:
with patch.object(
requests, "get", return_value=response_get
) as requests_get:
self.client.get(
self.reverse_action(
"log_into_github",
),
{"code": code},
status_code_assertion=status.HTTP_409_CONFLICT,
)

requests_post.assert_called_once_with(
url="https://github.com/login/oauth/access_token",
headers={"Accept": "application/json"},
params={
"client_id": settings.GITHUB_CLIENT_ID,
"client_secret": settings.GITHUB_CLIENT_SECRET,
"code": code,
},
timeout=5,
)
requests_get.assert_called_once_with(
url="https://api.github.com/user",
headers={
"Accept": "application/json",
"Authorization": "Bearer 123254",
},
timeout=5,
)

def test_log_into_github__new_contributor(self):
"""Add user to the contributor data table"""
code = "3e074f3e12656707cf7f"

response_post = requests.Response()
response_post.status_code = status.HTTP_200_OK
response_post.encoding = "utf-8"
# pylint: disable-next=protected-access
response_post._content = json.dumps(
{"access_token": "123254", "token_type": "Bearer"}
).encode("utf-8")

response_get = requests.Response()
response_get.status_code = status.HTTP_200_OK
response_get.encoding = "utf-8"
# pylint: disable-next=protected-access
response_get._content = json.dumps(
{
"id": 999999999999999,
"email": "[email protected]",
"name": "contributor new",
"location": "London",
"html_url": "https://github.com/contributornew",
"avatar_url": "https://contributornew.github.io/",
}
).encode("utf-8")

with patch.object(
requests, "post", return_value=response_post
) as requests_post:
with patch.object(
requests, "get", return_value=response_get
) as requests_get:
self.client.get(
self.reverse_action(
"log_into_github",
),
{"code": code},
)

requests_post.assert_called_once_with(
url="https://github.com/login/oauth/access_token",
headers={"Accept": "application/json"},
params={
"client_id": settings.GITHUB_CLIENT_ID,
"client_secret": settings.GITHUB_CLIENT_SECRET,
"code": code,
},
timeout=5,
)
requests_get.assert_called_once_with(
url="https://api.github.com/user",
headers={
"Accept": "application/json",
"Authorization": "Bearer 123254",
},
timeout=5,
)

def test_log_into_github__invalid_serializer(self):
"""User data from Github is not in the valid format."""
code = "3e074f3e12656707cf7f"

response_post = requests.Response()
response_post.status_code = status.HTTP_200_OK
response_post.encoding = "utf-8"
# pylint: disable-next=protected-access
response_post._content = json.dumps(
{"access_token": "123254", "token_type": "Bearer"}
).encode("utf-8")

response_get = requests.Response()
response_get.status_code = status.HTTP_200_OK
response_get.encoding = "utf-8"
# pylint: disable-next=protected-access
response_get._content = json.dumps(
{
"id": 999999999999999,
"email": "1223533",
"name": "contributor new",
"location": "London",
"html_url": "https://github.com/contributornew",
"avatar_url": "https://contributornew.github.io/",
}
).encode("utf-8")

with patch.object(
requests, "post", return_value=response_post
) as requests_post:
with patch.object(
requests, "get", return_value=response_get
) as requests_get:
self.client.get(
self.reverse_action(
"log_into_github",
),
{"code": code},
status_code_assertion=status.HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS,
)

requests_post.assert_called_once_with(
url="https://github.com/login/oauth/access_token",
headers={"Accept": "application/json"},
params={
"client_id": settings.GITHUB_CLIENT_ID,
"client_secret": settings.GITHUB_CLIENT_SECRET,
"code": code,
},
timeout=5,
)
requests_get.assert_called_once_with(
url="https://api.github.com/user",
headers={
"Accept": "application/json",
"Authorization": "Bearer 123254",
},
timeout=5,
)

0 comments on commit e1d3b28

Please sign in to comment.