implemented the Ticker module with a native ProseMirror document renderer and integrated API support for structured content, navigation trees, and proxied files
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:marianum_mobile/api/marianumconnect/queries/get_ticker_nav/get_ticker_nav_response.dart';
|
||||
import 'package:marianum_mobile/api/marianumconnect/queries/get_ticker_page/get_ticker_page_response.dart';
|
||||
import 'package:marianum_mobile/view/pages/ticker/ticker_view.dart';
|
||||
|
||||
List<TickerNavSection> _sections() => [
|
||||
TickerNavSection(
|
||||
title: 'Infos',
|
||||
pages: [
|
||||
TickerNavPage(title: 'Über uns', slug: 'about', kind: TickerPageKind.content),
|
||||
TickerNavPage(
|
||||
title: 'Webseite',
|
||||
slug: 'web',
|
||||
kind: TickerPageKind.redirect,
|
||||
externalUrl: 'https://marianum-fulda.de',
|
||||
),
|
||||
],
|
||||
),
|
||||
];
|
||||
|
||||
Widget _host() => MaterialApp(
|
||||
home: TickerScaffold(
|
||||
sections: _sections(),
|
||||
homeBuilder: (context, onLinkTap) => const Text('HOME'),
|
||||
pageBuilder: (context, slug, onLinkTap) => Text('PAGE:$slug'),
|
||||
),
|
||||
);
|
||||
|
||||
Finder _appBarText(String text) =>
|
||||
find.descendant(of: find.byType(AppBar), matching: find.text(text));
|
||||
|
||||
// The home surface stays mounted (IndexedStack) while a page is open, so
|
||||
// "which content is shown" is the stack index, not widget presence.
|
||||
int _shownIndex(WidgetTester tester) =>
|
||||
tester.widget<IndexedStack>(find.byType(IndexedStack)).index!;
|
||||
|
||||
const String _menuTooltip = 'Open navigation menu';
|
||||
|
||||
void main() {
|
||||
group('narrow layout (< 900)', () {
|
||||
testWidgets('uses a drawer reachable via the burger button', (tester) async {
|
||||
await tester.pumpWidget(_host());
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Nav is hidden behind the drawer, not shown as a sidebar.
|
||||
expect(find.text('Über uns'), findsNothing);
|
||||
expect(find.byTooltip(_menuTooltip), findsOneWidget);
|
||||
|
||||
await tester.tap(find.byTooltip(_menuTooltip));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(Drawer), findsOneWidget);
|
||||
expect(find.text('Über uns'), findsOneWidget);
|
||||
expect(find.text('Aktuelles'), findsOneWidget);
|
||||
});
|
||||
});
|
||||
|
||||
group('wide layout (>= 900)', () {
|
||||
Future<void> pumpWide(WidgetTester tester) async {
|
||||
tester.view.physicalSize = const Size(1200, 2000);
|
||||
tester.view.devicePixelRatio = 1.0;
|
||||
addTearDown(tester.view.resetPhysicalSize);
|
||||
addTearDown(tester.view.resetDevicePixelRatio);
|
||||
await tester.pumpWidget(_host());
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
|
||||
testWidgets('shows a permanent sidebar and no drawer', (tester) async {
|
||||
await pumpWide(tester);
|
||||
|
||||
expect(find.byType(Drawer), findsNothing);
|
||||
expect(find.byTooltip(_menuTooltip), findsNothing);
|
||||
// Sidebar nav item is visible without any interaction.
|
||||
expect(find.text('Über uns'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('selecting a page swaps content, title and home action', (
|
||||
tester,
|
||||
) async {
|
||||
await pumpWide(tester);
|
||||
|
||||
expect(_shownIndex(tester), 0);
|
||||
expect(find.text('PAGE:about'), findsNothing);
|
||||
expect(_appBarText('Ticker'), findsOneWidget);
|
||||
expect(find.byIcon(Icons.home_outlined), findsNothing);
|
||||
|
||||
await tester.tap(find.text('Über uns'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(_shownIndex(tester), 1);
|
||||
expect(find.text('PAGE:about'), findsOneWidget);
|
||||
expect(_appBarText('Über uns'), findsOneWidget);
|
||||
expect(find.byIcon(Icons.home_outlined), findsOneWidget);
|
||||
|
||||
await tester.tap(find.byIcon(Icons.home_outlined));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(_shownIndex(tester), 0);
|
||||
expect(find.text('PAGE:about'), findsNothing);
|
||||
expect(_appBarText('Ticker'), findsOneWidget);
|
||||
expect(find.byIcon(Icons.home_outlined), findsNothing);
|
||||
});
|
||||
});
|
||||
|
||||
group('back gesture', () {
|
||||
testWidgets('pops from a sub-page back to home via the tab navigator', (
|
||||
tester,
|
||||
) async {
|
||||
tester.view.physicalSize = const Size(1200, 2000);
|
||||
tester.view.devicePixelRatio = 1.0;
|
||||
addTearDown(tester.view.resetPhysicalSize);
|
||||
addTearDown(tester.view.resetDevicePixelRatio);
|
||||
await tester.pumpWidget(_host());
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.text('Über uns'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(_shownIndex(tester), 1);
|
||||
|
||||
final navigator = tester.state<NavigatorState>(find.byType(Navigator));
|
||||
// The LocalHistoryEntry is what makes the enclosing tab shell delegate
|
||||
// the system back to this navigator instead of switching tabs.
|
||||
expect(navigator.canPop(), isTrue);
|
||||
|
||||
await navigator.maybePop();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(_shownIndex(tester), 0);
|
||||
expect(_appBarText('Ticker'), findsOneWidget);
|
||||
expect(navigator.canPop(), isFalse);
|
||||
});
|
||||
|
||||
testWidgets('home selection releases the back interception', (
|
||||
tester,
|
||||
) async {
|
||||
tester.view.physicalSize = const Size(1200, 2000);
|
||||
tester.view.devicePixelRatio = 1.0;
|
||||
addTearDown(tester.view.resetPhysicalSize);
|
||||
addTearDown(tester.view.resetDevicePixelRatio);
|
||||
await tester.pumpWidget(_host());
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.text('Über uns'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.byIcon(Icons.home_outlined));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final navigator = tester.state<NavigatorState>(find.byType(Navigator));
|
||||
expect(navigator.canPop(), isFalse);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user