feat(gui): recâbler import/export de configuration par email (P1-3)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
95
tests/unit/test_gui_v6_config_share.py
Normal file
95
tests/unit/test_gui_v6_config_share.py
Normal file
@@ -0,0 +1,95 @@
|
||||
"""Export / import de configuration (P1-3) — format compatible merge_params.
|
||||
|
||||
Pur : sérialisation/désérialisation et fusion, sans display ni filedialog.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from gui_v6.config_share import build_export_payload, import_config_file
|
||||
|
||||
|
||||
def test_export_payload_has_v5_schema():
|
||||
payload = build_export_payload(
|
||||
whitelist=["Dr Métier", "Service ORL"],
|
||||
blacklist=["DUPONT"],
|
||||
version="2026.06.29",
|
||||
)
|
||||
assert payload["version"] == "2026.06.29"
|
||||
assert "date_export" in payload
|
||||
assert payload["whitelist_phrases"] == ["Dr Métier", "Service ORL"]
|
||||
assert payload["blacklist_force_mask_terms"] == ["DUPONT"]
|
||||
|
||||
|
||||
def test_export_payload_is_json_serializable():
|
||||
payload = build_export_payload(whitelist=["A"], blacklist=["B"], version="1")
|
||||
json.dumps(payload) # ne doit pas lever
|
||||
|
||||
|
||||
def test_import_merges_into_user_config(tmp_path, monkeypatch):
|
||||
cfg = tmp_path / "dictionnaires.yml"
|
||||
cfg.write_text("whitelist_phrases: [Existant]\n", encoding="utf-8")
|
||||
incoming = tmp_path / "recu.json"
|
||||
incoming.write_text(
|
||||
json.dumps({
|
||||
"version": "1", "date_export": "2026-06-29",
|
||||
"whitelist_phrases": ["Nouveau"],
|
||||
"blacklist_force_mask_terms": ["MASQUERMOI"],
|
||||
}),
|
||||
encoding="utf-8",
|
||||
)
|
||||
added = import_config_file(incoming, cfg)
|
||||
assert added is True
|
||||
import yaml
|
||||
merged = yaml.safe_load(cfg.read_text(encoding="utf-8"))
|
||||
assert "Existant" in merged["whitelist_phrases"]
|
||||
assert "Nouveau" in merged["whitelist_phrases"]
|
||||
assert "MASQUERMOI" in merged["blacklist"]["force_mask_terms"]
|
||||
|
||||
|
||||
def test_import_returns_false_when_nothing_new(tmp_path):
|
||||
cfg = tmp_path / "dictionnaires.yml"
|
||||
cfg.write_text("whitelist_phrases: [Deja]\n", encoding="utf-8")
|
||||
incoming = tmp_path / "recu.json"
|
||||
incoming.write_text(
|
||||
json.dumps({"whitelist_phrases": ["Deja"], "blacklist_force_mask_terms": []}),
|
||||
encoding="utf-8",
|
||||
)
|
||||
assert import_config_file(incoming, cfg) is False
|
||||
|
||||
|
||||
def test_import_preserves_unmanaged_yaml_keys(tmp_path):
|
||||
# Une config riche : l'import ne doit toucher QUE whitelist/blacklist,
|
||||
# et préserver toutes les autres sections (anti-perte de données).
|
||||
cfg = tmp_path / "dictionnaires.yml"
|
||||
cfg.write_text(
|
||||
"version: 3\n"
|
||||
"whitelist_phrases: [Existant]\n"
|
||||
"blacklist:\n"
|
||||
" force_mask_terms: [DEJA]\n"
|
||||
" autre_sous_cle: [GARDER]\n"
|
||||
"regex_overrides:\n"
|
||||
" - rule_a\n"
|
||||
"flags:\n"
|
||||
" strict: true\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
incoming = tmp_path / "recu.json"
|
||||
incoming.write_text(
|
||||
json.dumps({"whitelist_phrases": ["Nouveau"], "blacklist_force_mask_terms": ["MASQUERMOI"]}),
|
||||
encoding="utf-8",
|
||||
)
|
||||
assert import_config_file(incoming, cfg) is True
|
||||
import yaml
|
||||
merged = yaml.safe_load(cfg.read_text(encoding="utf-8"))
|
||||
# Clés non gérées intactes
|
||||
assert merged["version"] == 3
|
||||
assert merged["regex_overrides"] == ["rule_a"]
|
||||
assert merged["flags"] == {"strict": True}
|
||||
assert merged["blacklist"]["autre_sous_cle"] == ["GARDER"]
|
||||
# Listes gérées fusionnées
|
||||
assert "Existant" in merged["whitelist_phrases"]
|
||||
assert "Nouveau" in merged["whitelist_phrases"]
|
||||
assert "DEJA" in merged["blacklist"]["force_mask_terms"]
|
||||
assert "MASQUERMOI" in merged["blacklist"]["force_mask_terms"]
|
||||
Reference in New Issue
Block a user