Skip to content

Commit

Permalink
feat: implement protection section (#407)
Browse files Browse the repository at this point in the history
  • Loading branch information
Grodien authored Nov 22, 2024
1 parent 319de6b commit 731b2ad
Show file tree
Hide file tree
Showing 25 changed files with 1,006 additions and 39 deletions.
6 changes: 6 additions & 0 deletions das_client/assets/icons/icon_protection_section.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
67 changes: 67 additions & 0 deletions das_client/integration_test/test/train_journey_table_test.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
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';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/service_point_row.dart';
import 'package:das_client/app/pages/profile/profile_page.dart';
import 'package:design_system_flutter/design_system_flutter.dart';
Expand Down Expand Up @@ -33,6 +34,70 @@ void main() {
}
});

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

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

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

// check first train station
expect(find.text('Genève-Aéroport'), findsOneWidget);

// Scroll to first protection section
await tester.dragUntilVisible(find.text('Gilly-Bursinel'), scrollableFinder, const Offset(0, -20));

var protectionSectionRow = findDASTableRowByText('km 32.2');
expect(protectionSectionRow, findsOneWidget);
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);

// Scroll to next protection section
await tester.dragUntilVisible(find.text('Yverdon-les-Bains'), scrollableFinder, const Offset(0, -20));
await tester.pumpAndSettle();

protectionSectionRow = findDASTableRowByText('km 45.8');
expect(protectionSectionRow, findsOneWidget);
expect(find.descendant(of: protectionSectionRow, matching: find.text('L')), findsOneWidget);

// Scroll to next protection section
await tester.dragUntilVisible(find.text('Lengnau'), scrollableFinder, const Offset(0, -20));
await tester.pumpAndSettle();

protectionSectionRow = findDASTableRowByText('km 86.7');
expect(protectionSectionRow, findsOneWidget);
expect(find.descendant(of: protectionSectionRow, matching: find.text('FL')), findsOneWidget);

// Scroll to next protection section
await tester.dragUntilVisible(find.text('WANZ'), scrollableFinder, const Offset(0, -20));
await tester.pumpAndSettle();

protectionSectionRow = findDASTableRowByText('km 45.9');
expect(protectionSectionRow, findsOneWidget);
expect(find.descendant(of: protectionSectionRow, matching: find.text('FL')), findsOneWidget);

// Scroll to next protection section
await tester.dragUntilVisible(find.text('Mellingen Heitersberg'), scrollableFinder, const Offset(0, -20));
await tester.pumpAndSettle();

protectionSectionRow = findDASTableRowByText('km 21.5');
expect(protectionSectionRow, findsOneWidget);
expect(find.descendant(of: protectionSectionRow, matching: find.text('F')), findsOneWidget);

// Scroll to next protection section
await tester.dragUntilVisible(find.text('Flughafen'), scrollableFinder, const Offset(0, -20));
await tester.pumpAndSettle();

protectionSectionRow = findDASTableRowByText('km 6.6');
expect(find.descendant(of: protectionSectionRow, matching: find.text('FL')), findsNothing);
expect(find.descendant(of: protectionSectionRow, matching: find.text('F')), findsNothing);
expect(find.descendant(of: protectionSectionRow, matching: find.text('L')), findsNothing);
});

