# -*- coding: utf-8 -*- # # Copyright (C) 2017 Branko Majic # # This file is part of Django Conntrackt. # # Django Conntrackt is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # Django Conntrackt is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # details. # # You should have received a copy of the GNU General Public License along with # Django Conntrackt. If not, see . # # Standard library imports. import json from StringIO import StringIO from zipfile import ZipFile, ZIP_DEFLATED # Python third-party library imports. import mock # Django imports. from django.template import Context, Template, TemplateSyntaxError from django.test import TestCase from django.urls import reverse # Application imports from conntrackt.templatetags.conntrackt_tags import html_link, active_link, current_url_equals # Test imports. from .helpers import create_get_request @mock.patch('conntrackt.templatetags.conntrackt_tags.urls.reverse') class HtmlLinkTest(TestCase): def test_url_reverse_called_with_passed_in_args(self, mock_reverse): """ Tests if URL reversing is performed using the correct set of passed-in arguments. """ html_link("My link", "my_view", 'arg1', 'arg2', 'arg3') mock_reverse.assert_called_once_with("my_view", args=('arg1', 'arg2', 'arg3')) def test_url_reverse_called_without_args_if_they_are_not_passed_in(self, mock_reverse): """ Tests if URL reverse is performed without using any positional arguments if they are not specified. """ kwargs = { "id": "myid", "class": "myclass", "title": "mytitle", } html_link("My link", "my_view", **kwargs) mock_reverse.assert_called_once_with("my_view", args=()) def test_html_id_applied_to_output_element(self, mock_reverse): """ Tests if id attribute is filled-in correctly in the HTML tag. """ # Mock a view we want to reverse. mock_reverse.return_value = "/my/url" kwargs = { 'id': "my_id", } link = html_link("My link", "my_view", **kwargs) self.assertIn('id="my_id"', link) def test_html_class_applied_to_output_element(self, mock_reverse): """ Tests if class attribute is filled-in correctly in the HTML tag. """ # Mock a view we want to reverse. mock_reverse.return_value = "/my/url" kwargs = { 'class': "class1,class2,class3", } link = html_link("My link", "my_view", **kwargs) self.assertIn('class="class1,class2,class3"', link) def test_html_title_applied_to_output_element(self, mock_reverse): """ Tests if title attribute is filled-in correctly in the HTML tag. """ # Mock a view we want to reverse. mock_reverse.return_value = "/my/url" kwargs = { 'title': "My title", } link = html_link("My link", "my_view", **kwargs) self.assertIn('title="My title"', link) def test_get_parameter_applied_to_output_element_link(self, mock_reverse): """ Tests if generated URL contains the passed-in get argument. """ # Mock a view we want to reverse. mock_reverse.return_value = "/my/url" kwargs = { 'get': "MyGetParameter", } link = html_link("My link", "my_view", **kwargs) self.assertIn('href="/my/url?MyGetParameter"', link) def test_rendered_output_format(self, mock_reverse): """ Tests if the rendered output format is correct. """ mock_reverse.return_value = "/my/url" link = html_link( "My link", "my_view", **{ "id": "my_id", "class": "my_class", "title": "my_title", "get": "MyGetParameter=20", } ) self.assertEqual(link, 'My link') def test_invalid_passed_in_keyword_argument_raises_exception(self, mock_reverse): """ Tests if passing-in a non-supported keyword argument raises an exception (if parameter validation works correctly). """ with self.assertRaises(TemplateSyntaxError): html_link("My link", "my_view", invalid_keyword="some-value") def test_rendered_output_not_escaped(self, mock_reverse): """ Tests if rendered output is not double-escaped by Django. """ mock_reverse.return_value = "/my/url" template = Template('{% load conntrackt_tags %}{% html_link "My link" "my_view" class="my_class" title="my_title" id="my_id" get="MyGetParameter=20" %}') context = Context() rendered_output = template.render(context) self.assertEqual(rendered_output, 'My link') def test_html_escapes_passed_in_values(self, mock_reverse): """ Tests if values passed-in as keyword arguments are escaped within resulting output. """ mock_reverse.return_value = "/my/url" link = html_link( "My link", "my_view", **{ "id": "my_id", "class": "my_class", "title": "my_title", "get": "MyGetParameter=", } ) self.assertEqual(link, 'My </a> link') class CurrentUrlEqualsTest(TestCase): def get_context_for_view(self, view, *args, **kwargs): """ Returns a Context instance where the request path has been constructed using the passed-in view (or view name), and view positional/keyword arguments. Arguments: view View function or name for request object. args Positional arguments to pass into the view. kwargs Keyword arguments to pass into the view. Returns: django.template.Context instance with request. """ request = create_get_request(reverse(view, args=args, kwargs=kwargs)) context = Context({'request': request}) return context def test_non_matching_url_returns_false(self): request = create_get_request("/this/url/does/not/exist") context = Context({'request': request}) self.assertEqual(current_url_equals(context, 'index'), False) def test_matching_url_returns_true(self): context = self.get_context_for_view('project_create') self.assertEqual(current_url_equals(context, 'project_create'), True) def test_matching_url_with_different_args_returns_false(self): context = self.get_context_for_view('project', 1) self.assertEqual(current_url_equals(context, 'project', 2), False) def test_matching_url_with_different_kwargs_returns_false(self): context = self.get_context_for_view('project', pk=1) self.assertEqual(current_url_equals(context, 'project', pk=2), False) def test_matching_url_with_GET_parameters_returns_true(self): request = create_get_request(reverse('project', kwargs={'pk': 1}) + '?my_get_param=10') context = Context({'request': request}) self.assertEqual(current_url_equals(context, 'project', pk=1), True) class ActiveLinkTest(TestCase): def get_context_for_view(self, view, *args, **kwargs): """ Returns a Context instance where the request path has been constructed using the passed-in view (or view name), and view positional/keyword arguments. Arguments: view View function or name for request object. args Positional arguments to pass into the view. kwargs Keyword arguments to pass into the view. Returns: django.template.Context instance with request. """ request = create_get_request(reverse(view, args=args, kwargs=kwargs)) context = Context({'request': request}) return context def test_empty_string_returned_on_view_without_arguments_and_no_match(self): context = self.get_context_for_view('index') self.assertEqual(active_link(context, 'project_create'), '') def test_default_value_returned_on_view_without_arguments_and_match(self): context = self.get_context_for_view('index') self.assertEqual(active_link(context, 'index'), 'active') def test_empty_string_returned_on_view_with_positional_arguments_and_no_match(self): context = self.get_context_for_view('project', 1) self.assertEqual(active_link(context, 'project', 'active', 2), '') def test_value_returned_on_view_with_positional_arguments_and_match(self): context = self.get_context_for_view('project', 1) self.assertEqual(active_link(context, 'project', 'active', 1), 'active') def test_empty_string_returned_on_view_with_keyword_arguments_and_no_match(self): context = self.get_context_for_view('project', 1) self.assertEqual(active_link(context, 'project', pk=2), '') def test_default_value_returned_on_view_with_keyword_arguments_and_match(self): context = self.get_context_for_view('project', 1) self.assertEqual(active_link(context, 'project', pk=1), 'active') def test_provided_value_returned_on_view_with_matching_url(self): context = self.get_context_for_view('project', 1) self.assertEqual(active_link(context, 'project', 'myvalue', 1), 'myvalue') self.assertEqual(active_link(context, 'project', 'myvalue', pk=1), 'myvalue')