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
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
import { Capacitor } from '@capacitor/core';
|
||||
import { DailyNotificationPlugin } from '@timesafari/daily-notification-plugin';
|
||||
|
||||
// Mock classes for testing when shared utilities aren't available
|
||||
// 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
|
||||
|
||||
Reference in New Issue
Block a user