Files
astrololo/services/data/tests/test_bases.py
T
gitea 4c1e7f8808
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m30s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m29s
Testy / Testy warstwy bazodanowej (ochrona baz) (pull_request) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 12s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 8s
build / build (push) Successful in 40s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m3s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m35s
Testy / Testy warstwy bazodanowej (ochrona baz) (push) Successful in 9m29s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 14s
Testy / Kontrola składni wszystkich warstw (push) Successful in 10s
feat: przegląd baz na udziale + globalne włączanie/wyłączanie (DAN-15/PRE-09)
Wymaganie przedefiniowane pod model serwerowy (#47): nie wybiera się folderu —
pliki leżą na stałym NFS. Potrzeba za to WIDZIEĆ, jakie bazy są dostępne i móc
zdecydować, które biorą udział w interpretacji.

Warstwa danych: `bases.py` (lista plików + metaopis: nazwa, ścieżka, rozmiar,
data, stan) i endpoint `/bases`. Wyłączone bazy są ODSIEWANE z kandydatów przy
wyszukiwaniu, więc naprawdę nie biorą udziału w interpretacji — nie tylko znikają
z listy. Lista wyłączonych wchodzi do klucza cache zapytań: bez tego zmiana
ustawień oddawałaby wynik sprzed zmiany, czyli treść bazy uznanej za wyłączoną.
`list_bases()` doszło do interfejsu dostawcy jako OPCJONALNE (SQL nie operuje na
plikach → pusto, zamiast wywrotki).

Przelot logika → prezentacja i ekran „Ustawienia" z tabelą baz. Przez łącze idą
SAME METADANE — podgląd listy nie jest kolejną drogą do wyniesienia treści.

Stan przełączników jest DEKLARATYWNY (`DISABLED_BASES`), nie klikalny — i to jest
świadome: udział z bazami montujemy read-only, a katalog cache to `emptyDir`, więc
zapisany przełącznik ginąłby przy restarcie poda i po cichu włączał z powrotem
wyłączoną bazę. Ekran mówi wprost, jak wyłączyć bazę i dlaczego nie klikaniem.
Tryb klikalny wymagałby dołożenia trwałego wolumenu.

Weryfikacja na żywym łańcuchu: `/bases` przechodzi przez SZYFROWANE łącze
(logic→data), pokazuje 3 bazy z metaopisem i stanem; wyszukiwanie daje 3 → 2 → 0
wierszy w miarę wyłączania baz. Testy: dane +6, prezentacja +6. Dane 13,
logika 277, prezentacja 249.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-03 22:09:27 +02:00

51 lines
1.8 KiB
Python

"""Przegląd baz na udziale i ich globalne wyłączanie (DAN-15 / PRE-09)."""
import pytest
from app import bases
@pytest.fixture(autouse=True)
def _clean_env(monkeypatch):
monkeypatch.delenv("DISABLED_BASES", raising=False)
ROOT = "/dane"
PATHS = [f"{ROOT}/main_base.xlsx", f"{ROOT}/archiwum/stara.xlsx"]
def test_everything_enabled_by_default():
for b in bases.list_bases(ROOT, PATHS):
assert b["enabled"] is True
def test_disable_by_file_name(monkeypatch):
monkeypatch.setenv("DISABLED_BASES", "stara.xlsx")
state = {b["name"]: b["enabled"] for b in bases.list_bases(ROOT, PATHS)}
assert state == {"main_base.xlsx": True, "stara.xlsx": False}
def test_disable_by_relative_path(monkeypatch):
"""Wpis może wskazywać ścieżkę względną, nie tylko samą nazwę."""
monkeypatch.setenv("DISABLED_BASES", "archiwum/stara.xlsx")
assert bases.is_enabled(f"{ROOT}/archiwum/stara.xlsx", ROOT) is False
assert bases.is_enabled(f"{ROOT}/main_base.xlsx", ROOT) is True
def test_entries_are_trimmed_and_multiple(monkeypatch):
monkeypatch.setenv("DISABLED_BASES", " stara.xlsx , main_base.xlsx ")
assert [b["enabled"] for b in bases.list_bases(ROOT, PATHS)] == [False, False]
def test_listing_carries_metadata_not_content(tmp_path):
"""Metaopis: nazwa, ścieżka, rozmiar, data — ŻADNEJ treści bazy."""
f = tmp_path / "baza.xlsx"
f.write_bytes(b"x" * 2048)
item = bases.list_bases(tmp_path, [str(f)])[0]
assert set(item) == {"name", "path", "size_mb", "modified", "enabled"}
assert item["name"] == "baza.xlsx" and item["size_mb"] is not None and item["modified"]
def test_missing_file_does_not_crash_the_listing():
item = bases.list_bases(ROOT, [f"{ROOT}/nie-ma.xlsx"])[0]
assert item["size_mb"] is None and item["modified"] is None