Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement langsamfahrstellen (#87) #413

Merged
merged 15 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
133 changes: 102 additions & 31 deletions das_client/integration_test/test/train_journey_table_test.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:das_client/app/pages/journey/train_journey/widgets/table/additional_speed_restriction_row.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/cells/bracket_station_body.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/cells/route_cell_body.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/protection_section_row.dart';
Expand All @@ -12,6 +13,63 @@ import '../util/test_utils.dart';

void main() {
group('train journey table test', () {
testWidgets('test additional speed restriction row is displayed correctly', (tester) async {
await prepareAndStartApp(tester);

// load train journey by filling out train selection page
await _loadTrainJourney(tester, trainNumber: '500');

final scrollableFinder = find.byType(ListView);
expect(scrollableFinder, findsOneWidget);

final asrRow = findDASTableRowByText('km 64.200 - km 47.200');
expect(asrRow, findsOneWidget);

final asrIcon = find.descendant(
of: asrRow, matching: find.byKey(AdditionalSpeedRestrictionRow.additionalSpeedRestrictionIconKey));
expect(asrIcon, findsOneWidget);

final asrSpeed = find.descendant(of: asrRow, matching: find.text('60'));
expect(asrSpeed, findsOneWidget);

// check all cells are colored
final coloredCells = find.descendant(
of: asrRow,
matching: find.byWidgetPredicate((it) =>
it is Container &&
it.decoration is BoxDecoration &&
(it.decoration as BoxDecoration).color == AdditionalSpeedRestrictionRow.additionalSpeedRestrictionColor));
expect(coloredCells, findsNWidgets(11));
});

testWidgets('test other rows are displayed correctly', (tester) async {
await prepareAndStartApp(tester);

// load train journey by filling out train selection page
await _loadTrainJourney(tester, trainNumber: '500');

final scrollableFinder = find.byType(ListView);
expect(scrollableFinder, findsOneWidget);

final testRows = ['Genève', 'km 32.2', 'Lengnau', 'WANZ'];

for (final rowText in testRows) {
await tester.dragUntilVisible(find.text(rowText), scrollableFinder, const Offset(0, -50));

final testRow = findDASTableRowByText(rowText);
expect(testRow, findsOneWidget);

// check first 3 cells are colored
final coloredCells = find.descendant(
of: testRow,
matching: find.byWidgetPredicate((it) =>
it is Container &&
it.decoration is BoxDecoration &&
(it.decoration as BoxDecoration).color == AdditionalSpeedRestrictionRow.additionalSpeedRestrictionColor));
expect(coloredCells, findsNWidgets(3));
}
});

testWidgets('check if all table columns with header are present', (tester) async {
await prepareAndStartApp(tester);

Expand All @@ -34,6 +92,38 @@ void main() {
}
});

testWidgets('test route is displayed correctly', (tester) async {
await prepareAndStartApp(tester);

// load train journey by filling out train selection page
await _loadTrainJourney(tester, trainNumber: '9999');

final scrollableFinder = find.byType(ListView);
expect(scrollableFinder, findsOneWidget);

final stopRouteRow = findDASTableRowByText('Bahnhof A');
final nonStoppingPassRouteRow = findDASTableRowByText('Haltestelle B');
expect(stopRouteRow, findsOneWidget);
expect(nonStoppingPassRouteRow, findsOneWidget);

// check stop circles
final stopRoute = find.descendant(of: stopRouteRow, matching: find.byKey(RouteCellBody.stopKey));
final nonStoppingPassRoute =
find.descendant(of: nonStoppingPassRouteRow, matching: find.byKey(RouteCellBody.stopKey));
expect(stopRoute, findsOneWidget);
expect(nonStoppingPassRoute, findsNothing);

// check route start
final routeStart = find.byKey(RouteCellBody.routeStartKey);
expect(routeStart, findsOneWidget);

await tester.dragUntilVisible(find.byKey(RouteCellBody.routeEndKey), scrollableFinder, const Offset(0, -50));

// check route end
final routeEnd = find.byKey(RouteCellBody.routeEndKey);
expect(routeEnd, findsOneWidget);
});

testWidgets('test protection secions are displayed correctly', (tester) async {
await prepareAndStartApp(tester);

Expand All @@ -54,7 +144,8 @@ void main() {
expect(find.descendant(of: protectionSectionRow, matching: find.text('FL')), findsOneWidget);
expect(find.descendant(of: protectionSectionRow, matching: find.text('32.2')), findsOneWidget);
// Verify icon is displayed
expect(find.descendant(of: protectionSectionRow, matching: find.byKey(ProtectionSectionRow.protectionSectionKey)), findsOneWidget);
expect(find.descendant(of: protectionSectionRow, matching: find.byKey(ProtectionSectionRow.protectionSectionKey)),
findsOneWidget);

// Scroll to next protection section
await tester.dragUntilVisible(find.text('Yverdon-les-Bains'), scrollableFinder, const Offset(0, -20));
Expand Down Expand Up @@ -157,6 +248,11 @@ void main() {
// load train journey by filling out train selection page
await _loadTrainJourney(tester, trainNumber: '9999');

final scrollableFinder = find.byType(ListView);
expect(scrollableFinder, findsOneWidget);

await tester.dragUntilVisible(find.text('Klammerbahnhof D1'), scrollableFinder, const Offset(0, -50));

final bracketStationD = findDASTableRowByText('Klammerbahnhof D');
final bracketStationD1 = findDASTableRowByText('Klammerbahnhof D1');
expect(bracketStationD, findsOneWidget);
Expand All @@ -181,6 +277,11 @@ void main() {
// load train journey by filling out train selection page
await _loadTrainJourney(tester, trainNumber: '9999');

final scrollableFinder = find.byType(ListView);
expect(scrollableFinder, findsOneWidget);

await tester.dragUntilVisible(find.text('Halt auf Verlangen C'), scrollableFinder, const Offset(0, -50));

final stopOnDemandRow = findDASTableRowByText('Halt auf Verlangen C');
expect(stopOnDemandRow, findsOneWidget);

Expand All @@ -195,34 +296,6 @@ void main() {
expect(stopRoute, findsNothing);
});

testWidgets('test route is displayed correctly', (tester) async {
await prepareAndStartApp(tester);

// load train journey by filling out train selection page
await _loadTrainJourney(tester, trainNumber: '9999');

final stopRouteRow = findDASTableRowByText('Bahnhof A');
final nonStoppingPassRouteRow = findDASTableRowByText('Haltestelle B');
expect(stopRouteRow, findsOneWidget);
expect(nonStoppingPassRouteRow, findsOneWidget);

// check stop circles
final stopRoute = find.descendant(of: stopRouteRow, matching: find.byKey(RouteCellBody.stopKey));
final nonStoppingPassRoute = find.descendant(of: nonStoppingPassRouteRow, matching: find.byKey(RouteCellBody.stopKey));
expect(stopRoute, findsOneWidget);
expect(nonStoppingPassRoute, findsNothing);

// check route start
final startStationRow = findDASTableRowByText('Bahnhof A');
final routeStart = find.descendant(of: startStationRow, matching: find.byKey(RouteCellBody.routeStartKey));
expect(routeStart, findsOneWidget);

// check route end
final endStationRow = findDASTableRowByText('Klammerbahnhof D1');
final routeEnd = find.descendant(of: endStationRow, matching: find.byKey(RouteCellBody.routeEndKey));
expect(routeEnd, findsOneWidget);
});

testWidgets('test halt is displayed italic', (tester) async {
await prepareAndStartApp(tester);

Expand All @@ -237,8 +310,6 @@ void main() {
.byWidgetPredicate((it) => it is Text && it.data == 'Schlieren' && it.style?.fontStyle != FontStyle.italic);
expect(schlierenText, findsOneWidget);
});


});
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import 'package:das_client/app/i18n/i18n.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/base_row_builder.dart';
import 'package:das_client/app/widgets/assets.dart';
import 'package:das_client/app/widgets/table/das_table_cell.dart';
import 'package:das_client/model/journey/additional_speed_restriction_data.dart';
import 'package:design_system_flutter/design_system_flutter.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';

class AdditionalSpeedRestrictionRow extends BaseRowBuilder<AdditionalSpeedRestrictionData> {
rawi-coding marked this conversation as resolved.
Show resolved Hide resolved
static const Key additionalSpeedRestrictionIconKey = Key('addition_speed_restrction_icon_key');
static const Color additionalSpeedRestrictionColor = SBBColors.orange;

AdditionalSpeedRestrictionRow({
super.height = 44.0,
required super.metadata,
required super.data,
}) : super(rowColor: additionalSpeedRestrictionColor);

@override
DASTableCell informationCell(BuildContext context) {
return DASTableCell(
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text('${context.l10n.p_train_journey_table_kilometre_label} ${data.restriction.kmFrom.toStringAsFixed(3)} '
'- ${context.l10n.p_train_journey_table_kilometre_label} ${data.restriction.kmTo.toStringAsFixed(3)}'),
],
),
);
}

@override
DASTableCell iconsCell2(BuildContext context) {
return DASTableCell(
child: SvgPicture.asset(
AppAssets.iconAdditionalSpeedRestriction,
key: additionalSpeedRestrictionIconKey,
),
alignment: Alignment.center);
}

@override
DASTableCell graduatedSpeedCell(BuildContext context) {
return DASTableCell(
child: Text(data.restriction.speed.toString()),
alignment: Alignment.center,
);
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import 'package:das_client/app/pages/journey/train_journey/widgets/table/additional_speed_restriction_row.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/cells/route_cell_body.dart';
import 'package:das_client/app/widgets/table/das_table_cell.dart';
import 'package:das_client/app/widgets/table/das_table_row.dart';
import 'package:das_client/model/journey/additional_speed_restriction.dart';
import 'package:das_client/model/journey/base_data.dart';
import 'package:das_client/model/journey/metadata.dart';
import 'package:flutter/material.dart';

abstract class BaseRowBuilder extends DASTableRowBuilder {
class BaseRowBuilder<T extends BaseData> extends DASTableRowBuilder {
Grodien marked this conversation as resolved.
Show resolved Hide resolved
const BaseRowBuilder({
super.height,
this.kilometre,
super.height = 44.0,
this.defaultAlignment = Alignment.bottomCenter,
this.rowColor,
this.isCurrentPosition = false,
required this.metadata,
required this.data,
});

final List<double>? kilometre;
final Alignment defaultAlignment;
final Color? rowColor;
final bool isCurrentPosition;
final Metadata metadata;
final T data;

@override
DASTableRow build(BuildContext context) {
Expand All @@ -39,31 +43,37 @@ abstract class BaseRowBuilder extends DASTableRowBuilder {
}

DASTableCell kilometreCell(BuildContext context) {
if (kilometre == null || kilometre!.isEmpty) {
if (data.kilometre.isEmpty) {
return DASTableCell.empty();
}

return DASTableCell(
color: getSpecialCellColor(),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(kilometre![0].toStringAsFixed(1)),
if (kilometre!.length > 1) Text(kilometre![1].toStringAsFixed(1))
Text(data.kilometre[0].toStringAsFixed(1)),
if (data.kilometre.length > 1) Text(data.kilometre[1].toStringAsFixed(1))
],
),
alignment: Alignment.centerLeft);
}

DASTableCell timeCell(BuildContext context) {
return DASTableCell(child: Text('06:05:52'), alignment: defaultAlignment);
return DASTableCell(color: getSpecialCellColor(), child: Text('06:05:52'), alignment: defaultAlignment);
}

DASTableCell routeCell(BuildContext context) {
return DASTableCell(
color: getSpecialCellColor(),
padding: EdgeInsets.all(0.0),
alignment: null,
child: RouteCellBody(isCurrentPosition: isCurrentPosition),
child: RouteCellBody(
isCurrentPosition: metadata.currentPosition == data,
isRouteStart: metadata.routeStart == data,
isRouteEnd: metadata.routeEnd == data,
),
);
}

Expand All @@ -72,15 +82,15 @@ abstract class BaseRowBuilder extends DASTableRowBuilder {
}

DASTableCell graduatedSpeedCell(BuildContext context) {
return DASTableCell(child: Text('85'), alignment: defaultAlignment);
return DASTableCell.empty();
}

DASTableCell advisedSpeedCell(BuildContext context) {
return DASTableCell(child: Text('100'), alignment: defaultAlignment);
return DASTableCell.empty();
}

DASTableCell brakedWeightSpeedCell(BuildContext context) {
return DASTableCell(child: Text('95'), alignment: defaultAlignment);
return DASTableCell.empty();
}

// TODO: clarify use of different icon cells and set appropriate name
Expand All @@ -101,4 +111,16 @@ abstract class BaseRowBuilder extends DASTableRowBuilder {
DASTableCell actionsCell(BuildContext context) {
return DASTableCell.empty();
}

Color? getSpecialCellColor() {
return getAdditionalSpeedRestriction() != null
? AdditionalSpeedRestrictionRow.additionalSpeedRestrictionColor
: null;
}

AdditionalSpeedRestriction? getAdditionalSpeedRestriction() {
return metadata.additionalSpeedRestrictions
.where((it) => it.orderFrom <= data.order && it.orderTo >= data.order)
.firstOrNull;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ class RouteCellBody extends StatelessWidget {
final isDarkTheme = SBBBaseStyle.of(context).brightness == Brightness.dark;
final lineColor = isDarkTheme ? SBBColors.white : SBBColors.black;
return Positioned(
key: isRouteStart ? routeStartKey : isRouteEnd ? routeEndKey : null,
key: isRouteStart
? routeStartKey
: isRouteEnd
? routeEndKey
: null,
top: isRouteStart ? height - sbbDefaultSpacing : -sbbDefaultSpacing,
bottom: isRouteEnd ? sbbDefaultSpacing : -sbbDefaultSpacing,
right: 0,
Expand Down
Loading