Added unittest for node_url templatetag. Fixed issues uncovered with unittests. Added...
authorStephen Burrows <stephen.r.burrows@gmail.com>
Wed, 20 Oct 2010 21:43:53 +0000 (17:43 -0400)
committerStephen Burrows <stephen.r.burrows@gmail.com>
Wed, 20 Oct 2010 21:45:27 +0000 (17:45 -0400)
fixtures/test_fixtures.json [new file with mode: 0644]
templatetags/nodes.py
tests.py [new file with mode: 0644]

diff --git a/fixtures/test_fixtures.json b/fixtures/test_fixtures.json
new file mode 100644 (file)
index 0000000..18f6962
--- /dev/null
@@ -0,0 +1,219 @@
+[
+    {
+        "pk": 1, 
+        "model": "philo.tag", 
+        "fields": {
+            "name": "Test tag", 
+            "slug": "test-tag"
+        }
+    }, 
+    {
+        "pk": 1, 
+        "model": "philo.node", 
+        "fields": {
+            "view_object_id": 1, 
+            "slug": "never", 
+            "parent": 3, 
+            "view_content_type": [
+                "philo", 
+                "page"
+            ]
+        }
+    }, 
+    {
+        "pk": 2, 
+        "model": "philo.node", 
+        "fields": {
+            "view_object_id": 1, 
+            "slug": "blog", 
+            "parent": 3, 
+            "view_content_type": [
+                "penfield", 
+                "blogview"
+            ]
+        }
+    }, 
+    {
+        "pk": 3, 
+        "model": "philo.node", 
+        "fields": {
+            "view_object_id": 1, 
+            "slug": "root", 
+            "parent": null, 
+            "view_content_type": [
+                "philo", 
+                "redirect"
+            ]
+        }
+    }, 
+    {
+        "pk": 1, 
+        "model": "philo.redirect", 
+        "fields": {
+            "status_code": 302, 
+            "target": "never"
+        }
+    }, 
+    {
+        "pk": 1, 
+        "model": "philo.template", 
+        "fields": {
+            "mimetype": "text/html", 
+            "code": "Never is working!\r\n{% node_url %}", 
+            "name": "Never", 
+            "parent": null, 
+            "documentation": "", 
+            "slug": "never"
+        }
+    }, 
+    {
+        "pk": 2, 
+        "model": "philo.template", 
+        "fields": {
+            "mimetype": "text/html", 
+            "code": "An index page!\r\n{% node_url %}\r\n\r\n{% for entry in entries %}\r\n<h4><a href='{% node_url with entry %}'>{{ entry.title }}</a></h4>\r\n<div class='post content'>\r\n{{ entry.content }}\r\n</div>\r\n{% endfor %}", 
+            "name": "Index", 
+            "parent": null, 
+            "documentation": "", 
+            "slug": "index"
+        }
+    }, 
+    {
+        "pk": 3, 
+        "model": "philo.template", 
+        "fields": {
+            "mimetype": "text/html", 
+            "code": "Entry detail page.", 
+            "name": "Entry", 
+            "parent": null, 
+            "documentation": "", 
+            "slug": "entry"
+        }
+    }, 
+    {
+        "pk": 4, 
+        "model": "philo.template", 
+        "fields": {
+            "mimetype": "text/html", 
+            "code": "Tag page!", 
+            "name": "Tag", 
+            "parent": null, 
+            "documentation": "", 
+            "slug": "tag"
+        }
+    }, 
+    {
+        "pk": 5, 
+        "model": "philo.template", 
+        "fields": {
+            "mimetype": "text/html", 
+            "code": "Entry archive page!", 
+            "name": "Entry Archives!", 
+            "parent": null, 
+            "documentation": "", 
+            "slug": "entry-archives"
+        }
+    }, 
+    {
+        "pk": 6, 
+        "model": "philo.template", 
+        "fields": {
+            "mimetype": "text/html", 
+            "code": "tag archives...", 
+            "name": "Tag Archives", 
+            "parent": null, 
+            "documentation": "", 
+            "slug": "tag-archives"
+        }
+    }, 
+    {
+        "pk": 1, 
+        "model": "philo.page", 
+        "fields": {
+            "template": 1, 
+            "title": "Never"
+        }
+    }, 
+    {
+        "pk": 2, 
+        "model": "philo.page", 
+        "fields": {
+            "template": 2, 
+            "title": "Index"
+        }
+    }, 
+    {
+        "pk": 3, 
+        "model": "philo.page", 
+        "fields": {
+            "template": 3, 
+            "title": "Entry"
+        }
+    }, 
+    {
+        "pk": 4, 
+        "model": "philo.page", 
+        "fields": {
+            "template": 4, 
+            "title": "Tag"
+        }
+    }, 
+    {
+        "pk": 5, 
+        "model": "philo.page", 
+        "fields": {
+            "template": 5, 
+            "title": "Entry Archive"
+        }
+    }, 
+    {
+        "pk": 6, 
+        "model": "philo.page", 
+        "fields": {
+            "template": 6, 
+            "title": "Tag Archive Page"
+        }
+    }, 
+    {
+        "pk": 1, 
+        "model": "penfield.blog", 
+        "fields": {
+            "slug": "free-lovin", 
+            "title": "Free lovin'"
+        }
+    }, 
+    {
+        "pk": 1, 
+        "model": "penfield.blogentry", 
+        "fields": {
+            "content": "Lorem ipsum.\r\n\r\nDolor sit amet.", 
+            "author": 1, 
+            "title": "First Entry", 
+            "excerpt": "", 
+            "blog": 1, 
+            "date": "2010-10-20 10:38:58", 
+            "slug": "first-entry", 
+            "tags": [
+                1
+            ]
+        }
+    }, 
+    {
+        "pk": 1, 
+        "model": "penfield.blogview", 
+        "fields": {
+            "entry_archive_page": 5, 
+            "tag_page": 4, 
+            "feed_suffix": "feed", 
+            "entry_permalink_style": "D", 
+            "tag_permalink_base": "tags", 
+            "feeds_enabled": true, 
+            "entries_per_page": null, 
+            "tag_archive_page": 6, 
+            "blog": 1, 
+            "entry_permalink_base": "entries", 
+            "index_page": 2, 
+            "entry_page": 3
+        }
+    }
+]
index 6cee439..8a98630 100644 (file)
@@ -3,6 +3,7 @@ from django.conf import settings
 from django.contrib.sites.models import Site
 from django.core.urlresolvers import reverse, NoReverseMatch
 from django.template.defaulttags import kwarg_re
