# Map Feature Test Plan — Canteen Asset Tracker ## Map Stack - **Library:** Leaflet 1.9.4 (open-source) - **Tiles:** OpenStreetMap (free, no API key) - **Plugins:** Leaflet Draw (geofence polygons), Leaflet Heat (heatmap) - **Linking:** Google Maps Directions link opens externally ## Test Areas ### Frontend (UI) - [ ] Map tab loads with OpenStreetMap tiles visible - [ ] Asset pins render from API data - [ ] Pin popups show name, machine_id, category, status, address, Directions link, Details button - [ ] Directions link opens Google Maps in new tab - [ ] Pin toggle (show/hide) works - [ ] Heatmap toggle works - [ ] GPS center button centers map + shows blue dot - [ ] GPS toast shown when no GPS available - [ ] "Add Geofence" draw mode activates polygon drawing - [ ] Drawing mode cancellation clears temp layers - [ ] Saved geofence renders as colored polygon - [ ] Geofence popup shows name + Edit/Delete buttons - [ ] Edit geofence trigger - [ ] Delete geofence trigger ### API (50 tests in tests/test_map_api.py — all passing) - [x] GET /api/geofences returns all geofences with parsed points (sorted by name) - [x] POST /api/geofences creates geofence (with default color, duplicate names allowed) - [x] PUT /api/geofences/:id updates geofence (name, color, points, partial updates) - [x] DELETE /api/geofences/:id deletes geofence (204, verify gone) - [x] POST /api/geofences/check returns matching geofences for a point - [x] GET /api/proximity returns assets near GPS point (radius_meters, sorted by distance, max 50) - [x] GET /api/assets?limit=1000 returns assets with lat/lng for pins - [x] GPS coordinates survive asset update (PATCH semantics: null = preserve) - [ ] Asset pins refresh when new assets are added (frontend concern) ### Edge Cases - [x] Asset with null lat/lng excluded from proximity/pins - [x] Empty geofence list (no geofences) — returns [] - [x] Invalid geofence polygon (self-intersecting) — no crash - [x] Duplicate geofence name — allowed, both returned - [x] 404 on update/delete nonexistent geofence - [x] 422 on missing required fields (name, points, lat, lng) - [x] Proximity radius bounds (min=1, max=50000, default=200) - [x] Asset partial coordinates (lat-only, lng-only) - [ ] Very large number of pins (performance) — frontend concern - [ ] Map container hidden then shown (invalidateSize) — frontend concern