# Geofence Testing Guide This document describes how to test the geofencing functionality. ## Prerequisites - Database initialized: `npm run db:init` - SMTP configured in `.env` or admin panel - MQTT broker running (for full integration test) ## Test Scripts ### 1. Database & Logic Test Tests geofence core functionality without MQTT or emails. ```bash npm run test:geofence ``` **What it does:** - Creates a test geofence in Frankfurt (50.1109, 8.6821) - Simulates 4 location updates (Outside → Inside → Inside → Outside) - Generates Enter and Exit events - Shows event history **Expected output:** ``` ✓ Created geofence (ID: ...) 📌 Processing location "Outside (Start)"... 📏 Distance from center: 1158m (OUTSIDE) ℹ No event (no state change) 📌 Processing location "Inside (Enter)"... 📏 Distance from center: 0m (INSIDE) 🔔 Generated ENTER event (ID: 1) 📌 Processing location "Inside (Stay)"... 📏 Distance from center: 73m (INSIDE) ℹ No event (no state change) 📌 Processing location "Outside (Exit)"... 📏 Distance from center: 1158m (OUTSIDE) 🔔 Generated EXIT event (ID: 2) Total events generated: 2 ``` ### 2. Email Notification Test Tests SMTP connection and email delivery without MQTT. ```bash npm run test:geofence:email ``` **What it does:** - Connects to SMTP server - Sends a test geofence notification email - Validates email template rendering **Expected output:** ``` ✓ SMTP connection successful! ✓ Email prepared ✅ Email sent successfully! Message ID: <...> Check your inbox at: joachim.hummel@gmail.com ``` **Email you should receive:** - Subject: "Device A hat Test Zone betreten" - Formatted HTML with geofence details - Time, position, distance from center ### 3. Full MQTT Integration Test Tests the complete flow: MQTT → Location → Geofence → Email. **Requirements:** - MQTT broker must be accessible - Admin credentials in `.env` (MQTT_ADMIN_USERNAME, MQTT_ADMIN_PASSWORD) ```bash npm run test:geofence:mqtt ``` **What it does:** - Creates a test geofence - Connects to MQTT broker - Publishes 4 OwnTracks location messages - Triggers geofence events - Results in email notifications (if dev server is running) **Expected output:** ``` ✓ Created test geofence: "MQTT Integration Test Zone" ✓ Connected to MQTT broker 📡 Publishing location: Outside (Start) ✓ Published 📡 Publishing location: Inside (Enter - should trigger EMAIL) ✓ Published ... ✅ Published 4 MQTT location messages ✅ Expected: 2 email notifications (Enter + Exit) ``` ## Manual Testing with OwnTracks ### Setup 1. Create a geofence via API or script 2. Configure OwnTracks app with your MQTT credentials 3. Move device in/out of geofence zone ### Create Geofence Manually ```bash # Get session cookie from browser (login first) curl -X POST http://localhost:3000/api/geofences \ -H "Content-Type: application/json" \ -H "Cookie: authjs.session-token=YOUR_COOKIE" \ -d '{ "name": "My Test Zone", "center_latitude": 50.1109, "center_longitude": 8.6821, "radius_meters": 500, "device_id": "12", "color": "#10b981" }' ``` ### Send Test MQTT Message ```bash # ENTER geofence (inside the zone) mosquitto_pub -h localhost -p 1883 \ -u admin -P 'YOUR_ADMIN_PASSWORD' \ -t "owntracks/user/12" \ -m '{"_type":"location","tid":"12","lat":50.1109,"lon":8.6821,"tst":'"$(date +%s)"',"batt":85,"vel":0}' # Wait 5 seconds, then EXIT geofence (outside the zone) mosquitto_pub -h localhost -p 1883 \ -u admin -P 'YOUR_ADMIN_PASSWORD' \ -t "owntracks/user/12" \ -m '{"_type":"location","tid":"12","lat":50.1200,"lon":8.6900,"tst":'"$(date +%s)"',"batt":84,"vel":5}' ``` **Expected:** - Dev server logs show: `✓ Location saved: 12 at (...)` - Geofence events logged: `[Geofence] Detected 1 event(s) for device 12` - Email notification sent to owner ## Verify Results ### Check Events in Database ```bash sqlite3 data/database.sqlite " SELECT id, event_type, timestamp, CAST(distance_from_center AS INTEGER) as distance, CASE notification_sent WHEN 0 THEN 'Pending' WHEN 1 THEN 'Sent' WHEN 2 THEN 'Failed' END as notification FROM GeofenceEvent ORDER BY id DESC LIMIT 10 " ``` ### Check Geofences ```bash sqlite3 data/database.sqlite " SELECT id, name, device_id, radius_meters, is_active FROM Geofence " ``` ### View Events via API ```bash curl http://localhost:3000/api/geofences \ -H "Cookie: authjs.session-token=YOUR_COOKIE" ``` ## Troubleshooting ### No Events Generated **Problem:** Location updates don't trigger events. **Possible causes:** 1. **Duplicate location** - The unique index prevents duplicate locations - Solution: Send locations with unique timestamps and coordinates 2. **Geofence inactive** - Check `is_active = 1` in database 3. **Wrong device** - Geofence is for different device 4. **MQTT subscriber not running** - Start dev server: `npm run dev` ### Email Not Received **Problem:** Events are created but no email arrives. **Check:** 1. **SMTP configuration** - Test with `npm run test:geofence:email` 2. **User email** - Check owner has email in database: ```bash sqlite3 data/database.sqlite "SELECT id, username, email FROM User" ``` 3. **Notification status** - Check `notification_sent` in GeofenceEvent table 4. **Spam folder** - Check your spam/junk folder ### MQTT Connection Failed **Problem:** `MQTT connection error: ECONNREFUSED` or `Not authorized` **Solutions:** 1. **Check broker URL** - Verify `MQTT_BROKER_URL` in `.env` 2. **Check credentials** - Verify `MQTT_ADMIN_USERNAME` and `MQTT_ADMIN_PASSWORD` 3. **Broker running** - Check: `nc -zv localhost 1883` 4. **Firewall** - Ensure port 1883 is open ## Cleanup ### Delete Test Geofences ```bash # List all geofences sqlite3 data/database.sqlite "SELECT id, name FROM Geofence" # Delete specific geofence (CASCADE deletes events and status) sqlite3 data/database.sqlite "DELETE FROM Geofence WHERE id = 'GEOFENCE_ID'" # Or via API curl -X DELETE http://localhost:3000/api/geofences/GEOFENCE_ID \ -H "Cookie: authjs.session-token=YOUR_COOKIE" ``` ### Delete Old Events ```bash # Delete events older than 30 days sqlite3 data/database.sqlite " DELETE FROM GeofenceEvent WHERE timestamp < datetime('now', '-30 days') " ``` ## Next Steps After successful testing: 1. **Deploy to production** - Ensure SMTP and MQTT are configured 2. **Create frontend UI** - Visual geofence editor on map (not yet implemented) 3. **Configure real devices** - Set up OwnTracks on mobile devices 4. **Monitor notifications** - Check GeofenceEvent table regularly ## Test Summary | Test | What it validates | Duration | |------|------------------|----------| | `npm run test:geofence` | Database, logic, calculations | ~1 second | | `npm run test:geofence:email` | SMTP, email templates | ~3 seconds | | `npm run test:geofence:mqtt` | Full integration chain | ~10 seconds | | Manual OwnTracks test | Real-world usage | Varies | All tests are **non-destructive** and create test data that can be easily cleaned up.