+from django.utils.encoding import smart_str
 from philo.exceptions import ViewCanNotProvideSubpath
 
 
@@ -26,32 +27,36 @@ class NodeURLNode(template.Node):
                else:
                        node = context['node']
                
-               if self.with_obj is not None:
-                       try:
-                               view_name, args, kwargs = node.view.get_reverse_params(self.with_obj.resolve(context))
-                       except ViewCanNotProvideSubpath:
-                               return settings.TEMPLATE_STRING_IF_INVALID
-               elif self.view_name is not None:
-                       view_name = self.view_name
-                       args = [arg.resolve(context) for arg in self.args]
-                       kwargs = dict([(smart_str(k, 'ascii'), v.resolve(context)) for k, v in self.kwargs.items()])
-               else:
-                       return node.get_absolute_url()
-               
-               if not node.view.accepts_subpath:
+               if not node:
                        return settings.TEMPLATE_STRING_IF_INVALID
                
-               url = ''
-               try:
-                       subpath = reverse(view_name, urlconf=node.view, args=args, kwargs=kwargs)
-               except NoReverseMatch:
-                       if self.as_var is None:
-                               raise
+               if self.with_obj is None and self.view_name is None:
+                       url = node.get_absolute_url()
                else:
-                       if subpath[0] == '/':
-                               subpath = subpath[1:]
+                       if not node.view.accepts_subpath:
+                               return settings.TEMPLATE_STRING_IF_INVALID
+                       
+                       if self.with_obj is not None:
+                               try:
+                                       view_name, args, kwargs = node.view.get_reverse_params(self.with_obj.resolve(context))
+                               except ViewCanNotProvideSubpath:
+                                       return settings.TEMPLATE_STRING_IF_INVALID
+                       else: # self.view_name is not None
+                               view_name = self.view_name
+                               args = [arg.resolve(context) for arg in self.args]
+                               kwargs = dict([(smart_str(k, 'ascii'), v.resolve(context)) for k, v in self.kwargs.items()])
                        
