Skip to content

Commit 7e2f881

Browse files
authored
Merge pull request #38 from ashtanko/feature/launch_details_screen
Implement launch details screen
2 parents 023a79d + 8ea9176 commit 7e2f881

File tree

97 files changed

+9041
-321
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+9041
-321
lines changed

.github/workflows/ci.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ on:
88
pull_request:
99
branches: [ main ]
1010

11+
concurrency:
12+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
13+
cancel-in-progress: true
14+
1115
defaults:
1216
run:
1317
shell: bash
@@ -124,6 +128,7 @@ jobs:
124128
flutter pub get
125129
flutter test integration_test/app_test.dart --flavor dev
126130
flutter test integration_test/appearance_test.dart --flavor dev
131+
flutter test integration_test/launch_navigation_test.dart --flavor dev
127132
flutter test integration_test/launch_test.dart --flavor dev
128133
flutter test integration_test/launches_mock_test.dart --flavor dev
129134
flutter test integration_test/launches_test.dart --flavor dev

Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@
55
rebuild:
66
flutter clean
77
flutter pub get
8-
flutter pub run build_runner build --delete-conflicting-outputs
8+
dart run build_runner build --delete-conflicting-outputs
99
fluttergen -c pubspec.yaml
1010

1111
# Generate code with build_runner
1212
gen:
13-
flutter pub run build_runner build --delete-conflicting-outputs
13+
dart run build_runner build --delete-conflicting-outputs
1414

1515
# Generate code and localizations
1616
genAll:
17-
flutter pub run build_runner build --delete-conflicting-outputs
17+
dart run build_runner build --delete-conflicting-outputs
1818
flutter pub run intl_utils:generate
1919
fluttergen -c pubspec.yaml
2020

