Skip to content

Commit

Permalink
Merge ef057b1 into bc9132f
Browse files Browse the repository at this point in the history
  • Loading branch information
dyohan9 committed Jul 5, 2019
2 parents bc9132f + ef057b1 commit d49cf25
Show file tree
Hide file tree
Showing 13 changed files with 479 additions and 184 deletions.
8 changes: 4 additions & 4 deletions bothub/api/v1/routers.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from rest_framework import routers

from .views import NewRepositoryViewSet
from .views import MyRepositoriesViewSet
from .views import SearchRepositoriesViewSet
from .views import RepositoryViewSet
from .views import NewRepositoryExampleViewSet
from .views import RepositoryExampleViewSet
Expand Down Expand Up @@ -31,7 +31,7 @@
class Router(routers.SimpleRouter):
routes = [
# Dynamically generated list routes.
# Generated using @list_route decorator
# Generated using @action decorator
# on methods of the viewset.
routers.DynamicRoute(
url=r'^{prefix}/{url_path}{trailing_slash}$',
Expand All @@ -40,7 +40,7 @@ class Router(routers.SimpleRouter):
initkwargs={},
),
# Dynamically generated detail routes.
# Generated using @detail_route decorator on methods of the viewset.
# Generated using @action decorator on methods of the viewset.
routers.DynamicRoute(
url=r'^{prefix}/{lookup}/{url_path}{trailing_slash}$',
name='{basename}-{url_name}',
Expand Down Expand Up @@ -99,7 +99,7 @@ def get_lookup_regex(self, viewset, lookup_prefix=''):

router = Router()
router.register('repository/new', NewRepositoryViewSet)
router.register('my-repositories', MyRepositoriesViewSet)
router.register('search-repositories', SearchRepositoriesViewSet)
router.register('repository', RepositoryViewSet)
router.register('example/new', NewRepositoryExampleViewSet)
router.register('example', RepositoryExampleViewSet)
Expand Down
1 change: 0 additions & 1 deletion bothub/api/v1/serializers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
AnalyzeTextSerializer,
EvaluateSerializer,
EditRepositorySerializer,
VoteSerializer,
RepositoryAuthorizationRoleSerializer,
)

Expand Down
10 changes: 0 additions & 10 deletions bothub/api/v1/serializers/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from bothub.common.models import Repository
from bothub.common.models import RepositoryCategory
from bothub.common.models import RepositoryAuthorization
from bothub.common.models import RepositoryVote
from bothub.common.models import RequestRepositoryAuthorization
from bothub.common.languages import LANGUAGE_CHOICES

Expand Down Expand Up @@ -85,7 +84,6 @@ class Meta:
'requirements_to_train',
'languages_ready_for_train',
'languages_warnings',
'votes_sum',
'created_at',
]

Expand Down Expand Up @@ -190,14 +188,6 @@ class EvaluateSerializer(serializers.Serializer):
language = serializers.ChoiceField(LANGUAGE_CHOICES, required=True)


class VoteSerializer(serializers.ModelSerializer):
class Meta:
model = RepositoryVote
fields = [
'vote',
]


class RepositoryAuthorizationRoleSerializer(serializers.ModelSerializer):
class Meta:
model = RepositoryAuthorization
Expand Down
124 changes: 18 additions & 106 deletions bothub/api/v1/tests/test_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,12 @@
from bothub.common.models import Repository
from bothub.common.models import RepositoryExample
from bothub.common.models import RepositoryExampleEntity
from bothub.common.models import RepositoryVote
from bothub.common.models import RepositoryAuthorization
from bothub.common.models import RequestRepositoryAuthorization

from ..views import NewRepositoryViewSet
from ..views import RepositoryViewSet
from ..views import MyRepositoriesViewSet
from ..views import SearchRepositoriesViewSet
from ..views import RepositoriesViewSet

from .utils import create_user_and_token
Expand Down Expand Up @@ -447,7 +446,7 @@ def test_forbidden(self):
status.HTTP_403_FORBIDDEN)


class MyRepositoriesTestCase(TestCase):
class SearchRepositoriesTestCase(TestCase):
def setUp(self):
self.factory = RequestFactory()

