Browse Source

feat(test-apps): update Android test app with Phase 4 TimeSafari components

- Added Phase 4 imports: EndorserAPIClient, SecurityManager, TimeSafariNotificationManager
- Enhanced ConfigLoader with Phase 4 configuration methods
- Updated TimeSafariAndroidTestApp class with Phase 4 component integration
- Added comprehensive Phase 4 test methods:
  - testSecurityManager(): JWT generation/verification testing
  - testEndorserAPIClient(): Endorser.ch API integration testing
  - testTimeSafariNotificationManager(): Notification generation testing
  - testPhase4Integration(): Complete workflow testing
- Added Phase 4 initialization in constructor and setupEventListeners
- Updated HTML with Phase 4 test buttons and UI sections
- Enhanced configuration with security and EndorserAPI settings
- Added TimeSafari user configuration with preferences and test data

Android test app now fully supports Phase 4 TimeSafari integration testing
master
Matthew Raymer 3 days ago
parent
commit
f33d96d7a6
  1. 11
      test-apps/android-test/src/index.html
  2. 328
      test-apps/android-test/src/index.ts

11
test-apps/android-test/src/index.html

@ -392,6 +392,17 @@
</div>
</div>
<!-- Phase 4: TimeSafari Components Testing -->
<div class="ui-section">
<h3>🚀 Phase 4: TimeSafari Components</h3>
<div class="button-grid">
<button id="test-security-manager" class="btn-primary">Test SecurityManager</button>
<button id="test-endorser-api-client" class="btn-primary">Test EndorserAPIClient</button>
<button id="test-notification-manager" class="btn-primary">Test NotificationManager</button>
<button id="test-phase4-integration" class="btn-secondary">Test Complete Integration</button>
</div>
</div>
<!-- Error Handling Section -->
<div class="ui-section">
<h3>⚠️ Error Handling</h3>

328
test-apps/android-test/src/index.ts

