Skip to content

Commit

Permalink
feat: adding navigation drawer (#299)
Browse files Browse the repository at this point in the history
  • Loading branch information
Grodien authored Oct 14, 2024
1 parent 72d035b commit 8890805
Show file tree
Hide file tree
Showing 31 changed files with 542 additions and 97 deletions.
Binary file added .github/.DS_Store
Binary file not shown.
2 changes: 1 addition & 1 deletion .github/workflows/flutter_android_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
java-version: '17'
- uses: subosito/flutter-action@v2
with:
flutter-version: '3.22.2'
flutter-version: '3.24.3'
- name: Prepare Flutter Build
env:
ANDROID_KEYSTORE_STRING: ${{ secrets.ANDROID_KEYSTORE }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/flutter_browserstack_android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
java-version: '17'
- uses: subosito/flutter-action@v2
with:
flutter-version: '3.22.2'
flutter-version: '3.24.3'
- name: Prepare Flutter Build
env:
ANDROID_KEYSTORE_STRING: ${{ secrets.ANDROID_KEYSTORE }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/flutter_browserstack_ios.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
java-version: '17'
- uses: subosito/flutter-action@v2
with:
flutter-version: '3.22.2'
flutter-version: '3.24.3'
- run: flutter pub get
- run: flutter pub run build_runner build --delete-conflicting-outputs
- shell: bash
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
java-version: '17'
- uses: subosito/flutter-action@v2
with:
flutter-version: '3.22.2'
flutter-version: '3.24.3'
- name: Install the Apple signing certificate and appstore connect key
env:
SBB_APPSTORE_BASE64: ${{ secrets.SBB_APPSTORE_BASE64 }}
Expand Down Expand Up @@ -136,7 +136,7 @@ jobs:
java-version: '17'
- uses: subosito/flutter-action@v2
with:
flutter-version: '3.22.2'
flutter-version: '3.24.3'
- name: Prepare Flutter Android Build
env:
ANDROID_KEYSTORE_STRING: ${{ secrets.ANDROID_KEYSTORE }}
Expand Down
2 changes: 1 addition & 1 deletion das_client/.fvm/fvm_config.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"flutterSdkVersion": "3.22.2",
"flutterSdkVersion": "3.24.3",
"flavors": {}
}
16 changes: 16 additions & 0 deletions das_client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,22 @@ The app is available in three languages:
<img src="https://img.shields.io/badge/%F0%9F%87%AE%F0%9F%87%B9_italian_(it)-999999?style=for-the-badge" alt="Italian"/>
</div>

Localization terms/keys conform to the following format:

```
<PREFIX>_<CONTEXT?>_<LABEL>
```

The prefix is mandatory and indicates the scope of the term. Valid prefixes are:

| Prefix | Scope | Description |
| --- | --- | --- |
| c | Common | Common terms that can be used in the whole app |
| p | Page | Terms that belong to a specific page |
| w | Widget | Terms that bleong to a specific widget |

The context is optional and indicate where a localization is used. When a localization is scoped to a page or widget, the context MUST be equal to the name of that page or widget. For example, localizations used on the login page would start with `p_login_`.

## Code style

This application uses the code style defined in the [Flutter Wiki][2]. The
Expand Down
32 changes: 4 additions & 28 deletions das_client/integration_test/app_test.dart
Original file line number Diff line number Diff line change
@@ -1,43 +1,19 @@
import 'package:das_client/flavor.dart';
import 'package:das_client/main.dart';
import 'package:design_system_flutter/design_system_flutter.dart';
import 'package:fimber/fimber.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';

import 'di.dart';
import 'test/fahrbild_test.dart' as FahrbildTests;
import 'test/navigation_test.dart' as NavigationTests;

void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
Fimber.plantTree(DebugTree());

group('home screen test', () {
testWidgets('load fahrbild company=1088, train=9232', (tester) async {
// Load app widget.
await prepareAndStartApp(tester);

await tester.pump(const Duration(seconds: 1));

// Verify we have trainnumber with 9232.
expect(find.text('9232'), findsOneWidget);

// Verify we have company with 1088.
expect(find.text('1088'), findsOneWidget);

// check that the primary button is enabled
var primaryButton = find.byWidgetPredicate((widget) => widget is SBBPrimaryButton).first;
expect(tester.widget<SBBPrimaryButton>(primaryButton).onPressed, isNotNull);

// press load Fahrordnung button
await tester.tap(primaryButton);

// wait for fahrbild to load
await tester.pumpAndSettle(const Duration(seconds: 1));

// check if station is present
expect(find.text('MEER-GRENS'), findsOneWidget);
});
});
FahrbildTests.main();
NavigationTests.main();
}

Future<void> prepareAndStartApp(WidgetTester tester) async {
Expand Down
26 changes: 16 additions & 10 deletions das_client/integration_test/di.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,24 @@ import 'auth/mqtt_client_user_connector.dart';

class IntegrationTestDI {
const IntegrationTestDI._();
static bool _initialized = false;

static Future<void> init(Flavor flavor) {
Fimber.i('Initialize integration test dependency injection');
GetIt.I.registerFlavor(flavor);
GetIt.I.registerTokenSpecProvider();
GetIt.I.registerOidcClient();
_registerIntegrationTestAuthenticator();
GetIt.I.registerBackendService();
_registerMqttClientConnector();
GetIt.I.registerMqttService();
GetIt.I.registerRepositories();
GetIt.I.registerServices();
if (_initialized) {
return GetIt.I.allReady();
} else {
Fimber.i('Initialize integration test dependency injection');
GetIt.I.registerFlavor(flavor);
GetIt.I.registerTokenSpecProvider();
GetIt.I.registerOidcClient();
_registerIntegrationTestAuthenticator();
GetIt.I.registerBackendService();
_registerMqttClientConnector();
GetIt.I.registerMqttService();
GetIt.I.registerRepositories();
GetIt.I.registerServices();
_initialized = true;
}
return GetIt.I.allReady();
}

Expand Down
37 changes: 37 additions & 0 deletions das_client/integration_test/test/fahrbild_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import 'package:design_system_flutter/design_system_flutter.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';

import '../app_test.dart';

void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

group('home screen test', () {
testWidgets('load fahrbild company=1088, train=9232', (tester) async {
// Load app widget.
await prepareAndStartApp(tester);

await tester.pump(const Duration(seconds: 1));

// Verify we have trainnumber with 9232.
expect(find.text('9232'), findsOneWidget);

// Verify we have company with 1088.
expect(find.text('1088'), findsOneWidget);

// check that the primary button is enabled
var primaryButton = find.byWidgetPredicate((widget) => widget is SBBPrimaryButton).first;
expect(tester.widget<SBBPrimaryButton>(primaryButton).onPressed, isNotNull);

// press load Fahrordnung button
await tester.tap(primaryButton);

// wait for fahrbild to load
await tester.pumpAndSettle(const Duration(seconds: 1));

// check if station is present
expect(find.text('MEER-GRENS'), findsOneWidget);
});
});
}
126 changes: 126 additions & 0 deletions das_client/integration_test/test/navigation_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import 'package:design_system_flutter/design_system_flutter.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';

import '../app_test.dart';

void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

group('navigation drawer tests', () {
testWidgets('should show navigation drawer', (tester) async {
// Load app widget.
await prepareAndStartApp(tester);

await tester.pump(const Duration(seconds: 1));

// check that there is a drawer
var scaffold = find.byWidgetPredicate((widget) => widget is Scaffold).first;
expect(tester.widget<Scaffold>(scaffold).drawer, isNotNull);

// check that drawer is not shown
expect(find.text('Fahrtinfo'), findsNothing);
expect(find.text('Links'), findsNothing);
expect(find.text('Einstellungen'), findsNothing);
expect(find.text('Profil'), findsNothing);

// open drawer
final ScaffoldState scaffoldState = tester.firstState(find.byType(Scaffold));
scaffoldState.openDrawer();

// wait for drawer to open
await tester.pumpAndSettle(const Duration(seconds: 1));

// check if navigation elements are present
expect(find.text('Fahrtinfo'), findsOneWidget);
expect(find.text('Links'), findsOneWidget);
expect(find.text('Einstellungen'), findsOneWidget);
expect(find.text('Profil'), findsOneWidget);
});

testWidgets('test navigate to links', (tester) async {
// Load app widget.
await prepareAndStartApp(tester);

await tester.pump(const Duration(seconds: 1));

// open drawer
final ScaffoldState scaffoldState = tester.firstState(find.byType(Scaffold));
scaffoldState.openDrawer();

// wait for drawer to open
await tester.pumpAndSettle(const Duration(seconds: 1));

// check if navigation elements are present
expect(find.text('Links'), findsOneWidget);

var gestureDetector = find.ancestor(of: find.text('Links'), matching: find.byType(GestureDetector)).first;
await tester.tap(gestureDetector);

await tester.pumpAndSettle(const Duration(seconds: 1));

// Check drawer is closed
expect(find.text('Einstellungen'), findsNothing);
expect(find.text('Profil'), findsNothing);

expect(find.text('Links'), findsOneWidget);
});

testWidgets('test navigate to settings', (tester) async {
// Load app widget.
await prepareAndStartApp(tester);

await tester.pump(const Duration(seconds: 1));

// open drawer
final ScaffoldState scaffoldState = tester.firstState(find.byType(Scaffold));
scaffoldState.openDrawer();

// wait for drawer to open
await tester.pumpAndSettle(const Duration(seconds: 1));

// check if navigation elements are present
expect(find.text('Einstellungen'), findsOneWidget);

var gestureDetector = find.ancestor(of: find.text('Einstellungen'), matching: find.byType(GestureDetector)).first;
await tester.tap(gestureDetector);

await tester.pumpAndSettle(const Duration(seconds: 1));

// Check drawer is closed
expect(find.text('Link'), findsNothing);
expect(find.text('Profil'), findsNothing);

expect(find.text('Einstellungen'), findsOneWidget);
});

testWidgets('test navigate to profile', (tester) async {
// Load app widget.
await prepareAndStartApp(tester);

await tester.pump(const Duration(seconds: 1));

// open drawer
final ScaffoldState scaffoldState = tester.firstState(find.byType(Scaffold));
scaffoldState.openDrawer();

// wait for drawer to open
await tester.pumpAndSettle(const Duration(seconds: 1));

// check if navigation elements are present
expect(find.text('Profil'), findsOneWidget);

var gestureDetector = find.ancestor(of: find.text('Profil'), matching: find.byType(GestureDetector)).first;
await tester.tap(gestureDetector);

await tester.pumpAndSettle(const Duration(seconds: 1));

// Check drawer is closed
expect(find.text('Link'), findsNothing);
expect(find.text('Einstellungen'), findsNothing);

expect(find.text('Profil'), findsOneWidget);
});
});
}
6 changes: 6 additions & 0 deletions das_client/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ PODS:
- Flutter
- isar_flutter_libs (1.0.0):
- Flutter
- package_info_plus (0.4.5):
- Flutter
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
Expand All @@ -28,6 +30,7 @@ DEPENDENCIES:
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
- integration_test (from `.symlinks/plugins/integration_test/ios`)
- isar_flutter_libs (from `.symlinks/plugins/isar_flutter_libs/ios`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)

SPEC REPOS:
Expand All @@ -47,6 +50,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/integration_test/ios"
isar_flutter_libs:
:path: ".symlinks/plugins/isar_flutter_libs/ios"
package_info_plus:
:path: ".symlinks/plugins/package_info_plus/ios"
path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/darwin"

Expand All @@ -58,6 +63,7 @@ SPEC CHECKSUMS:
flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12
integration_test: ce0a3ffa1de96d1a89ca0ac26fca7ea18a749ef4
isar_flutter_libs: b69f437aeab9c521821c3f376198c4371fa21073
package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46

PODFILE CHECKSUM: d9dad56c0cd0b4fd8b4fe3034a53fd42a0b990f6
Expand Down
6 changes: 5 additions & 1 deletion das_client/l10n/strings_de.arb
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@
"p_train_selection_trainnumber_description": "Zugnummer",
"p_train_selection_trainnumber_placeholder": "z.B. 711",
"p_train_selection_company_description": "Company code",
"p_train_selection_company_placeholder": "z.B. 0085"
"p_train_selection_company_placeholder": "z.B. 0085",
"w_navigation_drawer_fahrtinfo_title": "Fahrtinfo",
"w_navigation_drawer_links_title": "Links",
"w_navigation_drawer_settings_title": "Einstellungen",
"w_navigation_drawer_profile_title": "Profil"
}
Loading

0 comments on commit 8890805

Please sign in to comment.