from unittest.mock import patch, ANY

from django.http import QueryDict
from django.test import TestCase
from recuperateur_reseau_viaire.forms import Graph_viaire_ville_informationForm


class form_creation_Graph_viaire_ville_informationTestCase(TestCase):

    def test_creation_form_vide(self):
        """
        Ce teste créé un formulaire de création de Graph_viaire_ville_information vide et ne doit pas être valide
        """
        form = Graph_viaire_ville_informationForm()
        self.assertFalse(form.is_valid())

    @patch('OSM_outils.OMSnx_enregistrement.OMSnx_enregistrement.recuperer_graphe_viaire_ville')
    def test_creation_form_une_ville_non_existante(self, mock_recuperer_graphe_viaire_ville):
        """
        Ce test créé un formulaire de création de Graph_viaire_ville_information avec un nom de ville qui n'existe pas
        """
        entree_form = QueryDict('gvvi_nom=coooooommmmmmuuuuuunnnnnneeeeee')
        form = Graph_viaire_ville_informationForm(entree_form)
        mock_recuperer_graphe_viaire_ville.side_effect = ValueError("erreur : \"" + entree_form.get("gvvi_nom") + "\"")
        self.assertFalse(form.is_valid())
        self.assertTrue("ville non trouvée : " + entree_form.get("gvvi_nom") in form.errors["gvvi_nom"])

    def test_creation_form_une_ville_basic_fichier_existe_deja(self):
        """
        Ce test va voir si une ville avec un nom connu fonctionne. Ici, c'est le nom d'un fichier dans le dossier Data.
        """
        nom_ville = "Saint-Laurent-sur-Saône"
        entree_form = QueryDict('gvvi_nom='+nom_ville)
        form = Graph_viaire_ville_informationForm(entree_form)
        self.assertTrue(form.is_valid())

    @patch('OSM_outils.OMSnx_enregistrement.OMSnx_enregistrement.sauvegarde_graphique')
    @patch('OSM_outils.OMSnx_enregistrement.OMSnx_enregistrement.chemin_vers_fichier_ville')
    def test_creation_form_une_ville_basic(self, mock_chemin_vers_fichier_ville, mock_sauvegarde_graphique):
        """
        Ce test va voir si une ville avec un nom connu fonctionne.
        """
        nom_ville = "Vaudherland"
        mock_chemin_vers_fichier_ville.return_value = "./../Data/Vaudherland.graphml"
        entree_form = QueryDict('gvvi_nom='+nom_ville)
        form = Graph_viaire_ville_informationForm(entree_form)
        self.assertTrue(form.is_valid())
        mock_sauvegarde_graphique.assert_called_once_with(ANY, nom_ville)

    def test_creation_form_plusieurs_villes_une_ville_n_existe_pas(self):
        """
        Ici, on test la création d'une ville composé de plusieurs communes dont l'une des communes n'existe pas.
        """
        nom_ville = "super ville"
        nom_ville_englobees = ["Bolbec", "coooooommmmmmuuuuuunnnnnneeeeee"]
        entree_form = QueryDict("gvvi_nom=" + nom_ville + "&gvvi_nom_ajout=" + nom_ville_englobees[0] + "&gvvi_nom_ajout=" + nom_ville_englobees[1])
        form = Graph_viaire_ville_informationForm(entree_form)
        form.is_valid()
        self.assertTrue("ville non trouvée : " + nom_ville_englobees[1] in form.errors["gvvi_nom"])

    @patch('OSM_outils.OMSnx_enregistrement.OMSnx_enregistrement.sauvegarde_graphique')
    @patch('OSM_outils.OMSnx_enregistrement.OMSnx_enregistrement.recuperer_graphe_viaire_ville')
    def test_creation_form_plusieurs_ville_basic(self, mock_recuperer_graphe_viaire_ville, mock_sauvegarde_graphique):
        """
        Ce test va voir si plusieurs villes avec des noms connus de nominatim fonctionnent.
        """
        nom_fichier = "fusion_commune"
        nom_ville_englobees = ["Bolbec", "Gruchet-le-valasse"]
        mock_recuperer_graphe_viaire_ville.return_value = None
        str_entree_form = 'gvvi_nom=' + nom_fichier
        for nom_ville in nom_ville_englobees:
            str_entree_form = str_entree_form + "&gvvi_nom_ajout=" + nom_ville
        entree_form = QueryDict(str_entree_form)
        form = Graph_viaire_ville_informationForm(entree_form)
        self.assertTrue(form.is_valid())
        mock_sauvegarde_graphique.assert_called_once_with(ANY, nom_fichier)

    def test_creation_form_plusieurs_villes_du_meme_nom(self):
        """
        Cette méthode test s'il est possible d'avoir un ensemble de ville composée de villes du même nom.
        """
        nom_fichier = "fusion_commune"
        nom_ville_englobees = ["Bolbec", "Gruchet-le-valasse", "Bolbec", "Rouen"]
        str_entree_form = 'gvvi_nom=' + nom_fichier
        for nom_ville in nom_ville_englobees:
            str_entree_form = str_entree_form + "&gvvi_nom_ajout="+nom_ville
        entree_form = QueryDict(str_entree_form)
        form = Graph_viaire_ville_informationForm(entree_form)
        self.assertFalse(form.is_valid())
        self.assertEqual("plusieurs villes englobées portent le même nom", form.errors["__all__"][0])