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
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>
51 lines
1.8 KiB
Python
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
|