Skip to content

Venue & Lantern Testing Guide

Overview

This guide walks you through testing the new venue and lantern lighting functionality across multiple devices.


Quick Setup

1. Seed Test Venues (One-Time Setup)

Make sure dev server is running first: npm run dev

Open your browser's developer console (F12) and run:

javascript
// The seed function is automatically available in dev mode
await window.seedVenues()

You should see output like:

🌱 Seeding test venues...
✅ Created: Brew & Co Coffee
✅ Created: Sunset Yoga Studio
... (8 venues total)
🎉 Seeding complete! Created 8/8 venues.

Verify in Firestore Console:

  1. Go to Firebase Console → Firestore Database
  2. You should see a venues collection with 8 documents
  3. Each document has: name, address, lat, lng, category, activeLanternCount, etc.

If you don't see venues in Firestore:

  • Check browser console for errors
  • Verify you're logged in (auth required to create venues)
  • Check Firebase project: Should be lantern-app-dev
  • Deploy Firestore rules if needed: firebase deploy --only firestore:rules

This will create 8 test venues in downtown San Diego.


2. Set Location Spoofing

In .env.local:

bash
# San Diego coordinates (downtown Gaslamp Quarter)
VITE_DEV_TEST_LOCATION="32.7157,-117.1611"

Restart dev server: npm run dev


Testing Workflow

Single Device Test

  1. Login to the app with a test account

  2. Open Dashboard (should be default view)

  3. Click the Fire icon (bottom nav)

  4. Lantern Hub opens → Click "Light Lantern"

  5. Select a venue from the nearby list (should show all 8 test venues)

  6. Lantern lights → You'll see:

    • Active lantern in Lantern Hub
    • Countdown timer (2 hours)
    • Venue name and details
  7. Extinguish → Click "Extinguish Lantern" in Lantern Hub


Multi-Device Test (Waves)

Device A (User 1)

  1. Login with user1@test.com
  2. Set location spoof to San Diego (32.7157,-117.1611)
  3. Light lantern at Brew & Co Coffee
  4. Leave Lantern Hub open

Device B (User 2)

  1. Login with user2@test.com
  2. Set same location spoof
  3. Light lantern at Brew & Co Coffee (same venue)
  4. Both users now have active lanterns at the same venue

Test Wave Interaction (Coming Next)

  • User 2 should see User 1's lantern in the venue
  • User 2 can send a "Wave" to User 1
  • User 1 receives wave notification
  • Both can start a chat

Test Venues

All venues are clustered around downtown San Diego:

Venue NameCategoryMerchant?
Brew & Co CoffeeCoffee ShopNo
Sunset Yoga StudioYoga StudioNo
The Gaslamp TavernBarNo
Pacific Bites RestaurantRestaurantNo
Zen Wellness SpaWellnessNo
Harbor Fitness GymGymNo
Pages & Prose BookstoreBookstoreNo
Urban BowlsRestaurantYes (demo merchant)

Firestore Security Rules

Before testing, ensure these rules are deployed:

javascript
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Venues - read-only for all authenticated users
    match /venues/{venueId} {
      allow read: if request.auth != null;
      allow write: if false; // Admin only (manual seed)
    }
    
    // Lanterns - users can only manage their own
    match /lanterns/{lanternId} {
      allow read: if request.auth != null;
      allow create: if request.auth != null 
        && request.resource.data.userId == request.auth.uid;
      allow update, delete: if request.auth != null 
        && resource.data.userId == request.auth.uid;
    }
  }
}

Deploy with:

bash
firebase deploy --only firestore:rules

Troubleshooting

"No venues found nearby"

  • Check .env.local has VITE_DEV_TEST_LOCATION set
  • Restart dev server
  • Open ProfileSettings → Location Spoofing panel → Verify coordinates
  • Ensure venues were seeded successfully

"Unable to get your location"

  • Browser location permission may be blocked
  • Use the debug panel in ProfileSettings to manually set location
  • Check console for geolocation errors

