import django.test
import django.template.context
from django.template import base as template
from django.test import TestCase
from fack.templatetags import faqtags
from fack.models import Topic


class FAQTagsSyntaxTests(TestCase):
    """
    Tests for the syntax/compliation functions.

    These are broken out here so that they don't have to be
    django.test.TestCases, which are slower.
    """

    def compile(self, tagfunc, token_contents):
        """
        Mock out a call to a template compliation function.

        Assumes the tag doesn't use the parser, so this won't work for block tags.
        """
        try:
            token_block = template.TokenType.BLOCK
        except AttributeError:
            token_block = template.TOKEN_BLOCK
        t = template.Token(token_block, token_contents)
        return tagfunc(None, t)

    def test_faqs_for_topic_compile(self):
        t = self.compile(faqtags.faqs_for_topic, "faqs_for_topic 15 'some-slug' as faqs")
        self.assertEqual(t.num.var, "15")
        self.assertEqual(t.topic.var, "'some-slug'")
        self.assertEqual(t.varname, "faqs")

    def test_faqs_for_topic_too_few_arguments(self):
        self.assertRaises(template.TemplateSyntaxError,
                          self.compile,
                          faqtags.faqs_for_topic,
                          "faqs_for_topic 15 'some-slug' as")

    def test_faqs_for_topic_too_many_arguments(self):
        self.assertRaises(template.TemplateSyntaxError,
                          self.compile,
                          faqtags.faqs_for_topic,
                          "faqs_for_topic 15 'some-slug' as varname foobar")

    def test_faqs_for_topic_bad_as(self):
        self.assertRaises(template.TemplateSyntaxError,
                          self.compile,
                          faqtags.faqs_for_topic,
                          "faqs_for_topic 15 'some-slug' blahblah varname")

    def test_faq_list_compile(self):
        t = self.compile(faqtags.faq_list, "faq_list 15 as faqs")
        self.assertEqual(t.num.var, "15")
        self.assertEqual(t.varname, "faqs")

    def test_faq_list_too_few_arguments(self):
        self.assertRaises(template.TemplateSyntaxError,
                          self.compile,
                          faqtags.faq_list,
                          "faq_list 15")

    def test_faq_list_too_many_arguments(self):
        self.assertRaises(template.TemplateSyntaxError,
                          self.compile,
                          faqtags.faq_list,
                          "faq_list 15 as varname foobar")

    def test_faq_list_bad_as(self):
        self.assertRaises(template.TemplateSyntaxError,
                          self.compile,
                          faqtags.faq_list,
                          "faq_list 15 blahblah varname")


class FAQTagsNodeTests(django.test.TestCase):
    """
    Tests for the node classes themselves, and hence the rendering functions.
    """
    fixtures = ['faq_test_data.json']

    def test_faqs_for_topic_node(self):
        context = django.template.context.Context()
        node = faqtags.FaqListNode(num='5', topic='"silly-questions"', varname="faqs")
        content = node.render(context)
        self.assertEqual(content, "")
        self.assertQuerysetEqual(context['faqs'],
            ['<Question: What is your favorite color?>',
             '<Question: What is your quest?>'])

    def test_faqs_for_topic_node_variable_arguments(self):
        """
        Test faqs_for_topic with a variable arguments.
        """
        context = django.template.context.Context({'topic': Topic.objects.get(pk=1), 'number': 1})
        node = faqtags.FaqListNode(num='number', topic='topic', varname="faqs")
        content = node.render(context)
        self.assertEqual(content, "")
        self.assertQuerysetEqual(context['faqs'], ["<Question: What is your favorite color?>"])

    def test_faqs_for_topic_node_invalid_variables(self):
        context = django.template.context.Context()
        node = faqtags.FaqListNode(num='number', topic='topic', varname="faqs")
        content = node.render(context)
        self.assertEqual(content, "")
        self.assertTrue("faqs" not in context, "faqs variable shouldn't have been added to the context.")

    def test_faq_list_node(self):
        context = django.template.context.Context()
        node = faqtags.FaqListNode(num='5', varname="faqs")
        content = node.render(context)
        self.assertEqual(content, "")
        self.assertQuerysetEqual(context['faqs'],
            ['<Question: What is your favorite color?>',
             '<Question: What is your quest?>',
             '<Question: What is Django-fack?>'])

    def test_faq_list_node_variable_arguments(self):
        """
        Test faqs_for_topic with a variable arguments.
        """
        context = django.template.context.Context({'topic': Topic.objects.get(pk=1), 'number': 1})
        node = faqtags.FaqListNode(num='number', varname="faqs")
        content = node.render(context)
        self.assertEqual(content, "")
        self.assertQuerysetEqual(context['faqs'], ["<Question: What is your favorite color?>"])

    def test_faq_list_node_invalid_variables(self):
        context = django.template.context.Context()
        node = faqtags.FaqListNode(num='number', varname="faqs")
        content = node.render(context)
        self.assertEqual(content, "")
        self.assertTrue("faqs" not in context, "faqs variable shouldn't have been added to the context.")

    def test_faq_topic_list(self):
        context = django.template.context.Context()
        node = faqtags.TopicListNode(varname="topic_list")
        content = node.render(context)
        self.assertEqual(content, "")
        self.assertTrue("topic_list" in context, "topic_list should be in context")
        self.assertEqual(len(context['topic_list']), 2)
