from unittest.mock import patch import pytest from openrgb_hue.scenes import ( BUNDLED_CSV_PATH, SceneNotFoundError, get_scene, list_scene_names, load_scenes, refresh_bundled_csv, ) SAMPLE_CSV = ( "Scene,Light,Red,Green,Blue,Brightness\n" "Alpha,light.hue_1,255,0,0,255\n" "Alpha,light.hue_2,0,255,0,200\n" "Beta,light.hue_1,0,0,255,100\n" ) @pytest.fixture def sample_csv_path(tmp_path): path = tmp_path / "scenes.csv" path.write_text(SAMPLE_CSV, encoding="utf-8") return path def test_load_scenes_groups_by_name_preserving_order(sample_csv_path): scenes = load_scenes(sample_csv_path) assert list(scenes.keys()) == ["Alpha", "Beta"] assert len(scenes["Alpha"].lights) == 2 assert len(scenes["Beta"].lights) == 1 def test_list_scene_names(sample_csv_path): assert list_scene_names(sample_csv_path) == ["Alpha", "Beta"] def test_get_scene_case_insensitive(sample_csv_path): scene = get_scene("alpha", sample_csv_path) assert scene.name == "Alpha" def test_get_scene_missing_raises_with_suggestion(sample_csv_path): with pytest.raises(SceneNotFoundError, match="Alpha"): get_scene("Alphaa", sample_csv_path) def test_bundled_csv_has_103_scenes_of_10_lights_each(): scenes = load_scenes(BUNDLED_CSV_PATH) assert len(scenes) == 103 assert all(len(scene.lights) == 10 for scene in scenes.values()) def test_refresh_bundled_csv_writes_validated_data(tmp_path): dest = tmp_path / "scenes.csv" class FakeResponse: def __enter__(self): return self def __exit__(self, *exc): return False def read(self): return SAMPLE_CSV.encode("utf-8") with patch("openrgb_hue.scenes.urllib.request.urlopen", return_value=FakeResponse()): result = refresh_bundled_csv(dest=dest, url="https://example.invalid/scenes.csv") assert result == dest assert dest.read_text(encoding="utf-8") == SAMPLE_CSV def test_refresh_bundled_csv_rejects_invalid_data(tmp_path): dest = tmp_path / "scenes.csv" class FakeResponse: def __enter__(self): return self def __exit__(self, *exc): return False def read(self): return b"not,a,valid,csv\n" with patch("openrgb_hue.scenes.urllib.request.urlopen", return_value=FakeResponse()): with pytest.raises(ValueError): refresh_bundled_csv(dest=dest, url="https://example.invalid/scenes.csv") assert not dest.exists()