-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add drf yasg 1.21.7 in requirements * add gap_api app and redoc documentation * fix typing in model factories * fix lint * Refactore code * Clean schema --------- Co-authored-by: Irwan Fathurrahman <[email protected]>
- Loading branch information
1 parent
80cb1b0
commit 1dea7d0
Showing
25 changed files
with
390 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,3 +37,5 @@ django-celery-beat==2.5.0 | |
redis==4.3.4 | ||
|
||
psycopg2-binary==2.9.9 | ||
# drf yasg | ||
drf-yasg==1.21.7 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# coding=utf-8 | ||
""" | ||
Tomorrow Now GAP. | ||
.. note:: Core factories. | ||
""" | ||
|
||
from typing import Generic, TypeVar | ||
|
||
import factory | ||
from django.contrib.auth import get_user_model | ||
|
||
T = TypeVar('T') | ||
User = get_user_model() | ||
|
||
|
||
class BaseMetaFactory(Generic[T], factory.base.FactoryMetaClass): | ||
"""Base meta factory class.""" | ||
|
||
def __call__(cls, *args, **kwargs) -> T: | ||
"""Override the default Factory() syntax to call the default strategy. | ||
Returns an instance of the associated class. | ||
""" | ||
return super().__call__(*args, **kwargs) | ||
|
||
|
||
class BaseFactory(Generic[T], factory.django.DjangoModelFactory): | ||
"""Base factory class to make the factory return correct class typing.""" | ||
|
||
@classmethod | ||
def create(cls, **kwargs) -> T: | ||
"""Create an instance of the model, and save it to the database.""" | ||
return super().create(**kwargs) | ||
|
||
|
||
class UserF( | ||
BaseFactory[User], metaclass=BaseMetaFactory[User] | ||
): | ||
"""Factory class for User.""" | ||
|
||
class Meta: # noqa | ||
model = User | ||
|
||
username = factory.Sequence( | ||
lambda n: u'username %s' % n | ||
) | ||
first_name = 'John' | ||
last_name = 'Doe' |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# coding=utf-8 | ||
""" | ||
Tomorrow Now GAP. | ||
.. note:: Common class for unit tests. | ||
""" | ||
|
||
from django.test import TestCase | ||
from rest_framework.test import APIRequestFactory | ||
from core.factories import UserF | ||
|
||
|
||
class BaseAPIViewTest(TestCase): | ||
"""Base class for API test.""" | ||
|
||
def setUp(self): | ||
"""Init test class.""" | ||
self.factory = APIRequestFactory() | ||
self.superuser = UserF.create( | ||
is_staff=True, | ||
is_superuser=True, | ||
is_active=True | ||
) | ||
self.user_1 = UserF.create( | ||
is_active=True | ||
) | ||
|
||
|
||
class FakeResolverMatchV1: | ||
"""Fake class to mock versioning.""" | ||
|
||
namespace = 'v1' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# coding=utf-8 | ||
""" | ||
Tomorrow Now GAP. | ||
.. note:: User APIs | ||
""" | ||
|
||
from drf_yasg.utils import swagger_auto_schema | ||
from rest_framework.permissions import IsAuthenticated | ||
from rest_framework.response import Response | ||
from rest_framework.views import APIView | ||
|
||
from gap_api.serializers.common import APIErrorSerializer | ||
from gap_api.serializers.user import UserInfoSerializer | ||
from gap_api.utils.helper import ApiTag | ||
|
||
|
||
class UserInfo(APIView): | ||
"""API to return user info.""" | ||
|
||
permission_classes = [IsAuthenticated] | ||
|
||
@swagger_auto_schema( | ||
operation_id='user-info', | ||
tags=[ApiTag.USER], | ||
responses={ | ||
200: UserInfoSerializer, | ||
400: APIErrorSerializer | ||
} | ||
) | ||
def get(self, request, *args, **kwargs): | ||
"""Login user info. | ||
Return current login user information. | ||
""" | ||
return Response( | ||
status=200, data=UserInfoSerializer(request.user).data | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# coding=utf-8 | ||
""" | ||
Tomorrow Now GAP. | ||
.. note:: App Config for GAP API | ||
""" | ||
|
||
from django.apps import AppConfig | ||
|
||
|
||
class GapApiConfig(AppConfig): | ||
"""App Config for GAP API.""" | ||
|
||
default_auto_field = 'django.db.models.BigAutoField' | ||
name = 'gap_api' |
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# coding=utf-8 | ||
""" | ||
Tomorrow Now GAP. | ||
.. note:: Common serializer class. | ||
""" | ||
|
||
from rest_framework import serializers | ||
|
||
|
||
class APIErrorSerializer(serializers.Serializer): | ||
"""Serializer for error in the API.""" | ||
|
||
detail = serializers.CharField() | ||
|
||
|
||
class NoContentSerializer(serializers.Serializer): | ||
"""Empty serializer for API that returns 204 No Content.""" | ||
|
||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# coding=utf-8 | ||
""" | ||
Tomorrow Now GAP. | ||
.. note:: User serializer class. | ||
""" | ||
|
||
from django.contrib.auth import get_user_model | ||
from rest_framework import serializers | ||
|
||
User = get_user_model() | ||
|
||
|
||
class UserInfoSerializer(serializers.ModelSerializer): | ||
"""Serializer for User Info.""" | ||
|
||
class Meta: # noqa | ||
model = User | ||
fields = ['username', 'email', 'first_name', 'last_name'] | ||
swagger_schema_fields = { | ||
'title': 'User Info', | ||
'example': { | ||
'username': '[email protected]', | ||
'email': '[email protected]', | ||
'first_name': 'Jane', | ||
'last_name': 'Doe' | ||
} | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# coding=utf-8 | ||
""" | ||
Tomorrow Now GAP. | ||
.. note:: Unit tests for User API. | ||
""" | ||
|
||
from django.urls import reverse | ||
|
||
from core.tests.common import FakeResolverMatchV1, BaseAPIViewTest | ||
from gap_api.api_views.user import UserInfo | ||
|
||
|
||
class UserInfoAPITest(BaseAPIViewTest): | ||
"""User info api test case.""" | ||
|
||
def test_get_user_info_without_auth(self): | ||
"""Test get user info without authentication.""" | ||
view = UserInfo.as_view() | ||
request = self.factory.get( | ||
reverse('api:v1:user-info') | ||
) | ||
request.resolver_match = FakeResolverMatchV1 | ||
response = view(request) | ||
self.assertEqual(response.status_code, 401) | ||
|
||
def test_get_user_info(self): | ||
"""Test get user info with superuser.""" | ||
view = UserInfo.as_view() | ||
request = self.factory.get( | ||
reverse('api:v1:user-info') | ||
) | ||
request.user = self.superuser | ||
request.resolver_match = FakeResolverMatchV1 | ||
response = view(request) | ||
self.assertEqual(response.status_code, 200) | ||
self.assertEqual(response.data['username'], self.superuser.username) | ||
self.assertEqual( | ||
response.data['first_name'], self.superuser.first_name | ||
) | ||
self.assertEqual(response.data['last_name'], self.superuser.last_name) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# coding=utf-8 | ||
""" | ||
Tomorrow Now GAP. | ||
.. note:: GAP API urls. | ||
""" | ||
|
||
from django.urls import include, re_path | ||
|
||
urlpatterns = [ | ||
re_path( | ||
r'^v1/', include(('gap_api.urls.v1', 'v1'), namespace='v1') | ||
) | ||
] |
Oops, something went wrong.