Skip to content

Commit

Permalink
feat(listUsersFunctionality): enable an authenticated user to view th…
Browse files Browse the repository at this point in the history
…e list and profiles of existing authors

- add a view class to display all authors
- add profile as part of the fields in the user serializer
- add a path to the urls
- render the data

[Finishes #164069231]
  • Loading branch information
Peace-Apple committed Mar 13, 2019
1 parent 978b926 commit 3b6c305
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 16 deletions.
7 changes: 4 additions & 3 deletions authors/apps/authentication/renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ def render(self, data, media_type=None, renderer_context=None):
# the default JSONRenderer to handle rendering errors, so we need to
# check for this case.
errors = ''
response = json.dumps({'user': data})
if isinstance(data, list):
return json.dumps({'authorslist': data})
try:
errors = data.get('errors', None)
except:
Expand All @@ -23,6 +26,4 @@ def render(self, data, media_type=None, renderer_context=None):
return super(UserJSONRenderer, self).render(data)

# Finally, we can render our data under the "user" namespace.
return json.dumps({
'user': data
})
return response
4 changes: 3 additions & 1 deletion authors/apps/authentication/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from rest_framework import serializers

from authors.apps.profiles.serializers import ProfileSerializer
from .models import User

from .validators import validate_email
Expand Down Expand Up @@ -140,6 +141,7 @@ class UserSerializer(serializers.ModelSerializer):
# characters. These values are the default provided by Django. We could
# change them, but that would create extra work while introducing no real
# benefit, so let's just stick with the defaults.
profile = ProfileSerializer(many=False, read_only=True, required=False)
password = serializers.CharField(
max_length=128,
min_length=8,
Expand All @@ -148,7 +150,7 @@ class UserSerializer(serializers.ModelSerializer):

class Meta:
model = User
fields = ('email', 'username', 'password')
fields = ('email', 'username', 'password', 'profile', )

# The `read_only_fields` option is an alternative for explicitly
# specifying the field with `read_only=True` like we did for password
Expand Down
1 change: 0 additions & 1 deletion authors/apps/profiles/tests/test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,3 @@
"bio": "everything tech",
"image": "https://localhost:8000/people.png"
}

39 changes: 39 additions & 0 deletions authors/apps/profiles/tests/test_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,42 @@ def test_incorrect_user_update_profile(self):
url = reverse('profiles:update_profile', kwargs={'username': 'testuser12'})
response = self.client.put(url, update_profile, format='json')
self.assertEquals(response.status_code, 403)

def test_authorized_get_authors_list(self):
"""Test an authorised user getting authors list showing profiles of existing authors """
self.authorize_user()
url = reverse('profiles:authors_list')
response = self.client.get(url)
self.assertEquals(response.status_code, 200)

def test_unauthorized_get_authors_list(self):
"""Test an unauthorised user getting authors list showing profiles of existing authors """
url = reverse('profiles:authors_list')
response = self.client.get(url)
self.assertEquals(response.status_code, 403)

def test_authorized_user_using_wrong_request_method_to_get_authors_list(self):
"""Test authorized user getting authors list using wrong request method"""
self.authorize_user()
url = reverse('profiles:authors_list')
response = self.client.post(url)
self.assertEquals(response.status_code, 405)

def test_unauthorized_user_using_wrong_request_method_to_get_authors_list(self):
"""Test unauthorized user getting authors list using wrong request method"""
url = reverse('profiles:authors_list')
response = self.client.post(url)
self.assertEquals(response.status_code, 403)

def test_correct_authors_list_data_is_returned(self):
"""Test the correct data that is returned in the authors list"""
self.authorize_user()
url = reverse('profiles:authors_list')
response = self.client.get(url)
self.assertEquals(response.data[0]['email'], 'testuser@gmail.com')
self.assertEquals(response.data[0]['username'], 'testuser12')
self.assertIn('email', response.data[0]['profile'])
self.assertIn('username', response.data[0]['profile'])
self.assertIn('image', response.data[0]['profile'])
self.assertIn('bio', response.data[0]['profile'])
self.assertEquals(response.status_code, 200)
4 changes: 3 additions & 1 deletion authors/apps/profiles/urls.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from django.urls import path
from .views import (ProfileRetrieveAPIView,
ListAuthorsAPIView, ProfileUpdateAPIView)
ListAuthorsAPIView, ProfileUpdateAPIView, AuthorsAPIView)