@ -1,6 +1,18 @@
import { Capacitor } from '@capacitor/core';
// Mock classes for testing when shared utilities aren't available
import { DailyNotificationPlugin } from '@timesafari/daily-notification-plugin';
// Phase 4: Import TimeSafari components
import { EndorserAPIClient, TIMESAFARI_ENDSORER_CONFIG } from '../../../src/typescript/EndorserAPIClient';
import { SecurityManager, TIMESAFARI_SECURITY_CONFIG } from '../../../src/typescript/SecurityManager';
import { TimeSafariNotificationManager, DEFAULT_TIMESAFARI_PREFERENCES } from '../../../src/typescript/TimeSafariNotificationManager';
import {
TimeSafariUser,
TimeSafariPreferences,
EnhancedTimeSafariNotification,
TimeSafariNotificationType
} from '../../../src/definitions';
// Enhanced ConfigLoader for Phase 4
class ConfigLoader {
private static instance: ConfigLoader;
private config: any;
@ -25,13 +37,28 @@ class ConfigLoader {
},
endorser: {
baseUrl: 'http://10.0.2.2:3001/api/v2/report',
apiKey: 'test-api-key'
apiKey: 'test-api-key',
// Phase 4: Enhanced EndorserAPI configuration
timeoutMs: 15000,
maxRetries: 3,
enableParallel: true,
maxConcurrent: 3
},
security: {
// Phase 4: Security configuration
enableCryptoSigning: true,
enableJWTGeneration: true,
jwtExpirationMinutes: 60,
signatureAlgorithm: 'ES256K',
credentialStorage: 'secure_element'
},
testData: {
userDid: 'user:test',
userDid: 'did:example:android-test-user',
lastKnownOfferId: '0',
lastKnownPlanId: '0',
starredPlanIds: ['plan:test']
starredPlanIds: ['plan:test-1', 'plan:test-2'],
favoritePersonIds: ['person:test-1'],
favoriteItemIds: ['item:test-1']
}
};
}
@ -50,6 +77,39 @@ class ConfigLoader {
return `${this.config.endorser.baseUrl}${endpoints[endpoint] || endpoint}`;
}
// Phase 4: Enhanced configuration methods
getEndorserAPIConfig() {
return {
baseUrl: this.config.endorser.baseUrl.replace('/api/v2/report', ''),
timeoutMs: this.config.endorser.timeoutMs,
maxRetries: this.config.endorser.maxRetries,
enableParallel: this.config.endorser.enableParallel,
maxConcurrent: this.config.endorser.maxConcurrent
};
}
getSecurityConfig() {
return {
enableCryptoSigning: this.config.security.enableCryptoSigning,
enableJWTGeneration: this.config.security.enableJWTGeneration,
jwtExpirationMinutes: this.config.security.jwtExpirationMinutes,
signatureAlgorithm: this.config.security.signatureAlgorithm,
credentialStorage: this.config.security.credentialStorage
};
}
getTimeSafariUser(): TimeSafariUser {
return {
activeDid: this.config.testData.userDid,
preferences: DEFAULT_TIMESAFARI_PREFERENCES,
starredPlanIds: this.config.testData.starredPlanIds,
favoritePersonIds: this.config.testData.favoritePersonIds,
favoriteItemIds: this.config.testData.favoriteItemIds,
lastKnownOfferId: this.config.testData.lastKnownOfferId,
lastKnownPlanId: this.config.testData.lastKnownPlanId
};
}
getAuthHeaders(): any {
return {
'Authorization': `Bearer ${this.config.endorser.apiKey}`,
@ -338,7 +398,7 @@ class ErrorDisplay {
}
}
// Enhanced test interface for TimeSafari Android integration
// Enhanced test interface for TimeSafari Android integration with Phase 4 components
class TimeSafariAndroidTestApp {
private statusElement: HTMLElement;
private logElement: HTMLElement;
@ -346,6 +406,11 @@ class TimeSafariAndroidTestApp {
private notificationService: MockDailyNotificationService;
private logger: TestLogger;
// Phase 4: TimeSafari components
private endorserAPIClient: EndorserAPIClient;
private securityManager: SecurityManager;
private timeSafariNotificationManager: TimeSafariNotificationManager;
// UI Components
private permissionManager: PermissionManager;
private settingsPanel: SettingsPanel;
@ -359,6 +424,11 @@ class TimeSafariAndroidTestApp {
this.logger = new TestLogger('debug');
this.notificationService = new MockDailyNotificationService(this.configLoader.getConfig());
// Phase 4: Initialize TimeSafari components
this.endorserAPIClient = new EndorserAPIClient(this.configLoader.getEndorserAPIConfig());
this.securityManager = new SecurityManager(this.configLoader.getSecurityConfig());
this.timeSafariNotificationManager = new TimeSafariNotificationManager();
// Initialize UI components
this.permissionManager = new PermissionManager(
document.getElementById('permission-status-container')!,
@ -370,7 +440,8 @@ class TimeSafariAndroidTestApp {
this.setupEventListeners();
this.initializeUI();
this.log('TimeSafari Android Test app initialized with enhanced UI');
this.initializePhase4Components();
this.log('TimeSafari Android Test app initialized with Phase 4 components');
}
private setupEventListeners() {
@ -392,6 +463,12 @@ class TimeSafariAndroidTestApp {
document.getElementById('battery-status')?.addEventListener('click', () => this.checkBatteryStatus());
document.getElementById('exact-alarm-status')?.addEventListener('click', () => this.checkExactAlarmStatus());
document.getElementById('reboot-recovery')?.addEventListener('click', () => this.checkRebootRecovery());
// Phase 4: TimeSafari component testing
document.getElementById('test-security-manager')?.addEventListener('click', () => this.testSecurityManager());
document.getElementById('test-endorser-api-client')?.addEventListener('click', () => this.testEndorserAPIClient());
document.getElementById('test-notification-manager')?.addEventListener('click', () => this.testTimeSafariNotificationManager());
document.getElementById('test-phase4-integration')?.addEventListener('click', () => this.testPhase4Integration());
}
private async initializeUI(): Promise<void> {
@ -408,6 +485,49 @@ class TimeSafariAndroidTestApp {
}
}
// Phase 4: Initialize TimeSafari components
private async initializePhase4Components(): Promise<void> {
try {
this.log('Initializing Phase 4 TimeSafari components...');
// Initialize SecurityManager with test DID
const timeSafariUser = this.configLoader.getTimeSafariUser();
const securityInitialized = await this.securityManager.initialize(timeSafariUser.activeDid);
if (securityInitialized) {
this.log('✅ SecurityManager initialized successfully');
// Generate JWT token for API authentication
const jwt = await this.securityManager.generateJWT({
scope: 'notifications',
audience: 'endorser-api'
});
if (jwt) {
this.endorserAPIClient.setAuthToken(jwt);
this.log('✅ JWT token generated and set for EndorserAPI');
}
} else {
this.log('❌ SecurityManager initialization failed');
}
// Initialize TimeSafariNotificationManager
const managerInitialized = await this.timeSafariNotificationManager.initialize(timeSafariUser);
if (managerInitialized) {
this.log('✅ TimeSafariNotificationManager initialized successfully');
} else {
this.log('❌ TimeSafariNotificationManager initialization failed');
}
this.log('Phase 4 components initialization completed');
} catch (error) {
this.log('Error initializing Phase 4 components:', error);
this.errorDisplay.showError(error as Error);
}
}
// Enhanced UI methods
private async checkPermissions(): Promise<void> {
try {
@ -802,6 +922,200 @@ class TimeSafariAndroidTestApp {
private updateStatus(status: string) {
this.statusElement.textContent = status;
}
// Phase 4: TimeSafari component test methods
private async testSecurityManager(): Promise<void> {
try {
this.log('🔐 Testing SecurityManager...');
const timeSafariUser = this.configLoader.getTimeSafariUser();
// Test JWT generation
const jwt = await this.securityManager.generateJWT({
scope: 'test',
audience: 'test-api'
});
if (jwt) {
this.log('✅ JWT generation successful');
this.log('JWT token:', jwt.substring(0, 50) + '...');
// Test JWT verification
const claims = await this.securityManager.verifyJWT(jwt);
if (claims) {
this.log('✅ JWT verification successful');
this.log('Claims:', claims);
} else {
this.log('❌ JWT verification failed');
}
} else {
this.log('❌ JWT generation failed');
}
// Test operation history
const history = this.securityManager.getOperationHistory();
this.log(`Security operations performed: ${history.length}`);
this.log('SecurityManager test completed');
} catch (error) {
this.log('SecurityManager test failed:', error);
this.errorDisplay.showError(error as Error);
}
}
private async testEndorserAPIClient(): Promise<void> {
try {
this.log('🌐 Testing EndorserAPIClient...');
const timeSafariUser = this.configLoader.getTimeSafariUser();
// Test offers to person
this.log('Testing offers to person...');
const offersResponse = await this.endorserAPIClient.fetchOffersToPerson(
timeSafariUser.activeDid,
timeSafariUser.lastKnownOfferId,
undefined
);
this.log(`✅ Offers fetched: ${offersResponse.data.length} offers`);
if (offersResponse.data.length > 0) {
this.log('Sample offer:', offersResponse.data[0]);
}
// Test offers to projects
this.log('Testing offers to projects...');
const projectsResponse = await this.endorserAPIClient.fetchOffersToProjectsOwnedByMe(
timeSafariUser.lastKnownOfferId
);
this.log(`✅ Project offers fetched: ${projectsResponse.data.length} offers`);
// Test project updates
if (timeSafariUser.starredPlanIds && timeSafariUser.starredPlanIds.length > 0) {
this.log('Testing project updates...');
const updatesResponse = await this.endorserAPIClient.fetchProjectsLastUpdated(
timeSafariUser.starredPlanIds,
timeSafariUser.lastKnownPlanId,
undefined
);
this.log(`✅ Project updates fetched: ${updatesResponse.data.length} updates`);
}
this.log('EndorserAPIClient test completed');
} catch (error) {
this.log('EndorserAPIClient test failed:', error);
this.errorDisplay.showError(error as Error);
}
}
private async testTimeSafariNotificationManager(): Promise<void> {
try {
this.log('📱 Testing TimeSafariNotificationManager...');
// Test notification generation
this.log('Generating TimeSafari notifications...');
const notifications = await this.timeSafariNotificationManager.generateNotifications({
forceFetch: false,
includeMetadata: true,
filterByPriority: true,
maxNotifications: 10,
cacheTtl: 300000
});
this.log(`✅ Generated ${notifications.length} notifications`);
// Display notification details
notifications.forEach((notification, index) => {
this.log(`Notification ${index + 1}:`, {
type: notification.type,
subtype: notification.subtype,
priority: notification.notificationPriority,
timestamp: new Date(notification.timestamp).toISOString(),
disabled: notification.disabled,
sound: notification.sound,
vibration: notification.vibration
});
});
// Test statistics
const stats = this.timeSafariNotificationManager.getStatistics();
this.log('Manager statistics:', stats);
this.log('TimeSafariNotificationManager test completed');
} catch (error) {
this.log('TimeSafariNotificationManager test failed:', error);
this.errorDisplay.showError(error as Error);
}
}
private async testPhase4Integration(): Promise<void> {
try {
this.log('🚀 Testing complete Phase 4 integration...');
const timeSafariUser = this.configLoader.getTimeSafariUser();
// Test complete workflow
this.log('Step 1: Security authentication...');
const jwt = await this.securityManager.generateJWT({
scope: 'notifications',
audience: 'endorser-api'
});
if (!jwt) {
throw new Error('JWT generation failed');
}
this.endorserAPIClient.setAuthToken(jwt);
this.log('✅ Authentication successful');
this.log('Step 2: Fetching TimeSafari data...');
const bundle = await this.endorserAPIClient.fetchAllTimeSafariNotifications({
activeDid: timeSafariUser.activeDid,
starredPlanIds: timeSafariUser.starredPlanIds || [],
lastKnownOfferId: timeSafariUser.lastKnownOfferId,
lastKnownPlanId: timeSafariUser.lastKnownPlanId,
fetchOffersToPerson: true,
fetchOffersToProjects: true,
fetchProjectUpdates: true,
notificationPreferences: {
offers: true,
projects: true,
people: false,
items: true
}
});
this.log(`✅ Data fetched successfully: ${bundle.success}`);
this.log('Bundle metadata:', bundle.metadata);
this.log('Step 3: Generating notifications...');
const notifications = await this.timeSafariNotificationManager.generateNotifications({
forceFetch: true,
includeMetadata: true,
maxNotifications: 20
});
this.log(`✅ Generated ${notifications.length} notifications`);
// Summary
this.log('🎉 Phase 4 integration test completed successfully!');
this.log('Summary:', {
securityInitialized: this.securityManager.isInitialized(),
apiClientReady: !!this.endorserAPIClient,
managerInitialized: this.timeSafariNotificationManager.isInitialized(),
notificationsGenerated: notifications.length,
bundleSuccess: bundle.success
});
} catch (error) {
this.log('Phase 4 integration test failed:', error);
this.errorDisplay.showError(error as Error);
}
}
}
// Initialize app when DOM is ready

Loading…
Cancel
Save