""" Pruebas del programa de escritorio: dónde guarda los datos, cómo se cambian de sitio la primera vez y la copia que hace al abrir. Se simula el instalable (sys.frozen) con carpetas temporales; no se toca nada del equipo. python3 -m unittest discover -s pruebas -v """ from __future__ import annotations import os import sys import tarfile import tempfile import unittest from pathlib import Path from unittest import mock sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) from cartera import instalacion, servidor # noqa: E402 from cartera.operaciones import Cartera, ErrorOperacion # noqa: E402 class ComoInstalable(unittest.TestCase): def setUp(self): self._tmp = tempfile.TemporaryDirectory() self.addCleanup(self._tmp.cleanup) raiz = Path(self._tmp.name) self.programa = raiz / "descargas" self.programa.mkdir() self.personal = raiz / "casa" / "caudal" for parche in (mock.patch.object(sys, "frozen", True, create=True), mock.patch.object(sys, "executable", str(self.programa / "caudal")), mock.patch.dict(os.environ, {"XDG_DATA_HOME": str(raiz / "casa")}), mock.patch.object(sys, "platform", "linux")): parche.start() self.addCleanup(parche.stop) os.environ.pop("APPIMAGE", None) def abrir(self): base, _ = instalacion.base_actual() app = servidor.App(Cartera(base / "datos")) self.addCleanup(lambda: app.cartera.cerrar()) return app class TestDondeVivenLosDatos(ComoInstalable): def test_sin_nada_van_a_la_carpeta_del_usuario(self): self.assertEqual(instalacion.base_actual(), (self.personal, "personal")) def test_con_carpeta_junto_al_programa_se_usa_esa(self): (self.programa / "caudal-datos").mkdir() self.assertEqual(instalacion.base_actual(), (self.programa / "caudal-datos", "portatil")) def test_una_appimage_mira_junto_a_su_fichero_no_donde_se_monta(self): otra = Path(self._tmp.name) / "usb" (otra / "caudal-datos").mkdir(parents=True) with mock.patch.dict(os.environ, {"APPIMAGE": str(otra / "Caudal.AppImage")}): self.assertEqual(instalacion.base_actual(), (otra / "caudal-datos", "portatil")) def test_desde_el_codigo_no_hay_nada_que_elegir(self): with mock.patch.object(sys, "frozen", False, create=True): with tempfile.TemporaryDirectory() as t: app = servidor.App(Cartera(Path(t) / "datos")) self.addCleanup(app.cartera.cerrar) self.assertIsNone(app.estado()["instalacion"]) class TestElegirLaPrimeraVez(ComoInstalable): def test_se_puede_llevar_junto_al_programa_y_volver(self): app = self.abrir() ins = app.estado()["instalacion"] self.assertEqual((ins["modo"], ins["elegible"], ins["portatil_posible"]), ("personal", True, True)) ins = app.instalacion_mover("portatil") self.assertEqual((ins["modo"], ins["carpeta"]), ("portatil", str(self.programa / "caudal-datos"))) self.assertFalse(self.personal.exists()) # no quedan dos copias app.cartera.guardar_activo({"nombre": "Un fondo", "tipo": "Fondo", "codigo": "IE00B03HCZ61"}) self.assertTrue((self.programa / "caudal-datos" / "datos" / "activos.jsonl").is_file()) def test_con_algo_apuntado_ya_no_se_mueve(self): app = self.abrir() app.cartera.guardar_activo({"nombre": "Un fondo", "tipo": "Fondo", "codigo": "IE00B03HCZ61"}) self.assertFalse(app.estado()["instalacion"]["elegible"]) with self.assertRaises(ErrorOperacion): app.instalacion_mover("portatil") self.assertTrue((self.personal / "datos" / "activos.jsonl").is_file()) def test_no_pisa_datos_que_ya_hubiera_en_el_destino(self): app = self.abrir() ajena = self.programa / "caudal-datos" with mock.patch.object(instalacion, "base_actual", return_value=(self.personal, "personal")): (ajena / "datos").mkdir(parents=True) (ajena / "datos" / "activos.jsonl").write_text("{}\n") with self.assertRaises(ValueError): instalacion.mover("portatil") self.assertEqual((ajena / "datos" / "activos.jsonl").read_text(), "{}\n") app.cartera.cerrar() def test_si_la_carpeta_del_programa_no_deja_escribir_se_dice(self): app = self.abrir() with mock.patch.object(instalacion, "se_puede_escribir_junto_al_programa", return_value=False): self.assertFalse(app.estado()["instalacion"]["portatil_posible"]) class TestEnElMenuDeAplicaciones(ComoInstalable): def setUp(self): super().setUp() self.lanzador = self.personal.parent / "applications" / "caudal.desktop" self.icono = self.personal.parent / "icons" / "hicolor" / "scalable" / "apps" / "caudal.svg" def test_se_anade_y_se_quita_desde_el_programa(self): app = self.abrir() self.assertEqual(app.estado()["instalacion"]["lanzador"], {"puesto": False}) self.assertEqual(app.instalacion_lanzador(True)["lanzador"], {"puesto": True}) lineas = self.lanzador.read_text(encoding="utf-8").splitlines() self.assertEqual(lineas[0], "[Desktop Entry]") self.assertIn(f'Exec="{self.programa / "caudal"}"', lineas) self.assertIn(f"Icon={self.icono}", lineas) self.assertIn("Terminal=false", lineas) self.assertIn("