feat(prezentacja): zapamiętane predykcje okresowe (PRE-22) + wymaganie o cache-bustingu
build / build (push) Successful in 1m4s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 12m9s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Failing after 1m6s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 38s
Testy / Kontrola składni wszystkich warstw (push) Successful in 20s
build / build (push) Successful in 1m4s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 12m9s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Failing after 1m6s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 38s
Testy / Kontrola składni wszystkich warstw (push) Successful in 20s
Piata wskazowka partnerow: Kalendarz ma pozwalac liczyc predykcje dla KILKU okresow i je zachowywac, zeby wszystkie trafily potem do raportu („Skompiluj", PRE-23/24). Nowy predictions.js — magazyn w localStorage, tak jak wspolne dane formularza (PRE-21): serwer zostaje bezstanowy, zadne dane urodzeniowe ani tresci z baz nie laduja po stronie uslugi. Zakladka „Skompiluj" odczyta to samo miejsce przez window.astrololoPredictions (jedno zrodlo prawdy). Decyzje projektowe: - KLUCZEM TOZSAMOSCI JEST OKRES. Ponowne policzenie tego samego zakresu podmienia wpis zamiast dokladac duplikat — inaczej lista puchlaby przy kazdej probie z innym modelem albo budzetem. Dzieki temu zapis jest idempotentny, wiec dziala tez wariant bez strumienia (zapis przy wczytaniu strony z gotowym wynikiem) i odswiezenie niczego nie mnozy. - progress.js OGLASZA gotowy horoskop zdarzeniem `astrololo:horoscope` z profilem, zamiast sam zapisywac. To okno postepu, a nie magazyn — zapisywanie zostaje odpowiedzialnoscia predictions.js. Filtr po profilu pilnuje, zeby interpretacja natalna nie trafila na liste predykcji okresowych. - Przepelniony magazyn (horoskopy bywaja dlugie) jest ZGLASZANY uzytkownikowi, a nie polykany — inaczej wynik znikalby po cichu. UI: lista zapamietanych predykcji na Kalendarzu — okres, data zapisu, objetosc i przycisk usuwania. Skrypt podpiety w timeline.html (nie w base.html), zeby nie kolidowac z rownolegle otwartym #29. PRE-26 — dopisane wymaganie o wersjonowaniu plikow statycznych. Przy PRE-25 przegladarka podala STARY styles.css i powiekszanie kosmogramu „nie dzialalo", mimo ze klasa byla nakladana. Objaw jest zdradliwy: szablony sa nowe, wiec strona wyglada na zaktualizowana, a funkcja po prostu milczy. Po wdrozeniu moze to spotkac uzytkownikow. Weryfikacja na zywej aplikacji: dwa okresy zapisane; powtorzenie tego samego zakresu podmienilo wpis (dalej 2, tekst zaktualizowany); lista posortowana po dacie; predykcje przetrwaly przejscie na inna zakladke i powrot; interpretacja natalna NIE wpadla na liste; usuwanie zmniejszylo licznik 2 -> 1 i przerysowalo liste. Testy: 14 nowych. Calosc: prezentacja 101 passed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit was merged in pull request #30.
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
"""Zapamiętane predykcje okresowe (PRE-22).
|
||||
|
||||
Magazyn żyje w JS (localStorage), więc znów pilnujemy go strukturalnie. Sedno:
|
||||
predykcje mają PRZEŻYĆ przejście na inną zakładkę i trafić do raportu, a lista
|
||||
nie może puchnąć od powtórzonych prób na tym samym okresie.
|
||||
"""
|
||||
import pathlib
|
||||
|
||||
APP = pathlib.Path(__file__).resolve().parents[1] / "app"
|
||||
JS = (APP / "static" / "predictions.js").read_text(encoding="utf-8")
|
||||
PROGRESS = (APP / "static" / "progress.js").read_text(encoding="utf-8")
|
||||
TIMELINE = (APP / "templates" / "timeline.html").read_text(encoding="utf-8")
|
||||
|
||||
|
||||
# ─────────────────────────────── podpięcie ───────────────────────────────
|
||||
|
||||
def test_script_loaded_on_calendar_tab():
|
||||
assert "predictions.js" in TIMELINE
|
||||
|
||||
|
||||
def test_loaded_after_progress_script():
|
||||
"""Nasłuchuje zdarzenia, które wysyła progress.js — musi być załadowany po nim,
|
||||
inaczej przegapi pierwsze wywołanie."""
|
||||
assert TIMELINE.index("progress.js") < TIMELINE.index("predictions.js")
|
||||
|
||||
|
||||
def test_calendar_has_container_for_the_list():
|
||||
assert 'id="savedPredictions"' in TIMELINE
|
||||
|
||||
|
||||
def test_progress_announces_finished_horoscope():
|
||||
"""Okno postępu ogłasza gotowy horoskop zdarzeniem, zamiast samo go zapisywać
|
||||
— to okno postępu, a nie magazyn."""
|
||||
assert "astrololo:horoscope" in PROGRESS
|
||||
assert "profile" in PROGRESS.split("astrololo:horoscope")[1][:200]
|
||||
|
||||
|
||||
# ─────────────────────────────── zachowanie ──────────────────────────────
|
||||
|
||||
def test_only_period_horoscopes_are_stored():
|
||||
"""Interpretacja natalna ma NIE trafiać na listę predykcji okresowych."""
|
||||
assert "'period'" in JS
|
||||
|
||||
|
||||
def test_same_period_replaces_instead_of_duplicating():
|
||||
"""Ponowne policzenie tego samego zakresu podmienia wpis. Inaczej lista
|
||||
puchłaby przy każdej próbie z innym modelem."""
|
||||
assert "function upsert" in JS
|
||||
assert "p.from_date === entry.from_date" in JS
|
||||
assert "p.to_date === entry.to_date" in JS
|
||||
|
||||
|
||||
def test_entry_carries_period_and_text():
|
||||
for field in ("from_date", "to_date", "text", "saved_at"):
|
||||
assert field in JS, f"wpis nie niesie pola {field}"
|
||||
|
||||
|
||||
def test_incomplete_result_is_not_stored():
|
||||
"""Bez tekstu albo bez dat nie ma czego zapamiętać — nie zapisujemy śmieci."""
|
||||
assert "if (!text || !from || !to) return null;" in JS
|
||||
|
||||
|
||||
def test_list_can_be_pruned():
|
||||
assert "function remove" in JS
|
||||
assert "data-drop" in JS
|
||||
|
||||
|
||||
def test_full_storage_is_reported_not_swallowed():
|
||||
"""Horoskopy bywają długie. Gdy magazyn się przepełni, użytkownik musi się
|
||||
o tym dowiedzieć, zamiast po cichu stracić wynik."""
|
||||
assert "pełny" in JS or "pelny" in JS
|
||||
assert "return false;" in JS
|
||||
|
||||
|
||||
def test_corrupt_storage_does_not_break_the_page():
|
||||
assert "catch" in JS and "Array.isArray" in JS
|
||||
|
||||
|
||||
def test_storage_is_exposed_for_the_compile_tab():
|
||||
"""Zakładka „Skompiluj" (PRE-23) ma czytać to samo miejsce — jedno źródło prawdy."""
|
||||
assert "window.astrololoPredictions" in JS
|
||||
|
||||
|
||||
def test_does_nothing_on_other_tabs():
|
||||
assert "if (!document.getElementById('savedPredictions')) return;" in JS
|
||||
|
||||
|
||||
def test_reload_does_not_duplicate():
|
||||
"""Wariant bez strumienia zapisuje przy wczytaniu strony — klucz to okres,
|
||||
więc odświeżenie nie mnoży wpisów."""
|
||||
assert "id: from + '..' + to" in JS
|
||||
Reference in New Issue
Block a user