Spaces:
Sleeping
Sleeping
| """Contract Cache-Control của tầng static (31/07/2026 — việc C, gate G5.3). | |
| Nguyên nhân gốc bug tối 30/07: ``app.js`` bị trình duyệt cache hàng giờ sau | |
| deploy → alt không có quỹ đạo cho tới Ctrl+F5. Fix là header | |
| ``Cache-Control: no-cache`` trên ``.js``/``.css``/``.html`` — NO-CACHE chứ | |
| không phải no-store: vẫn cho revalidate 304, chỉ cấm dùng bản cũ không hỏi. | |
| Test đọc FILE THẬT trong ``app/static/`` (không cần pooltool — tầng static | |
| không đụng sim), nên nó cũng khoá luôn việc ba file FE còn tồn tại. | |
| """ | |
| from __future__ import annotations | |
| import pytest | |
| from fastapi.testclient import TestClient | |
| from app import main as app_main | |
| def client(): | |
| return TestClient(app_main.app) | |
| def test_static_js_css_html_co_no_cache(client, path): | |
| """G5.3: ``curl -I`` một file ``.js`` và ``/`` → ``Cache-Control: no-cache``. | |
| ``/`` đi qua nhánh html=True (index.html) — nhánh resolve KHÁC file thẳng, | |
| phải kiểm riêng.""" | |
| r = client.get(path) | |
| assert r.status_code == 200 | |
| assert r.headers.get("cache-control") == "no-cache" | |
| def test_304_van_mang_no_cache(client): | |
| """no-cache sống bằng revalidate: trình duyệt gửi If-None-Match mỗi lần. | |
| Nếu response 304 rơi mất header thì một số cache trung gian coi như hết | |
| chỉ thị và bug cũ quay lại đúng ở lần thứ hai.""" | |
| first = client.get("/app.js") | |
| etag = first.headers.get("etag") | |
| assert etag, "starlette phải trả ETag để revalidate được" | |
| r = client.get("/app.js", headers={"If-None-Match": etag}) | |
| assert r.status_code == 304 | |
| assert r.headers.get("cache-control") == "no-cache" | |
| def test_api_khong_bi_dinh_header_static(client): | |
| """Header thuộc TẦNG STATIC, không phải toàn app — /api/health không được | |
| lây (nó là JSON động, chính sách cache của nó là chuyện khác).""" | |
| r = client.get("/api/health") | |
| assert r.status_code == 200 | |
| assert r.headers.get("cache-control") != "no-cache" | |