Commits

Stefan Scherfke committed 5b6a4b3

Added tests for the chart type classes.

Comments (0)

Files changed (5)

lastfm/tests.py

-# encoding: utf-8
-
-"""
-Tests for the last.fm app.
-
-"""
-
-
-from django.test import TestCase
-import mock
-
-from lastfm.templatetags import lastfm_widget
-
-
-class TemplateTagsTestCase(TestCase):
-    """Test the template tag for the last.fm widget."""
-
-    def setUp(self):
-        self.parser = mock.Mock(spec=['compile_filter'])
-        self.token = mock.Mock(spec=['split_contents'])
-
-    def test_get_sidebar_widgets(self):
-        """
-        Test if ``lastfm_widget.get_lastfm_widget()`` returns a node with the
-        correct variable name.
-
-        """
-        tag = 'get_lastfm_widget'
-        var_name = 'widgets'
-        self.token.split_contents.return_value = (tag, 'as', var_name)
-
-        node = lastfm_widget.get_lastfm_widget(self.parser, self.token)
-        self.assertEqual(node.var_name, var_name)
-
-    @mock.patch('django.template.loader.get_template')
-    @mock.patch('django.template.Context')
-    def test_lastfm_widget_node(self, get_template, Context):
-        """
-        Test if the template node contains the correct template variables.
-
-        """
-        class ContextMock(dict):
-            autoescape = object()
-        context = ContextMock()
-        # template = get_template.return_value
-
-        var_name = 'widgets'
-        node = lastfm_widget.LastfmWidgetNode(var_name)
-        node.render(context)
-
-        self.assertTrue(var_name in context)
-        widget = context[var_name]
-        self.assertTrue('title' in widget)
-        self.assertTrue('content' in widget)

lastfm/tests/__init__.py

+from lastfm.tests.templatetags import *  # NOQA
+from lastfm.tests.views import *  # NOQA

lastfm/tests/templatetags.py

+# encoding: utf-8
+
+"""
+Tests for the last.fm app.
+
+"""
+
+
+from django.test import TestCase
+import mock
+
+from lastfm.templatetags import lastfm_widget
+
+
+class TemplateTagsTestCase(TestCase):
+    """Test the template tag for the last.fm widget."""
+
+    def setUp(self):
+        self.parser = mock.Mock(spec=['compile_filter'])
+        self.token = mock.Mock(spec=['split_contents'])
+
+    def test_get_sidebar_widgets(self):
+        """
+        Test if ``lastfm_widget.get_lastfm_widget()`` returns a node with the
+        correct variable name.
+
+        """
+        tag = 'get_lastfm_widget'
+        var_name = 'widgets'
+        self.token.split_contents.return_value = (tag, 'as', var_name)
+
+        node = lastfm_widget.get_lastfm_widget(self.parser, self.token)
+        self.assertEqual(node.var_name, var_name)
+
+    @mock.patch('django.template.loader.get_template')
+    @mock.patch('django.template.Context')
+    def test_lastfm_widget_node(self, get_template, Context):
+        """
+        Test if the template node contains the correct template variables.
+
+        """
+        class ContextMock(dict):
+            autoescape = object()
+        context = ContextMock()
+        # template = get_template.return_value
+
+        var_name = 'widgets'
+        node = lastfm_widget.LastfmWidgetNode(var_name)
+        node.render(context)
+
+        self.assertTrue(var_name in context)
+        widget = context[var_name]
+        self.assertTrue('title' in widget)
+        self.assertTrue('content' in widget)

lastfm/tests/views.py

