waterleaf / tests /test_ui.py
hkaraoguz's picture
Replace Perenual with local care baselines
d70a4af verified
Raw
History Blame
4.2 kB
import json
import pytest
from waterleaf.application import WaterleafApplication
from waterleaf.models import TaxonCandidate
from waterleaf.storage import GardenStore
from waterleaf.ui import _candidate_label, _parse_optional_interval, build_ui
class NoopCare:
def get_care(self, scientific_name):
raise AssertionError("Not called while building UI")
class NoopWeather:
def geocode(self, query):
raise AssertionError("Not called while building UI")
def forecast(self, latitude, longitude):
raise AssertionError("Not called while building UI")
class NoopIdentification:
def identify(self, image_paths):
raise AssertionError("Not called while building UI")
class NoopTaxonomy:
def suggest(self, query, limit=10):
return []
def test_ui_contains_dashboard_capture_confirmation_and_export(tmp_path):
application = WaterleafApplication(
store=GardenStore(tmp_path / "waterleaf.sqlite3"),
media_directory=tmp_path / "media",
export_directory=tmp_path / "exports",
public_base_url="https://waterleaf.example",
care=NoopCare(),
weather=NoopWeather(),
)
demo = build_ui(
application,
identification=NoopIdentification(),
taxonomy=NoopTaxonomy(),
sample_image="assets/sample-lavender.png",
)
config_file = demo.get_config_file()
config = json.dumps(config_file, default=str)
assert "Waterleaf" in config
assert "Add plant" in config
assert "Analyze photos" in config
assert "Confirm species" in config
assert "Generate 30-day calendar" in config
assert "Sign in with Hugging Face" in config
assert "Plant photo (required)" in config
assert "Database match (required)" in config
assert "Plant nickname (required)" in config
assert "City (required)" in config
assert "Watering time (required)" in config
assert "Watering interval in days" in config
assert "Leave blank when a local baseline is available" in config
assert "Example: 7" in config
assert "Garden location" not in config
assert "Interval override" not in config
city = next(
component
for component in config_file["components"]
if component.get("props", {}).get("label") == "City (required)"
)
assert city["props"]["value"] == "Stockholm, Sweden"
def test_ui_handlers_are_not_exposed_as_public_api(tmp_path):
application = WaterleafApplication(
store=GardenStore(tmp_path / "waterleaf.sqlite3"),
media_directory=tmp_path / "media",
export_directory=tmp_path / "exports",
public_base_url="https://waterleaf.example",
care=NoopCare(),
weather=NoopWeather(),
)
demo = build_ui(
application,
identification=NoopIdentification(),
taxonomy=NoopTaxonomy(),
sample_image="assets/sample-lavender.png",
)
dependencies = demo.get_config_file()["dependencies"]
assert dependencies
assert all(item["api_visibility"] != "public" for item in dependencies)
save_dependency = next(
item for item in dependencies if item["api_name"] == "save"
)
assert len(save_dependency["outputs"]) == 2
def test_optional_watering_interval_accepts_blank_or_one_to_thirty_days():
assert _parse_optional_interval("") is None
assert _parse_optional_interval("7") == 7
with pytest.raises(ValueError, match="whole number from 1 to 30"):
_parse_optional_interval("0")
with pytest.raises(ValueError, match="whole number from 1 to 30"):
_parse_optional_interval("weekly")
def test_candidate_label_shows_common_and_scientific_names():
candidate = TaxonCandidate(
taxon_key="2927305",
scientific_name="Lavandula angustifolia",
common_name="English lavender",
confidence=0.8,
)
unavailable = candidate.model_copy(
update={"common_name": "Lavandula angustifolia"}
)
assert _candidate_label(candidate) == (
"English lavender | Lavandula angustifolia | 80%"
)
assert _candidate_label(unavailable) == (
"Lavandula angustifolia | Common name unavailable | 80%"
)