Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added modifications to polls and stories API #851

Merged
merged 10 commits into from
Jan 12, 2022
46 changes: 46 additions & 0 deletions ureport/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,29 @@ def get_images(self, obj):
for image in obj.get_featured_images()
]

# Function to use ?fields and ?exclude API calls for specific attributes in stories
def __init__(self, *args, **kwargs):
# Don't pass the 'fields' arg up to the superclass
request = kwargs.get("context", {}).get("request")
str_exclude_fields = request.GET.get("exclude", "") if request else None
str_fields = request.GET.get("fields", "") if request else None
fields = str_fields.split(",") if str_fields else None
exclude_fields = str_exclude_fields.split(",") if str_exclude_fields else None

# Instantiate the superclass normally
super(StoryReadSerializer, self).__init__(*args, **kwargs)

if exclude_fields is not None:
# Drop any fields that are specified in the `exclude` argument.
exclude_allowed = set(exclude_fields)
for field_name in exclude_allowed:
self.fields.pop(field_name)
elif fields is not None:
allowed_fields = set(fields)
existing_data = set(self.fields)
for field_names in existing_data - allowed_fields:
self.fields.pop(field_names)

class Meta:
model = Story
fields = (
Expand All @@ -122,6 +145,29 @@ class PollReadSerializer(serializers.ModelSerializer):
category = CategoryReadSerializer()
questions = SerializerMethodField()

# Function to use ?fields and ?exclude API calls for specific attributes in polls
def __init__(self, *args, **kwargs):
# Don't pass the 'fields' arg up to the superclass
request = kwargs.get("context", {}).get("request")
str_exclude_fields = request.GET.get("exclude", "") if request else None
str_fields = request.GET.get("fields", "") if request else None
fields = str_fields.split(",") if str_fields else None
exclude_fields = str_exclude_fields.split(",") if str_exclude_fields else None

# Instantiate the superclass normally
super(PollReadSerializer, self).__init__(*args, **kwargs)

if exclude_fields is not None:
# Drop any fields that are specified in the `exclude` argument.
exclude_allowed = set(exclude_fields)
for field_name in exclude_allowed:
self.fields.pop(field_name)
elif fields is not None:
allowed_fields = set(fields)
existing_data = set(self.fields)
for field_names in existing_data - allowed_fields:
self.fields.pop(field_names)

def get_questions(self, obj):
questions = []
for question in obj.get_questions():
Expand Down
184 changes: 184 additions & 0 deletions ureport/api/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,40 @@ def test_polls_by_org_list_with_flow_uuid_parameter(self):
self.assertEqual(response.data["count"], 1)
self.assertEqual(response.data["results"][0]["title"], "registration")

def test_polls_by_org_list_with_fields_parameter(self):
url = "/api/v1/polls/org/%d/?fields=%s" % (self.uganda.pk, "title")
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
count_polls = Poll.objects.filter(org=self.uganda, is_active=True, has_synced=True).count()
self.assertEqual(response.data["count"], count_polls)
polls = [self.second_featured_poll, self.first_featured_poll, self.another_poll, self.reg_poll]
for i in range(count_polls):
self.assertEqual(response.data["results"][i]["title"], polls[i].title)

def test_polls_by_org_list_with_exclude_parameter(self):
url = "/api/v1/polls/org/%d/?exclude=%s,%s,%s,%s,%s,%s" % (
self.uganda.pk,
"flow_uuid",
"title",
"category",
"poll_date",
"modified_on",
"created_on",
)
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
count_polls = Poll.objects.filter(org=self.uganda, is_active=True, has_synced=True).count()
poll = self.reg_poll
self.assertEqual(response.data["count"], count_polls)
self.assertDictEqual(
response.data["results"][3],
dict(
id=poll.pk,
org=poll.org_id,
questions=[],
),
)

def test_featured_poll_by_org_list_when_featured_polls_exists(self):
url = "/api/v1/polls/org/%d/featured/" % self.uganda.pk
response = self.client.get(url)
Expand All @@ -410,6 +444,13 @@ def test_featured_poll_by_org_list_when_featured_polls_exists(self):
self.assertEqual(response.data["count"], 2)
self.assertTrue(response.data["results"][0]["modified_on"] > response.data["results"][1]["modified_on"])

def test_featured_poll_by_org_list_with_fields_parameter_when_featured_polls_exists(self):
url = "/api/v1/polls/org/%d/featured/?fields=%s" % (self.uganda.pk, "created_on")
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data["count"], 2)
self.assertTrue(response.data["results"][0]["created_on"] > response.data["results"][1]["created_on"])

