import 'dart:convert'; import 'dart:io'; import 'package:test/test.dart'; /// The certificate's SHA-256 as `tool/release/android-certificate.sha256` /// pins it, the release tool's way: the first line that isn't a comment. String _pinned() => File('tool/release/android-certificate.sha256') .readAsLinesSync() .map((line) => line.trim()) .firstWhere((line) => line.isNotEmpty && !line.startsWith('#')); void main() { test("learn.halkyon.eu's assetlinks.json names Halkyon Learn signed with " 'the key releases are signed with, and nothing else (ADR 0020, D9)', () { final caddyfile = File('deploy/Caddyfile').readAsStringSync(); final body = RegExp(r'handle @assetlinks \{[^}]*respond `([^`]*)` 200') .firstMatch(caddyfile)?[1]; expect(body, isNotNull, reason: 'the Caddyfile answers assetlinks.json'); expect(jsonDecode(body!), [ { 'relation': ['delegate_permission/common.handle_all_urls'], 'target': { 'namespace': 'android_app', 'package_name': 'app.halkyon.learn', 'sha256_cert_fingerprints': [_pinned()], }, }, ]); // Colon-separated upper-case hex, as Android's verifier compares it. expect(_pinned(), matches(RegExp(r'^([0-9A-F]{2}:){31}[0-9A-F]{2}$'))); }); }