Expand All @@ -464,20 +463,19 @@ def setUp(self):
language=languages.LANGUAGE_EN)
self.repository.categories.add(self.category)

def request(self, token):
authorization_header = {
'HTTP_AUTHORIZATION': 'Token {}'.format(token.key),
}
def request(self, nickname):
request = self.factory.get(
'/api/my-repositories/',
**authorization_header)
response = MyRepositoriesViewSet.as_view({'get': 'list'})(request)
'/api/search-repositories/?nickname={}'.format(nickname)
)
response = SearchRepositoriesViewSet.as_view(
{'get': 'list'}
)(request, nickname=nickname)
response.render()
content_data = json.loads(response.content)
return (response, content_data,)

def test_okay(self):
response, content_data = self.request(self.owner_token)
response, content_data = self.request('owner')
self.assertEqual(response.status_code, 200)
self.assertEqual(
content_data.get('count'),
Expand All @@ -486,8 +484,15 @@ def test_okay(self):
uuid.UUID(content_data.get('results')[0].get('uuid')),
self.repository.uuid)

def test_empty_okay(self):
response, content_data = self.request(self.user_token)
def test_empty_with_user_okay(self):
response, content_data = self.request('fake')
self.assertEqual(response.status_code, 200)
self.assertEqual(
content_data.get('count'),
0)

def test_empty_without_user_okay(self):
response, content_data = self.request('')
self.assertEqual(response.status_code, 200)
self.assertEqual(
content_data.get('count'),
Expand Down Expand Up @@ -758,96 +763,3 @@ def test_none_entities(self):
language_status = languages_status.get(language)
for entity in language_status.get('examples').get('entities'):
self.failIfEqual(entity, None)


class RepositoryVoteTestCase(TestCase):
def setUp(self):
self.factory = RequestFactory()

self.owner, self.owner_token = create_user_and_token('owner')
self.user, self.user_token = create_user_and_token()

self.repository = Repository.objects.create(
owner=self.owner,
name='Testing',
slug='test',
language=languages.LANGUAGE_EN)

def request(self, repository, data={}, token=None):
authorization_header = {
'HTTP_AUTHORIZATION': 'Token {}'.format(token.key),
} if token else {}
request = self.factory.post(
'/api/repository/{}/{}/vote/'.format(
repository.owner.nickname,
repository.slug),
data,
**authorization_header)
response = RepositoryViewSet.as_view(
{'post': 'vote'})(request)
response.render()
content_data = json.loads(response.content)
return (response, content_data,)

def test_unauthorized(self):
response, content_data = self.request(self.repository)
self.assertEqual(
response.status_code,
status.HTTP_401_UNAUTHORIZED)

def test_invalid_vote(self):
response, content_data = self.request(
self.repository,
{
'vote': 2,
},
self.user_token)
self.assertEqual(
response.status_code,
status.HTTP_400_BAD_REQUEST)
self.assertIn(
'vote',
content_data.keys())

def test_vote_up(self):
response, content_data = self.request(
self.repository,
{
'vote': RepositoryVote.UP_VOTE,
},
self.user_token)
self.assertEqual(
response.status_code,
status.HTTP_201_CREATED)
vote = RepositoryVote.objects.get(
repository=self.repository,
user=self.user)
self.assertEqual(
vote.vote,
RepositoryVote.UP_VOTE)
self.assertEqual(
self.repository.votes_sum,
1)
self.assertEqual(
content_data.get('votes_sum'),
1)

def test_vote_down(self):
response, content_data = self.request(
self.repository,
{
'vote': RepositoryVote.DOWN_VOTE,
},
self.user_token)
self.assertEqual(
response.status_code,
status.HTTP_201_CREATED)
vote = RepositoryVote.objects.get(
repository=self.repository,
user=self.user)
self.assertEqual(
vote.vote,
RepositoryVote.DOWN_VOTE)
self.assertEqual(
self.repository.votes_sum,
-1)
62 changes: 25 additions & 37 deletions bothub/api/v1/views.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from rest_framework.viewsets import GenericViewSet
from rest_framework import mixins
from rest_framework import permissions
from rest_framework.decorators import detail_route
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.exceptions import APIException
from rest_framework.exceptions import NotFound
Expand All @@ -24,7 +24,6 @@
from bothub.common.models import RepositoryExample
from bothub.common.models import RepositoryTranslatedExample
from bothub.common.models import RepositoryCategory
from bothub.common.models import RepositoryVote
from bothub.common.models import RepositoryAuthorization
from bothub.common.models import RequestRepositoryAuthorization
from bothub.common.models import RepositoryEntity
Expand All @@ -48,7 +47,6 @@
from .serializers import EvaluateSerializer
from .serializers import EditRepositorySerializer
from .serializers import NewRepositoryTranslatedExampleSerializer
from .serializers import VoteSerializer
from .serializers import RepositoryAuthorizationRoleSerializer
from .serializers import NewRequestRepositoryAuthorizationSerializer
from .serializers import RequestRepositoryAuthorizationSerializer
Expand Down Expand Up @@ -404,18 +402,29 @@ def create(self, request, *args, **kwargs):
headers=headers)