integration_test/app_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ void main() {
1414
app.main([]);
1515
await tester.pumpAndSettle();
1616

17-
// expect(find.text('Launches'), findsOneWidget);
17+
expect(find.text('Launches'), findsAtLeast(1));
1818
expect(find.text('Emails'), findsOneWidget);
1919
expect(find.text('Settings'), findsOneWidget);
2020

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import 'package:flutter/foundation.dart';
2+
import 'package:flutter_bloc_app_template/main.dart' as app;
3+
import 'package:flutter_test/flutter_test.dart';
4+
import 'package:integration_test/integration_test.dart';
5+
6+
void main() {
7+
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
8+
9+
setUp(() {});
10+
11+
testWidgets('launch test', (
12+
WidgetTester tester,
13+
) async {
14+
app.main([]);
15+
await tester.pumpAndSettle();
16+
17+
final firstItem = find.byKey(const Key('FalconSat1'));
18+
19+
expect(firstItem, findsOneWidget);
20+
await tester.ensureVisible(firstItem);
21+
await tester.tap(firstItem);
22+
23+
await tester.pumpAndSettle();
24+
expect(find.text('FalconSat'), findsOneWidget);
25+
});
26+
}

integration_test/launch_test.dart

Lines changed: 66 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,79 @@
1-
import 'package:flutter/foundation.dart';
2-
import 'package:flutter_bloc_app_template/features/launches/widget/launch_item.dart';
3-
import 'package:flutter_bloc_app_template/main.dart' as app;
1+
import 'dart:ui';
2+
3+
import 'package:flutter_bloc_app_template/features/launch/bloc/launch_bloc.dart';
4+
import 'package:flutter_bloc_app_template/features/launch/launch_screen.dart';
45
import 'package:flutter_test/flutter_test.dart';
56
import 'package:integration_test/integration_test.dart';
7+
import 'package:mocktail/mocktail.dart';
8+
9+
import '../test/bloc/utils.dart';
10+
import '../test/features/launch/launch_screen_test.dart';
611

712
void main() {
813
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
914

10-
setUp(() {});
15+
late LaunchBloc launchBloc;
16+
17+
setUp(() {
18+
launchBloc = MockLaunchBloc();
19+
});
1120

12-
testWidgets('launch test', (
13-
WidgetTester tester,
14-
) async {
15-
app.main([]);
21+
Future<void> pumpLaunchScreen(
22+
WidgetTester tester, {
23+
required Locale locale,
24+
}) async {
25+
when(() => launchBloc.state).thenReturn(
26+
const LaunchSuccessState(
27+
launch: mockLaunchResource,
28+
),
29+
);
30+
31+
await tester.pumpLocalizedWidgetWithBloc<LaunchBloc>(
32+
bloc: launchBloc,
33+
child: const LaunchScreenBlocContent(flightNumber: 1),
34+
locale: locale,
35+
);
1636
await tester.pumpAndSettle();
37+
}
1738

18-
final firstItem = find.byKey(const Key('FalconSat1'));
39+
void expectLaunchTexts(
40+
String flightName, {
41+
List<String> additionalTexts = const [],
42+
}) {
43+
expect(find.text('Starlink-1'), findsOneWidget);
44+
expect(find.text(flightName), findsOneWidget);
45+
for (final text in additionalTexts) {
46+
expect(find.text(text), findsAtLeast(1));
47+
}
48+
}
1949

20-
expect(firstItem, findsOneWidget);
21-
await tester.ensureVisible(firstItem);
22-
await tester.tap(find.byType(LaunchItem).first);
50+
group('Launch Screen Tests', () {
51+
testWidgets('launch test', (tester) async {
52+
await pumpLaunchScreen(tester, locale: const Locale('en'));
53+
expectLaunchTexts('Flight #100');
54+
});
2355

24-
await tester.pumpAndSettle();
25-
expect(find.text('FalconSat'), findsOneWidget);
56+
testWidgets('launch uk test', (tester) async {
57+
await pumpLaunchScreen(tester, locale: const Locale('uk'));
58+
expectLaunchTexts(
59+
'Політ #100',
60+
additionalTexts: ['Місія успішна'],
61+
);
62+
});
63+
64+
testWidgets('launch pt test', (tester) async {
65+
await pumpLaunchScreen(tester, locale: const Locale('pt'));
66+
expectLaunchTexts(
67+
'Voo #100',
68+
additionalTexts: ['Missão bem-sucedida'],
69+
);
70+
});
71+
testWidgets('launch de test', (tester) async {
72+
await pumpLaunchScreen(tester, locale: const Locale('de'));
73+
expectLaunchTexts(
74+
'Flug #100',
75+
additionalTexts: ['Mission erfolgreich'],
76+
);
77+
});
2678
});
2779
}

lib/app/localization.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const appSupportedLocales = <Locale>[
1010
Locale('en', ''),
1111
Locale('de', ''),
1212
Locale('pt', ''),
13+
Locale('uk', ''),
1314
];
1415

1516
const appLocalizationsDelegates = <LocalizationsDelegate<dynamic>>[
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import 'package:freezed_annotation/freezed_annotation.dart';
2+
3+
part 'network_core_model.freezed.dart';
4+
part 'network_core_model.g.dart';
5+
6+
@freezed
7+
abstract class NetworkCoreModel with _$NetworkCoreModel {
8+
const factory NetworkCoreModel({
9+
@JsonKey(name: 'core_serial') String? coreSerial,
10+
int? flight,
11+
int? block,
12+
bool? gridfins,
13+
bool? legs,
14+
bool? reused,
15+
@JsonKey(name: 'land_success') bool? landSuccess,
16+
@JsonKey(name: 'landing_intent') bool? landingIntent,
17+
@JsonKey(name: 'landing_type') String? landingType,
18+
@JsonKey(name: 'landing_vehicle') String? landingVehicle,
19+
}) = _NetworkCoreModel;
20+
21+
const NetworkCoreModel._();
22+
23+
factory NetworkCoreModel.fromJson(Map<String, dynamic> json) =>
24+
_$NetworkCoreModelFromJson(json);
25+
}

0 commit comments

Comments
 (0)