def setUp(self):
     self.prestations = mock()
     self.storage = mock()
     self.devis = Devis(self.prestations, self.storage)
class TestJaneCreeUnDevis(unittest.TestCase):
    
    def setUp(self):
        self.prestations = mock()
        self.storage = mock()
        self.devis = Devis(self.prestations, self.storage)
    
    def test_Jane_ajoute_une_prestation_existante_a_un_devis_prestation_ajoutee(self):
        """Test quand Jane ajoute une prestation existante a un devis, la prestation est bien ajoutee"""
        
        """
        given   : une prestation valide (proposee par l'entreprise), un devis non finalise
        when    : ajoute la prestation au devis
        then    : l'ensemble des prestations du devis contient la prestation
        """
        
        new_prestation = mock()
        when(self.storage).includes(self.devis).thenReturn(False)
        self.devis.addPrestation(new_prestation)
        verify(self.prestations).append(new_prestation)

    def test_Jane_edite_son_devis_en_pdf(self):
        """Test l'edition d'un devis en pdf"""
        
        """
        given   : un devis contenant des prestations
        when    : edite le devis en pdf
        then    : la version pdf contient un recapitulatif des prestations sous la forme "#{nom} - CU: #{PU}euros"
        """
            
        prestation = mock()
        lib = mock()
        when(self.prestations).select().thenReturn([prestation])
        
        self.devis.buildPDF(lib)
        verify(lib).build_output_for(self.devis)
        
    def test_total_HT(self):
        """Test le calcul du total HT du devis"""
        
        """
        given   : un devis contenant des prestations
        when    : calcule le total HT du devis
        then    : retourne la somme HT de l'ensemble des prestations contenues dans le devis
        """
        
        prestation = mock()
        when(prestation).coutHT().thenReturn(45)
        
        prestation2 = mock()
        when(prestation2).coutHT().thenReturn(35)
        
        when(self.prestations).select().thenReturn([prestation, prestation2])
        totalHT = self.devis.computeTotalHT()
        expectedTotal = 80
        self.assertEqual(expectedTotal, totalHT)
        
    def test_total_TTC(self):
        """Test le calcul du total TTC du devis"""
        
        """
        given   : un devis contenant des prestations
        when    : calcule le total TTC du devis
        then    : retourne la somme TTC de l'ensemble des prestations contenues dans le devis
        """
        
        prestation = mock()
        when(prestation).coutHT().thenReturn(45)
        
        prestation2 = mock()
        when(prestation2).coutHT().thenReturn(35)
        
        when(self.prestations).select().thenReturn([prestation, prestation2])
        taux = 19.8
        totalTTC = self.devis.computeTotalTTC(taux)

        expectedTotal = 80 * 1.198
        self.assertEqual(expectedTotal, totalTTC)
        
    def test_Jane_sauve_un_devis_dans_le_storage(self):
        """Test quand Jane sauvegarde le devis dans la base"""
        
        """
        given   : un devis
        when    : sauve le devis dans la base
        then    : la base contient le devis
        """
        
        self.devis.store()
        when(self.storage).includes(self.devis).thenReturn(False)
        verify(self.storage).insert(self.devis)
        
    def test_Jane_sauve_un_devis__deja_sauve_dans_le_storage_leve_une_exception(self):
        """Test quand Jane sauvegarde le devis dans la base"""
        
        """
        given   : un devis deja sauve dans la base
        when    : sauve le devis dans la base
        then    : une exception est levee (DevisFinalise)
        """
        
        when(self.storage).includes(self.devis).thenReturn(True)
        self.assertRaises(DevisFinalise, self.devis.store)
        
    def test_Jane_sauve_un_devis__deja_sauve_dans_le_storage_leve_une_exception(self):
        """Test quand Jane sauvegarde le devis dans la base"""
        
        """
        given   : un devis
        when    : sauve le devis dans la base
        then    : la base ne re-ajoute pas le devis
        """
        
        when(self.storage).includes(self.devis).thenReturn(True)
        try:
            self.devis.store()
        except(DevisFinalise):
            pass
        verify(self.storage, never).insert(self.devis)
        
            
    def test_Jane_ajoute_dans_un_devis_sauve_leve_exception(self):
        """Test quand Jane essaye d'ajouter dans un devis deja sauve, leve une exception"""
        
        """
        given   : une prestation valide, un devis sauve dans la base
        when    : on ajoute la prestation au devis
        then    : leve une exception (DevisFinalise)
        """
        
        new_prestation = mock()
        when(self.storage).includes(self.devis).thenReturn(True)
        self.assertRaises(DevisFinalise, self.devis.addPrestation, new_prestation) 
        
    def test_Jane_ajoute_dans_un_devis_sauve_ajoute_pas(self):
        """Test quand Jane essaye de modifer un devis deja sauve, n'ajoute rien"""
        
        """
        given   : une prestation valide, un devis sauve dans la base
        when    : on ajoute la prestation au devis
        then    : la prestation n'est pas ajoutee au devis
        """
        
        new_prestation = mock()
        when(self.storage).includes(self.devis).thenReturn(True)
        try:
            self.devis.addPrestation(new_prestation)
        except(DevisFinalise):
            pass
        verify(self.prestations, never).append(new_prestation)
        
    def test_Jane_modifie_quantite_prestation_existante_dans_un_devis_non_sauve(self):
        """test la modifiaction d'une prestation existante dans un devis non sauve"""
        
        """
        given   : un devis non sauve dans la base et une prestation qui est dans le devis
        when    : on modifie la quantite de la prestation du devis
        then    : la quantite est modifiee
        """
        
        prestation = mock()   

        new_quantity = 5
        when(self.prestations).includes(prestation).thenReturn(True)
        self.devis.change_number_of_to(prestation, new_quantity)
        verify(self.prestations).set_number_of_to(prestation, new_quantity)
        
    def test_Jane_modifie_quantite_prestation_inexistante_dans_un_devis_non_sauve_leve_une_exception(self):    
        """test la modification de la quantite d'une prestation qui n'apparait pas sur un devis non finalise. Une exception est levee"""
        
        """
        given   : un devis non sauve dans la base et une prestation non presente sur le devis
        when    : on modifie la quantite
        then    : leve une exception (PrestationInconnue)
        """
        
        prestation = mock()   
        when(self.prestations).includes(prestation).thenReturn(False)
        new_quantity = 5
        self.assertRaises(PrestationInconnue, self.devis.change_number_of_to, prestation, new_quantity)
        
    def test_Jane_modifie_quantite_prestation_inexistante_dans_un_devis_non_sauve_ne_modifie_pas(self):    
        """test la modification de la quantite d'une prestation qui n'apparait pas sur un devis non finalise. La quantite n'est pas modifiee (pas de sens de toute facon)"""
        
        """
        given   : un devis non sauve dans la base et une prestation non presente sur le devis
        when    : on modifie la quantite
        then    : la quantite n'est pas modifiee
        """
        
        prestation = mock()   
        when(self.prestations).includes(prestation).thenReturn(False)
        new_quantity = 5
        try:
            self.devis.change_number_of_to(prestation, new_quantity)
        except (PrestationInconnue):
            pass
        verify(self.prestations, never).set_number_of_to(prestation, new_quantity)
        
    def test_Jane_modifie_quantite_prestation_existante_dans_un_devis_sauve_leve_une_exception(self):    
        """test la modification de la quantite d'une prestation qui apparait sur un devis finalise. Une exception est levee"""
        
        """
        given   : un devis sauve dans la base et une prestation presente sur le devis
        when    : on modifie la quantite
        then    : leve une exception (DevisFinalise)
        """
        
        prestation = mock()   
        when(self.prestations).includes(prestation).thenReturn(True)
        when(self.storage).includes(self.devis).thenReturn(True)
        new_quantity = 5
        self.assertRaises(DevisFinalise, self.devis.change_number_of_to, prestation, new_quantity)
        

    def test_Jane_modifie_quantite_prestation_existante_dans_un_devis_sauve_leve_ne_modifie_pas(self):    
        """test la modification de la quantite d'une prestation qui apparait sur un devis finalise. La quantite n'est pas modifiee"""
        
        """
        given   : un devis sauve dans la base et une prestation presente sur le devis
        when    : on modifie la quantite
        then    : la quantite n'est pas modifiee
        """
        
        prestation = mock()   
        when(self.prestations).includes(prestation).thenReturn(True)
        when(self.storage).includes(self.devis).thenReturn(True)
        new_quantity = 5
        try:
            self.devis.change_number_of_to(prestation, new_quantity)
        except (DevisFinalise):
            pass
        verify(self.prestations, never).set_number_of_to(prestation, new_quantity)