testWidgets('test scrolling to last train station', (tester) async {
await prepareAndStartApp(tester);

Expand Down Expand Up @@ -172,6 +237,8 @@ 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
Expand Up @@ -7,7 +7,7 @@ abstract class BaseRowBuilder extends DASTableRowBuilder {
const BaseRowBuilder({
super.height,
this.kilometre,
this.defaultAlignment = Alignment.centerLeft,
this.defaultAlignment = Alignment.bottomCenter,
this.rowColor,
this.isCurrentPosition = false,
});
Expand All @@ -23,22 +23,22 @@ abstract class BaseRowBuilder extends DASTableRowBuilder {
height: height,
color: rowColor,
cells: [
kilometreCell(),
timeCell(),
routeCell(),
iconsCell1(),
informationCell(),
iconsCell2(),
iconsCell3(),
graduatedSpeedCell(),
brakedWeightSpeedCell(),
advisedSpeedCell(),
actionsCell(),
kilometreCell(context),
timeCell(context),
routeCell(context),
iconsCell1(context),
informationCell(context),
iconsCell2(context),
iconsCell3(context),
graduatedSpeedCell(context),
brakedWeightSpeedCell(context),
advisedSpeedCell(context),
actionsCell(context),
],
);
}

DASTableCell kilometreCell() {
DASTableCell kilometreCell(BuildContext context) {
if (kilometre == null || kilometre!.isEmpty) {
return DASTableCell.empty();
}
Expand All @@ -55,50 +55,50 @@ abstract class BaseRowBuilder extends DASTableRowBuilder {
alignment: Alignment.centerLeft);
}

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

DASTableCell routeCell() {
DASTableCell routeCell(BuildContext context) {
return DASTableCell(
padding: EdgeInsets.all(0.0),
alignment: null,
child: RouteCellBody(isCurrentPosition: isCurrentPosition),
);
}

DASTableCell informationCell() {
DASTableCell informationCell(BuildContext context) {
return DASTableCell.empty();
}

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

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

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

// TODO: clarify use of different icon cells and set appropriate name
DASTableCell iconsCell1() {
DASTableCell iconsCell1(BuildContext context) {
return DASTableCell.empty();
}

// TODO: clarify use of different icon cells and set appropriate name
DASTableCell iconsCell2() {
DASTableCell iconsCell2(BuildContext context) {
return DASTableCell.empty();
}

// TODO: clarify use of different icon cells and set appropriate name
DASTableCell iconsCell3() {
DASTableCell iconsCell3(BuildContext context) {
return DASTableCell.empty();
}

DASTableCell actionsCell() {
DASTableCell actionsCell(BuildContext context) {
return DASTableCell.empty();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
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/metadata.dart';
import 'package:das_client/model/journey/protection_section.dart';
import 'package:design_system_flutter/design_system_flutter.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';

class ProtectionSectionRow extends BaseRowBuilder {
static const Key protectionSectionKey = Key('protection_section_key');

ProtectionSectionRow({
super.height = 44.0,
required this.metadata,
required this.protectionSection,
}) : super(rowColor: SBBColors.peach, kilometre: protectionSection.kilometre);

final Metadata metadata;
final ProtectionSection protectionSection;

@override
DASTableCell informationCell(BuildContext context) {
return DASTableCell(
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
'${context.l10n.p_train_journey_table_kilometre_label} ${protectionSection.kilometre[0].toStringAsFixed(1)}'),
Spacer(),
Text('${protectionSection.isOptional ? 'F' : ''}${protectionSection.isLong ? 'L' : ''}'),
],
),
);
}

@override
DASTableCell iconsCell2(BuildContext context) {
return DASTableCell(
child: SvgPicture.asset(
AppAssets.iconProtectionSection,
key: protectionSectionKey,
),
alignment: Alignment.bottomCenter);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ class ServicePointRow extends BaseRowBuilder {

ServicePointRow({
super.height = 64.0,
super.defaultAlignment = _defaultAlignment,
this.isRouteStart = false,
this.isRouteEnd = false,
required this.metadata,
Expand All @@ -28,19 +27,18 @@ class ServicePointRow extends BaseRowBuilder {
final Metadata metadata;
final ServicePoint servicePoint;

static const Alignment _defaultAlignment = Alignment.bottomCenter;

final bool isRouteStart;
final bool isRouteEnd;

@override
DASTableCell informationCell() {
DASTableCell informationCell(BuildContext context) {
final servicePointName = servicePoint.name.localized;
final textStyle = servicePoint.isStation
? SBBTextStyles.largeBold.copyWith(fontSize: 24.0)
: SBBTextStyles.largeLight.copyWith(fontSize: 24.0, fontStyle: FontStyle.italic);
return DASTableCell(
alignment: _defaultAlignment,
alignment: defaultAlignment,
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expand All @@ -53,7 +51,7 @@ class ServicePointRow extends BaseRowBuilder {
}

@override
DASTableCell iconsCell1() {
DASTableCell iconsCell1(BuildContext context) {
return DASTableCell(
padding: EdgeInsets.fromLTRB(0, sbbDefaultSpacing * 0.5, 0, sbbDefaultSpacing * 0.5),
child: Stack(
Expand All @@ -77,7 +75,7 @@ class ServicePointRow extends BaseRowBuilder {
}

@override
DASTableCell routeCell() {
DASTableCell routeCell(BuildContext context) {
return DASTableCell(
padding: EdgeInsets.all(0.0),
alignment: null,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import 'package:das_client/app/bloc/train_journey_cubit.dart';
import 'package:das_client/app/i18n/i18n.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/protection_section_row.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/service_point_row.dart';
import 'package:das_client/app/widgets/table/das_table.dart';
import 'package:das_client/app/widgets/table/das_table_column.dart';
import 'package:das_client/model/journey/datatype.dart';
import 'package:das_client/model/journey/journey.dart';
import 'package:das_client/model/journey/protection_section.dart';
import 'package:das_client/model/journey/service_point.dart';
import 'package:design_system_flutter/design_system_flutter.dart';
import 'package:flutter/material.dart';
Expand Down Expand Up @@ -49,6 +51,9 @@ class TrainJourney extends StatelessWidget {
isRouteStart: index == 0,
isRouteEnd: index == journey.data.length - 1,
).build(context);
case Datatype.protectionSection:
return ProtectionSectionRow(metadata: journey.metadata, protectionSection: rowData as ProtectionSection)
.build(context);
}
})
],
Expand Down
1 change: 1 addition & 0 deletions das_client/lib/app/widgets/assets.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ class AppAssets {

static const iconHeaderStop = '$_iconsDir/icon_header_stop.svg';
static const iconStopOnRequest = '$_iconsDir/icon_stop_on_request.svg';
static const iconProtectionSection = '$_iconsDir/icon_protection_section.svg';
}
3 changes: 2 additions & 1 deletion das_client/lib/model/journey/datatype.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
enum Datatype {
servicePoint;
servicePoint,
protectionSection;
}
10 changes: 10 additions & 0 deletions das_client/lib/model/journey/protection_section.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import 'package:das_client/model/journey/base_data.dart';
import 'package:das_client/model/journey/datatype.dart';

class ProtectionSection extends BaseData {
ProtectionSection({required this.isOptional, required this.isLong, required super.order, required super.kilometre})
: super(type: Datatype.protectionSection);

final bool isOptional;
final bool isLong;
}
Loading

0 comments on commit 731b2ad

Please sign in to comment.