mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-09-29 12:52:13 +02:00
Keep application pages in portrait and let player sheets inherit rotation from the full player. Restore portrait on navigation, replacement, removal, and completed dismissal; discard stale minimization geometry when the screen rotates on close. Validated with 12 Flutter tests and targeted analysis. iOS simulator build confirms portrait startup from a landscape device. Platform orientation restrictions still apply on large Android displays and multitasking iPads.
157 lines
4.7 KiB
Dart
157 lines
4.7 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:spotiflac_android/screens/now_playing_screen.dart';
|
|
import 'package:spotiflac_android/services/app_orientation.dart';
|
|
|
|
class _PlayerRoute extends NowPlayingRoute {
|
|
@override
|
|
Widget buildPage(
|
|
BuildContext context,
|
|
Animation<double> animation,
|
|
Animation<double> secondaryAnimation,
|
|
) => const SizedBox.expand();
|
|
}
|
|
|
|
void main() {
|
|
TestWidgetsFlutterBinding.ensureInitialized();
|
|
const portrait = ['DeviceOrientation.portraitUp'];
|
|
const player = [
|
|
'DeviceOrientation.portraitUp',
|
|
'DeviceOrientation.landscapeLeft',
|
|
'DeviceOrientation.landscapeRight',
|
|
];
|
|
final requests = <List<String>>[];
|
|
final messenger =
|
|
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger;
|
|
|
|
setUp(() {
|
|
requests.clear();
|
|
messenger.setMockMethodCallHandler(SystemChannels.platform, (call) async {
|
|
if (call.method == 'SystemChrome.setPreferredOrientations') {
|
|
requests.add((call.arguments as List<dynamic>).cast<String>());
|
|
}
|
|
return null;
|
|
});
|
|
});
|
|
tearDown(
|
|
() => messenger.setMockMethodCallHandler(SystemChannels.platform, null),
|
|
);
|
|
|
|
Future<NavigatorState> pumpApp(WidgetTester tester) async {
|
|
final key = GlobalKey<NavigatorState>();
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
navigatorKey: key,
|
|
navigatorObservers: [AppOrientationObserver()],
|
|
home: const Scaffold(body: Text('Library')),
|
|
),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
expect(requests, [portrait]);
|
|
return key.currentState!;
|
|
}
|
|
|
|
test('startup requests portrait before the first route is built', () async {
|
|
await setAppOrientation();
|
|
expect(requests, [portrait]);
|
|
});
|
|
|
|
testWidgets('only the full player enables landscape; sheets inherit it', (
|
|
tester,
|
|
) async {
|
|
final navigator = await pumpApp(tester);
|
|
navigator.push(_PlayerRoute());
|
|
await tester.pumpAndSettle();
|
|
expect(requests, [portrait, player]);
|
|
|
|
showModalBottomSheet<void>(
|
|
context: navigator.context,
|
|
builder: (_) =>
|
|
const SizedBox(height: 100, child: Text('Player options')),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
expect(requests, [portrait, player]);
|
|
navigator.pop();
|
|
await tester.pumpAndSettle();
|
|
expect(requests, [portrait, player]);
|
|
|
|
navigator.push(
|
|
MaterialPageRoute<void>(
|
|
builder: (_) => const Scaffold(body: Text('Album')),
|
|
),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
expect(requests, [portrait, player, portrait]);
|
|
navigator.pop();
|
|
await tester.pumpAndSettle();
|
|
expect(requests, [portrait, player, portrait, player]);
|
|
await tester.binding.handlePopRoute();
|
|
await tester.pumpAndSettle();
|
|
expect(requests, [portrait, player, portrait, player, portrait]);
|
|
expect(tester.takeException(), isNull);
|
|
});
|
|
|
|
testWidgets('cancelled dismissal keeps rotation; completed drag locks it', (
|
|
tester,
|
|
) async {
|
|
final navigator = await pumpApp(tester);
|
|
final route = _PlayerRoute();
|
|
navigator.push(route);
|
|
await tester.pumpAndSettle();
|
|
route.startDrag();
|
|
route.updateDrag(
|
|
DragUpdateDetails(
|
|
globalPosition: const Offset(0, 240),
|
|
delta: const Offset(0, 240),
|
|
primaryDelta: 240,
|
|
),
|
|
600,
|
|
);
|
|
await tester.pump();
|
|
route.cancelDrag();
|
|
await tester.pumpAndSettle();
|
|
expect(requests, [portrait, player]);
|
|
route.startDrag();
|
|
route.endDrag(
|
|
DragEndDetails(
|
|
primaryVelocity: 1200,
|
|
velocity: const Velocity(pixelsPerSecond: Offset(0, 1200)),
|
|
),
|
|
600,
|
|
);
|
|
await tester.pumpAndSettle();
|
|
expect(requests, [portrait, player, portrait]);
|
|
expect(tester.takeException(), isNull);
|
|
});
|
|
|
|
testWidgets('removing and replacing routes cannot leave landscape enabled', (
|
|
tester,
|
|
) async {
|
|
final navigator = await pumpApp(tester);
|
|
final firstPlayer = _PlayerRoute();
|
|
navigator.push(firstPlayer);
|
|
await tester.pumpAndSettle();
|
|
final secondPlayer = _PlayerRoute();
|
|
navigator.push(secondPlayer);
|
|
await tester.pumpAndSettle();
|
|
navigator.removeRoute(firstPlayer);
|
|
await tester.pumpAndSettle();
|
|
expect(requests, [portrait, player]);
|
|
navigator.pushReplacement(
|
|
MaterialPageRoute<void>(
|
|
builder: (_) => const Scaffold(body: Text('Settings')),
|
|
),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
expect(requests, [portrait, player, portrait]);
|
|
final thirdPlayer = _PlayerRoute();
|
|
navigator.push(thirdPlayer);
|
|
await tester.pumpAndSettle();
|
|
navigator.removeRoute(thirdPlayer);
|
|
await tester.pumpAndSettle();
|
|
expect(requests, [portrait, player, portrait, player, portrait]);
|
|
expect(tester.takeException(), isNull);
|
|
});
|
|
}
|