Files
location-mqtt-tracker-app/docs/geofence-testing.md
Joachim Hummel 781e50b68a Add geofence testing documentation and finalize setup
**Documentation:**
- Added docs/geofence-testing.md with comprehensive test guide
- Includes all test scripts, manual testing procedures
- Troubleshooting section for common issues
- Cleanup instructions

**Configuration:**
- Updated admin user email to joachim.hummel@gmail.com
- Restored MQTT_BROKER_URL to mosquitto (Docker setup)
- Fixed test-mqtt-geofence.js to use admin credentials

**Test Results:**
 Database & Logic Test - Working perfectly
 Email Notification Test - Email sent successfully
 MQTT Integration - Server connects, receives messages
⚠️ Full chain test - Works but duplicate detection prevents retests

**What's Working:**
- Geofence creation and management via API
- Distance calculations (Haversine formula)
- Enter/Exit event generation with state tracking
- SMTP email delivery with React Email templates
- MQTT subscriber integration

**Ready for Production:**
The geofencing MVP is fully functional and ready for real-world
testing with OwnTracks devices sending unique location updates.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 18:40:33 +00:00

7.0 KiB
Raw Permalink Blame History

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.

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.

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)
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

# 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

# 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

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

sqlite3 data/database.sqlite "
  SELECT
    id,
    name,
    device_id,
    radius_meters,
    is_active
  FROM Geofence
"

View Events via API

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:
    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

# 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

# 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.