Files
IKAR/test/file_download_test.dart
T

145 lines
4.6 KiB
Dart

import 'dart:io';
import 'package:flutter_test/flutter_test.dart';
import 'package:open_filex/open_filex.dart';
import 'package:path_provider_platform_interface/path_provider_platform_interface.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
import 'package:ikar/core/utils/download_history.dart';
import 'package:ikar/core/utils/file_download.dart';
import 'package:ikar/core/utils/media_cache.dart';
import 'package:shared_preferences/shared_preferences.dart';
class _Paths extends PathProviderPlatform with MockPlatformInterfaceMixin {
_Paths(this.path);
final String path;
@override
Future<String?> getApplicationSupportPath() async => path;
}
class _RealHttpOverrides extends HttpOverrides {}
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
late Directory directory;
late PathProviderPlatform paths;
setUp(() {
directory = Directory.systemTemp.createTempSync('qlyra_file_download_');
paths = PathProviderPlatform.instance;
PathProviderPlatform.instance = _Paths(directory.path);
MediaCache.resetForTesting();
DownloadHistory.resetForTesting();
SharedPreferences.setMockInitialValues({});
});
tearDown(() {
MediaCache.resetForTesting();
DownloadHistory.resetForTesting();
PathProviderPlatform.instance = paths;
directory.deleteSync(recursive: true);
});
for (final name in [
'report.pdf',
'archive.zip',
'document.docx',
'data.bin',
'song.mp3',
'picture.png',
]) {
test(
'$name downloads on first tap and opens offline on second tap',
() async {
await HttpOverrides.runWithHttpOverrides(() async {
final server = await HttpServer.bind(InternetAddress.loopbackIPv4, 0);
addTearDown(() => server.close(force: true));
final bytes = List<int>.generate(2048, (i) => i % 256);
var requests = 0;
server.listen((request) async {
requests++;
request.response.contentLength = bytes.length;
request.response.add(bytes);
await request.response.close();
});
var resolves = 0;
var opens = 0;
var ready = 0;
final progress = <double>[];
Future<String?> resolve() async {
resolves++;
return 'http://127.0.0.1:${server.port}/file';
}
Future<OpenResult> open(String path) async {
opens++;
expect(await File(path).readAsBytes(), bytes);
return OpenResult(type: ResultType.done, message: 'done');
}
final first = await openCachedFile(
name,
resolve,
downloadOnlyIfMissing: true,
openFile: open,
onReady: () => ready++,
onProgress: progress.add,
download: DownloadMetadata(
cacheName: name,
name: name,
kind: downloadKindForName(name),
),
);
expect(first.ok, isTrue);
expect(first.downloaded, isTrue);
expect(opens, 0);
expect(ready, 1);
expect(progress.last, 1);
expect(DownloadHistory.records.value.single.name, name);
await server.close(force: true);
final second = await openCachedFile(
name,
resolve,
downloadOnlyIfMissing: true,
openFile: open,
);
expect(second.ok, isTrue);
expect(second.downloaded, isFalse);
expect(opens, 1);
expect(resolves, 1);
expect(requests, 1);
}, _RealHttpOverrides());
},
);
}
test('missing URL resets progress and permits retry', () async {
var ready = 0;
final result = await openCachedFile(
'missing.pdf',
() async => null,
downloadOnlyIfMissing: true,
onReady: () => ready++,
openFile: (_) async => throw StateError('must not open'),
);
expect(result.ok, isFalse);
expect(result.path, isNull);
expect(ready, 1);
expect(await MediaCache.existing('missing.pdf'), isNull);
});
test('no viewer keeps the downloaded document available', () async {
final file = await MediaCache.fileFor('report.pdf');
await file.writeAsBytes([1, 2, 3]);
final result = await openCachedFile(
'report.pdf',
() async => throw StateError('must not resolve'),
downloadOnlyIfMissing: true,
openFile: (_) async =>
OpenResult(type: ResultType.noAppToOpen, message: 'No viewer'),
);
expect(result.noAppToOpen, isTrue);
expect(result.path, file.path);
expect(await file.readAsBytes(), [1, 2, 3]);
});
}