Files
pgames-manager/backend/tests/test_gallery.py
T
mrleo1nid 19924e1c5a
CI / frontend (push) Failing after 22s
CI / backend (push) Failing after 42s
feat: unlock in-game galleries per owned version
2026-10-27 15:45:22 +03:00

83 lines
4.1 KiB
Python

import asyncio
from types import SimpleNamespace
from unittest.mock import AsyncMock
import pytest
from fastapi import HTTPException
from app import gallery
from app.routers import versions
from app.schemas import ForkIn, GallerySettingsIn
@pytest.mark.parametrize(("game", "expected"), [
({"build": {"name": "MIST"}, "screens": {"rewatchgirlselectscreen": {}}}, True),
({"init": [{"k": "call", "f": {"k": "name", "id": "Gallery"}}]}, True),
({"screens": {"replay": {"k": "call", "f": {"k": "name", "id": "Replay"}}}}, True),
({"init": [], "screens": {}}, False),
({"engine": "naninovel", "init": [{"k": "call", "f": {"k": "name", "id": "Gallery"}}]}, False),
])
def test_supported_gallery_detection(monkeypatch, game, expected):
monkeypatch.setattr(gallery, "file_json", lambda *_: game)
assert gallery.available({"files": {"game.json": {}}}) is expected
assert not gallery.available(None)
def test_only_owner_can_toggle_gallery_and_scripts_are_not_modified(monkeypatch):
manifest = {"files": {"game.json": {"hash": "unchanged"}}}
v = SimpleNamespace(owner_id=7, status="ready", manifest=manifest, gallery_unlocked=False)
monkeypatch.setattr(versions, "get_version", AsyncMock(return_value=v))
monkeypatch.setattr(versions, "gallery_available", lambda _: True)
db = SimpleNamespace(commit=AsyncMock())
async def scenario():
body = GallerySettingsIn(gallery_unlocked=True)
with pytest.raises(HTTPException) as error:
await versions.update_gallery(1, body, SimpleNamespace(id=8), db)
assert error.value.status_code == 403
assert not v.gallery_unlocked
result = await versions.update_gallery(1, body, SimpleNamespace(id=7), db)
assert result.gallery_unlocked
assert result.manifest is manifest
await versions.update_gallery(1, GallerySettingsIn(gallery_unlocked=False), SimpleNamespace(id=7), db)
assert not v.gallery_unlocked
assert db.commit.await_count == 2
asyncio.run(scenario())
@pytest.mark.parametrize(("state", "supported", "code"), [("converting", True, 409), ("ready", False, 422)])
def test_gallery_requires_ready_supported_game(monkeypatch, state, supported, code):
v = SimpleNamespace(owner_id=7, status=state, manifest={}, gallery_unlocked=False)
monkeypatch.setattr(versions, "get_version", AsyncMock(return_value=v))
monkeypatch.setattr(versions, "gallery_available", lambda _: supported)
db = SimpleNamespace(commit=AsyncMock())
with pytest.raises(HTTPException) as error:
asyncio.run(versions.update_gallery(1, GallerySettingsIn(gallery_unlocked=True), SimpleNamespace(id=7), db))
assert error.value.status_code == code
db.commit.assert_not_awaited()
def test_player_manifest_uses_version_flag_instead_of_shared_manifest(monkeypatch):
shared = {"files": {"game.json": {"hash": "unchanged"}}}
v = SimpleNamespace(id=1, status="ready", manifest=shared, revision_id="revision", gallery_unlocked=True)
monkeypatch.setattr(versions, "get_version", AsyncMock(return_value=v))
result = asyncio.run(versions.version_manifest(1, SimpleNamespace(id=7), None))
assert result["galleryUnlocked"] is True
assert "galleryUnlocked" not in shared
v.gallery_unlocked = False
assert asyncio.run(versions.version_manifest(1, SimpleNamespace(id=7), None))["galleryUnlocked"] is False
def test_fork_inherits_gallery_setting_but_can_change_it_independently(monkeypatch):
parent = SimpleNamespace(id=1, game_id=2, status="ready", gallery_unlocked=True,
manifest={"files": {}}, revision_id="base", report={}, size_bytes=1)
monkeypatch.setattr(versions, "get_version", AsyncMock(return_value=parent))
monkeypatch.setattr(versions, "has_perm", lambda *_: True)
added = []
db = SimpleNamespace(add=added.append, commit=AsyncMock())
fork = asyncio.run(versions.fork_version(1, ForkIn(name="My fork"), SimpleNamespace(id=7), db))
assert fork.gallery_unlocked is True
fork.gallery_unlocked = False
assert parent.gallery_unlocked is True
assert fork.manifest is parent.manifest