Skip to content

Commit

Permalink
Override contributor create method
Browse files Browse the repository at this point in the history
  • Loading branch information
SalmanAsh committed Jul 30, 2024
1 parent a055538 commit 58d4254
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 158 deletions.
38 changes: 36 additions & 2 deletions api/serializers/contributor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,49 @@
© Ocado Group
Created on 12/07/2024 at 14:07:59(+01:00).
"""
from typing import Any, Dict

from codeforlife.serializers import ModelSerializer
from codeforlife.user.models import User

from ..models import Contributor


# pylint: disable-next=missing-class-docstring,too-many-ancestors
class ContributorSerializer(ModelSerializer[User, Contributor]):
"""Contributor serializer class"""

class Meta:
model = Contributor
fields = ["id", "email", "name", "location", "html_url", "avatar_url"]
extra_kwargs: Dict[str, Dict[str, Any]] = {"id": {"validators": []}}

def create(self, validated_data):
try:
# Update an existing contributor
contributor = Contributor.objects.get(pk=validated_data["id"])
contributor.email = validated_data["email"]
contributor.name = validated_data["name"]
contributor.location = validated_data["location"]
contributor.html_url = validated_data["html_url"]
contributor.avatar_url = validated_data["avatar_url"]

contributor.save(
update_fields=[
"email",
"name",
"location",
"html_url",
"avatar_url",
]
)
except Contributor.DoesNotExist:
# Create a new contributor
contributor = Contributor.objects.create(
id=validated_data["id"],
email=validated_data["email"],
name=validated_data["name"],
location=validated_data["location"],
html_url=validated_data["html_url"],
avatar_url=validated_data["avatar_url"],
)

return contributor
41 changes: 8 additions & 33 deletions api/views/contributor.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

# pylint: disable-next=missing-class-docstring,too-many-ancestors
class ContributorViewSet(ModelViewSet[User, Contributor]):
http_method_names = ["get", "post"] # "post"
http_method_names = ["get"] # "post"
permission_classes = [AllowAny]
serializer_class = ContributorSerializer
queryset = Contributor.objects.all()
Expand Down Expand Up @@ -66,42 +66,17 @@ def log_into_github(self, request: Request):
url="https://api.github.com/user",
headers={
"Accept": "application/json",
# pylint: disable-next=line-too-long
"Authorization": f"{auth_data['token_type']} {auth_data['access_token']}",
},
timeout=5,
)

user_data = response.json()
if not user_data["email"]:
return Response(
data="Email null",
status=status.HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS,
)

# Check if user is already a contributor
gh_id = user_data["id"]
contributor_data = {
"id": gh_id,
"email": user_data["email"],
"name": user_data["name"],
"location": user_data["location"],
"html_url": user_data["html_url"],
"avatar_url": user_data["avatar_url"],
}

try:
# Update an existing contributor
contributor = Contributor.objects.get(pk=gh_id)
serializer = ContributorSerializer(
contributor, data=contributor_data
)
except Contributor.DoesNotExist:
# Create a new contributor
serializer = ContributorSerializer(data=contributor_data)

if serializer.is_valid():
serializer.save()
return Response(status=status.HTTP_200_OK)
serializer = self.get_serializer(data=response.json())
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
return Response(
status=status.HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS,
serializer.data,
status=status.HTTP_201_CREATED,
headers=self.get_success_headers(serializer.data),
)
124 changes: 1 addition & 123 deletions api/views/contributor_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,6 @@ def test_retrieve(self):
"""Can retrieve a single contributor."""
self.client.retrieve(model=self.contributor1)

def test_create(self):
"""Can create a contributor."""
self.client.create(
data={
"id": 100,
"email": "[email protected]",
"name": "Test Contributor",
"location": "Hatfield",
"html_url": "https://github.com/contributortest",
"avatar_url": "https://contributortest.github.io/",
}
)

def test_log_into_github__no_code(self):
"""Login API call does not return a code."""
self.client.get(
Expand Down Expand Up @@ -118,56 +105,6 @@ def test_log_into_github__code_expired(self):
timeout=5,
)

def test_log_into_github__null_email(self):
"""Users must have their email as PUBLIC on github"""
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": "3e074f3e12656707cf7f"},
# pylint: disable-next=line-too-long
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": "3e074f3e12656707cf7f",
},
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 logged-in in the past and exists as a contributor"""
response_post = requests.Response()
Expand Down Expand Up @@ -204,7 +141,7 @@ def test_log_into_github__existing_contributor(self):
"log_into_github",
),
{"code": "3e074f3e12656707cf7f"},
status_code_assertion=status.HTTP_200_OK,
status_code_assertion=status.HTTP_201_CREATED,
)

requests_post.assert_called_once_with(
Expand Down Expand Up @@ -285,62 +222,3 @@ def test_log_into_github__new_contributor(self):
},
timeout=5,
)

def test_log_into_github__invalid_serializer(self):
"""User data retrieved from Github is not in the valid format."""
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": "3e074f3e12656707cf7f"},
# pylint: disable-next=line-too-long
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": "3e074f3e12656707cf7f",
},
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 58d4254

Please sign in to comment.