Files
reelbox/test/download_android_child_dispatch_test.dart

125 lines
4.1 KiB
Dart

import 'dart:async';
import 'dart:convert';
import 'package:background_downloader/background_downloader.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
class _Storage implements PersistentStorage {
@override
Future<void> initialize() async {}
@override
Future<List<TaskRecord>> retrieveAllTaskRecords() async => [];
@override
Future<void> removeResumeData(String? id) async {}
@override
Future<void> removePausedTask(String? id) async {}
@override
dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
final messenger =
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger;
const native = MethodChannel('com.bbflight.background_downloader');
const connectivity = MethodChannel('dev.fluttercommunity.plus/connectivity');
const events = MethodChannel('dev.fluttercommunity.plus/connectivity_status');
const codec = StandardMethodCodec();
late FileDownloader downloader;
final oldPlatform = debugDefaultTargetPlatformOverride;
setUpAll(() async {
debugDefaultTargetPlatformOverride = TargetPlatform.android;
messenger.setMockMethodCallHandler(connectivity, (_) async => ['wifi']);
messenger.setMockMethodCallHandler(events, (_) async => null);
downloader = FileDownloader(persistentStorage: _Storage());
await downloader.ready;
});
tearDownAll(() {
downloader.destroy();
debugDefaultTargetPlatformOverride = oldPlatform;
messenger.setMockMethodCallHandler(native, null);
messenger.setMockMethodCallHandler(connectivity, null);
messenger.setMockMethodCallHandler(events, null);
});
Future<Object?> enqueueChild(String id) async {
final reply = Completer<ByteData?>();
final parent = ParallelDownloadTask(
taskId: 'parent-$id',
url: 'https://example.test/video.mp4',
);
final child = DownloadTask(
taskId: id,
url: parent.url,
group: FileDownloader.chunkGroup,
);
// Exercise the real plugin background handler and its JSON worker.
// ignore: deprecated_member_use
messenger.handlePlatformMessage(
'com.bbflight.background_downloader.background',
codec.encodeMethodCall(
MethodCall('enqueueChild', [
jsonEncode(parent.toJson()),
jsonEncode(child.toJson()),
]),
),
reply.complete,
);
return codec.decodeEnvelope(
(await reply.future.timeout(const Duration(seconds: 3)))!,
);
}
test('child acknowledgement waits for native scheduling', () async {
final dispatched = Completer<void>();
final scheduled = Completer<bool>();
messenger.setMockMethodCallHandler(native, (call) async {
if (call.method == 'enqueue') {
dispatched.complete();
return scheduled.future;
}
return true;
});
var replied = false;
final reply = enqueueChild('pending-child').then((value) {
replied = true;
return value;
});
await dispatched.future.timeout(const Duration(seconds: 3));
await Future<void>.delayed(Duration.zero);
expect(replied, isFalse);
scheduled.complete(true);
expect(await reply, isTrue);
});
test(
'native child dispatch error returns failure without a detached error',
() async {
messenger.setMockMethodCallHandler(native, (call) async {
throw PlatformException(
code: 'scheduler_rejected',
message: 'Fixture rejection',
);
});
expect(await enqueueChild('throwing-child'), isFalse);
await Future<void>.delayed(const Duration(milliseconds: 150));
},
);
test('child enqueue rejection is not acknowledged as success', () async {
var attempts = 0;
messenger.setMockMethodCallHandler(native, (call) async {
if (call.method == 'enqueue') attempts++;
return false;
});
final accepted = await enqueueChild('rejected-child');
// Drain the old detached 100ms enqueue before asserting/teardown too.
await Future<void>.delayed(const Duration(milliseconds: 150));
expect(attempts, 1);
expect(accepted, isFalse);
});
}