Browse Source
- Add serverMode configuration to test-user-zero config - Supports: localhost, staging, production, mock, custom - Auto-detects platform (Android/iOS/Web) for localhost URLs - Android emulator uses 10.0.2.2 for host machine localhost - Add getApiServerUrl() helper function - Returns correct URL based on serverMode and platform - Handles Android emulator special case (10.0.2.2) - Update TestUserZeroAPI to respect serverMode - Checks mock mode before making network calls - Uses getApiServerUrl() for base URL resolution - Allows runtime URL switching via setBaseUrl() - Add localhost testing configuration - Configurable port and HTTPS settings - Development mode headers support - Create localhost testing guide - Step-by-step setup instructions - Platform-specific localhost addresses explained - Quick test API server example - Troubleshooting common issues - Monitoring prefetch execution commands - Update Capacitor config to use getApiServerUrl() - Fixes breaking change from api.server removal This enables testing prefetch functionality with a local development API server running on localhost, perfect for development and debugging of the 5-minute prefetch scheduling feature.master
3 changed files with 381 additions and 8 deletions
@ -0,0 +1,293 @@ |
|||
# Localhost Testing Guide |
|||
|
|||
**Author**: Matthew Raymer |
|||
**Version**: 1.0.0 |
|||
**Status**: Testing Setup |
|||
|
|||
## Overview |
|||
|
|||
This guide explains how to test the daily notification plugin's prefetch functionality with a localhost development API server running on your host machine. |
|||
|
|||
## Android Emulator Localhost Access |
|||
|
|||
On Android emulator, `localhost` (127.0.0.1) refers to the **emulator itself**, not your host machine. To access your host machine's localhost from the Android emulator, use: |
|||
|
|||
**`10.0.2.2`** - Special alias that maps to host machine's localhost |
|||
|
|||
### Platform-Specific Localhost Addresses |
|||
|
|||
- **Android Emulator**: `http://10.0.2.2:PORT` |
|||
- **iOS Simulator**: `http://localhost:PORT` or `http://127.0.0.1:PORT` |
|||
- **Web Browser**: `http://localhost:PORT` |
|||
|
|||
## Setup Steps |
|||
|
|||
### 1. Start Your Local Development Server |
|||
|
|||
Start your TimeSafari API server on your host machine: |
|||
|
|||
```bash |
|||
# Example: If using Node.js/Express |
|||
cd /path/to/timesafari-api |
|||
npm start |
|||
# Server starts on http://localhost:3000 |
|||
``` |
|||
|
|||
### 2. Configure Test App for Localhost |
|||
|
|||
Edit `test-apps/daily-notification-test/src/config/test-user-zero.ts`: |
|||
|
|||
```typescript |
|||
api: { |
|||
serverMode: "localhost", // Change from "mock" to "localhost" |
|||
servers: { |
|||
localhost: { |
|||
android: "http://10.0.2.2:3000", // Match your local server port |
|||
ios: "http://localhost:3000", |
|||
web: "http://localhost:3000" |
|||
}, |
|||
// ... other server configs |
|||
}, |
|||
// ... |
|||
}, |
|||
testing: { |
|||
enableMockResponses: false, // Disable mocks to use real localhost API |
|||
// ... |
|||
} |
|||
``` |
|||
|
|||
### 3. Update Starred Plans in Test App |
|||
|
|||
In the test app UI (UserZeroView), use `updateStarredPlans()` to set which project IDs to query: |
|||
|
|||
```typescript |
|||
// In UserZeroView.vue or your test code |
|||
await DailyNotification.updateStarredPlans({ |
|||
planIds: ["test_project_1", "test_project_2", "test_project_3"] |
|||
}); |
|||
``` |
|||
|
|||
### 4. Schedule Notification for Testing |
|||
|
|||
Schedule a notification that will trigger prefetch 5 minutes before: |
|||
|
|||
```typescript |
|||
await DailyNotification.scheduleDailyNotification({ |
|||
time: "11:25", // Current time + 5+ minutes for testing |
|||
title: "Test Notification", |
|||
body: "Testing prefetch with localhost", |
|||
priority: "high" |
|||
}); |
|||
``` |
|||
|
|||
The prefetch will run 5 minutes before (11:20 in this example) and query your localhost API. |
|||
|
|||
## Testing Prefetch Flow |
|||
|
|||
### Expected Timeline |
|||
|
|||
1. **T-0**: You schedule notification for `11:25` |
|||
2. **T+0**: Plugin schedules prefetch for `11:20` (5 minutes before) |
|||
3. **T+0**: Plugin logs: |
|||
``` |
|||
DN|SCHEDULE_FETCH_START time=... |
|||
DN|WORK_ENQUEUED work_id=... fetch_at=... delay_ms=... |
|||
``` |
|||
4. **T+~5 minutes**: WorkManager triggers prefetch at `11:20` |
|||
5. **T+~5 minutes**: Plugin queries `http://10.0.2.2:3000/api/v2/report/plansLastUpdatedBetween` |
|||
6. **T+~10 minutes**: Notification displays at `11:25` |
|||
|
|||
### Monitoring Prefetch |
|||
|
|||
Watch logs for prefetch execution: |
|||
|
|||
```bash |
|||
# Filter for prefetch-related logs |
|||
adb logcat | grep -E "DN|SCHEDULE_FETCH|FETCH_PROJECT|WORK_ENQUEUED" |
|||
|
|||
# Watch WorkManager queue |
|||
adb shell dumpsys jobscheduler | grep daily_notification |
|||
|
|||
# Monitor network requests (if your server logs them) |
|||
# Check your localhost server logs for POST requests to /api/v2/report/plansLastUpdatedBetween |
|||
``` |
|||
|
|||
## Localhost API Server Requirements |
|||
|
|||
Your localhost API server must implement: |
|||
|
|||
### Endpoint: `POST /api/v2/report/plansLastUpdatedBetween` |
|||
|
|||
**Request:** |
|||
```json |
|||
{ |
|||
"planIds": ["test_project_1", "test_project_2"], |
|||
"afterId": "optional_jwt_id_for_pagination" |
|||
} |
|||
``` |
|||
|
|||
**Response:** |
|||
```json |
|||
{ |
|||
"data": [ |
|||
{ |
|||
"planSummary": { |
|||
"jwtId": "jwt_id_1", |
|||
"handleId": "test_project_1", |
|||
"name": "Test Project 1", |
|||
"description": "Project description", |
|||
"issuerDid": "did:key:...", |
|||
"agentDid": "did:key:...", |
|||
"startTime": "2025-01-01T00:00:00Z", |
|||
"endTime": "2025-01-31T23:59:59Z" |
|||
}, |
|||
"previousClaim": { |
|||
"jwtId": "previous_jwt_id", |
|||
"claimType": "project_update" |
|||
} |
|||
} |
|||
], |
|||
"hitLimit": false, |
|||
"pagination": { |
|||
"hasMore": false, |
|||
"nextAfterId": null |
|||
} |
|||
} |
|||
``` |
|||
|
|||
**Headers Required:** |
|||
- `Authorization: Bearer <JWT_TOKEN>` |
|||
- `Content-Type: application/json` |
|||
- `User-Agent: TimeSafari-DailyNotificationPlugin/1.0.0` |
|||
|
|||
## Quick Test Script |
|||
|
|||
Create a minimal localhost API server for testing: |
|||
|
|||
```javascript |
|||
// test-api-server.js |
|||
const express = require('express'); |
|||
const app = express(); |
|||
|
|||
app.use(express.json()); |
|||
|
|||
app.post('/api/v2/report/plansLastUpdatedBetween', (req, res) => { |
|||
console.log('📥 Prefetch request received:', { |
|||
planIds: req.body.planIds, |
|||
afterId: req.body.afterId, |
|||
headers: req.headers |
|||
}); |
|||
|
|||
// Return mock response |
|||
res.json({ |
|||
data: [ |
|||
{ |
|||
planSummary: { |
|||
jwtId: `${Date.now()}_test_123`, |
|||
handleId: req.body.planIds[0] || "test_project", |
|||
name: "Localhost Test Project", |
|||
description: "Testing prefetch from localhost", |
|||
issuerDid: "did:test:issuer", |
|||
agentDid: "did:test:agent", |
|||
startTime: new Date().toISOString(), |
|||
endTime: new Date(Date.now() + 86400000).toISOString() |
|||
}, |
|||
previousClaim: { |
|||
jwtId: "previous_test_jwt", |
|||
claimType: "project_update" |
|||
} |
|||
} |
|||
], |
|||
hitLimit: false, |
|||
pagination: { |
|||
hasMore: false, |
|||
nextAfterId: null |
|||
} |
|||
}); |
|||
}); |
|||
|
|||
app.listen(3000, () => { |
|||
console.log('🧪 Test API server running on http://localhost:3000'); |
|||
console.log('📡 Android emulator should use: http://10.0.2.2:3000'); |
|||
}); |
|||
``` |
|||
|
|||
Run with: |
|||
```bash |
|||
node test-api-server.js |
|||
``` |
|||
|
|||
## Troubleshooting |
|||
|
|||
### Prefetch Not Executing |
|||
|
|||
1. **Check WorkManager queue:** |
|||
```bash |
|||
adb shell dumpsys jobscheduler | grep -A 20 "daily_notification" |
|||
``` |
|||
|
|||
2. **Verify prefetch was scheduled:** |
|||
```bash |
|||
adb logcat | grep "DN|SCHEDULE_FETCH" |
|||
``` |
|||
|
|||
3. **Check if WorkManager has constraints:** |
|||
- Battery optimization might be blocking execution |
|||
- Network might not be available |
|||
- Device might be in deep sleep |
|||
|
|||
### Cannot Connect to Localhost |
|||
|
|||
1. **Android Emulator**: Use `10.0.2.2` not `localhost` or `127.0.0.1` |
|||
2. **Firewall**: Check if your firewall is blocking port 3000 |
|||
3. **Server not running**: Verify server is listening on correct port |
|||
4. **Wrong port**: Match the port in config with your server's port |
|||
|
|||
### Network Timeout |
|||
|
|||
Increase timeout in config: |
|||
|
|||
```typescript |
|||
testing: { |
|||
timeoutMs: 60000, // Increase from 30000 to 60000 |
|||
} |
|||
``` |
|||
|
|||
### Authentication Errors |
|||
|
|||
Your localhost server should accept the JWT token generated by the plugin. For testing, you can: |
|||
|
|||
1. **Disable JWT validation** in your localhost server |
|||
2. **Use a test JWT secret** that matches plugin config |
|||
3. **Log the JWT** in your server to see what's being sent |
|||
|
|||
## Switching Between Mock and Localhost |
|||
|
|||
You can switch modes without rebuilding: |
|||
|
|||
1. **Mock Mode** (offline testing): |
|||
```typescript |
|||
api.serverMode = "mock"; |
|||
testing.enableMockResponses = true; |
|||
``` |
|||
|
|||
2. **Localhost Mode** (real API calls to localhost): |
|||
```typescript |
|||
api.serverMode = "localhost"; |
|||
testing.enableMockResponses = false; |
|||
``` |
|||
|
|||
3. **Staging Mode** (real API calls to staging): |
|||
```typescript |
|||
api.serverMode = "staging"; |
|||
testing.enableMockResponses = false; |
|||
``` |
|||
|
|||
## Next Steps |
|||
|
|||
- Test prefetch execution with real localhost API |
|||
- Monitor network traffic to verify requests |
|||
- Test with different starred plan IDs |
|||
- Verify prefetch timing (5 minutes before notification) |
|||
- Test notification delivery after prefetch completes |
|||
|
|||
Loading…
Reference in new issue