class MyRepositoriesViewSet(
class SearchRepositoriesViewSet(
mixins.ListModelMixin,
GenericViewSet):
"""
List all user's repositories
"""
queryset = Repository.objects
serializer_class = RepositorySerializer
permission_classes = [permissions.IsAuthenticated]
lookup_field = 'nickname'

def get_queryset(self, *args, **kwargs):
return self.queryset.filter(owner=self.request.user)
try:
if self.request.query_params.get('nickname', None):
return self.queryset.filter(
owner__nickname=self.request.query_params.get(
'nickname',
self.request.user
)
)
else:
return self.queryset.filter(owner=self.request.user)
except TypeError:
return self.queryset.none()


class RepositoryViewSet(
Expand Down Expand Up @@ -448,7 +457,8 @@ class RepositoryViewSet(
RepositoryPermission,
]

@detail_route(
@action(
detail=True,
methods=['GET'],
url_name='repository-languages-status')
def languagesstatus(self, request, **kwargs):
Expand All @@ -460,7 +470,8 @@ def languagesstatus(self, request, **kwargs):
'languages_status': repository.languages_status,
})

@detail_route(
@action(
detail=True,
methods=['GET'],
url_name='repository-authorization')
def authorization(self, request, **kwargs):
Expand All @@ -474,7 +485,8 @@ def authorization(self, request, **kwargs):
serializer = RepositoryAuthorizationSerializer(user_authorization)
return Response(serializer.data)

@detail_route(
@action(
detail=True,
methods=['GET'],
url_name='repository-train')
def train(self, request, **kwargs):
Expand All @@ -493,7 +505,8 @@ def train(self, request, **kwargs):
code=request.status_code)
return Response(request.json()) # pragma: no cover

@detail_route(
@action(
detail=True,
methods=['POST'],
url_name='repository-analyze',
permission_classes=[])
Expand Down Expand Up @@ -524,7 +537,8 @@ def analyze(self, request, **kwargs):
message = error.get('message') # pragma: no cover
raise APIException(detail=message) # pragma: no cover

@detail_route(
@action(
detail=True,
methods=['POST'],
url_name='repository-evaluate')
def evaluate(self, request, **kwargs):
Expand Down Expand Up @@ -558,32 +572,6 @@ def evaluate(self, request, **kwargs):
code=request.status_code)
return Response(request.json()) # pragma: no cover

@detail_route(
methods=['POST'],
url_name='repository-vote',
permission_classes=[
IsAuthenticated,
])
def vote(self, request, **kwargs):
user = request.user
repository = self.get_object()
instance, created = RepositoryVote.objects.get_or_create(
user=user,
repository=repository,
defaults={
'vote': RepositoryVote.NEUTRAL_VOTE,
})
serializer = VoteSerializer(
data=request.data,
instance=instance)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(
{
'votes_sum': repository.votes_sum,
},
status=status.HTTP_201_CREATED)

def get_serializer_class(self):
if self.request and self.request.method in \
['OPTIONS'] + WRITE_METHODS or not self.request:
Expand Down
Loading

0 comments on commit d49cf25

Please sign in to comment.