#!/usr/bin/env python3
#
# Copyright (c) 2019 Miklos Vajna and contributors.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""The test_webframe module covers the webframe module."""

from typing import List
from typing import TYPE_CHECKING
from typing import Tuple
from typing import cast
import configparser
import datetime
import os
import unittest
import unittest.mock
import time

# pylint: disable=unused-import
import yattag

import webframe

if TYPE_CHECKING:
    # pylint: disable=no-name-in-module,import-error,unused-import
    from wsgiref.types import StartResponse  # noqa: F401


class TestHandleStatic(unittest.TestCase):
    """Tests handle_static()."""
    def test_happy(self) -> None:
        """Tests the happy path: css case."""
        content, content_type = webframe.handle_static("/osm/static/osm.css")
        self.assertTrue(len(content))
        self.assertEqual(content_type, "text/css")

    def test_javascript(self) -> None:
        """Tests the javascript case."""
        content, content_type = webframe.handle_static("/osm/static/sorttable.js")
        self.assertTrue(len(content))
        self.assertEqual(content_type, "application/x-javascript")

    def test_else(self) -> None:
        """Tests the case when the content type is not recognized."""
        content, content_type = webframe.handle_static("/osm/static/test.xyz")
        self.assertFalse(len(content))
        self.assertFalse(len(content_type))


class TestHandleException(unittest.TestCase):
    """Tests handle_exception()."""
    def test_happy(self) -> None:
        """Tests the happy path."""
        environ = {
            "PATH_INFO": "/"
        }

        def start_response(status: str, response_headers: List[Tuple[str, str]]) -> None:
            self.assertTrue(status.startswith("500"))
            header_dict = dict(response_headers)
            self.assertEqual(header_dict["Content-type"], "text/html; charset=utf-8")

        try:
            int("a")
        # pylint: disable=broad-except
        except Exception:
            callback = cast('StartResponse', start_response)
            output_iterable = webframe.handle_exception(environ, callback)
            output_list = cast(List[bytes], output_iterable)
            self.assertTrue(output_list)
            output = output_list[0].decode('utf-8')
            self.assertIn("ValueError", output)
            return
        self.fail()


class TestLocalToUiTz(unittest.TestCase):
    """Tests local_to_ui_tz()."""
    def test_happy(self) -> None:
        """Tests the happy path."""
        def get_abspath(path: str) -> str:
            if os.path.isabs(path):
                return path
            return os.path.join(os.path.dirname(__file__), path)

        def get_config() -> configparser.ConfigParser:
            config = configparser.ConfigParser()
            config.read_dict({"wsgi": {"timezone": "Europe/Budapest"}})
            return config

        with unittest.mock.patch('util.get_abspath', get_abspath):
            with unittest.mock.patch('webframe.get_config', get_config):
                local_dt = datetime.datetime.fromtimestamp(0)
                ui_dt = webframe.local_to_ui_tz(local_dt)
                if time.strftime('%Z%z') == "CET+0100":
                    self.assertEqual(ui_dt.timestamp(), 0)


class TestFillMissingHeaderItems(unittest.TestCase):
    """Tests fill_missing_header_items()."""
    def test_happy(self) -> None:
        """Tests the happy path."""
        streets = "no"
        relation_name = "gazdagret"
        items: List[yattag.doc.Doc] = []
        webframe.fill_missing_header_items(streets, relation_name, items)
        html = items[0].getvalue()
        self.assertIn("Missing house numbers", html)
        self.assertNotIn("Missing streets", html)


if __name__ == '__main__':
    unittest.main()

[((114, 4, 114, 19), 'unittest.main', 'unittest.main', ({}, {}), '()', False, 'import unittest\n'), ((34, 32, 34, 77), 'webframe.handle_static', 'webframe.handle_static', ({(34, 55, 34, 76): '"""/osm/static/osm.css"""'}, {}), "('/osm/static/osm.css')", False, 'import webframe\n'), ((40, 32, 40, 82), 'webframe.handle_static', 'webframe.handle_static', ({(40, 55, 40, 81): '"""/osm/static/sorttable.js"""'}, {}), "('/osm/static/sorttable.js')", False, 'import webframe\n'), ((46, 32, 46, 78), 'webframe.handle_static', 'webframe.handle_static', ({(46, 55, 46, 77): '"""/osm/static/test.xyz"""'}, {}), "('/osm/static/test.xyz')", False, 'import webframe\n'), ((107, 8, 107, 73), 'webframe.fill_missing_header_items', 'webframe.fill_missing_header_items', ({(107, 43, 107, 50): 'streets', (107, 52, 107, 65): 'relation_name', (107, 67, 107, 72): 'items'}, {}), '(streets, relation_name, items)', False, 'import webframe\n'), ((83, 15, 83, 34), 'os.path.isabs', 'os.path.isabs', ({(83, 29, 83, 33): 'path'}, {}), '(path)', False, 'import os\n'), ((88, 21, 88, 48), 'configparser.ConfigParser', 'configparser.ConfigParser', ({}, {}), '()', False, 'import configparser\n'), ((92, 13, 92, 65), 'unittest.mock.patch', 'unittest.mock.patch', ({(92, 33, 92, 51): '"""util.get_abspath"""', (92, 53, 92, 64): 'get_abspath'}, {}), "('util.get_abspath', get_abspath)", False, 'import unittest\n'), ((68, 23, 68, 60), 'typing.cast', 'cast', ({(68, 28, 68, 43): '"""StartResponse"""', (68, 45, 68, 59): 'start_response'}, {}), "('StartResponse', start_response)", False, 'from typing import cast\n'), ((69, 30, 69, 74), 'webframe.handle_exception', 'webframe.handle_exception', ({(69, 56, 69, 63): 'environ', (69, 65, 69, 73): 'callback'}, {}), '(environ, callback)', False, 'import webframe\n'), ((70, 26, 70, 60), 'typing.cast', 'cast', ({(70, 31, 70, 42): 'List[bytes]', (70, 44, 70, 59): 'output_iterable'}, {}), '(List[bytes], output_iterable)', False, 'from typing import cast\n'), ((85, 32, 85, 57), 'os.path.dirname', 'os.path.dirname', ({(85, 48, 85, 56): '__file__'}, {}), '(__file__)', False, 'import os\n'), ((93, 17, 93, 71), 'unittest.mock.patch', 'unittest.mock.patch', ({(93, 37, 93, 58): '"""webframe.get_config"""', (93, 60, 93, 70): 'get_config'}, {}), "('webframe.get_config', get_config)", False, 'import unittest\n'), ((94, 27, 94, 61), 'datetime.datetime.fromtimestamp', 'datetime.datetime.fromtimestamp', ({(94, 59, 94, 60): '0'}, {}), '(0)', False, 'import datetime\n'), ((95, 24, 95, 57), 'webframe.local_to_ui_tz', 'webframe.local_to_ui_tz', ({(95, 48, 95, 56): 'local_dt'}, {}), '(local_dt)', False, 'import webframe\n'), ((96, 19, 96, 40), 'time.strftime', 'time.strftime', ({(96, 33, 96, 39): '"""%Z%z"""'}, {}), "('%Z%z')", False, 'import time\n')]