Ctrl K
ComunidadGuías…

test_merge_daily_noms_nettoyes.py

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
"""Backlog « journalières sans distinction si deux caméras se nettoient pareil » :
« Garage » et « Garage! » donnent le même dossier par safe_name, et leurs
journalières s'écrivaient au même chemin, l'une écrasant l'autre. Elles
reçoivent maintenant des clés distinctes, comme les homonymes de deux réseaux
(test_merge_daily_homonymes.py), sans toucher aux caméras qui n'entrent pas en
collision."""

from __future__ import annotations

import json
import tempfile
import unittest
from pathlib import Path
try:
    from zoneinfo import ZoneInfo
except ImportError:  # Python 3.8, édition Windows 7
    from backports.zoneinfo import ZoneInfo

import merge_daily
from test_merge_daily_homonymes import mp4_structurel


class NomsQuiSeNettoientPareil(unittest.TestCase):
    def setUp(self):
        self.tmp = tempfile.TemporaryDirectory()
        self.addCleanup(self.tmp.cleanup)
        self.input_dir = Path(self.tmp.name)
        self.tz = ZoneInfo("Europe/Paris")

    def _registre(self, cameras, reseau=""):
        clips = {}
        for numero, camera in enumerate(cameras):
            chemin = f"c{numero}.mp4"
            (self.input_dir / chemin).write_bytes(mp4_structurel())
            clips[f"k{numero}"] = {
                "camera": camera, "network_id": reseau, "device_id": "",
                "created_at": f"2026-09-01T1{numero}:00:00+00:00", "path": chemin,
            }
        (self.input_dir / merge_daily.DOWNLOAD_STATE).write_text(
            json.dumps({"version": 2, "clips": clips}), encoding="utf-8")

    def _cles(self):
        groupes = merge_daily.load_groups(self.input_dir, self.tz)
        return {camera for camera, _ in groupes}

    def _dossiers_distincts(self, cles):
        self.assertEqual(len({merge_daily.safe_name(c).casefold() for c in cles}), len(cles), cles)

    def test_garage_et_garage_point_d_exclamation_ne_partagent_plus_un_dossier(self):
        self._registre(["Garage", "Garage!"])
        cles = self._cles()
        self.assertEqual(len(cles), 2)
        self._dossiers_distincts(cles)
        # Le nom déjà propre garde son dossier : l'historique déjà assemblé reste.
        self.assertIn("Garage", cles)

    def test_le_choix_ne_depend_pas_de_l_ordre_du_registre(self):
        self._registre(["Garage!", "Garage"])
        premiere = self._cles()
        self._registre(["Garage", "Garage!"])
        self.assertEqual(premiere, self._cles())

    def test_trois_noms_qui_se_nettoient_pareil(self):
        self._registre(["Garage", "Garage!", "Garage?"])
        cles = self._cles()
        self.assertEqual(len(cles), 3)
        self._dossiers_distincts(cles)
        self.assertIn("Garage", cles)

    def test_la_casse_seule_distingue_deux_dossiers(self):
        # Windows et macOS confondent « Salon » et « salon » : même dossier.
        self._registre(["Salon", "salon"])
        cles = self._cles()
        self.assertEqual(len(cles), 2)
        self._dossiers_distincts(cles)

    def test_un_suffixe_qui_existe_deja_n_est_pas_reutilise(self):
        self._registre(["Garage", "Garage!", "Garage! (2)"])
        cles = self._cles()
        self.assertEqual(len(cles), 3)
        self._dossiers_distincts(cles)

    def test_noms_sans_collision_inchanges(self):
        self._registre(["Salon", "jardin", "Bureau", "Portail", "Terrasse1"])
        self.assertEqual(self._cles(), {"Salon", "jardin", "Bureau", "Portail", "Terrasse1"})

    def test_meme_nom_a_espace_final_reste_une_seule_camera(self):
        # La forme réelle de production : « jardin » et « jardin » + espace.
        self._registre(["jardin", "jardin "])
        self.assertEqual(self._cles(), {"jardin"})

    def test_deux_reseaux_et_un_nom_voisin_restent_distincts(self):
        entrees = {
            "a": {"camera": "jardin", "network_id": "1", "created_at": "2026-09-01T10:00:00+00:00"},
            "b": {"camera": "jardin", "network_id": "2", "created_at": "2026-09-01T11:00:00+00:00"},
            "c": {"camera": "jardin!", "network_id": "1", "created_at": "2026-09-01T12:00:00+00:00"},
        }
        cles = merge_daily._cles_camera_par_collision(entrees)
        finales = {merge_daily._camera_key(cles, e, e["camera"]) for e in entrees.values()}
        self.assertEqual(len(finales), 3, finales)
        self._dossiers_distincts(finales)

    def test_les_clips_se_repartissent_entre_les_deux_cles(self):
        self._registre(["Garage", "Garage!"])
        groupes = merge_daily.load_groups(self.input_dir, self.tz)
        self.assertEqual(sorted(len(v) for v in groupes.values()), [1, 1])

    def test_les_journees_indisponibles_utilisent_les_memes_cles(self):
        self._registre(["Garage", "Garage!"])
        (self.input_dir / "c0.mp4").unlink()
        (self.input_dir / "c1.mp4").unlink()
        jours, _ = merge_daily.journees_a_source_indisponible(self.input_dir, self.tz)
        cles_groupes = self._cles()
        self.assertEqual({camera for camera, _ in jours}, cles_groupes)


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