build: add reproducible Android release verification
Pin Gradle inputs and dependency metadata, then enforce analyze, lint, build, R8, immutability, and regression gates in CI.
This commit is contained in:
1 parent
c9826c15a0
commit
7e66109e8d
11 files changed
+9788
-8
No files matched your search
@@ -0,0 +1,58 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
test('notification updates do not trust ActivityManager process visibility', () {
|
||||
final source = File(
|
||||
'android/app/src/main/kotlin/com/paladinvpn/app/MainActivity.kt',
|
||||
).readAsStringSync();
|
||||
|
||||
expect(source, isNot(contains('ActivityManager')));
|
||||
expect(source, isNot(contains('isVpnServiceProcessAlive')));
|
||||
expect(source, isNot(contains('VPN_PROCESS_SUFFIX')));
|
||||
expect(source, contains('NotificationManagerCompat.from(this).notify'));
|
||||
});
|
||||
|
||||
test('SOCKS reads use one total deadline instead of per-chunk timeout', () {
|
||||
final source = File('lib/logic/local_socks_tester.dart').readAsStringSync();
|
||||
|
||||
expect(
|
||||
source,
|
||||
contains('timeout.inMicroseconds - elapsed.elapsedMicroseconds'),
|
||||
);
|
||||
expect(
|
||||
source,
|
||||
contains("throw TimeoutException('Socket read timed out', timeout);"),
|
||||
);
|
||||
});
|
||||
|
||||
test('Hivemind captures cancellation generation before first async lookup', () {
|
||||
final source = File('lib/logic/hivemind_service.dart').readAsStringSync();
|
||||
final callIdIndex = source.indexOf('final callId = ++_currentCallId;');
|
||||
final deviceIdIndex =
|
||||
source.indexOf('final deviceId = await CryptoService.getDeviceId();');
|
||||
|
||||
expect(callIdIndex, greaterThanOrEqualTo(0));
|
||||
expect(deviceIdIndex, greaterThan(callIdIndex));
|
||||
expect(
|
||||
source.substring(deviceIdIndex),
|
||||
contains('_throwIfCancelled(callId);'),
|
||||
);
|
||||
expect(
|
||||
source,
|
||||
contains('_currentCallId++;\n _expectedNonce = null;'),
|
||||
);
|
||||
});
|
||||
|
||||
test('notification text is cached only after native update succeeds', () {
|
||||
final source =
|
||||
File('lib/logic/notification_service.dart').readAsStringSync();
|
||||
final invokeIndex =
|
||||
source.indexOf("await _channel.invokeMethod<void>('updateNotificationText'");
|
||||
final cacheIndex = source.indexOf('_lastText = text;');
|
||||
|
||||
expect(invokeIndex, greaterThanOrEqualTo(0));
|
||||
expect(cacheIndex, greaterThan(invokeIndex));
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user