Add pytest suite and Gitea Actions CI/CD pipeline
CI / build-and-scan (pull_request) Successful in 56s
CI / build-and-scan (pull_request) Successful in 56s
83 tests (94% coverage of src/py) covering the builder pipeline (gallery sync, HTML/CSS generation, image processing, full site build) and the Flask webui (routes, uploads, theme/font management). Dockerfile gains a `test` stage (pytest) between the wheel builder and the prod image, and pins the alpine base to a full patch tag so Renovate can classify updates. CI workflow builds, smoke-tests, runs the suite, scans with Trivy, and publishes/releases on merge to main, following the same pipeline already running on adguard-cidre.
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
import yaml
|
||||
|
||||
from src.py.builder import gallery_builder as gb
|
||||
|
||||
|
||||
def _setup_repo(tmp_path, monkeypatch):
|
||||
(tmp_path / "config" / "photos" / "gallery").mkdir(parents=True)
|
||||
(tmp_path / "config" / "photos" / "hero").mkdir(parents=True)
|
||||
monkeypatch.chdir(tmp_path)
|
||||
|
||||
|
||||
def test_load_yaml_missing_file(tmp_path, monkeypatch):
|
||||
_setup_repo(tmp_path, monkeypatch)
|
||||
assert gb.load_yaml("config/gallery.yaml") == {}
|
||||
|
||||
|
||||
def test_load_yaml_and_save_yaml_roundtrip(tmp_path, monkeypatch):
|
||||
_setup_repo(tmp_path, monkeypatch)
|
||||
data = {"gallery": {"images": [{"src": "gallery/a.jpg", "tags": ["x"]}]}}
|
||||
gb.save_yaml(data, "config/gallery.yaml")
|
||||
|
||||
loaded = gb.load_yaml("config/gallery.yaml")
|
||||
assert loaded == data
|
||||
|
||||
|
||||
def test_get_all_image_paths_filters_and_sorts(tmp_path, monkeypatch, make_image):
|
||||
_setup_repo(tmp_path, monkeypatch)
|
||||
gallery_dir = tmp_path / "config" / "photos" / "gallery"
|
||||
make_image(gallery_dir / "b.jpg")
|
||||
make_image(gallery_dir / "a.png", fmt="PNG")
|
||||
(gallery_dir / "notes.txt").write_text("ignore me", encoding="utf-8")
|
||||
|
||||
paths = gb.get_all_image_paths(gallery_dir)
|
||||
|
||||
assert paths == ["gallery/a.png", "gallery/b.jpg"]
|
||||
|
||||
|
||||
def test_update_gallery_adds_new_and_removes_deleted(tmp_path, monkeypatch, make_image, capsys):
|
||||
_setup_repo(tmp_path, monkeypatch)
|
||||
gallery_dir = tmp_path / "config" / "photos" / "gallery"
|
||||
make_image(gallery_dir / "kept.jpg")
|
||||
make_image(gallery_dir / "new.jpg")
|
||||
|
||||
gb.save_yaml(
|
||||
{
|
||||
"gallery": {
|
||||
"images": [
|
||||
{"src": "gallery/kept.jpg", "tags": ["portrait"]},
|
||||
{"src": "gallery/gone.jpg", "tags": ["stale"]},
|
||||
]
|
||||
}
|
||||
},
|
||||
gb.GALLERY_YAML,
|
||||
)
|
||||
|
||||
gb.update_gallery()
|
||||
|
||||
result = gb.load_yaml(gb.GALLERY_YAML)
|
||||
images = {img["src"]: img for img in result["gallery"]["images"]}
|
||||
assert set(images) == {"gallery/kept.jpg", "gallery/new.jpg"}
|
||||
assert images["gallery/kept.jpg"]["tags"] == ["portrait"]
|
||||
assert images["gallery/new.jpg"]["tags"] == []
|
||||
|
||||
|
||||
def test_update_gallery_no_changes(tmp_path, monkeypatch, make_image, capsys):
|
||||
_setup_repo(tmp_path, monkeypatch)
|
||||
gallery_dir = tmp_path / "config" / "photos" / "gallery"
|
||||
make_image(gallery_dir / "only.jpg")
|
||||
gb.save_yaml(
|
||||
{"gallery": {"images": [{"src": "gallery/only.jpg", "tags": []}]}},
|
||||
gb.GALLERY_YAML,
|
||||
)
|
||||
|
||||
gb.update_gallery()
|
||||
|
||||
out = capsys.readouterr().out
|
||||
assert "No changes to gallery.yaml (gallery)" in out
|
||||
|
||||
|
||||
def test_update_hero_adds_new_and_removes_deleted(tmp_path, monkeypatch, make_image):
|
||||
_setup_repo(tmp_path, monkeypatch)
|
||||
hero_dir = tmp_path / "config" / "photos" / "hero"
|
||||
make_image(hero_dir / "kept.jpg")
|
||||
make_image(hero_dir / "new.jpg")
|
||||
|
||||
gb.save_yaml(
|
||||
{
|
||||
"hero": {
|
||||
"images": [
|
||||
{"src": "hero/kept.jpg"},
|
||||
{"src": "hero/gone.jpg"},
|
||||
]
|
||||
}
|
||||
},
|
||||
gb.GALLERY_YAML,
|
||||
)
|
||||
|
||||
gb.update_hero()
|
||||
|
||||
result = gb.load_yaml(gb.GALLERY_YAML)
|
||||
srcs = {img["src"] for img in result["hero"]["images"]}
|
||||
assert srcs == {"hero/kept.jpg", "hero/new.jpg"}
|
||||
|
||||
|
||||
def test_update_gallery_on_empty_yaml_initializes_section(tmp_path, monkeypatch, make_image):
|
||||
_setup_repo(tmp_path, monkeypatch)
|
||||
gallery_dir = tmp_path / "config" / "photos" / "gallery"
|
||||
make_image(gallery_dir / "only.jpg")
|
||||
|
||||
gb.update_gallery()
|
||||
|
||||
result = gb.load_yaml(gb.GALLERY_YAML)
|
||||
assert result["gallery"]["images"][0]["src"] == "gallery/only.jpg"
|
||||
Reference in New Issue
Block a user