Geofence test screen
This commit is contained in:
@@ -0,0 +1,254 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
|
||||
import 'package:tasq/models/app_settings.dart';
|
||||
import 'package:tasq/models/profile.dart';
|
||||
import 'package:tasq/providers/profile_provider.dart';
|
||||
import 'package:tasq/providers/workforce_provider.dart';
|
||||
import 'package:tasq/providers/location_provider.dart';
|
||||
import 'package:tasq/screens/admin/geofence_test_screen.dart';
|
||||
|
||||
void main() {
|
||||
// Polygon from existing unit test (CRMC)
|
||||
final polygonJson = [
|
||||
{"lat": 7.2025231, "lng": 124.2339774},
|
||||
{"lat": 7.2018791, "lng": 124.2334463},
|
||||
{"lat": 7.2013362, "lng": 124.2332049},
|
||||
{"lat": 7.2011393, "lng": 124.2332907},
|
||||
{"lat": 7.2009531, "lng": 124.2334195},
|
||||
{"lat": 7.200655, "lng": 124.2339344},
|
||||
{"lat": 7.2000749, "lng": 124.2348465},
|
||||
{"lat": 7.199501, "lng": 124.2357645},
|
||||
{"lat": 7.1990597, "lng": 124.2364595},
|
||||
{"lat": 7.1986557, "lng": 124.2371331},
|
||||
{"lat": 7.1992252, "lng": 124.237168},
|
||||
{"lat": 7.199494, "lng": 124.2372713},
|
||||
{"lat": 7.1997415, "lng": 124.2374604},
|
||||
{"lat": 7.1999383, "lng": 124.2377071},
|
||||
{"lat": 7.2001938, "lng": 124.2380934},
|
||||
{"lat": 7.2011411, "lng": 124.2364357},
|
||||
{"lat": 7.2025231, "lng": 124.2339774},
|
||||
];
|
||||
|
||||
ProviderScope buildApp({required List<Override> overrides}) {
|
||||
return ProviderScope(
|
||||
overrides: overrides,
|
||||
child: const MaterialApp(home: GeofenceTestScreen()),
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('non-admin cannot access', (tester) async {
|
||||
await tester.pumpWidget(
|
||||
buildApp(overrides: [isAdminProvider.overrideWith((ref) => false)]),
|
||||
);
|
||||
|
||||
await tester.pump();
|
||||
expect(find.text('Admin access required.'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('polygon geofence - inside shown', (tester) async {
|
||||
final profile = Profile(id: 'p1', role: 'admin', fullName: 'Admin');
|
||||
final insidePos = Position(
|
||||
latitude: 7.2009,
|
||||
longitude: 124.2360,
|
||||
timestamp: DateTime.now(),
|
||||
accuracy: 1.0,
|
||||
altitude: 0.0,
|
||||
altitudeAccuracy: 0.0,
|
||||
heading: 0.0,
|
||||
speed: 0.0,
|
||||
speedAccuracy: 0.0,
|
||||
headingAccuracy: 0.0,
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
buildApp(
|
||||
overrides: [
|
||||
currentProfileProvider.overrideWith((ref) => Stream.value(profile)),
|
||||
isAdminProvider.overrideWith((ref) => true),
|
||||
geofenceProvider.overrideWith(
|
||||
(ref) =>
|
||||
Future.value(GeofenceConfig.fromJson({'polygon': polygonJson})),
|
||||
),
|
||||
currentPositionProvider.overrideWith(
|
||||
(ref) => Future.value(insidePos),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('Inside geofence'), findsOneWidget);
|
||||
expect(find.byIcon(Icons.check_circle), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('polygon geofence - outside shown', (tester) async {
|
||||
final profile = Profile(id: 'p1', role: 'admin', fullName: 'Admin');
|
||||
final outsidePos = Position(
|
||||
latitude: 7.2060,
|
||||
longitude: 124.2360,
|
||||
timestamp: DateTime.now(),
|
||||
accuracy: 1.0,
|
||||
altitude: 0.0,
|
||||
altitudeAccuracy: 0.0,
|
||||
heading: 0.0,
|
||||
speed: 0.0,
|
||||
speedAccuracy: 0.0,
|
||||
headingAccuracy: 0.0,
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
buildApp(
|
||||
overrides: [
|
||||
currentProfileProvider.overrideWith((ref) => Stream.value(profile)),
|
||||
isAdminProvider.overrideWith((ref) => true),
|
||||
geofenceProvider.overrideWith(
|
||||
(ref) =>
|
||||
Future.value(GeofenceConfig.fromJson({'polygon': polygonJson})),
|
||||
),
|
||||
currentPositionProvider.overrideWith(
|
||||
(ref) => Future.value(outsidePos),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('Outside geofence'), findsOneWidget);
|
||||
expect(find.byIcon(Icons.cancel), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('circle geofence - inside shown', (tester) async {
|
||||
final profile = Profile(id: 'p1', role: 'admin', fullName: 'Admin');
|
||||
final cfg = GeofenceConfig(lat: 0.0, lng: 0.0, radiusMeters: 1000.0);
|
||||
final insidePos = Position(
|
||||
latitude: 0.005,
|
||||
longitude: 0.0,
|
||||
timestamp: DateTime.now(),
|
||||
accuracy: 1.0,
|
||||
altitude: 0.0,
|
||||
altitudeAccuracy: 0.0,
|
||||
heading: 0.0,
|
||||
speed: 0.0,
|
||||
speedAccuracy: 0.0,
|
||||
headingAccuracy: 0.0,
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
buildApp(
|
||||
overrides: [
|
||||
currentProfileProvider.overrideWith((ref) => Stream.value(profile)),
|
||||
isAdminProvider.overrideWith((ref) => true),
|
||||
geofenceProvider.overrideWith((ref) => Future.value(cfg)),
|
||||
currentPositionProvider.overrideWith(
|
||||
(ref) => Future.value(insidePos),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('Inside geofence'), findsOneWidget);
|
||||
expect(find.byIcon(Icons.check_circle), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('circle geofence - outside shown', (tester) async {
|
||||
final profile = Profile(id: 'p1', role: 'admin', fullName: 'Admin');
|
||||
final cfg = GeofenceConfig(lat: 0.0, lng: 0.0, radiusMeters: 1000.0);
|
||||
final outsidePos = Position(
|
||||
latitude: 0.02,
|
||||
longitude: 0.0,
|
||||
timestamp: DateTime.now(),
|
||||
accuracy: 1.0,
|
||||
altitude: 0.0,
|
||||
altitudeAccuracy: 0.0,
|
||||
heading: 0.0,
|
||||
speed: 0.0,
|
||||
speedAccuracy: 0.0,
|
||||
headingAccuracy: 0.0,
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
buildApp(
|
||||
overrides: [
|
||||
currentProfileProvider.overrideWith((ref) => Stream.value(profile)),
|
||||
isAdminProvider.overrideWith((ref) => true),
|
||||
geofenceProvider.overrideWith((ref) => Future.value(cfg)),
|
||||
currentPositionProvider.overrideWith(
|
||||
(ref) => Future.value(outsidePos),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('Outside geofence'), findsOneWidget);
|
||||
expect(find.byIcon(Icons.cancel), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('live tracking toggle follows stream', (tester) async {
|
||||
final profile = Profile(id: 'p1', role: 'admin', fullName: 'Admin');
|
||||
final cfg = GeofenceConfig(lat: 0.0, lng: 0.0, radiusMeters: 1000.0);
|
||||
|
||||
final initialPos = Position(
|
||||
latitude: 0.02,
|
||||
longitude: 0.0,
|
||||
timestamp: DateTime.now(),
|
||||
accuracy: 1.0,
|
||||
altitude: 0.0,
|
||||
altitudeAccuracy: 0.0,
|
||||
heading: 0.0,
|
||||
speed: 0.0,
|
||||
speedAccuracy: 0.0,
|
||||
headingAccuracy: 0.0,
|
||||
);
|
||||
|
||||
final livePos = Position(
|
||||
latitude: 0.005,
|
||||
longitude: 0.0,
|
||||
timestamp: DateTime.now(),
|
||||
accuracy: 1.0,
|
||||
altitude: 0.0,
|
||||
altitudeAccuracy: 0.0,
|
||||
heading: 0.0,
|
||||
speed: 0.0,
|
||||
speedAccuracy: 0.0,
|
||||
headingAccuracy: 0.0,
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
buildApp(
|
||||
overrides: [
|
||||
currentProfileProvider.overrideWith((ref) => Stream.value(profile)),
|
||||
isAdminProvider.overrideWith((ref) => true),
|
||||
geofenceProvider.overrideWith((ref) => Future.value(cfg)),
|
||||
currentPositionProvider.overrideWith(
|
||||
(ref) => Future.value(initialPos),
|
||||
),
|
||||
currentPositionStreamProvider.overrideWith(
|
||||
(ref) => Stream.value(livePos),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// initial state is the one-shot position (outside)
|
||||
expect(find.text('Outside geofence'), findsOneWidget);
|
||||
|
||||
// enable live tracking
|
||||
await tester.tap(find.byKey(const Key('live-switch')));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// stream value should now be used and indicate inside
|
||||
expect(find.text('Inside geofence'), findsOneWidget);
|
||||
expect(find.byIcon(Icons.check_circle), findsOneWidget);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user