"Lantern not appearing in Hub"

  • Check Firestore console → lanterns collection
  • Verify user is authenticated (check localStorage for auth token)
  • Check browser console for errors
  • Try refreshing the page

"Lantern expired immediately"

  • Check system clock (ensure it's accurate)
  • Lanterns expire after 2 hours by default
  • Check expiresAt field in Firestore document

Next Steps

Once basic venue/lantern functionality works:

  1. Build Wave System

    • Query active lanterns at same venue
    • Send/receive wave notifications
    • Accept/reject wave UI
  2. Add Real-time Sync

    • Live lantern count updates
    • Wave notifications via Firestore listeners
    • Chat message sync
  3. Add Merchant Offers

    • Wire Urban Bowls (demo merchant) to offer system
    • Show offers when checking in at merchant venues
    • Redemption flow

Geofencing Testing

Added: 2026-01-18 (Issue #28)

Overview

Lantern lighting now requires users to be within a venue's geofence (default 100m, or custom venue.radius). This is validated both client-side and server-side via Cloud Functions.

Why server-side validation?
Client-side JavaScript can be modified by users (via DevTools or direct Firestore writes). The lightLanternSecure Cloud Function performs tamper-proof validation on Google's servers, preventing users from faking their location to light lanterns at venues they're not actually at. This is critical for merchant trust and offer redemption integrity.

Test Scenarios

Test 1: Within Geofence (Should Succeed)

  1. Set location at venue coordinates:
    javascript
    localStorage.setItem('dev_spoofed_location', JSON.stringify({latitude: 32.7157, longitude: -117.1611}))
    location.reload()
  2. Navigate to a nearby venue and light a lantern
  3. Expected: Lantern lights successfully
  4. Console shows: 🔥 Lantern lit via Cloud Function (Xm from venue)

Test 2: Outside Geofence (Should Fail)

  1. Set location 500m away:
    javascript
    localStorage.setItem('dev_spoofed_location', JSON.stringify({latitude: 32.7200, longitude: -117.1611}))
    location.reload()
  2. Try to light a lantern at Brew & Co Coffee
  3. Expected: Error message: "You must be within 100m of Brew & Co Coffee to light a lantern. You are currently 478m away."

Test 3: Boundary Edge Case (~100m)

  1. Set location approximately 100m from venue:
    javascript
    localStorage.setItem('dev_spoofed_location', JSON.stringify({latitude: 32.7166, longitude: -117.1611}))
    location.reload()
  2. Try to light a lantern
  3. Expected: Should succeed (boundary is inclusive)

Test 4: Custom Venue Radius

Some venues may have custom radius values in Firestore. To test:

  1. In Firestore, set a venue's radius field to 200 (meters)
  2. Position yourself at 150m away
  3. Expected: Should succeed (within 200m custom radius)

Unit Tests

Run the automated geofencing tests:

bash
npm test -- --run src/__tests__/geofencing.test.js src/__tests__/lanternProximity.test.js

Coverage:

  • geofencing.test.js - 15 tests for distance calculation and formatting
  • lanternProximity.test.js - 13 tests for lantern lighting proximity validation

Cloud Function Verification

To verify server-side validation is working:

  1. Open browser DevTools → Network tab
  2. Light a lantern successfully
  3. Look for lightLanternSecure request to Cloud Functions
  4. Response should include distanceMeters field

If Cloud Function is unavailable, client falls back to local validation with console warning:

Cloud Function unavailable, falling back to client-side validation

Clean Up Test Data

To remove all test venues:

javascript
// In browser console
import { db } from './src/firebase'
import { collection, getDocs, deleteDoc } from 'firebase/firestore'

const venuesRef = collection(db, 'venues')
const snapshot = await getDocs(venuesRef)
for (const doc of snapshot.docs) {
  await deleteDoc(doc.ref)
  console.log('Deleted:', doc.id)
}

To remove all test lanterns:

javascript
const lanternsRef = collection(db, 'lanterns')
const snapshot = await getDocs(lanternsRef)
for (const doc of snapshot.docs) {
  await deleteDoc(doc.ref)
  console.log('Deleted:', doc.id)
}

Built with VitePress