#!/usr/bin/env python3
# -*- coding: utf-8 -*-

###################
#    This file test the WebScript.py file
#    from the command line and display the result in a web interface.
#    Copyright (C) 2021  Maurice Lambert

#    This program 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.

#    This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
###################

"""This file test the WebScripts.py file"""

from unittest import TestCase, main
from types import MethodType
from typing import List
from json import load
from os import path
import sys

sys.path = [path.join(path.dirname(__file__), ".."), *sys.path]
sys.path.append(path.join(path.dirname(__file__), ".."))

from WebScripts.utils import DefaultNamespace, get_ip, get_file_content, get_real_path, get_encodings, get_ini_dict, MissingAttributesError, WebScriptsConfigurationError

class TestDefaultNamespace(TestCase):

	def setUp(self):
		self.default_namespace = DefaultNamespace()

	def test_update(self):
		self.default_namespace.update(test="test")

		self.assertEqual(
			getattr(self.default_namespace, "test", None),
			"test"
		)

		self.default_namespace.update(test="test1")

		self.assertEqual(
			getattr(self.default_namespace, "test", None),
			"test1"
		)

	def test_check_required(self):
		self.default_namespace.__required__ = ["test"]
		self.default_namespace.test = None

		with self.assertRaises(MissingAttributesError):
			self.default_namespace.check_required()

		del self.default_namespace.test

		with self.assertRaises(MissingAttributesError):
			self.default_namespace.check_required()

		self.default_namespace.test = "test"
		self.default_namespace.check_required()

	def test_get_missings(self):
		self.default_namespace.__required__ = ["test"]
		
		self.default_namespace.test = None
		self.assertListEqual(
			self.default_namespace.get_missings(),
			["test"],
		)

		del self.default_namespace.test
		self.assertListEqual(
			self.default_namespace.get_missings(),
			["test"],
		)

		self.default_namespace.test = "test"
		self.assertListEqual(
			self.default_namespace.get_missings(),
			[],
		)

	def test_get_unexpecteds(self):
		self.default_namespace.__required__ = []
		self.default_namespace.__optional__ = []

		self.default_namespace.test = "test"

		self.assertListEqual(
			self.default_namespace.get_unexpecteds(),
			["test"],
		)

	def test_get_dict(self):
		self.default_namespace.method = MethodType(print, self.default_namespace)
		self.default_namespace.__required__ = ["test"]
		self.default_namespace.test = "test"

		self.assertDictEqual(
			self.default_namespace.get_dict(),
			{"test": "test"},
		)

	def test_export_as_json(self):
		self.default_namespace.test = "test"
		self.default_namespace.export_as_json()

		self.assertTrue(path.exists("export_DefaultNamespace.json"))
		
		with open("export_DefaultNamespace.json") as file:
			self.assertDictEqual(load(file), {"test": "test"})

		self.default_namespace.export_as_json("test.json")

		self.assertTrue(path.exists("test.json"))
		
		with open("test.json") as file:
			self.assertDictEqual(load(file), {"test": "test"})

	def test_build_types(self):
		self.default_namespace.five_ = 5
		self.default_namespace.five = "5"
		self.default_namespace.null = None
		self.default_namespace.true_ = True
		self.default_namespace.true = "true"
		self.default_namespace.false_ = False
		self.default_namespace.false = "false"

		self.default_namespace.list = "a,b,c,d"
		self.default_namespace.listStr = "a,b,c,d"
		self.default_namespace.listInt = "1,2,3,4"

		self.default_namespace.__types__ = {
			"int": int,
			"five": int,
			"five_": int,
			"list": list,
			"bool": bool,
			"true": bool,
			"true_": bool,
			"false": bool,
			"false_": bool,
			"listStr": List[str],
			"listInt": List[int],
			"listError": List[int],
		}

		self.default_namespace.build_types()

		self.assertTrue(self.default_namespace.true)
		self.assertTrue(self.default_namespace.true_)
		self.assertIsNone(self.default_namespace.null)
		self.assertFalse(self.default_namespace.false)
		self.assertFalse(self.default_namespace.false_)
		self.assertEqual(self.default_namespace.five, 5)
		self.assertEqual(self.default_namespace.five_, 5)

		self.default_namespace.int = "error"
		with self.assertRaises(WebScriptsConfigurationError):
			self.default_namespace.build_types()

		self.default_namespace.bool = "error"
		with self.assertRaises(WebScriptsConfigurationError):
			self.default_namespace.build_types()

		self.default_namespace.listError = "1,2,3,d"
		with self.assertRaises(WebScriptsConfigurationError):
			self.default_namespace.build_types()

	def test_set_default(self):
		self.default_namespace.__defaults__ = {
			"test": "value",
			"test1": "value",
		}

		self.default_namespace.test = "test"
		self.default_namespace.set_defaults()

		self.assertEqual(self.default_namespace.test, "test")
		self.assertEqual(self.default_namespace.test1, "value")

	def test_get(self):
		self.default_namespace.test = "test"
		self.assertEqual(
			self.default_namespace.get("test", "value"),
			"test",
		)

		self.assertEqual(
			self.default_namespace.get("test2", "value"),
			"value",
		)

	def test_getitem(self):
		self.default_namespace.test = "test"
		self.assertEqual(
			self.default_namespace["test"],
			"test",
		)

if __name__ == '__main__':
    main()