From 327e5937f1375d574c55e133ca87a06a6406e34e Mon Sep 17 00:00:00 2001 From: chillaranand Date: Sun, 3 Jul 2016 17:33:47 +0530 Subject: [PATCH 01/16] Use bytesio instead of stringio --- junction/proposals/dashboard.py | 4 ++-- tests/integrations/test_reviewer_views.py | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/junction/proposals/dashboard.py b/junction/proposals/dashboard.py index 799d636e..f676a573 100644 --- a/junction/proposals/dashboard.py +++ b/junction/proposals/dashboard.py @@ -4,13 +4,13 @@ # Standard Library import collections import uuid +import io # Third Party Stuff from django.contrib.auth.decorators import login_required from django.core.exceptions import PermissionDenied from django.http import HttpResponse from django.shortcuts import get_object_or_404, render -from django.utils.six import StringIO from django.views.decorators.http import require_http_methods from xlsxwriter.workbook import Workbook @@ -272,7 +272,7 @@ def export_reviewer_votes(request, conference_slug): for i in ProposalSectionReviewerVoteValue.objects.order_by('-vote_value')) header = ('Proposal Type', 'Title', 'Sum of reviewer votes', 'No. of reviewer votes') + \ tuple(vote_values_desc) + ('Public votes count', 'Vote Comments') - output = StringIO() + output = io.BytesIO() with Workbook(output) as book: for section in proposal_sections: diff --git a/tests/integrations/test_reviewer_views.py b/tests/integrations/test_reviewer_views.py index 75c0cec2..3ce2f60d 100644 --- a/tests/integrations/test_reviewer_views.py +++ b/tests/integrations/test_reviewer_views.py @@ -208,9 +208,8 @@ def test_post_review_proposal_vote_with_invalid_data(self, settings, login, assert response.status_code == 200 assert 'vote_value' in response.context['form_errors'] - def test_get_proposal_votes_dashboard(self, client, conferences, create_superuser): - username, password, user = create_superuser - client.login(username=username, password=password) + def test_get_proposal_votes_dashboard(self, login, conferences, create_superuser): + client = login[0] conference = conferences['future'] kwargs = {'conference_slug': conference.slug} From c2ebdb506b6cda800588f2ada5e1a7ceeb49a46c Mon Sep 17 00:00:00 2001 From: chillaranand Date: Tue, 5 Jul 2016 22:29:39 +0530 Subject: [PATCH 02/16] Add base api for proposals --- junction/proposals/views.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/junction/proposals/views.py b/junction/proposals/views.py index aa8b4933..814ef79e 100644 --- a/junction/proposals/views.py +++ b/junction/proposals/views.py @@ -14,6 +14,7 @@ from django.shortcuts import get_object_or_404, render from django.views.decorators.http import require_http_methods from hashids import Hashids +from rest_framework import generics # Junction Stuff from junction.base.constants import ConferenceSettingConstants, ConferenceStatus, ProposalReviewStatus, ProposalStatus @@ -409,3 +410,15 @@ def delete_proposal(request, conference_slug, slug): elif request.method == 'POST': proposal.delete() return HttpResponseRedirect(reverse('proposals-list', args=[conference.slug])) + + +class ProposalListApiView(generics.ListAPIView): + + serializer_class = serializers.ProposalSerializer + + def get_queryset(self): + queryset = Proposal.objects.all() + conference = self.request.query_params.get('conference', None) + if conference: + queryset = queryset.filter(conference__slug=conference) + return queryset From f46de5bb103dcc525117073660cdcb855e4d4bda Mon Sep 17 00:00:00 2001 From: chillaranand Date: Tue, 5 Jul 2016 22:29:57 +0530 Subject: [PATCH 03/16] Update api urls --- junction/urls.py | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/junction/urls.py b/junction/urls.py index 0f52b6c3..578e3fdf 100644 --- a/junction/urls.py +++ b/junction/urls.py @@ -13,6 +13,7 @@ from junction.conferences import views as conference_views from junction.devices.views import DeviceDetailApiView, DeviceListApiView from junction.feedback.views import FeedbackListApiView, FeedbackQuestionListApiView, view_feedback +from junction.proposals.views import ProposalListApiView from junction.schedule import views as schedule_views from junction.schedule.views import non_proposal_schedule_item_view @@ -23,7 +24,6 @@ router.register('conferences', conference_views.ConferenceView) router.register('venues', conference_views.VenueView) router.register('rooms', conference_views.RoomView) - router.register('schedules', schedule_views.ScheduleView) ''' @@ -66,18 +66,7 @@ url(r'^schedule_item/(?P\d+)/$', non_proposal_schedule_item_view, name="schedule-item"), - url(r'^api/v1/', include(router.urls)), - # Device - url(r'^api/v1/devices/$', DeviceListApiView.as_view(), name='device-list'), - url(r'^api/v1/devices/(?P<_uuid>[\w-]+)/$', DeviceDetailApiView.as_view(), - name='device-detail'), - # Feedback - url('^api/v1/feedback_questions/$', - FeedbackQuestionListApiView.as_view(), - name='feedback-questions-list'), - url('^api/v1/feedback/$', - FeedbackListApiView.as_view(), - name='feedback-list'), + # User Dashboard url(r'^profiles/', include('junction.profiles.urls', namespace="profiles")), @@ -97,6 +86,13 @@ RedirectView.as_view(pattern_name="proposals-list"), name='conference-detail'), + # api + url(r'^api/v1/', include(router.urls)), + url(r'^api/v1/devices/$', DeviceListApiView.as_view(), name='device-list'), + url(r'^api/v1/devices/(?P<_uuid>[\w-]+)/$', DeviceDetailApiView.as_view(), name='device-detail'), + url(r'^api/v1/feedback_questions/$', FeedbackQuestionListApiView.as_view(), name='feedback-questions-list'), + url(r'^api/v1/feedback/$', FeedbackListApiView.as_view(), name='feedback-list'), + url(r'^api/v1/proposals/$', ProposalListApiView.as_view(), name='proposal-list'), ) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) if settings.DEBUG: From 896e46ee55b65cd582a19f08c2e70bb96a897e59 Mon Sep 17 00:00:00 2001 From: chillaranand Date: Wed, 6 Jul 2016 23:27:20 +0530 Subject: [PATCH 04/16] Refactor proposal api --- junction/proposals/serializers.py | 32 ++++++++++++++++++++++++++++--- junction/proposals/views.py | 12 ------------ junction/urls.py | 2 +- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/junction/proposals/serializers.py b/junction/proposals/serializers.py index 2ed4e75c..29305456 100644 --- a/junction/proposals/serializers.py +++ b/junction/proposals/serializers.py @@ -1,7 +1,6 @@ -# Third Party Stuff from rest_framework import serializers -from .models import Proposal, ProposalSection, ProposalType +from .models import Proposal, ProposalSection, ProposalType, ProposalComment class ProposalSerializer(serializers.HyperlinkedModelSerializer): @@ -22,12 +21,39 @@ def get_author(self, proposal): class Meta: model = Proposal - fields = ('title', 'section', 'type', 'author', + fields = ('id', 'title', 'section', 'type', 'author', 'slug', 'description', 'target_audience', 'prerequisites', 'content_urls', 'speaker_info', 'speaker_links') +class ProposalCommentSerializer(serializers.ModelSerializer): + + commenter = serializers.SerializerMethodField() + + def get_commenter(self, comment): + return comment.proposal.author.username + + class Meta: + model = ProposalComment + fields = ('commenter', 'comment') + + +class ProposalListSerializer(serializers.ModelSerializer): + + comments = ProposalCommentSerializer(read_only=True, many=True, source='proposalcomment_set') + print(comments) + # def get_author(self, proposal): + # return proposal.author.username + + class Meta: + model = Proposal + fields = ('id', 'title', 'author', + 'slug', 'description', 'target_audience', + 'prerequisites', 'content_urls', 'speaker_info', + 'speaker_links', 'comments') + + class ProposalFilterSerializer(serializers.Serializer): proposal_section = serializers.PrimaryKeyRelatedField(queryset=ProposalSection.objects.all(), required=False) proposal_type = serializers.PrimaryKeyRelatedField(queryset=ProposalType.objects.all(), required=False) diff --git a/junction/proposals/views.py b/junction/proposals/views.py index 814ef79e..31e2460c 100644 --- a/junction/proposals/views.py +++ b/junction/proposals/views.py @@ -410,15 +410,3 @@ def delete_proposal(request, conference_slug, slug): elif request.method == 'POST': proposal.delete() return HttpResponseRedirect(reverse('proposals-list', args=[conference.slug])) - - -class ProposalListApiView(generics.ListAPIView): - - serializer_class = serializers.ProposalSerializer - - def get_queryset(self): - queryset = Proposal.objects.all() - conference = self.request.query_params.get('conference', None) - if conference: - queryset = queryset.filter(conference__slug=conference) - return queryset diff --git a/junction/urls.py b/junction/urls.py index 578e3fdf..304351e9 100644 --- a/junction/urls.py +++ b/junction/urls.py @@ -13,7 +13,7 @@ from junction.conferences import views as conference_views from junction.devices.views import DeviceDetailApiView, DeviceListApiView from junction.feedback.views import FeedbackListApiView, FeedbackQuestionListApiView, view_feedback -from junction.proposals.views import ProposalListApiView +from junction.proposals.api import ProposalListApiView from junction.schedule import views as schedule_views from junction.schedule.views import non_proposal_schedule_item_view From ec53e7e7cc951a51b7f0771b0f4df2dd84cc152a Mon Sep 17 00:00:00 2001 From: chillaranand Date: Thu, 7 Jul 2016 00:25:10 +0530 Subject: [PATCH 05/16] Add test cases for proposal api --- junction/proposals/api.py | 23 ++++++++++++++++++++ junction/urls.py | 2 +- tests/integrations/test_proposal_api.py | 28 +++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 junction/proposals/api.py create mode 100644 tests/integrations/test_proposal_api.py diff --git a/junction/proposals/api.py b/junction/proposals/api.py new file mode 100644 index 00000000..88fd04ad --- /dev/null +++ b/junction/proposals/api.py @@ -0,0 +1,23 @@ +from rest_framework import generics +from rest_framework.pagination import PageNumberPagination + +from junction.proposals import serializers +from junction.proposals.models import Proposal + + +class StandardResultsSetPagination(PageNumberPagination): + page_size = 2 + page_size_query_param = 'page' + + +class ProposalListApiView(generics.ListAPIView): + + serializer_class = serializers.ProposalListSerializer + pagination_class = StandardResultsSetPagination + + def get_queryset(self): + queryset = Proposal.objects.all() + conference = self.request.query_params.get('conference', None) + if conference: + queryset = queryset.filter(conference__slug=conference) + return queryset diff --git a/junction/urls.py b/junction/urls.py index 304351e9..f873403b 100644 --- a/junction/urls.py +++ b/junction/urls.py @@ -92,7 +92,7 @@ url(r'^api/v1/devices/(?P<_uuid>[\w-]+)/$', DeviceDetailApiView.as_view(), name='device-detail'), url(r'^api/v1/feedback_questions/$', FeedbackQuestionListApiView.as_view(), name='feedback-questions-list'), url(r'^api/v1/feedback/$', FeedbackListApiView.as_view(), name='feedback-list'), - url(r'^api/v1/proposals/$', ProposalListApiView.as_view(), name='proposal-list'), + url(r'^api/v1/proposals/$', ProposalListApiView.as_view(), name='proposals-list-api'), ) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) if settings.DEBUG: diff --git a/tests/integrations/test_proposal_api.py b/tests/integrations/test_proposal_api.py new file mode 100644 index 00000000..2563e02e --- /dev/null +++ b/tests/integrations/test_proposal_api.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- + +import pytest +from django.core.urlresolvers import reverse +from rest_framework.test import APITestCase +from rest_framework import status + + +pytestmark = pytest.mark.django_db + + +class TestProposalListApi: + + def test_get_proposals_list_without_conference(self, client): + url = '{}?conference={}'.format(reverse('proposals-list-api'), 'foo') + res = client.get(url) + + assert res.status_code == status.HTTP_200_OK + assert res.data['count'] == 0 + + def test_get_proposals_list(self, client, conferences, create_proposal): + conference = conferences['future'] + url = '{}?conference={}'.format(reverse('proposals-list-api'), conference.slug) + res = client.get(url) + + assert res.status_code == status.HTTP_200_OK + assert res.data['count'] == 1 + assert res.data['results'] != [] From b59c39343d38a3bef9c82e93c5ecd4c2e3215a57 Mon Sep 17 00:00:00 2001 From: chillaranand Date: Thu, 7 Jul 2016 19:36:02 +0530 Subject: [PATCH 06/16] Update proposal serializer --- junction/proposals/serializers.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/junction/proposals/serializers.py b/junction/proposals/serializers.py index 29305456..734345fe 100644 --- a/junction/proposals/serializers.py +++ b/junction/proposals/serializers.py @@ -21,10 +21,8 @@ def get_author(self, proposal): class Meta: model = Proposal - fields = ('id', 'title', 'section', 'type', 'author', - 'slug', 'description', 'target_audience', - 'prerequisites', 'content_urls', 'speaker_info', - 'speaker_links') + fields = ('title', 'section', 'type', 'author', 'slug', 'description', 'target_audience', + 'prerequisites', 'content_urls', 'speaker_info', 'speaker_links') class ProposalCommentSerializer(serializers.ModelSerializer): @@ -41,17 +39,20 @@ class Meta: class ProposalListSerializer(serializers.ModelSerializer): - comments = ProposalCommentSerializer(read_only=True, many=True, source='proposalcomment_set') - print(comments) - # def get_author(self, proposal): - # return proposal.author.username + comments = serializers.SerializerMethodField() + + def get_comments(self, proposal): + qset = ProposalComment.objects.filter(proposal=proposal, private=False, reviewer=False) + s_comments = ProposalCommentSerializer(qset, many=True) + return s_comments.data + + def get_author(self, proposal): + return proposal.author.username class Meta: model = Proposal - fields = ('id', 'title', 'author', - 'slug', 'description', 'target_audience', - 'prerequisites', 'content_urls', 'speaker_info', - 'speaker_links', 'comments') + fields = ('id', 'title', 'author', 'slug', 'description', 'target_audience', + 'prerequisites', 'content_urls', 'speaker_info', 'speaker_links', 'comments') class ProposalFilterSerializer(serializers.Serializer): From 1327e0974e6bde21bd28cad87cebe6891b90a26d Mon Sep 17 00:00:00 2001 From: chillaranand Date: Thu, 7 Jul 2016 20:05:46 +0530 Subject: [PATCH 07/16] Remove unused imports --- junction/proposals/views.py | 1 - tests/integrations/test_proposal_api.py | 1 - 2 files changed, 2 deletions(-) diff --git a/junction/proposals/views.py b/junction/proposals/views.py index 31e2460c..aa8b4933 100644 --- a/junction/proposals/views.py +++ b/junction/proposals/views.py @@ -14,7 +14,6 @@ from django.shortcuts import get_object_or_404, render from django.views.decorators.http import require_http_methods from hashids import Hashids -from rest_framework import generics # Junction Stuff from junction.base.constants import ConferenceSettingConstants, ConferenceStatus, ProposalReviewStatus, ProposalStatus diff --git a/tests/integrations/test_proposal_api.py b/tests/integrations/test_proposal_api.py index 2563e02e..23b81d1e 100644 --- a/tests/integrations/test_proposal_api.py +++ b/tests/integrations/test_proposal_api.py @@ -2,7 +2,6 @@ import pytest from django.core.urlresolvers import reverse -from rest_framework.test import APITestCase from rest_framework import status From dc654bad198103ec04c2de900d43228dac4d7edd Mon Sep 17 00:00:00 2001 From: chillaranand Date: Sun, 10 Jul 2016 00:02:36 +0530 Subject: [PATCH 08/16] Update serializer & queryset for proposal api --- junction/proposals/api.py | 3 ++- junction/proposals/serializers.py | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/junction/proposals/api.py b/junction/proposals/api.py index 88fd04ad..4c4d22bd 100644 --- a/junction/proposals/api.py +++ b/junction/proposals/api.py @@ -1,6 +1,7 @@ from rest_framework import generics from rest_framework.pagination import PageNumberPagination +from junction.base.constants import ProposalStatus from junction.proposals import serializers from junction.proposals.models import Proposal @@ -16,7 +17,7 @@ class ProposalListApiView(generics.ListAPIView): pagination_class = StandardResultsSetPagination def get_queryset(self): - queryset = Proposal.objects.all() + queryset = Proposal.objects.filter(deleted=False, status=ProposalStatus.PUBLIC) conference = self.request.query_params.get('conference', None) if conference: queryset = queryset.filter(conference__slug=conference) diff --git a/junction/proposals/serializers.py b/junction/proposals/serializers.py index 734345fe..7775cf32 100644 --- a/junction/proposals/serializers.py +++ b/junction/proposals/serializers.py @@ -3,7 +3,7 @@ from .models import Proposal, ProposalSection, ProposalType, ProposalComment -class ProposalSerializer(serializers.HyperlinkedModelSerializer): +class BaseProposalSerializer(serializers.HyperlinkedModelSerializer): section = serializers.SerializerMethodField() type = serializers.SerializerMethodField() author = serializers.SerializerMethodField() @@ -25,6 +25,10 @@ class Meta: 'prerequisites', 'content_urls', 'speaker_info', 'speaker_links') +class ProposalSerializer(BaseProposalSerializer): + pass + + class ProposalCommentSerializer(serializers.ModelSerializer): commenter = serializers.SerializerMethodField() @@ -37,7 +41,7 @@ class Meta: fields = ('commenter', 'comment') -class ProposalListSerializer(serializers.ModelSerializer): +class ProposalListSerializer(BaseProposalSerializer): comments = serializers.SerializerMethodField() From a0620c94bf42ad402b12fd33c72dceb9d86e0355 Mon Sep 17 00:00:00 2001 From: chillaranand Date: Sun, 10 Jul 2016 00:06:02 +0530 Subject: [PATCH 09/16] Update proposal fixtures --- tests/fixtures.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/fixtures.py b/tests/fixtures.py index d66cb7ba..d71fdc24 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -7,7 +7,7 @@ import mock import pytest -from junction.base.constants import ConferenceStatus +from junction.base.constants import ConferenceStatus, ProposalStatus from junction.conferences.models import ConferenceProposalReviewer from junction.proposals.models import ProposalSectionReviewer @@ -140,5 +140,6 @@ def create_proposal(conferences, create_user): proposal = factories.create_proposal(conference=conference, proposal_section=section, proposal_type=proposal_type, - author=user) + author=user, + status=ProposalStatus.PUBLIC) return proposal From 1362ae0aad5602974e5245c672929ef96354bb14 Mon Sep 17 00:00:00 2001 From: chillaranand Date: Sun, 10 Jul 2016 00:19:17 +0530 Subject: [PATCH 10/16] Remove blank line --- junction/proposals/permissions.py | 1 - 1 file changed, 1 deletion(-) diff --git a/junction/proposals/permissions.py b/junction/proposals/permissions.py index 023a5f23..c9ff02a9 100644 --- a/junction/proposals/permissions.py +++ b/junction/proposals/permissions.py @@ -57,4 +57,3 @@ def is_conference_moderator(user, conference): users = [mod.moderator for mod in conference.moderators.all()] return user in users - From 49f4d45e707c5e194322b93bad85eb208eed874c Mon Sep 17 00:00:00 2001 From: chillaranand Date: Mon, 11 Jul 2016 23:28:03 +0530 Subject: [PATCH 11/16] Add docs for proposal api --- docs/api.md | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/docs/api.md b/docs/api.md index 5fc1f955..95d08251 100644 --- a/docs/api.md +++ b/docs/api.md @@ -88,6 +88,51 @@ Junction provides API to access information about the conference, schedule, and ``` +### Proposals: List of proposals for the conference + +- Endpoint: `/api/v1/proposals/?conference=` + +- Allowed Methods: `GET` + +- Returns proposals of the conference. + +- Results are paginated. 20 results per page. Includes previous/next urls. + +- Sample Response: + +``` +{ + "count": 3, + "next": null, + "previous": "http://127.0.0.1:8000/api/v1/proposals/?conference=a-porro-conference", + "results": [ + { + "id": 25, + "title": "A porro - type 0 - section 0 -1", + "author": "fsdf", + "slug": "sadfaaaaaaaaaaaaaaaaaaaaa-2", + "description": "sdf", + "target_audience": 3, + "prerequisites": "", + "content_urls": "", + "speaker_info": "", + "speaker_links": "", + "comments": [ + { + "commenter": "fpqwe", + "comment": "good " + }, + { + "commenter": "fsdf", + "comment": "very good" + } + ] + } + ] +} +``` + + ### Schedule: List - Endpoint: `/api/v1/schedules/` From bd64a5d7e11eb1bfa3c40a513a013379515d5d3e Mon Sep 17 00:00:00 2001 From: chillaranand Date: Sun, 24 Jul 2016 21:50:45 +0530 Subject: [PATCH 12/16] Add proposal type & section to serializer --- junction/proposals/serializers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/junction/proposals/serializers.py b/junction/proposals/serializers.py index 7775cf32..487bfc7f 100644 --- a/junction/proposals/serializers.py +++ b/junction/proposals/serializers.py @@ -55,7 +55,7 @@ def get_author(self, proposal): class Meta: model = Proposal - fields = ('id', 'title', 'author', 'slug', 'description', 'target_audience', + fields = ('id', 'title', 'author', 'slug', 'section', 'type', 'description', 'target_audience', 'prerequisites', 'content_urls', 'speaker_info', 'speaker_links', 'comments') From 4f91634b4a8a8c6d19baaa5d760276cd98ff5991 Mon Sep 17 00:00:00 2001 From: chillaranand Date: Sun, 24 Jul 2016 22:06:30 +0530 Subject: [PATCH 13/16] Add test cases for pagination --- tests/fixtures.py | 8 ++++++++ tests/integrations/test_proposal_api.py | 5 +++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/fixtures.py b/tests/fixtures.py index d71fdc24..011cdee4 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -143,3 +143,11 @@ def create_proposal(conferences, create_user): author=user, status=ProposalStatus.PUBLIC) return proposal + + +@pytest.fixture +def create_proposals(conferences, create_user): + conference, user = conferences['future'], create_user['user'] + proposals = [factories.create_proposal(author=user, status=ProposalStatus.PUBLIC, conference=conference) + for i in range(30)] + return proposals diff --git a/tests/integrations/test_proposal_api.py b/tests/integrations/test_proposal_api.py index 23b81d1e..c7320994 100644 --- a/tests/integrations/test_proposal_api.py +++ b/tests/integrations/test_proposal_api.py @@ -17,11 +17,12 @@ def test_get_proposals_list_without_conference(self, client): assert res.status_code == status.HTTP_200_OK assert res.data['count'] == 0 - def test_get_proposals_list(self, client, conferences, create_proposal): + def test_get_proposals_list(self, client, conferences, create_proposals): conference = conferences['future'] url = '{}?conference={}'.format(reverse('proposals-list-api'), conference.slug) res = client.get(url) assert res.status_code == status.HTTP_200_OK - assert res.data['count'] == 1 + assert res.data['count'] == 30 + assert res.data['next'] == 'http://testserver/api/v1/proposals/?conference=future&page=2' assert res.data['results'] != [] From adcf5b3252a2c7ded6148dba910436bf922ebe19 Mon Sep 17 00:00:00 2001 From: chillaranand Date: Sun, 24 Jul 2016 22:11:49 +0530 Subject: [PATCH 14/16] Add test cases for proposal fields --- tests/integrations/test_proposal_api.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/integrations/test_proposal_api.py b/tests/integrations/test_proposal_api.py index c7320994..e3d00102 100644 --- a/tests/integrations/test_proposal_api.py +++ b/tests/integrations/test_proposal_api.py @@ -17,12 +17,13 @@ def test_get_proposals_list_without_conference(self, client): assert res.status_code == status.HTTP_200_OK assert res.data['count'] == 0 - def test_get_proposals_list(self, client, conferences, create_proposals): + def test_get_proposals_list(self, client, conferences, create_proposal, create_proposals): conference = conferences['future'] url = '{}?conference={}'.format(reverse('proposals-list-api'), conference.slug) res = client.get(url) assert res.status_code == status.HTTP_200_OK - assert res.data['count'] == 30 + assert res.data['count'] == 31 assert res.data['next'] == 'http://testserver/api/v1/proposals/?conference=future&page=2' - assert res.data['results'] != [] + assert res.data['results'][0]['author'] == 'username' + assert res.data['results'][0]['type'] == 'Workshop' From c07543daef680328040c24853a655a297aad7edd Mon Sep 17 00:00:00 2001 From: chillaranand Date: Sun, 2 Oct 2016 23:00:41 +0530 Subject: [PATCH 15/16] Configure pagination globally --- junction/proposals/api.py | 7 ------- settings/common.py | 3 ++- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/junction/proposals/api.py b/junction/proposals/api.py index 4c4d22bd..73ab4c83 100644 --- a/junction/proposals/api.py +++ b/junction/proposals/api.py @@ -1,20 +1,13 @@ from rest_framework import generics -from rest_framework.pagination import PageNumberPagination from junction.base.constants import ProposalStatus from junction.proposals import serializers from junction.proposals.models import Proposal -class StandardResultsSetPagination(PageNumberPagination): - page_size = 2 - page_size_query_param = 'page' - - class ProposalListApiView(generics.ListAPIView): serializer_class = serializers.ProposalListSerializer - pagination_class = StandardResultsSetPagination def get_queryset(self): queryset = Proposal.objects.filter(deleted=False, status=ProposalStatus.PUBLIC) diff --git a/settings/common.py b/settings/common.py index f07a5516..c6f4113d 100644 --- a/settings/common.py +++ b/settings/common.py @@ -230,7 +230,8 @@ CONN_MAX_AGE = 300 REST_FRAMEWORK = { - 'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',) + 'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',), + 'PAGE_SIZE': 20, } EXPLARA_API_TOKEN = "shjbalkfbdskjlbdskljbdskaljfb" From 64943360299cffcc108eb6f84412c549de4dea10 Mon Sep 17 00:00:00 2001 From: chillaranand Date: Sun, 2 Oct 2016 23:03:07 +0530 Subject: [PATCH 16/16] Remove comments from proposal list api --- junction/proposals/serializers.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/junction/proposals/serializers.py b/junction/proposals/serializers.py index 487bfc7f..9fd37d92 100644 --- a/junction/proposals/serializers.py +++ b/junction/proposals/serializers.py @@ -43,20 +43,13 @@ class Meta: class ProposalListSerializer(BaseProposalSerializer): - comments = serializers.SerializerMethodField() - - def get_comments(self, proposal): - qset = ProposalComment.objects.filter(proposal=proposal, private=False, reviewer=False) - s_comments = ProposalCommentSerializer(qset, many=True) - return s_comments.data - def get_author(self, proposal): return proposal.author.username class Meta: model = Proposal fields = ('id', 'title', 'author', 'slug', 'section', 'type', 'description', 'target_audience', - 'prerequisites', 'content_urls', 'speaker_info', 'speaker_links', 'comments') + 'prerequisites', 'content_urls', 'speaker_info', 'speaker_links') class ProposalFilterSerializer(serializers.Serializer):