mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-09-29 04:42:02 +02:00
feat(player): add native audio output controls
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:spotiflac_android/l10n/app_localizations.dart';
|
||||
import 'package:spotiflac_android/widgets/audio_output_button.dart';
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
const channel = MethodChannel('com.zarz.spotiflac/audio_output');
|
||||
final messenger =
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger;
|
||||
|
||||
Widget app({ValueChanged<bool>? onChanged}) => MaterialApp(
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
home: Scaffold(body: AudioOutputButton(onPickerChanged: onChanged)),
|
||||
);
|
||||
|
||||
tearDown(() {
|
||||
messenger.setMockMethodCallHandler(channel, null);
|
||||
messenger.setMockMethodCallHandler(SystemChannels.platform_views, null);
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'iOS embeds the native audio route control and forwards its presentation',
|
||||
(tester) async {
|
||||
int? viewId;
|
||||
final visibility = <bool>[];
|
||||
final updates = <MethodCall>[];
|
||||
MethodChannel? viewChannel;
|
||||
messenger.setMockMethodCallHandler(SystemChannels.platform_views, (
|
||||
call,
|
||||
) async {
|
||||
if (call.method == 'create') {
|
||||
final args = call.arguments as Map<Object?, Object?>;
|
||||
expect(args['viewType'], 'com.zarz.spotiflac/audio_output');
|
||||
viewId = args['id'] as int;
|
||||
viewChannel = MethodChannel(
|
||||
'com.zarz.spotiflac/audio_output/$viewId',
|
||||
);
|
||||
messenger.setMockMethodCallHandler(
|
||||
viewChannel!,
|
||||
(call) async => updates.add(call),
|
||||
);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
await tester.pumpWidget(app(onChanged: visibility.add));
|
||||
await tester.pumpAndSettle();
|
||||
expect(viewId, isNotNull);
|
||||
expect(updates.last.arguments, containsPair('label', 'Audio Output'));
|
||||
for (final open in [true, false]) {
|
||||
await messenger.handlePlatformMessage(
|
||||
viewChannel!.name,
|
||||
const StandardMethodCodec().encodeMethodCall(
|
||||
MethodCall('pickerChanged', open),
|
||||
),
|
||||
(_) {},
|
||||
);
|
||||
}
|
||||
expect(visibility, [true, false]);
|
||||
await tester.pumpWidget(const SizedBox());
|
||||
messenger.setMockMethodCallHandler(viewChannel!, null);
|
||||
},
|
||||
variant: TargetPlatformVariant.only(TargetPlatform.iOS),
|
||||
);
|
||||
|
||||
testWidgets('opens native output picker once and reports failure visibly', (
|
||||
tester,
|
||||
) async {
|
||||
final completion = Completer<bool>();
|
||||
var requests = 0;
|
||||
final visibility = <bool>[];
|
||||
messenger.setMockMethodCallHandler(channel, (call) {
|
||||
expect(call.method, 'show');
|
||||
requests++;
|
||||
return completion.future;
|
||||
});
|
||||
await tester.pumpWidget(app(onChanged: visibility.add));
|
||||
await tester.tap(find.byTooltip('Audio Output'));
|
||||
await tester.tap(find.byTooltip('Audio Output'));
|
||||
expect(requests, 1);
|
||||
expect(visibility, [true]);
|
||||
completion.complete(false);
|
||||
await tester.pumpAndSettle();
|
||||
expect(visibility, [true, false]);
|
||||
expect(find.text('Unable to open audio output settings.'), findsOneWidget);
|
||||
}, variant: TargetPlatformVariant.only(TargetPlatform.android));
|
||||
|
||||
testWidgets('successful native request has no error and disposal is safe', (
|
||||
tester,
|
||||
) async {
|
||||
messenger.setMockMethodCallHandler(channel, (_) async => true);
|
||||
await tester.pumpWidget(app());
|
||||
await tester.tap(find.byTooltip('Audio Output'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(SnackBar), findsNothing);
|
||||
|
||||
final completion = Completer<bool>();
|
||||
messenger.setMockMethodCallHandler(channel, (_) => completion.future);
|
||||
await tester.tap(find.byTooltip('Audio Output'));
|
||||
await tester.pumpWidget(const SizedBox());
|
||||
completion.complete(false);
|
||||
await tester.pumpAndSettle();
|
||||
expect(tester.takeException(), isNull);
|
||||
}, variant: TargetPlatformVariant.only(TargetPlatform.android));
|
||||
|
||||
testWidgets('unsupported desktop does not expose an inert control', (
|
||||
tester,
|
||||
) async {
|
||||
await tester.pumpWidget(app());
|
||||
expect(find.byType(IconButton), findsNothing);
|
||||
expect(find.byType(UiKitView), findsNothing);
|
||||
}, variant: TargetPlatformVariant.only(TargetPlatform.linux));
|
||||
}
|
||||
Reference in New Issue
Block a user