This guide explains how the integration test components work together to enable authenticated POD testing.
For test execution flows: See Test Execution Flows
Documentation index: See README.md for complete documentation navigation.
The testing framework consists of four main layers:
flowchart TB
subgraph "Test Layer"
A[Integration Tests<br/>pod_favorites_real_test.dart]
end
subgraph "Injection Layer"
B[CredentialInjector<br/>credential_injector.dart]
C[PodAuthAutomator<br/>pod_auth_automator.dart]
end
subgraph "Storage Layer"
D[FlutterSecureStorage<br/>OS Keychain/Credential Store]
end
subgraph "Application Layer"
E[MovieStar App<br/>main.dart]
F[Solidpod Package<br/>OAuth DPoP handling]
end
subgraph "External"
G[POD Server<br/>pods.dev.solidcommunity.au]
H[JSON Files<br/>test_credentials.json<br/>complete_auth_data.json]
end
A --> B
B --> C
B --> D
C --> H
C --> G
D --> F
F --> E
F --> G
Files: integration_test/workflows/pod_favorites_real_test.dart
Purpose: End-to-end tests that verify POD operations work correctly.
Key responsibilities:
CredentialInjector.injectFullAuth() before app startsCode example:
setUpAll() async {
await CredentialInjector.injectFullAuth(
autoRegenerateOnFailure: true,
);
}
testWidgets('can access POD data', (tester) async {
app.main();
await tester.pumpAndSettle();
// App should detect injected credentials
expect(find.text('Logged in'), findsOneWidget);
});
File: integration_test/helpers/credential_injector.dart
Purpose: Bridge between test environment and app’s secure storage.
Key responsibilities:
complete_auth_data.jsonFlutterSecureStorage under key
_solid_auth_dataData flow:
complete_auth_data.json
→ CredentialInjector
→ FlutterSecureStorage
→ solidpod package
→ MovieStar app
Key methods:
loadCompleteAuthData() - Reads JSON fileinjectCompleteAuthData() - Writes to secure storageinjectFullAuth() - Main entry point with auto-regenerationclearCredentials() - Test cleanupFile: integration_test/helpers/pod_auth_automator.dart
Purpose: Puppeteer-based browser automation for OAuth flow.
Key responsibilities:
Dependencies:
puppeteer - Browser automationpointycastle - RSA key generationhttp - OAuth token exchangetest_credentials.json - User credentialsPackage: flutter_secure_storage
Purpose: Platform-specific encrypted storage for sensitive data.
Platform implementations:
Key used by solidpod:
const _authDataSecureStorageKey = '_solid_auth_data';
Data stored:
Package: solidpod
Purpose: Solid POD client library for Flutter.
Key responsibilities:
Integration point with tests:
// App startup checks for injected auth data
final authData = await storage.read(key: '_solid_auth_data');
if (authData != null) {
// App recognizes as logged in
}
integration_test/
├── docs/ # Documentation
│ ├── README.md # Overview and navigation
│ ├── authentication.md # OAuth/DPoP concepts
│ ├── architecture.md # This file
│ ├── architecture-flows.md # Test execution flows
│ ├── json-files.md # JSON structure reference
│ ├── adapting.md # Reusability guide
│ ├── adapting-providers.md # Provider compatibility
│ ├── adapting-cicd.md # CI/CD integration
│ ├── testing-guide.md # Operational guide
│ ├── testing-troubleshooting.md # Common issues
│ └── setup-guide.md # Setup instructions
│
├── fixtures/ # Test data (git-ignored)
│ ├── test_credentials.json # POD account credentials
│ └── complete_auth_data.json # OAuth tokens + RSA keys
│
├── helpers/ # Test utilities
│ ├── credential_injector.dart # Inject auth to storage
│ └── pod_auth_automator.dart # Puppeteer automation
│
├── tools/ # Standalone scripts
│ └── generate_auth_data.dart # CLI tool to regenerate
│
├── utils/ # Test configuration
│ └── delays.dart # INTERACT delay constants
│
├── workflows/ # E2E test scenarios
│ ├── pod_favorites_real_test.dart # POD operations test
│ └── visual_login_test.dart # Manual visual testing
│
├── app_test.dart # Basic smoke test
└── app_hive_test.dart # Hive storage test
The MovieStar app detects injected credentials on startup:
Location: lib/main.dart or authentication provider
// Simplified example
Future<void> checkAuthStatus() async {
final storage = FlutterSecureStorage();
final authData = await storage.read(key: '_solid_auth_data');
if (authData != null) {
// Parse and use auth data
final data = jsonDecode(authData);
final webId = data['web_id'];
// App shows as logged in
}
}
Both CredentialInjector and solidpod package must use the same storage key:
// integration_test/helpers/credential_injector.dart
static const _authDataSecureStorageKey = '_solid_auth_data';
// solidpod package (internal)
const AUTH_DATA_KEY = '_solid_auth_data';
Breaking this contract: If keys mismatch, injected auth data won’t be found by the app.
complete_auth_data.json must match the structure solidpod expects:
{
"web_id": "...",
"rsa_info": {
"private_key_jwk": {...},
"public_key_jwk": {...}
},
"auth_response": {
"token": {...},
"credential": {...}
}
}
Breaking this contract: If structure changes, solidpod won’t parse auth data correctly.
See JSON Files Reference for complete structure documentation.
Tests must wait for app to fully initialize before making assertions:
app.main();
await tester.pumpAndSettle(const Duration(seconds: 5));
await Future.delayed(delay); // Allow styling to load
await tester.pump(interact); // Visual inspection delay
FlutterSecureStorage writes are asynchronous. Tests must await injection:
await CredentialInjector.injectFullAuth();
// Auth data guaranteed written before app launch
app.main();
CredentialInjector checks token expiry with 1-minute buffer:
final expiryTime =
DateTime.fromMillisecondsSinceEpoch(expiresAt * 1000);
final bufferTime = DateTime.now().add(const Duration(minutes: 1));
if (expiryTime.isBefore(bufferTime)) {
// Treat as expired
}
This prevents race conditions where tokens expire mid-test.
Development Machine:
├── test_credentials.json (git-ignored)
│ └── Never committed to repository
│
├── complete_auth_data.json (git-ignored)
│ └── Regenerated hourly, contains private keys
│
└── FlutterSecureStorage (OS-level encryption)
└── Encrypted by platform, cleared after tests
For CI environments:
test_credentials.json in GitHub
Secretscomplete_auth_data.jsonSee CI/CD Integration for CI setup details.