+from urllib import urlopen
+
+from django.test import TestCase
+import mock
+
+from lastfm import views
+
+
+class WeeklyTopArtistsTest(TestCase):
+
+    def setUp(self):
+        self.charts = views.WeeklyTopArtists()
+        self.test_data = {
+            'weeklyartistchart': {
+                'artist': [
+                    {'name': 'Test', 'playcount': '23'},
+                ],
+            },
+        }
+
+    def test_get_data(self):
+        ret = self.charts.get_data(self.test_data)
+        self.assertEqual(ret, self.test_data['weeklyartistchart']['artist'])
+
+    def test_get_item_title(self):
+        item = self.test_data['weeklyartistchart']['artist'][0]
+        ret = self.charts.get_item_title(item)
+        self.assertEqual(ret, '%s (%s plays)' %
+                (item['name'], item['playcount']))
+
+    def test_get_default_image(self):
+        ret = self.charts.get_default_image()
+        self.assertEqual(urlopen(ret).code, 200)
+
+    @mock.patch('urllib.urlopen')
+    def test_get_img_url(self, urlopen):
+        from StringIO import StringIO
+
+        item = self.test_data['weeklyartistchart']['artist'][0]
+
+        # normal case
+        json = ('{"images":{"image":{"sizes":{"size":[{"#text":'
+                '"original_url","name":"original"},{"#text":"large_url",'
+                '"name":"large"}]}}}}')
+        urlopen.return_value = StringIO(json)
+        ret = self.charts.get_img_url('large', item)
+        self.assertTrue(urlopen.called)
+        self.assertEqual(ret, 'large_url')
+
+        # 'large' not in list
+        json = ('{"images":{"image":{"sizes":{"size":[{"#text":'
+                '"original_url","name":"original"}]}}}}')
+        urlopen.return_value = StringIO(json)
+        ret = self.charts.get_img_url('large', item)
+        self.assertTrue(urlopen.called)
+        self.assertEqual(ret, 'original_url')
+
+        # 'large' not in list
+        json = '{"images":{"image":{"sizes":{"size":[]}}}}'
+        urlopen.return_value = StringIO(json)
+        ret = self.charts.get_img_url('large', item)
+        self.assertTrue(urlopen.called)
+        self.assertEqual(ret, '')
+
+        # Empty response from last.fm
+        urlopen.return_value = StringIO('')
+        ret = self.charts.get_img_url('large', item)
+        self.assertTrue(urlopen.called)
+        self.assertEqual(ret, '')
+
+
+class TopArtistsTest(TestCase):
+
+    def setUp(self):
+        self.charts = views.TopArtists()
+        self.test_data = {
+            'topartists': {
+                'artist': [
+                    {'name': 'Test', 'playcount': '23'},
+                ],
+            },
+        }
+
+    def test_get_data(self):
+        ret = self.charts.get_data(self.test_data)
+        self.assertEqual(ret, self.test_data['topartists']['artist'])
+
+    def test_get_item_title(self):
+        item = self.test_data['topartists']['artist'][0]
+        ret = self.charts.get_item_title(item)
+        self.assertEqual(ret, '%s (%s plays)' %
+                (item['name'], item['playcount']))
+
+    def test_get_default_image(self):
+        ret = self.charts.get_default_image()
+        self.assertEqual(urlopen(ret).code, 200)
 # encoding: utf-8
-
 """
 The AJAX code generate by the template tag (see
 :mod:`lastfm.templatetags.lastfm_widget`) doesn’t contact Last.fm directly,
 tracks or top artists).
 
 """
-
 import urllib
 
 from django.conf import settings
 LASTFM_IMG_SIZE = getattr(settings, 'LASTFM_IMG_SIZE', 'large')
 
 
-# TODO: move caching to url-conf
 @cache_page(60 * 5)
 def lastfm_data(request):
     """
             raise IOError('No artists found.')
         elif type(data) == dict:
             data = [data]
-    except IOError:
+    except (IOError, ValueError):
         return HttpResponse(json.dumps([]), mimetype='application/json')
 
     items = []
         try:
             img_data = json.loads(urllib.urlopen(
                     URL + params).read())['images']
-        except IOError:
+        except (IOError, ValueError):
             return ''
+
+        fallback = ''
         if 'image' in img_data:
             img_data = img_data['image']['sizes']['size']
             for img in img_data:
+                fallback = img['#text']
                 if img['name'] == img_size and img['#text']:
                     return img['#text']
+        return fallback
 
 
 class TopArtists(object):