from sqlalchemy import text def test_homeassistant_publish_records_location(location_client) -> None: client, engine = location_client response = client.post( "/homeassistant/publish", json={ "target": "location_recorder", "action": "record", "content": "{'person': 'tianyu', 'latitude': '1.23', 'longitude': '4.56'}", }, ) assert response.status_code == 200 assert response.text == "" with engine.connect() as conn: row = conn.execute( text( "SELECT person, latitude, longitude, altitude " "FROM location ORDER BY datetime DESC LIMIT 1" ) ).one() assert row.person == "tianyu" assert row.latitude == 1.23 assert row.longitude == 4.56 assert row.altitude == 0.0 def test_homeassistant_publish_records_location_with_altitude(location_client) -> None: client, engine = location_client response = client.post( "/homeassistant/publish", json={ "target": "location_recorder", "action": "record", "content": ( "{'person': 'tianyu-alt', 'latitude': '1.23', " "'longitude': '4.56', 'altitude': '7.89'}" ), }, ) assert response.status_code == 200 assert response.text == "" with engine.connect() as conn: row = conn.execute( text( "SELECT person, latitude, longitude, altitude " "FROM location ORDER BY datetime DESC LIMIT 1" ) ).one() assert row.person == "tianyu-alt" assert row.latitude == 1.23 assert row.longitude == 4.56 assert row.altitude == 7.89 def test_homeassistant_publish_rejects_invalid_envelope(location_client) -> None: client, _ = location_client response = client.post( "/homeassistant/publish", json={ "target": "location_recorder", "action": "record", "content": "{}", "extra": "not-allowed", }, ) assert response.status_code == 400 assert response.text == "bad request" assert "extra" not in response.text def test_homeassistant_publish_rejects_invalid_json_body(location_client) -> None: client, _ = location_client response = client.post( "/homeassistant/publish", content='{"target": "location_recorder", "action": "record", "content": ', headers={"Content-Type": "application/json"}, ) assert response.status_code == 400 assert response.text == "bad request" def test_homeassistant_publish_rejects_missing_content(location_client) -> None: client, _ = location_client response = client.post( "/homeassistant/publish", json={ "target": "location_recorder", "action": "record", }, ) assert response.status_code == 400 assert response.text == "bad request" assert "content" not in response.text def test_homeassistant_publish_returns_internal_error_for_unconfigured_ticktick(location_client) -> None: client, _ = location_client response = client.post( "/homeassistant/publish", json={ "target": "ticktick", "action": "create_action_task", "content": "{'action': 'take out trash', 'due_hour': 6}", }, ) assert response.status_code == 500 assert response.text == "internal server error" def test_homeassistant_publish_rejects_invalid_ticktick_content(location_client) -> None: client, _ = location_client response = client.post( "/homeassistant/publish", json={ "target": "ticktick", "action": "create_action_task", "content": "{}", }, ) assert response.status_code == 400 assert response.text == "bad request" def test_homeassistant_publish_returns_not_implemented_for_unknown_location_action( location_client, ) -> None: client, _ = location_client response = client.post( "/homeassistant/publish", json={ "target": "location_recorder", "action": "unknown_action", "content": "{}", }, ) assert response.status_code == 500 assert response.text == "internal server error" def test_homeassistant_publish_rejects_invalid_location_content(location_client) -> None: client, _ = location_client response = client.post( "/homeassistant/publish", json={ "target": "location_recorder", "action": "record", "content": "{'person': 'tianyu', 'latitude': 'bad-lat', 'longitude': '4.56'}", }, ) assert response.status_code == 400 assert response.text == "bad request" assert "bad-lat" not in response.text