def test_featured_poll_by_org_list_when_no_featured_polls_exists(self):
url = "/api/v1/polls/org/%d/featured/" % self.nigeria.pk
response = self.client.get(url)
Expand Down Expand Up @@ -500,6 +541,112 @@ def test_single_poll(self):
),
)

def test_single_poll_with_fields_parameter(self):
url = "/api/v1/polls/%d/?fields=%s,%s,%s" % (self.reg_poll.pk, "id", "title", "questions")
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
poll = self.reg_poll
self.assertDictEqual(
response.data,
dict(
id=poll.pk,
title=poll.title,
questions=[],
),
)

with patch("ureport.polls.models.PollQuestion.get_results") as mock_get_results:
mock_get_results.return_value = [dict(set=20, unset=10, open_ended=False, categories="CATEGORIES-DICT")]

poll_question = self.create_poll_question(self.superuser, self.reg_poll, "What's on mind? :)", "uuid1")

response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertDictEqual(
response.data,
dict(
id=poll.pk,
title=poll.title,
questions=[
dict(
id=poll_question.pk,
ruleset_uuid="uuid1",
title="What's on mind? :)",
results=dict(set=20, unset=10, open_ended=False, categories="CATEGORIES-DICT"),
results_by_age=[dict(set=20, unset=10, open_ended=False, categories="CATEGORIES-DICT")],
results_by_gender=[dict(set=20, unset=10, open_ended=False, categories="CATEGORIES-DICT")],
results_by_location=[
dict(set=20, unset=10, open_ended=False, categories="CATEGORIES-DICT")
],
)
],
),
)

poll_question.is_active = False
poll_question.save()

response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertDictEqual(
response.data,
dict(
id=poll.pk,
title=poll.title,
questions=[],
),
)

def test_single_poll_with_exclude_parameter(self):
url = "/api/v1/polls/%d/?exclude=%s,%s,%s,%s" % (self.reg_poll.pk, "id", "title", "category", "questions")
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
poll = self.reg_poll
self.assertDictEqual(
response.data,
dict(
flow_uuid=poll.flow_uuid,
org=poll.org_id,
poll_date=poll.poll_date.strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
modified_on=poll.modified_on.strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
created_on=poll.created_on.strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
),
)

with patch("ureport.polls.models.PollQuestion.get_results") as mock_get_results:
mock_get_results.return_value = [dict(set=20, unset=10, open_ended=False, categories="CATEGORIES-DICT")]

poll_question = self.create_poll_question(self.superuser, self.reg_poll, "What's on mind? :)", "uuid1")

response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertDictEqual(
response.data,
dict(
flow_uuid=poll.flow_uuid,
org=poll.org_id,
created_on=poll.created_on.strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
modified_on=poll.modified_on.strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
poll_date=poll.poll_date.strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
),
)

poll_question.is_active = False
poll_question.save()

response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertDictEqual(
response.data,
dict(
flow_uuid=poll.flow_uuid,
org=poll.org_id,
poll_date=poll.poll_date.strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
modified_on=poll.modified_on.strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
created_on=poll.created_on.strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
),
)

def test_news_item_by_org_list(self):
url = "/api/v1/news/org/%d/" % self.uganda.pk
url1 = "/api/v1/news/org/%d/" % self.nigeria.pk
Expand Down Expand Up @@ -602,6 +749,43 @@ def test_single_story(self):
dict(name=story.category.name, image_url=CategoryReadSerializer().get_image_url(story.category)),
)

def test_single_story_with_fields_parameter(self):
url = "/api/v1/stories/%d/?fields=%s" % (self.uganda_story.pk, "content")
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
story = self.uganda_story
self.assertDictEqual(
response.data,
dict(
content=story.content,
),
)

def test_single_story_with_exclude_parameter(self):
url = "/api/v1/stories/%d/?exclude=%s,%s,%s,%s" % (
self.uganda_story.pk,
"content",
"featured",
"images",
"category",
)
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
story = self.uganda_story
self.assertDictEqual(
response.data,
dict(
id=story.pk,
title=story.title,
video_id=story.video_id,
audio_link=story.audio_link,
summary=story.summary,
tags=story.tags,
org=story.org_id,
created_on=story.created_on.strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
),
)

def test_dashblock_by_org_list(self):
url_uganda = "/api/v1/dashblocks/org/%d/" % self.uganda.pk
url_nigeria = "/api/v1/dashblocks/org/%d/" % self.nigeria.pk
Expand Down
Loading