a0d1135db1
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m29s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m36s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 11s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 8s
build / build (push) Successful in 50s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m51s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m29s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 11s
Testy / Kontrola składni wszystkich warstw (push) Successful in 8s
Po deployu przeglądarka trzymała stare styles.css / *.js — ten sam URL, więc serwowała z cache mimo nowej wersji. Doklejamy do URL-a krótki HASH TREŚCI pliku: zmienił się plik → zmienił się URL → przeglądarka pobiera nowy; bez zmian URL zostaje ten sam i cache dalej działa (bustujemy tylko to, co się zmieniło). - `static_url(name)` + globalny helper Jinja `static()`: `/static/x?v=<md5[:8]>`. Hash liczony raz na proces (lru_cache) — nowy pod po deployu = świeży hash; brak pliku → `?v=0`, nie wywala strony. - Wszystkie odwołania w szablonach (styles.css, nasze *.js, vendor Leaflet) idą teraz przez helper zamiast surowego `/static/...`. Testy: +5 (hash w URL, zależny od treści, brak-pliku-bezpieczny, żaden szablon nie serwuje surowej ścieżki, base używa helpera). Test kolejności skryptów zaktualizowany pod nowy format. Prezentacja 214. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
42 lines
1.5 KiB
Python
42 lines
1.5 KiB
Python
"""Cache-busting plików statycznych (PRE-26).
|
|
|
|
Po deployu przeglądarka trzymała stare styles.css / *.js (ten sam URL). Doklejamy
|
|
hash treści → zmiana pliku zmienia URL. Regresja byłaby CICHA (użytkownik widzi
|
|
stary interfejs), więc pilnujemy strukturalnie.
|
|
"""
|
|
import os
|
|
import pathlib
|
|
import re
|
|
|
|
os.environ.pop("APP_PASSWORD", None) # import app.main bez bramki logowania
|
|
|
|
from app.main import _asset_version, static_url
|
|
|
|
TEMPLATES = pathlib.Path(__file__).resolve().parents[1] / "app" / "templates"
|
|
|
|
|
|
def test_static_url_carries_content_hash():
|
|
assert re.fullmatch(r"/static/styles\.css\?v=[0-9a-f]{8}", static_url("styles.css"))
|
|
|
|
|
|
def test_version_is_content_based_so_differs_between_files():
|
|
assert _asset_version("styles.css") != _asset_version("formsync.js")
|
|
|
|
|
|
def test_missing_file_does_not_crash():
|
|
assert static_url("nie-ma-takiego.js").endswith("?v=0")
|
|
|
|
|
|
def test_no_template_serves_raw_static_paths():
|
|
"""Żaden href/src nie może iść na surowe /static/... — omijałoby cache-busting."""
|
|
for f in TEMPLATES.glob("*.html"):
|
|
txt = f.read_text(encoding="utf-8")
|
|
assert 'src="/static/' not in txt, f"{f.name}: surowy src bez cache-bustingu"
|
|
assert 'href="/static/' not in txt, f"{f.name}: surowy href bez cache-bustingu"
|
|
|
|
|
|
def test_base_uses_helper_for_stylesheet_and_scripts():
|
|
base = (TEMPLATES / "base.html").read_text(encoding="utf-8")
|
|
assert "static('styles.css')" in base
|
|
assert "static('formsync.js')" in base
|