|
|
|
import 'dart:io';
|
|
|
|
|
|
|
|
import 'package:compass_app/config/dependencies.dart';
|
|
|
|
import 'package:compass_app/main.dart';
|
|
|
|
import 'package:compass_app/ui/activities/widgets/activities_screen.dart';
|
|
|
|
import 'package:compass_app/ui/auth/login/widgets/login_screen.dart';
|
|
|
|
import 'package:compass_app/ui/auth/logout/widgets/logout_button.dart';
|
|
|
|
import 'package:compass_app/ui/booking/widgets/booking_screen.dart';
|
|
|
|
import 'package:compass_app/ui/core/ui/custom_checkbox.dart';
|
|
|
|
import 'package:compass_app/ui/core/ui/home_button.dart';
|
[Compass App] Home screen with booking list (#2428)
This PR introduces the storage and retrieval of bookings.
### Server implementation
- New booking routes:
- GET `/booking`: Obtain the list ofer user bookings
- GET `/booking/{id}`: Obtain the specific booking object
- POST `/booking`: Creates a new booking
- The `BookingApiModel` objects are incomplete, the `Destination` is a
reference, not the full object, and the `Activity` list are also listed
as references only.
- Server booking always has an existing booking created (Alaska, North
America) for demo purposes.
- Storage is "in memory", stopping the server deletes all stored
bookings.
### New `BookingRepository`
- New repository class.
- Both local and remote implementations.
- Converts the `BookingApiModel` into a complete `Booking` that the app
can use, or a `BookingSummary` that only contains the necessary
information for the home screen.
### New `LocalDataService`
- Service that loads hard-coded data or from assets.
### New `HomeScreen`
- Route path: `/`
- Loads and displays the list of created bookings from the
`BookingRepository`.
- Tap on a booking title opens the `BookingScreen`.
- Floating Action Button to create a new booking.
### Changes in `BookingScreen`
- Can be accessed at the end of creating a booking or from the home
screen when tapping a booking title.
- Two commands:
- `createBooking`: Takes the stored `ItineraryConfig` and creates a
booking, the booking is stored to the `BookingRepository` (locally or on
the server).
- `loadBooking`: Takes a booking ID and loads that existing booking from
the `BookingRepository`.
- Simplified navigation: Once at `BookingScreen`, user can only navigate
back to `HomeScreen`.
- Share button converted to `FloatingActionButton`
### Integration Tests
- Updated to use new home screen.
- Updated to cover opening an existing booking in tests.
### TODO Next
- Refactor the `compass_model` project and move data model classes to
`server` and `app`, then delete project.
- Implement some user information for the home screen (e.g. retrieve
user name and profile picture url)
### Screencast
[Screencast from 2024-09-02
16-25-25.webm](https://github.com/user-attachments/assets/8aba4a61-def6-4752-a4e5-70cbed362524)
## Pre-launch Checklist
- [x] I read the [Flutter Style Guide] _recently_, and have followed its
advice.
- [x] I signed the [CLA].
- [x] I read the [Contributors Guide].
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] All existing and new tests are passing.
If you need help, consider asking for advice on the #hackers-devrel
channel on [Discord].
<!-- Links -->
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/master/docs/contributing/Style-guide-for-Flutter-repo.md
[CLA]: https://cla.developers.google.com/
[Discord]:
https://github.com/flutter/flutter/blob/master/docs/contributing/Chat.md
[Contributors Guide]:
https://github.com/flutter/samples/blob/main/CONTRIBUTING.md
3 months ago
|
|
|
import 'package:compass_app/ui/home/widgets/home_screen.dart';
|
|
|
|
import 'package:compass_app/ui/results/widgets/result_card.dart';
|
|
|
|
import 'package:compass_app/ui/results/widgets/results_screen.dart';
|
|
|
|
import 'package:compass_app/ui/search_form/widgets/search_form_screen.dart';
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
import 'package:integration_test/integration_test.dart';
|
|
|
|
import 'package:provider/provider.dart';
|
|
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
|
|
|
|
/// This Integration Test starts the Dart server
|
|
|
|
/// before launching the Compass-App with the remote configuration.
|
|
|
|
/// The app connects to its endpoints to perform login and create a booking.
|
|
|
|
void main() {
|
|
|
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
|
|
|
|
|
|
|
group('end-to-end test with remote data', () {
|
[Compass App] Home screen with booking list (#2428)
This PR introduces the storage and retrieval of bookings.
### Server implementation
- New booking routes:
- GET `/booking`: Obtain the list ofer user bookings
- GET `/booking/{id}`: Obtain the specific booking object
- POST `/booking`: Creates a new booking
- The `BookingApiModel` objects are incomplete, the `Destination` is a
reference, not the full object, and the `Activity` list are also listed
as references only.
- Server booking always has an existing booking created (Alaska, North
America) for demo purposes.
- Storage is "in memory", stopping the server deletes all stored
bookings.
### New `BookingRepository`
- New repository class.
- Both local and remote implementations.
- Converts the `BookingApiModel` into a complete `Booking` that the app
can use, or a `BookingSummary` that only contains the necessary
information for the home screen.
### New `LocalDataService`
- Service that loads hard-coded data or from assets.
### New `HomeScreen`
- Route path: `/`
- Loads and displays the list of created bookings from the
`BookingRepository`.
- Tap on a booking title opens the `BookingScreen`.
- Floating Action Button to create a new booking.
### Changes in `BookingScreen`
- Can be accessed at the end of creating a booking or from the home
screen when tapping a booking title.
- Two commands:
- `createBooking`: Takes the stored `ItineraryConfig` and creates a
booking, the booking is stored to the `BookingRepository` (locally or on
the server).
- `loadBooking`: Takes a booking ID and loads that existing booking from
the `BookingRepository`.
- Simplified navigation: Once at `BookingScreen`, user can only navigate
back to `HomeScreen`.
- Share button converted to `FloatingActionButton`
### Integration Tests
- Updated to use new home screen.
- Updated to cover opening an existing booking in tests.
### TODO Next
- Refactor the `compass_model` project and move data model classes to
`server` and `app`, then delete project.
- Implement some user information for the home screen (e.g. retrieve
user name and profile picture url)
### Screencast
[Screencast from 2024-09-02
16-25-25.webm](https://github.com/user-attachments/assets/8aba4a61-def6-4752-a4e5-70cbed362524)
## Pre-launch Checklist
- [x] I read the [Flutter Style Guide] _recently_, and have followed its
advice.
- [x] I signed the [CLA].
- [x] I read the [Contributors Guide].
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] All existing and new tests are passing.
If you need help, consider asking for advice on the #hackers-devrel
channel on [Discord].
<!-- Links -->
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/master/docs/contributing/Style-guide-for-Flutter-repo.md
[CLA]: https://cla.developers.google.com/
[Discord]:
https://github.com/flutter/flutter/blob/master/docs/contributing/Chat.md
[Contributors Guide]:
https://github.com/flutter/samples/blob/main/CONTRIBUTING.md
3 months ago
|
|
|
const port = '8080';
|
|
|
|
late Process p;
|
|
|
|
|
|
|
|
setUpAll(() async {
|
|
|
|
// Clear any stored shared preferences
|
|
|
|
final sharedPreferences = await SharedPreferences.getInstance();
|
|
|
|
await sharedPreferences.clear();
|
|
|
|
|
|
|
|
// Start the dart server
|
|
|
|
p = await Process.start(
|
|
|
|
'dart',
|
|
|
|
['run', 'bin/compass_server.dart'],
|
|
|
|
environment: {'PORT': port},
|
|
|
|
// Relative to the app/ folder
|
|
|
|
workingDirectory: '../server',
|
|
|
|
);
|
|
|
|
// Wait for server to start and print to stdout.
|
|
|
|
await p.stdout.first;
|
|
|
|
});
|
|
|
|
|
|
|
|
tearDownAll(() => p.kill());
|
|
|
|
|
|
|
|
testWidgets('should load app', (tester) async {
|
|
|
|
// Load app widget.
|
|
|
|
await tester.pumpWidget(
|
|
|
|
MultiProvider(
|
|
|
|
providers: providersRemote,
|
|
|
|
child: const MainApp(),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
|
|
|
// Login screen because logget out
|
|
|
|
expect(find.byType(LoginScreen), findsOneWidget);
|
|
|
|
});
|
|
|
|
|
[Compass App] Home screen with booking list (#2428)
This PR introduces the storage and retrieval of bookings.
### Server implementation
- New booking routes:
- GET `/booking`: Obtain the list ofer user bookings
- GET `/booking/{id}`: Obtain the specific booking object
- POST `/booking`: Creates a new booking
- The `BookingApiModel` objects are incomplete, the `Destination` is a
reference, not the full object, and the `Activity` list are also listed
as references only.
- Server booking always has an existing booking created (Alaska, North
America) for demo purposes.
- Storage is "in memory", stopping the server deletes all stored
bookings.
### New `BookingRepository`
- New repository class.
- Both local and remote implementations.
- Converts the `BookingApiModel` into a complete `Booking` that the app
can use, or a `BookingSummary` that only contains the necessary
information for the home screen.
### New `LocalDataService`
- Service that loads hard-coded data or from assets.
### New `HomeScreen`
- Route path: `/`
- Loads and displays the list of created bookings from the
`BookingRepository`.
- Tap on a booking title opens the `BookingScreen`.
- Floating Action Button to create a new booking.
### Changes in `BookingScreen`
- Can be accessed at the end of creating a booking or from the home
screen when tapping a booking title.
- Two commands:
- `createBooking`: Takes the stored `ItineraryConfig` and creates a
booking, the booking is stored to the `BookingRepository` (locally or on
the server).
- `loadBooking`: Takes a booking ID and loads that existing booking from
the `BookingRepository`.
- Simplified navigation: Once at `BookingScreen`, user can only navigate
back to `HomeScreen`.
- Share button converted to `FloatingActionButton`
### Integration Tests
- Updated to use new home screen.
- Updated to cover opening an existing booking in tests.
### TODO Next
- Refactor the `compass_model` project and move data model classes to
`server` and `app`, then delete project.
- Implement some user information for the home screen (e.g. retrieve
user name and profile picture url)
### Screencast
[Screencast from 2024-09-02
16-25-25.webm](https://github.com/user-attachments/assets/8aba4a61-def6-4752-a4e5-70cbed362524)
## Pre-launch Checklist
- [x] I read the [Flutter Style Guide] _recently_, and have followed its
advice.
- [x] I signed the [CLA].
- [x] I read the [Contributors Guide].
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] All existing and new tests are passing.
If you need help, consider asking for advice on the #hackers-devrel
channel on [Discord].
<!-- Links -->
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/master/docs/contributing/Style-guide-for-Flutter-repo.md
[CLA]: https://cla.developers.google.com/
[Discord]:
https://github.com/flutter/flutter/blob/master/docs/contributing/Chat.md
[Contributors Guide]:
https://github.com/flutter/samples/blob/main/CONTRIBUTING.md
3 months ago
|
|
|
testWidgets('Open a booking', (tester) async {
|
|
|
|
// Load app widget with local configuration
|
|
|
|
await tester.pumpWidget(
|
|
|
|
MultiProvider(
|
|
|
|
providers: providersRemote,
|
|
|
|
child: const MainApp(),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
|
|
|
// Login screen because logget out
|
|
|
|
expect(find.byType(LoginScreen), findsOneWidget);
|
|
|
|
|
|
|
|
// Perform login (credentials are prefilled)
|
|
|
|
await tester.tap(find.text('Login'));
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
|
|
|
// Home screen
|
|
|
|
expect(find.byType(HomeScreen), findsOneWidget);
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
|
|
|
// Tap on booking (Alaska is created by default)
|
|
|
|
await tester.tap(find.text('Alaska, North America'));
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
|
|
|
// Should be at booking screen
|
|
|
|
expect(find.byType(BookingScreen), findsOneWidget);
|
|
|
|
expect(find.text('Alaska'), findsOneWidget);
|
|
|
|
|
|
|
|
// Navigate back to home
|
|
|
|
await tester.tap(find.byType(HomeButton).first);
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
|
|
|
// Home screen
|
|
|
|
expect(find.byType(HomeScreen), findsOneWidget);
|
|
|
|
|
|
|
|
// Perform logout
|
|
|
|
await tester.tap(find.byType(LogoutButton).first);
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(find.byType(LoginScreen), findsOneWidget);
|
|
|
|
});
|
|
|
|
|
|
|
|
testWidgets('Create booking', (tester) async {
|
|
|
|
// Load app widget with local configuration
|
|
|
|
await tester.pumpWidget(
|
|
|
|
MultiProvider(
|
|
|
|
providers: providersRemote,
|
|
|
|
child: const MainApp(),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
|
|
|
// Login screen because logget out
|
|
|
|
expect(find.byType(LoginScreen), findsOneWidget);
|
|
|
|
|
|
|
|
// Perform login (credentials are prefilled)
|
|
|
|
await tester.tap(find.text('Login'));
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
[Compass App] Home screen with booking list (#2428)
This PR introduces the storage and retrieval of bookings.
### Server implementation
- New booking routes:
- GET `/booking`: Obtain the list ofer user bookings
- GET `/booking/{id}`: Obtain the specific booking object
- POST `/booking`: Creates a new booking
- The `BookingApiModel` objects are incomplete, the `Destination` is a
reference, not the full object, and the `Activity` list are also listed
as references only.
- Server booking always has an existing booking created (Alaska, North
America) for demo purposes.
- Storage is "in memory", stopping the server deletes all stored
bookings.
### New `BookingRepository`
- New repository class.
- Both local and remote implementations.
- Converts the `BookingApiModel` into a complete `Booking` that the app
can use, or a `BookingSummary` that only contains the necessary
information for the home screen.
### New `LocalDataService`
- Service that loads hard-coded data or from assets.
### New `HomeScreen`
- Route path: `/`
- Loads and displays the list of created bookings from the
`BookingRepository`.
- Tap on a booking title opens the `BookingScreen`.
- Floating Action Button to create a new booking.
### Changes in `BookingScreen`
- Can be accessed at the end of creating a booking or from the home
screen when tapping a booking title.
- Two commands:
- `createBooking`: Takes the stored `ItineraryConfig` and creates a
booking, the booking is stored to the `BookingRepository` (locally or on
the server).
- `loadBooking`: Takes a booking ID and loads that existing booking from
the `BookingRepository`.
- Simplified navigation: Once at `BookingScreen`, user can only navigate
back to `HomeScreen`.
- Share button converted to `FloatingActionButton`
### Integration Tests
- Updated to use new home screen.
- Updated to cover opening an existing booking in tests.
### TODO Next
- Refactor the `compass_model` project and move data model classes to
`server` and `app`, then delete project.
- Implement some user information for the home screen (e.g. retrieve
user name and profile picture url)
### Screencast
[Screencast from 2024-09-02
16-25-25.webm](https://github.com/user-attachments/assets/8aba4a61-def6-4752-a4e5-70cbed362524)
## Pre-launch Checklist
- [x] I read the [Flutter Style Guide] _recently_, and have followed its
advice.
- [x] I signed the [CLA].
- [x] I read the [Contributors Guide].
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] All existing and new tests are passing.
If you need help, consider asking for advice on the #hackers-devrel
channel on [Discord].
<!-- Links -->
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/master/docs/contributing/Style-guide-for-Flutter-repo.md
[CLA]: https://cla.developers.google.com/
[Discord]:
https://github.com/flutter/flutter/blob/master/docs/contributing/Chat.md
[Contributors Guide]:
https://github.com/flutter/samples/blob/main/CONTRIBUTING.md
3 months ago
|
|
|
// Home screen
|
|
|
|
expect(find.byType(HomeScreen), findsOneWidget);
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
|
|
|
// Select create new booking
|
|
|
|
await tester.tap(find.byKey(const ValueKey('booking-button')));
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
|
|
|
// Search destinations screen
|
|
|
|
expect(find.byType(SearchFormScreen), findsOneWidget);
|
|
|
|
|
|
|
|
// Select Europe because it is always the first result
|
|
|
|
await tester.tap(find.text('Europe'), warnIfMissed: false);
|
|
|
|
|
|
|
|
// Select dates
|
|
|
|
await tester.tap(find.text('Add Dates'));
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
final tomorrow = DateTime.now().add(const Duration(days: 1)).day;
|
|
|
|
final nextDay = DateTime.now().add(const Duration(days: 2)).day;
|
|
|
|
// Select first and last widget that matches today number
|
|
|
|
//and tomorrow number, sort of ensures a valid range
|
|
|
|
await tester.tap(find.text(tomorrow.toString()).first);
|
|
|
|
await tester.tap(find.text(nextDay.toString()).last);
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
await tester.tap(find.text('Save'));
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
|
|
|
// Select guests
|
|
|
|
await tester.tap(find.byKey(const ValueKey('add_guests')),
|
|
|
|
warnIfMissed: false);
|
|
|
|
|
|
|
|
// Refresh screen state
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
|
|
|
|
// Perform search and navigate to next screen
|
|
|
|
await tester.tap(find.byKey(const ValueKey('submit_button')));
|
|
|
|
await tester.pumpAndSettle(const Duration(seconds: 2));
|
|
|
|
|
|
|
|
// Results Screen
|
|
|
|
expect(find.byType(ResultsScreen), findsOneWidget);
|
|
|
|
|
|
|
|
// Amalfi Coast should be the first result for Europe
|
|
|
|
// Tap and navigate to activities screen
|
|
|
|
await tester.tap(find.byType(ResultCard).first);
|
|
|
|
await tester.pumpAndSettle(const Duration(seconds: 2));
|
|
|
|
|
|
|
|
// Activities Screen
|
|
|
|
expect(find.byType(ActivitiesScreen), findsOneWidget);
|
|
|
|
|
|
|
|
// Select one activity
|
|
|
|
await tester.tap(find.byType(CustomCheckbox).first);
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(find.text('1 selected'), findsOneWidget);
|
|
|
|
|
|
|
|
// Submit selection
|
|
|
|
await tester.tap(find.byKey(const ValueKey('confirm-button')));
|
|
|
|
await tester.pumpAndSettle(const Duration(seconds: 2));
|
|
|
|
|
|
|
|
// Should be at booking screen
|
|
|
|
expect(find.byType(BookingScreen), findsOneWidget);
|
|
|
|
expect(find.text('Amalfi Coast'), findsOneWidget);
|
|
|
|
|
|
|
|
// Navigate back to home
|
|
|
|
await tester.tap(find.byType(HomeButton).first);
|
|
|
|
await tester.pumpAndSettle();
|
[Compass App] Home screen with booking list (#2428)
This PR introduces the storage and retrieval of bookings.
### Server implementation
- New booking routes:
- GET `/booking`: Obtain the list ofer user bookings
- GET `/booking/{id}`: Obtain the specific booking object
- POST `/booking`: Creates a new booking
- The `BookingApiModel` objects are incomplete, the `Destination` is a
reference, not the full object, and the `Activity` list are also listed
as references only.
- Server booking always has an existing booking created (Alaska, North
America) for demo purposes.
- Storage is "in memory", stopping the server deletes all stored
bookings.
### New `BookingRepository`
- New repository class.
- Both local and remote implementations.
- Converts the `BookingApiModel` into a complete `Booking` that the app
can use, or a `BookingSummary` that only contains the necessary
information for the home screen.
### New `LocalDataService`
- Service that loads hard-coded data or from assets.
### New `HomeScreen`
- Route path: `/`
- Loads and displays the list of created bookings from the
`BookingRepository`.
- Tap on a booking title opens the `BookingScreen`.
- Floating Action Button to create a new booking.
### Changes in `BookingScreen`
- Can be accessed at the end of creating a booking or from the home
screen when tapping a booking title.
- Two commands:
- `createBooking`: Takes the stored `ItineraryConfig` and creates a
booking, the booking is stored to the `BookingRepository` (locally or on
the server).
- `loadBooking`: Takes a booking ID and loads that existing booking from
the `BookingRepository`.
- Simplified navigation: Once at `BookingScreen`, user can only navigate
back to `HomeScreen`.
- Share button converted to `FloatingActionButton`
### Integration Tests
- Updated to use new home screen.
- Updated to cover opening an existing booking in tests.
### TODO Next
- Refactor the `compass_model` project and move data model classes to
`server` and `app`, then delete project.
- Implement some user information for the home screen (e.g. retrieve
user name and profile picture url)
### Screencast
[Screencast from 2024-09-02
16-25-25.webm](https://github.com/user-attachments/assets/8aba4a61-def6-4752-a4e5-70cbed362524)
## Pre-launch Checklist
- [x] I read the [Flutter Style Guide] _recently_, and have followed its
advice.
- [x] I signed the [CLA].
- [x] I read the [Contributors Guide].
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] All existing and new tests are passing.
If you need help, consider asking for advice on the #hackers-devrel
channel on [Discord].
<!-- Links -->
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/master/docs/contributing/Style-guide-for-Flutter-repo.md
[CLA]: https://cla.developers.google.com/
[Discord]:
https://github.com/flutter/flutter/blob/master/docs/contributing/Chat.md
[Contributors Guide]:
https://github.com/flutter/samples/blob/main/CONTRIBUTING.md
3 months ago
|
|
|
|
|
|
|
// Home screen
|
|
|
|
expect(find.byType(HomeScreen), findsOneWidget);
|
|
|
|
|
|
|
|
// New Booking should appear
|
|
|
|
expect(find.text('Amalfi Coast, Europe'), findsOneWidget);
|
|
|
|
|
|
|
|
// Perform logout
|
|
|
|
await tester.tap(find.byType(LogoutButton).first);
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(find.byType(LoginScreen), findsOneWidget);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|