125 lines
4.1 KiB
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);
|
|
});
|
|
}
|