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

import unittest
from unittest.mock import Mock
from protocole_json import ProtocoleJson
from clientManager import ClientManager
from prompt import Prompt
from messages import Messages
from mock_print_answer import MockPrintAnswer


#Rapport: ceci teste la communication client-serveur lorsque la connection est en Json


class XmlTest(unittest.TestCase):

    mock_connexion = Mock
    mock_file_system = Mock
    mock_input = Mock
    protocol = ProtocoleJson
    client = ClientManager
    prompt = Prompt
    mock_print = MockPrintAnswer

    server_root = '/dropbox'

    def setUp(self):
        self.mock_connexion = Mock()
        self.mock_file_system = Mock()
        self.mock_input = Mock()
        self.protocol = ProtocoleJson(self.server_root)
        self.client = ClientManager(self.mock_connexion, self.protocol, self.mock_file_system)
        self.prompt = Prompt(self.client)
        self.prompt.input_command = self.mock_input
        self.mock_print = MockPrintAnswer()
        self.prompt.print_answer = self.mock_print.print_answer

    def testServerConnection_ServerIsConnected_ReturnYes(self):
        self.mock_input.side_effect = ["connecter?", "quitter"]
        self.mock_connexion.receive.side_effect = ["{ \"salutation\": \"bonjourClient\" }",
                                                   "{ \"reponse\": \"bye\" }"]

        self.prompt.start()

        expected_answer = Messages.YES
        self.assertTrue(expected_answer in self.mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testGetServerName_ReturnServerName(self):
        self.mock_input.side_effect = ["nomServeur?", "quitter"]
        server_name = "Ubuntu Dropbox 2.0"
        server_answer = "{ \"nomServeur\": \"" + server_name + "\" }"
        self.mock_connexion.receive.side_effect = [server_answer, "{ \"reponse\": \"bye\" }"]

        self.prompt.start()

        expected_answer = server_name
        self.assertTrue(expected_answer in self.mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testGetFolderList_NoErrors_ReturnFolderList(self):
        self.mock_input.side_effect = ["listeDossier? d1", "quitter"]
        server_answer = "{\"listeDossiers\": {" \
                        "\"dossier\": [" \
                        "\"d2\"," \
                        "\"d3\"," \
                        "\"d4\"]}}"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]

        self.prompt.start()

        expected_answer = ["d2", "d3", "d4"]
        self.assertTrue(expected_answer in self.mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testGetFolderList_InexistantFolder_ReturnInexistantFolder(self):
        self.mock_input.side_effect = ["listeDossier? d1", "quitter"]
        server_answer = "{ \"reponse\": \"erreurDossierInexistant\" }"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]
        prompt = Prompt(self.client)
        prompt.input_command = self.mock_input
        mock_print = MockPrintAnswer()
        prompt.print_answer = mock_print.print_answer

        prompt.start()

        expected_answer = Messages.FOLDER_NOT_FOUND
        self.assertTrue(expected_answer in mock_print.printed_answers)

    def testGetFolderList_CouldNotReadFolder_ReturnCouldNotReadFolder(self):
        self.mock_input.side_effect = ["listeDossier? d1", "quitter"]
        server_answer = "{ \"reponse\": \"erreurDossierLecture\" }"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]
        prompt = Prompt(self.client)
        prompt.input_command = self.mock_input
        mock_print = MockPrintAnswer()
        prompt.print_answer = mock_print.print_answer

        prompt.start()

        expected_answer = Messages.UNABLE_TO_READ_FOLDER
        self.assertTrue(expected_answer in mock_print.printed_answers)

    def testFolderExists_FolderExists_ReturnYes(self):
        self.mock_input.side_effect = ["dossier? d1", "quitter"]
        server_answer = "{\"listeDossiers\": {" \
                        "\"dossier\": [" \
                        "\"d2\"," \
                        "\"d3\"," \
                        "\"d4\"]}}"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]

        self.prompt.start()

        expected_answer = Messages.YES
        self.assertTrue(expected_answer in self.mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testFolderExists_FolderDoesntExist_ReturnNo(self):
        self.mock_input.side_effect = ["dossier? d1", "quitter"]
        server_answer = "{ \"reponse\": \"erreurDossierInexistant\" }"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]

        self.prompt.start()

        expected_answer = Messages.NO
        self.assertTrue(expected_answer in self.mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testCreateFolder_NoErrors_ReturnYes(self):
        self.mock_input.side_effect = ["creerDossier? d1", "quitter"]
        server_answer = "{ \"reponse\": \"ok\" }"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]

        self.prompt.start()

        expected_answer = Messages.YES
        self.assertTrue(expected_answer in self.mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testCreateFolder_FolderAlreadyExists_ReturnFolderAlreadyExists(self):
        self.mock_input.side_effect = ["creerDossier? d1", "quitter"]
        server_answer = "{ \"reponse\": \"erreurDossierExiste\" }"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]

        self.prompt.start()

        expected_answer = Messages.FOLDER_EXISTS
        self.assertTrue(expected_answer in self.mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testCreateFolder_FolderNotFound_ReturnFolderNotFound(self):
        self.mock_input.side_effect = ["creerDossier? d1", "quitter"]
        server_answer = "{ \"reponse\": \"erreurDossierInexistant\" }"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]

        self.prompt.start()

        expected_answer = Messages.FOLDER_NOT_FOUND
        self.assertTrue(expected_answer in self.mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testUpload_NoErrors_ReturnOk(self):
        self.mock_input.side_effect = ["televerser? d1/fichier1", "quitter"]
        server_answer = "{ \"reponse\": \"ok\" }"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]
        self.mock_file_system.get_md5_signature.return_value = "6aba532a54c9eb9aa30496fa7f22734d"
        self.mock_file_system.get_encoded_content.return_value = "c2FsdXQK"
        self.mock_file_system.get_file_modification_date.return_value = "1492380743.7447577"
        mock_print = MockPrintAnswer()
        self.prompt.print_answer = mock_print.print_answer

        self.prompt.start()

        expected_answer = Messages.OK
        self.assertTrue(expected_answer in mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testUpload_FileAlreadyExists_ReturnFileAlreadyExists(self):
        self.mock_input.side_effect = ["televerser? d1/fichier1", "quitter"]
        server_answer = "{ \"reponse\": \"erreurFichierExiste\" }"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]
        self.mock_file_system.get_md5_signature.return_value = "6aba532a54c9eb9aa30496fa7f22734d"
        self.mock_file_system.get_encoded_content.return_value = "c2FsdXQK"
        self.mock_file_system.get_file_modification_date.return_value = "1492380743.7447577"
        mock_print = MockPrintAnswer()
        self.prompt.print_answer = mock_print.print_answer

        self.prompt.start()

        expected_answer = Messages.FILE_EXISTS
        self.assertTrue(expected_answer in mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testUpload_FolderDoesntExist_ReturnFolderDoesntExist(self):
        self.mock_input.side_effect = ["televerser? d1/fichier1", "quitter"]
        server_answer = "{ \"reponse\": \"erreurDossierInexistant\" }"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]
        self.mock_file_system.get_md5_signature.return_value = "6aba532a54c9eb9aa30496fa7f22734d"
        self.mock_file_system.get_encoded_content.return_value = "c2FsdXQK"
        self.mock_file_system.get_file_modification_date.return_value = "1492380743.7447577"
        mock_print = MockPrintAnswer()
        self.prompt.print_answer = mock_print.print_answer

        self.prompt.start()

        expected_answer = Messages.FOLDER_NOT_FOUND
        self.assertTrue(expected_answer in mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testUpload_SignatureError_ReturnSignatureError(self):
        self.mock_input.side_effect = ["televerser? d1/fichier1", "quitter"]
        server_answer = "{ \"reponse\": \"erreurSignature\" }"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]
        self.mock_file_system.get_md5_signature.return_value = "mauvaise signature"
        self.mock_file_system.get_encoded_content.return_value = "c2FsdXQK"
        self.mock_file_system.get_file_modification_date.return_value = "1492380743.7447577"
        mock_print = MockPrintAnswer()
        self.prompt.print_answer = mock_print.print_answer

        self.prompt.start()

        expected_answer = Messages.SIGNATURE_ERROR
        self.assertTrue(expected_answer in mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testDownload_NoErrors_ReturnOk(self):
        self.mock_input.side_effect = ["telecharger? d1/fichier1", "quitter"]
        server_answer = "{\"fichier\": {" \
                        "\"signature\": \"6aba532a54c9eb9aa30496fa7f22734d\"," \
                        "\"contenu\": \"c2FsdXQK\"," \
                        "\"date\": \"1492380743.7447577\"}}"
        self.mock_file_system.folder_exists.return_value = True
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]

        self.prompt.start()

        expected_answer = Messages.OK
        self.assertTrue(expected_answer in self.mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testDownload_FileDoesntExist_ReturnFileDoesntExist(self):
        self.mock_input.side_effect = ["telecharger? d1/fichier1", "quitter"]
        server_answer = "{ \"reponse\": \"erreurFichierInexistant\" }"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]

        self.prompt.start()

        expected_answer = Messages.FILE_NOT_FOUND
        self.assertTrue(expected_answer in self.mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testDownload_CouldNotReadFile_ReturnCouldNotReadFile(self):
        self.mock_input.side_effect = ["telecharger? d1/fichier1", "quitter"]
        server_answer = "{ \"reponse\": \"erreurFichierLecture\" }"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]

        self.prompt.start()

        expected_answer = Messages.UNABLE_TO_READ_FILE
        self.assertTrue(expected_answer in self.mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testDeleteFolder_NoErrors_ReturnOk(self):
        self.mock_input.side_effect = ["supprimerDossier? d1", "quitter"]
        server_answer = "{ \"reponse\": \"ok\" }"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]

        self.prompt.start()

        expected_answer = Messages.OK
        self.assertTrue(expected_answer in self.mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testDeleteFolder_FolderDoesntExist_ReturnFolderDoesntExist(self):
        self.mock_input.side_effect = ["supprimerDossier? d1", "quitter"]
        server_answer = "{ \"reponse\": \"erreurDossierInexistant\" }"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]

        self.prompt.start()

        expected_answer = Messages.FOLDER_NOT_FOUND
        self.assertTrue(expected_answer in self.mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testDeleteFolder_CouldNotReadFolder_ReturnCouldNotReadFolder(self):
        self.mock_input.side_effect = ["supprimerDossier? d1", "quitter"]
        server_answer = "{ \"reponse\": \"erreurDossierLecture\" }"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]

        self.prompt.start()

        expected_answer = Messages.UNABLE_TO_READ_FOLDER
        self.assertTrue(expected_answer in self.mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testDeleteFile_NoErrors_ReturnOk(self):
        self.mock_input.side_effect = ["supprimerFichier? d1/fichier1", "quitter"]
        server_answer = "{ \"reponse\": \"ok\" }"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]

        self.prompt.start()

        expected_answer = Messages.OK
        self.assertTrue(expected_answer in self.mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testDeleteFile_FolderDoesntExist_ReturnFolderDoesntExist(self):
        self.mock_input.side_effect = ["supprimerFichier? d1", "quitter"]
        server_answer = "{ \"reponse\": \"erreurDossierInexistant\" }"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]

        self.prompt.start()

        expected_answer = Messages.FOLDER_NOT_FOUND
        self.assertTrue(expected_answer in self.mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testDeleteFile_FileDoesntExist_ReturnFileDoesntExist(self):
        self.mock_input.side_effect = ["supprimerFichier? d1", "quitter"]
        server_answer = "{ \"reponse\": \"erreurFichierInexistant\" }"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]

        self.prompt.start()

        expected_answer = Messages.FILE_NOT_FOUND
        self.assertTrue(expected_answer in self.mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testDeleteFile_CouldNotReadFile_ReturnCouldNotReadFile(self):
        self.mock_input.side_effect = ["supprimerFichier? d1/fichier1", "quitter"]
        server_answer = "{ \"reponse\": \"erreurFichierLecture\" }"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]

        self.prompt.start()

        expected_answer = Messages.UNABLE_TO_READ_FILE
        self.assertTrue(expected_answer in self.mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testFileExists_FileExists_ReturnYes(self):
        file_name = "d1/fichier1"
        self.mock_input.side_effect = ["fichier? " + file_name, "quitter"]
        server_answer = "{\"listeFichiers\": {" \
                        "\"fichier\": [" \
                        "\"d1/fichier1\"]}}"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]

        self.prompt.start()

        expected_answer = Messages.YES
        self.assertTrue(expected_answer in self.mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testFileExists_FileDoesntExist_ReturnNo(self):
        self.mock_input.side_effect = ["fichier? d1/fichier1", "quitter"]
        server_answer = "{ \"reponse\": \"erreurFichierInexistant\" }"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]

        self.prompt.start()

        expected_answer = Messages.NO
        self.assertTrue(expected_answer in self.mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testVerifyFileIdentical_IsIdentical_ReturnYes(self):
        self.mock_input.side_effect = ["fichierIdentique? d1/fichier1", "quitter"]
        self.mock_file_system.folder_exists.return_value = True
        self.mock_file_system.get_md5_signature.return_value = "6aba532a54c9eb9aa30496fa7f22734d"
        self.mock_file_system.get_file_modification_date.return_value = "1492380743.7447577"
        server_answer = "{ \"reponse\": \"oui\" }"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]

        self.prompt.start()

        expected_answer = Messages.YES
        self.assertTrue(expected_answer in self.mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testVerifyFileIdentical_FileDoesntExist_ReturnFileDoesntExist(self):
        self.mock_input.side_effect = ["fichierIdentique? d1/fichier1", "quitter"]
        self.mock_file_system.folder_exists.return_value = True
        self.mock_file_system.get_md5_signature.return_value = "6aba532a54c9eb9aa30496fa7f22734d"
        self.mock_file_system.get_file_modification_date.return_value = "1492380743.7447577"
        server_answer = "{ \"reponse\": \"erreurFichierInexistant\" }"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]

        self.prompt.start()

        expected_answer = Messages.FILE_NOT_FOUND
        self.assertTrue(expected_answer in self.mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testVerifyFileIdentical_CouldNotReadFile_ReturnCouldNotReadFile(self):
        self.mock_input.side_effect = ["identiqueFichier? d1/fichier1", "quitter"]
        self.mock_file_system.folder_exists.return_value = True
        self.mock_file_system.get_md5_signature.return_value = "6aba532a54c9eb9aa30496fa7f22734d"
        self.mock_file_system.get_file_modification_date.return_value = "1492380743.7447577"
        server_answer = "{ \"reponse\": \"erreurFichierLecture\" }"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]

        self.prompt.start()

        expected_answer = Messages.UNABLE_TO_READ_FILE
        self.assertTrue(expected_answer in self.mock_print.printed_answers)

    def testVerifyFileIsRecent_IsRecent_ReturnYes(self):
        self.mock_input.side_effect = ["fichierRecent? d1/fichier1", "quitter"]
        self.mock_file_system.folder_exists.return_value = True
        self.mock_file_system.get_md5_signature.return_value = "6aba532a54c9eb9aa30496fa7f22734d"
        self.mock_file_system.get_file_modification_date.return_value = "1492380743.7447577"
        server_answer = "{ \"reponse\": \"oui\" }"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]

        self.prompt.start()

        expected_answer = Messages.YES
        self.assertTrue(expected_answer in self.mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testVerifyFileIsRecent_IsNotRecent_ReturnNo(self):
        self.mock_input.side_effect = ["fichierIdentique? d1/fichier1", "quitter"]
        self.mock_file_system.folder_exists.return_value = True
        self.mock_file_system.get_md5_signature.return_value = "6aba532a54c9eb9aa30496fa7f22734d"
        self.mock_file_system.get_file_modification_date.return_value = "1492380743.7447577"
        server_answer = "{ \"reponse\": \"non\" }"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]

        self.prompt.start()

        expected_answer = Messages.NO
        self.assertTrue(expected_answer in self.mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testVerifyFileIsRecent_FileDoesntExist_ReturnFileDoesntExist(self):
        self.mock_input.side_effect = ["fichierRecent? d1/fichier1", "quitter"]
        self.mock_file_system.folder_exists.return_value = True
        self.mock_file_system.get_md5_signature.return_value = "6aba532a54c9eb9aa30496fa7f22734d"
        self.mock_file_system.get_file_modification_date.return_value = "1492380743.7447577"
        server_answer = "{ \"reponse\": \"erreurFichierInexistant\" }"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]

        self.prompt.start()

        expected_answer = Messages.FILE_NOT_FOUND
        self.assertTrue(expected_answer in self.mock_print.printed_answers)
        self.mock_print.delete_all_answers()

    def testVerifyFileIsRecent_CouldNotReadFile_ReturnCouldNotReadFile(self):
        self.mock_input.side_effect = ["recentFichier? d1/fichier1", "quitter"]
        self.mock_file_system.folder_exists.return_value = True
        self.mock_file_system.get_md5_signature.return_value = "6aba532a54c9eb9aa30496fa7f22734d"
        self.mock_file_system.get_file_modification_date.return_value = "1492380743.7447577"
        server_answer = "{ \"reponse\": \"erreurFichierLecture\" }"
        self.mock_connexion.receive.side_effect = [server_answer,  "{ \"reponse\": \"bye\" }"]

        self.prompt.start()

        expected_answer = Messages.UNABLE_TO_READ_FILE
        self.assertTrue(expected_answer in self.mock_print.printed_answers)

    def testQuit_ReturnBye(self):
        self.mock_input.side_effect = ["quitter"]
        server_answer = "{ \"reponse\": \"bye\" }"
        self.mock_connexion.receive.side_effect = [server_answer]

        self.prompt.start()

        expected_answer = Messages.BYE
        self.assertTrue(expected_answer in self.mock_print.printed_answers)
        self.mock_print.delete_all_answers()


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