-                       url = node.get_absolute_url() + subpath
+                       url = ''
+                       try:
+                               subpath = reverse(view_name, urlconf=node.view, args=args, kwargs=kwargs)
+                       except NoReverseMatch:
+                               if self.as_var is None:
+                                       raise
+                       else:
+                               if subpath[0] == '/':
+                                       subpath = subpath[1:]
+                               
+                               url = node.get_absolute_url() + subpath
                
                if self.as_var:
                        context[self.as_var] = url
diff --git a/tests.py b/tests.py
new file mode 100644 (file)
index 0000000..d9f743f
--- /dev/null
+++ b/tests.py
@@ -0,0 +1,74 @@
+from django.test import TestCase
+from django import template
+from django.conf import settings
+from philo.models import Node, Page, Template
+from philo.contrib.penfield.models import Blog, BlogView, BlogEntry
+
+
+class NodeURLTestCase(TestCase):
+       """Tests the features of the node_url template tag."""
+       urls = 'philo.urls'
+       fixtures = ['test_fixtures.json']
+       
+       def setUp(self):
+               if 'south' in settings.INSTALLED_APPS:
+                       from south.management.commands.migrate import Command
+                       command = Command()
+                       command.handle(all_apps=True)
+               
+               self.templates = [template.Template(string) for string in
+                       [
+                               "{% node_url %}", # 0
+                               "{% node_url for node2 %}", # 1
+                               "{% node_url as hello %}<p>{{ hello|slice:'1:' }}</p>", # 2
+                               "{% node_url for nodes|first %}", # 3
+                               "{% node_url with entry %}", # 4
+                               "{% node_url with entry for node2 %}", # 5
+                               "{% node_url with tag for node2 %}", # 6
+                               "{% node_url with date for node2 %}", # 7
+                               "{% node_url entries_by_day year=date|date:'Y' month=date|date:'m' day=date|date:'d' for node2 as goodbye %}<em>{{ goodbye|upper }}</em>", # 8
+                               "{% node_url entries_by_month year=date|date:'Y' month=date|date:'m' for node2 %}", # 9
+                               "{% node_url entries_by_year year=date|date:'Y' for node2 %}", # 10
+                       ]
+               ]
+               
+               nodes = Node.objects.all()
+               blog = Blog.objects.all()[0]
+               
+               self.context = template.Context({
+                       'node': nodes[0],
+                       'node2': nodes[1],
+                       'nodes': nodes,
+                       'entry': BlogEntry.objects.all()[0],
+                       'tag': blog.entry_tags.all()[0],
+                       'date': blog.entry_dates['day'][0]
+               })
+       
+       def test_nodeurl(self):
+               for i, template in enumerate(self.templates):
+                       t = template.render(self.context)
+                       
+                       if i == 0:
+                               self.assertEqual(t, "/root/never/")
+                       elif i == 1:
+                               self.assertEqual(t, "/root/blog/")
+                       elif i == 2:
+                               self.assertEqual(t, "<p>root/never/</p>")
+                       elif i == 3:
+                               self.assertEqual(t, "/root/never/")
+                       elif i == 4:
+                               self.assertEqual(t, settings.TEMPLATE_STRING_IF_INVALID)
+                       elif i == 5:
+                               self.assertEqual(t, "/root/blog/2010/10/20/first-entry")
+                       elif i == 6:
+                               self.assertEqual(t, "/root/blog/tags/test-tag/")
+                       elif i == 7:
+                               self.assertEqual(t, "/root/blog/2010/10/20")
+                       elif i == 8:
+                               self.assertEqual(t, "<em>/ROOT/BLOG/2010/10/20</em>")
+                       elif i == 9:
+                               self.assertEqual(t, "/root/blog/2010/10")
+                       elif i == 10:
+                               self.assertEqual(t, "/root/blog/2010/")
+                       else:
+                               print "Rendered as:\n%s\n\n" % t
\ No newline at end of file