Skip to content

Commit

Permalink
Merge pull request #1367 from kollivier/thumb-meet-nail
Browse files Browse the repository at this point in the history
[Fixes #1299] Restore thumbnail data to public channels API.
  • Loading branch information
Jordan Yoshihara authored May 17, 2019
2 parents 1897143 + 86f0d7a commit 67cea67
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 4 deletions.
16 changes: 16 additions & 0 deletions contentcuration/contentcuration/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -762,11 +762,27 @@ class PublicChannelSerializer(ChannelFieldMixin, serializers.ModelSerializer):
"""
kind_count = serializers.SerializerMethodField('generate_kind_count')
matching_tokens = serializers.SerializerMethodField('match_tokens')
icon_encoding = serializers.SerializerMethodField('get_thumbnail_encoding')

def match_tokens(self, channel):
tokens = json.loads(channel.tokens) if hasattr(channel, 'tokens') else []
return list(channel.secret_tokens.filter(token__in=tokens).values_list('token', flat=True))

def get_thumbnail_encoding(self, channel):
"""
Historically, we did not set channel.icon_encoding in the Studio database. We
only set it in the exported Kolibri sqlite db. So when Kolibri asks for the channel
information, fall back to the channel thumbnail data if icon_encoding is not set.
"""
if channel.icon_encoding:
return channel.icon_encoding
elif channel.thumbnail_encoding:
base64 = channel.thumbnail_encoding.get('base64')
if base64:
return base64

return None

def generate_kind_count(self, channel):
return channel.published_kind_count and json.loads(channel.published_kind_count)

Expand Down
35 changes: 35 additions & 0 deletions contentcuration/contentcuration/tests/test_public_api.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from base import BaseAPITestCase
from django.core.urlresolvers import reverse
from testdata import generated_base64encoding


class PublicAPITestCase(BaseAPITestCase):
Expand All @@ -11,8 +12,42 @@ class PublicAPITestCase(BaseAPITestCase):

def setUp(self):
super(PublicAPITestCase, self).setUp()
self.channel_list_url = reverse('get_public_channel_list', kwargs={'version': 'v1'})

def test_info_endpoint(self):
"""
Test that the public info endpoint returns the correct identifying information
about Studio.
"""
response = self.client.get(reverse('info'))
self.assertEqual(response.data['application'], 'studio')
self.assertEqual(response.data['device_name'], 'Kolibri Studio')

def test_empty_public_channels(self):
"""
Ensure that we get a valid, but empty, JSON response when there are no
public channels.
"""
response = self.get(self.channel_list_url)
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 0)

def test_public_channels_endpoint(self):
"""
Test that the public channels endpoint returns information about
public channels and that this information is correct.
"""
self.channel.public = True
self.channel.thumbnail_encoding = {'base64': generated_base64encoding()}
self.channel.main_tree.published = True
self.channel.main_tree.save()
self.channel.save()

response = self.client.get(self.channel_list_url)
self.assertEqual(response.status_code, 200)

assert len(response.data) == 1
first_channel = response.data[0]
self.assertEqual(first_channel['name'], self.channel.name)
self.assertEqual(first_channel['id'], self.channel.id)
self.assertEqual(first_channel['icon_encoding'], generated_base64encoding())
12 changes: 8 additions & 4 deletions contentcuration/contentcuration/views/public.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from django.db.models import Q
from django.db.models import TextField
from django.db.models import Value
from django.http import HttpResponse
from django.http import HttpResponseNotFound
from django.utils.translation import ugettext_lazy as _
from rest_framework import viewsets
Expand Down Expand Up @@ -59,7 +58,7 @@ def get_public_channel_list(request, version):
channel_list = _get_channel_list(version, request.query_params)
except LookupError:
return HttpResponseNotFound(_("Api endpoint {} is not available").format(version))
return HttpResponse(json.dumps(PublicChannelSerializer(channel_list, many=True).data))
return Response(PublicChannelSerializer(channel_list, many=True).data)


@api_view(['GET'])
Expand All @@ -72,7 +71,7 @@ def get_public_channel_lookup(request, version, identifier):
return HttpResponseNotFound(_("Api endpoint {} is not available").format(version))
if not channel_list.exists():
return HttpResponseNotFound(_("No channel matching {} found").format(identifier))
return HttpResponse(json.dumps(PublicChannelSerializer(channel_list, many=True).data))
return Response(PublicChannelSerializer(channel_list, many=True).data)


@api_view(['GET'])
Expand All @@ -82,7 +81,12 @@ def get_channel_name_by_id(request, channel_id):
channel = Channel.objects.filter(pk=channel_id).first()
if not channel:
return HttpResponseNotFound('Channel with id {} not found'.format(channel_id))
return HttpResponse(json.dumps({"name": channel.name, "description": channel.description, "version": channel.version}))
channel_info = {
"name": channel.name,
"description": channel.description,
"version": channel.version
}
return Response(channel_info)


class InfoViewSet(viewsets.ViewSet):
Expand Down

0 comments on commit 67cea67

Please sign in to comment.