urlpatterns = [
path('profiles/<username>', ProfileRetrieveAPIView.as_view(), name="get_profile"),
path('profiles/<username>/edit',
ProfileUpdateAPIView.as_view(), name="update_profile"),
path('profiles/', ListAuthorsAPIView.as_view(), name="users_profiles"),
path('authorslist/', AuthorsAPIView.as_view(), name="authors_list"),

]
35 changes: 25 additions & 10 deletions authors/apps/profiles/views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from rest_framework import generics, permissions, serializers, status
from rest_framework.response import Response
from django.shortcuts import get_object_or_404
from authors.apps.authentication.models import User
from authors.apps.authentication.renderers import UserJSONRenderer
from authors.apps.authentication.serializers import UserSerializer

from .models import Profile
from .permissions import IsOwnerOrReadOnly
Expand Down Expand Up @@ -31,16 +34,6 @@ def retrieve(self, request, username, *args, **kwargs):
return Response(profile, status=status.HTTP_200_OK)


class ListAuthorsAPIView(generics.ListAPIView):
"""
Implements listing of all users' profiles
"""
queryset = Profile.objects.all()
serializer_class = ProfileSerializer
renderer_classes = (ProfileJSONRenderer, )
permission_classes = (permissions.IsAuthenticated, )


class ProfileUpdateAPIView(generics.UpdateAPIView):
""" Allows the currently logged in user
to edit their user profile
Expand All @@ -52,3 +45,25 @@ def get_object(self):
username = self.kwargs.get("username")
obj = get_object_or_404(Profile, user__username=username)
return obj


class ListView(generics.ListAPIView):
permission_classes = (permissions.IsAuthenticated, )


class ListAuthorsAPIView(ListView):
"""
Implements listing of all users' profiles
"""
queryset = Profile.objects.all()
serializer_class = ProfileSerializer
renderer_classes = (ProfileJSONRenderer,)


class AuthorsAPIView(ListView):
"""
Displays a list of existing authors with their profiles.
"""
queryset = User.objects.all()
serializer_class = UserSerializer
renderer_classes = (UserJSONRenderer,)
14 changes: 14 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
astroid==2.1.0
autopep8==1.4.3
cachetools==3.1.0
certifi==2018.11.29
chardet==3.0.4
coreapi==2.3.3
coreschema==0.0.4
coverage==4.5.2
coveralls==1.6.0
dataclasses==0.6
defusedxml==0.5.0
dj-database-url==0.5.0
Django==2.1.5
Expand All @@ -14,13 +16,19 @@ django-extensions==2.1.5
django-filter==2.1.0
django-heroku==0.3.1
django-rest-swagger==2.2.0
django-stubs==0.9.0
djangorestframework==3.9.1
djangorestframework-jwt==1.11.0
djangorestframework-stubs==0.1.0
docopt==0.6.2
drf-yasg==1.14.0
facebook-sdk==3.1.0
future==0.17.1
google-api-python-client==1.7.8
google-auth==1.6.3
google-auth-httplib2==0.0.3
gunicorn==19.9.0
httplib2==0.12.1
idna==2.8
inflection==0.3.1
isort==4.3.4
Expand All @@ -29,10 +37,14 @@ Jinja2==2.10
lazy-object-proxy==1.3.1
MarkupSafe==1.1.1
mccabe==0.6.1
mypy==0.670
mypy-extensions==0.4.1
oauthlib==3.0.1
openapi-codec==1.3.2
psycopg2==2.7.6.1
psycopg2-binary==2.7.6.1
pyasn1==0.4.5
pyasn1-modules==0.2.4
pycodestyle==2.5.0
PyJWT==1.7.1
pylint==2.2.2
Expand All @@ -43,10 +55,12 @@ python3-openid==3.1.0
pytz==2018.9
requests==2.21.0
requests-oauthlib==1.2.0
rsa==4.0
ruamel.yaml==0.15.89
simplejson==3.16.0
six==1.12.0
typed-ast==1.3.1
typing-extensions==3.7.2
uritemplate==3.0.0
urllib3==1.24.1
validate-email==1.3
Expand Down

0 comments on commit 3b6c305

Please sign in to comment.