Spaces:
Paused
Paused
| """Tests for sample room data module.""" | |
| import pytest | |
| from pathlib import Path | |
| from ui.samples import ( | |
| SAMPLE_SCENARIOS, | |
| SAMPLE_SCENARIOS_BY_ID, | |
| SAMPLE_IMAGES_DIR, | |
| get_sample_choices, | |
| load_sample, | |
| load_sample_images, | |
| get_scenario_by_id, | |
| ) | |
| from ui.state import SessionState | |
| from ui.components import image_store | |
| class TestSampleScenarios: | |
| """Test sample scenario definitions.""" | |
| def test_four_scenarios_defined(self): | |
| """Verify exactly 4 sample scenarios are defined.""" | |
| assert len(SAMPLE_SCENARIOS) == 4 | |
| def test_scenario_ids_unique(self): | |
| """Verify all scenario IDs are unique.""" | |
| ids = [s.id for s in SAMPLE_SCENARIOS] | |
| assert len(ids) == len(set(ids)) | |
| def test_scenario_ids_expected(self): | |
| """Verify expected scenario IDs exist.""" | |
| expected_ids = {"bar_dining", "bar_area", "kitchen", "factory"} | |
| actual_ids = set(SAMPLE_SCENARIOS_BY_ID.keys()) | |
| assert actual_ids == expected_ids | |
| def test_all_scenarios_have_required_fields(self): | |
| """Verify all scenarios have required data fields.""" | |
| for scenario in SAMPLE_SCENARIOS: | |
| # Basic fields | |
| assert scenario.id | |
| assert scenario.name | |
| assert scenario.description | |
| assert scenario.image_files | |
| # Project data required fields | |
| assert "project_name" in scenario.project_data | |
| assert "address" in scenario.project_data | |
| assert "city" in scenario.project_data | |
| assert "state" in scenario.project_data | |
| assert "zip_code" in scenario.project_data | |
| assert "client_name" in scenario.project_data | |
| assert "fire_date" in scenario.project_data | |
| assert "assessment_date" in scenario.project_data | |
| assert "facility_classification" in scenario.project_data | |
| assert "construction_era" in scenario.project_data | |
| assert "assessor_name" in scenario.project_data | |
| # Room data required fields | |
| assert "name" in scenario.room_data | |
| assert "length_ft" in scenario.room_data | |
| assert "width_ft" in scenario.room_data | |
| assert "ceiling_height_ft" in scenario.room_data | |
| # Observations should have smoke/fire odor at minimum | |
| assert "smoke_fire_odor" in scenario.observations_data | |
| class TestSampleImages: | |
| """Test sample image file existence.""" | |
| def test_sample_images_dir_exists(self): | |
| """Verify sample images directory exists.""" | |
| assert SAMPLE_IMAGES_DIR.exists() | |
| assert SAMPLE_IMAGES_DIR.is_dir() | |
| def test_all_referenced_images_exist(self): | |
| """Verify all images referenced in scenarios exist on disk.""" | |
| missing_files = [] | |
| for scenario in SAMPLE_SCENARIOS: | |
| for filename in scenario.image_files: | |
| filepath = SAMPLE_IMAGES_DIR / filename | |
| if not filepath.exists(): | |
| missing_files.append(f"{scenario.id}: {filename}") | |
| assert not missing_files, f"Missing image files: {missing_files}" | |
| def test_bar_dining_has_3_images(self): | |
| """Verify Bar & Dining scenario has 3 images.""" | |
| scenario = SAMPLE_SCENARIOS_BY_ID["bar_dining"] | |
| assert len(scenario.image_files) == 3 | |
| def test_bar_area_has_3_images(self): | |
| """Verify Bar Area scenario has 3 images.""" | |
| scenario = SAMPLE_SCENARIOS_BY_ID["bar_area"] | |
| assert len(scenario.image_files) == 3 | |
| def test_kitchen_has_6_images(self): | |
| """Verify Kitchen scenario has 6 images.""" | |
| scenario = SAMPLE_SCENARIOS_BY_ID["kitchen"] | |
| assert len(scenario.image_files) == 6 | |
| def test_factory_has_1_image(self): | |
| """Verify Factory scenario has 1 image.""" | |
| scenario = SAMPLE_SCENARIOS_BY_ID["factory"] | |
| assert len(scenario.image_files) == 1 | |
| class TestGetSampleChoices: | |
| """Test get_sample_choices function.""" | |
| def test_returns_list_of_tuples(self): | |
| """Verify function returns list of (label, value) tuples.""" | |
| choices = get_sample_choices() | |
| assert isinstance(choices, list) | |
| for choice in choices: | |
| assert isinstance(choice, tuple) | |
| assert len(choice) == 2 | |
| def test_first_choice_is_placeholder(self): | |
| """Verify first choice is the placeholder.""" | |
| choices = get_sample_choices() | |
| label, value = choices[0] | |
| assert "Select" in label | |
| assert value == "" | |
| def test_returns_5_choices(self): | |
| """Verify returns 5 choices (1 placeholder + 4 scenarios).""" | |
| choices = get_sample_choices() | |
| assert len(choices) == 5 | |
| def test_all_scenario_ids_in_choices(self): | |
| """Verify all scenario IDs appear in choices.""" | |
| choices = get_sample_choices() | |
| values = [v for _, v in choices] | |
| assert "bar_dining" in values | |
| assert "bar_area" in values | |
| assert "kitchen" in values | |
| assert "factory" in values | |
| class TestLoadSample: | |
| """Test load_sample function.""" | |
| def test_load_valid_scenario_returns_session(self): | |
| """Verify loading valid scenario returns SessionState.""" | |
| session = load_sample("bar_dining") | |
| assert session is not None | |
| assert isinstance(session, SessionState) | |
| # Cleanup | |
| image_store.clear() | |
| def test_load_invalid_scenario_returns_none(self): | |
| """Verify loading invalid scenario returns None.""" | |
| session = load_sample("nonexistent_scenario") | |
| assert session is None | |
| def test_loaded_session_has_project_data(self): | |
| """Verify loaded session has correct project data.""" | |
| session = load_sample("bar_dining") | |
| assert session.project.project_name == "Sample: Bar & Dining Fire Assessment" | |
| assert session.project.city == "Springfield" | |
| assert session.project.state == "IL" | |
| # Cleanup | |
| image_store.clear() | |
| def test_loaded_session_has_room(self): | |
| """Verify loaded session has room data.""" | |
| session = load_sample("kitchen") | |
| assert len(session.rooms) == 1 | |
| assert session.rooms[0].name == "Commercial Kitchen" | |
| assert session.rooms[0].length_ft == 30.0 | |
| assert session.rooms[0].width_ft == 25.0 | |
| # Cleanup | |
| image_store.clear() | |
| def test_loaded_session_has_images(self): | |
| """Verify loaded session has images loaded into store.""" | |
| session = load_sample("bar_area") | |
| assert len(session.images) == 3 | |
| # Verify images are in store | |
| for img in session.images: | |
| assert image_store.get(img.id) is not None | |
| # Cleanup | |
| image_store.clear() | |
| def test_loaded_session_has_observations(self): | |
| """Verify loaded session has observations data.""" | |
| session = load_sample("factory") | |
| assert session.observations.smoke_fire_odor is True | |
| assert session.observations.odor_intensity == "strong" | |
| assert session.observations.large_char_particles is True | |
| # Cleanup | |
| image_store.clear() | |
| def test_loaded_session_tabs_marked_complete(self): | |
| """Verify loaded session has tabs marked as complete.""" | |
| session = load_sample("bar_dining") | |
| assert session.tab1_complete is True | |
| assert session.tab2_complete is True | |
| assert session.tab3_complete is True | |
| assert session.tab4_complete is True | |
| # Cleanup | |
| image_store.clear() | |
| def test_facility_classification_correct(self): | |
| """Verify facility classifications are set correctly.""" | |
| # Restaurant scenarios should be non-operational | |
| session = load_sample("bar_dining") | |
| assert session.project.facility_classification == "non-operational" | |
| image_store.clear() | |
| # Factory should be operational | |
| session = load_sample("factory") | |
| assert session.project.facility_classification == "operational" | |
| image_store.clear() | |
| def test_construction_era_correct(self): | |
| """Verify construction eras are set correctly.""" | |
| # Bar scenarios should be pre-1980 | |
| session = load_sample("bar_area") | |
| assert session.project.construction_era == "pre-1980" | |
| image_store.clear() | |
| # Kitchen should be 1980-2000 | |
| session = load_sample("kitchen") | |
| assert session.project.construction_era == "1980-2000" | |
| image_store.clear() | |
| class TestGetScenarioById: | |
| """Test get_scenario_by_id function.""" | |
| def test_returns_scenario_for_valid_id(self): | |
| """Verify returns scenario for valid ID.""" | |
| scenario = get_scenario_by_id("kitchen") | |
| assert scenario is not None | |
| assert scenario.id == "kitchen" | |
| assert scenario.name == "Kitchen" | |
| def test_returns_none_for_invalid_id(self): | |
| """Verify returns None for invalid ID.""" | |
| scenario = get_scenario_by_id("invalid_id") | |
| assert scenario is None | |
| class TestLoadSampleImages: | |
| """Test load_sample_images function.""" | |
| def test_loads_images_into_store(self): | |
| """Verify images are loaded into image_store.""" | |
| scenario = SAMPLE_SCENARIOS_BY_ID["bar_dining"] | |
| room_id = "test-room-123" | |
| image_metas = load_sample_images(scenario, room_id) | |
| assert len(image_metas) == 3 | |
| for meta in image_metas: | |
| assert meta.room_id == room_id | |
| assert image_store.get(meta.id) is not None | |
| # Cleanup | |
| image_store.clear() | |
| def test_image_metadata_has_correct_room_id(self): | |
| """Verify image metadata has correct room ID.""" | |
| scenario = SAMPLE_SCENARIOS_BY_ID["factory"] | |
| room_id = "factory-room-456" | |
| image_metas = load_sample_images(scenario, room_id) | |
| assert len(image_metas) == 1 | |
| assert image_metas[0].room_id == room_id | |
| # Cleanup | |
| image_store.clear() | |
| def test_image_ids_are_unique(self): | |
| """Verify each loaded image gets a unique ID.""" | |
| scenario = SAMPLE_SCENARIOS_BY_ID["kitchen"] | |
| room_id = "kitchen-room" | |
| image_metas = load_sample_images(scenario, room_id) | |
| ids = [meta.id for meta in image_metas] | |
| assert len(ids) == len(set(ids)) # All unique | |
| # Cleanup | |
| image_store.clear() | |