# awl.tests.test_utils.py
import sys
import django
from django.test import TestCase

from six import StringIO

from awl.tests.models import Link
from awl.utils import (URLTree, refetch, refetch_for_update, render_page,
    render_page_to_string, get_field_names)
from awl.waelsteng import FakeRequest

# ============================================================================

class UtilsTest(TestCase):
    def test_url_tree(self):
        # print_tree() exercises everything, so run it and capture stdout
        tree = URLTree()

        saved_stdout = sys.stderr
        try:
            out = StringIO()
            sys.stdout = out
            tree.print_tree()

            # check for some of our rankedmodel items in the output
            output = out.getvalue().split('\n')

            # django 2.0 and 1.11 have different URL syntax
            if django.VERSION[0] >= 2:
                self.assertIn('^rankedmodel\\/', output)
                self.assertIn(('^rankedmodel\\/^move/(\d+)/(\d+)/(\d+)/$, ' 
                    'name=awl-rankedmodel-move'), output)
            else: # pragma: no cover
                self.assertIn('^rankedmodel/', output)
                self.assertIn(('^rankedmodel/^move/(\d+)/(\d+)/(\d+)/$, ' 
                    'name=awl-rankedmodel-move'), output)

        finally:
            sys.stdout = saved_stdout

    def test_refetch(self):
        link = Link.objects.create(url='url', text='text')
        link.text = 'foo'

        link = refetch(link)
        self.assertEqual('url', link.url)
        self.assertEqual('text', link.text)

        link.text = 'foo'
        link = refetch_for_update(link)
        self.assertEqual('url', link.url)
        self.assertEqual('text', link.text)

    def test_renders(self):
        request = FakeRequest()
        expected = 'Hello World\n'

        result = render_page_to_string(request, 'sample.html', {'name':'World'})
        self.assertEqual(expected, result)

        response = render_page(request, 'sample.html', {'name':'World'})
        self.assertEqual(expected, response.content.decode('ascii'))

    def test_get_field_names(self):
        from awl.tests.models import Person

        # test defaults, ignore order
        expected = ['name', 'phone']
        result = get_field_names(Person)
        self.assertEqual(set(result), set(expected))

        # test ignore_auto, ignore_relations and exclude
        expected.extend(['id', 'building', 'address', 'courses', 'best_friend',
            'person'])
        expected.remove('phone')
        result = get_field_names(Person, ignore_auto=False,
            ignore_relations=False, exclude=['phone'])
        self.assertEqual(set(result), set(expected))
