music-assistant-server

2.1 KBPY
fixture_loader.py
2.1 KB58 lines • python
1"""Fixture management utilities for nicovideo tests."""
2
3from __future__ import annotations
4
5import json
6import pathlib
7from typing import TYPE_CHECKING, cast
8
9import pytest
10
11if TYPE_CHECKING:
12    from pydantic import BaseModel
13
14from tests.providers.nicovideo.types import JsonContainer
15
16
17class FixtureLoader:
18    """Loads and validates test fixtures with type validation."""
19
20    def __init__(self, fixtures_dir: pathlib.Path) -> None:
21        """Initialize the fixture manager with the directory containing fixtures."""
22        self.fixtures_dir = fixtures_dir
23
24    def load_fixture(self, relative_path: pathlib.Path) -> BaseModel | list[BaseModel] | None:
25        """Load and validate a JSON fixture against its expected type."""
26        data = self._load_json_fixture(relative_path)
27
28        fixture_type = self._get_fixture_type_from_path(relative_path)
29        if fixture_type is None:
30            pytest.fail(f"Unknown fixture type for {relative_path}")
31
32        try:
33            if isinstance(data, list):
34                return [fixture_type.model_validate(item) for item in data]
35            # Single object case
36            return fixture_type.model_validate(data)
37        except Exception as e:
38            pytest.fail(f"Failed to validate fixture {relative_path}: {e}")
39
40    def _get_fixture_type_from_path(self, relative_path: pathlib.Path) -> type[BaseModel] | None:
41        from tests.providers.nicovideo.fixture_data.fixture_type_mappings import (  # noqa: PLC0415 - Because it does not exist before generation
42            FIXTURE_TYPE_MAPPINGS,
43        )
44
45        for key, fixture_type in FIXTURE_TYPE_MAPPINGS.items():
46            if relative_path == pathlib.Path(key):
47                return fixture_type
48        return None
49
50    def _load_json_fixture(self, relative_path: pathlib.Path) -> JsonContainer:
51        """Load a JSON fixture file."""
52        fixture_path = self.fixtures_dir / relative_path
53        if not fixture_path.exists():
54            pytest.skip(f"Fixture {fixture_path} not found")
55
56        with fixture_path.open("r", encoding="utf-8") as f:
57            return cast("JsonContainer", json.load(f))
58