feat: add device authentication, place gates support, and PiP navigation features

This commit is contained in:
Hamza-Ayed
2026-09-19 12:34:26 +03:00
parent 55830beee8
commit ce896df30a
86 changed files with 3414 additions and 341 deletions
@@ -1,5 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:siro_maps/core/services/deep_link_service.dart';
import 'package:siro_maps/core/services/pip_service.dart';
import 'package:siro_maps/core/services/vehicle_icon_generator.dart';
import 'package:siro_maps/core/utils/arabic_search_normalizer.dart';
@@ -43,6 +45,23 @@ void main() {
isTrue,
);
});
test('Correctly identifies category queries vs specific landmarks', () {
// General categories -> true
expect(ArabicSearchNormalizer.isCategoryQuery('مسجد'), isTrue);
expect(ArabicSearchNormalizer.isCategoryQuery('مطعم'), isTrue);
expect(ArabicSearchNormalizer.isCategoryQuery('مخبز'), isTrue);
expect(ArabicSearchNormalizer.isCategoryQuery('سوبرماركت'), isTrue);
expect(ArabicSearchNormalizer.isCategoryQuery('دكان'), isTrue);
expect(ArabicSearchNormalizer.isCategoryQuery('كافيه'), isTrue);
expect(ArabicSearchNormalizer.isCategoryQuery('صيدلية'), isTrue);
expect(ArabicSearchNormalizer.isCategoryQuery('محطة بنزين'), isTrue);
// Specific landmarks / names -> false
expect(ArabicSearchNormalizer.isCategoryQuery('المدينة الطبية'), isFalse);
expect(ArabicSearchNormalizer.isCategoryQuery('سيتي مول'), isFalse);
expect(ArabicSearchNormalizer.isCategoryQuery('دوار الداخلية'), isFalse);
});
});
group('VehicleIconGenerator Tests', () {
@@ -85,4 +104,106 @@ void main() {
expect(VehicleIconGenerator.availableColors.any((c) => c.colorValue == 0xFF007AFF), isTrue);
});
});
group('DeepLinkService Tests', () {
test('Parses basic geo URI', () {
final target = DeepLinkService.instance.parseUri('geo:31.97869,35.83426');
expect(target, isNotNull);
expect(target!.destination.latitude, closeTo(31.97869, 0.0001));
expect(target.destination.longitude, closeTo(35.83426, 0.0001));
expect(target.autoStartNavigation, isFalse);
});
test('Parses geo URI with label in parenthesis', () {
final target = DeepLinkService.instance.parseUri('geo:31.97869,35.83426?q=31.97869,35.83426(المدينة%20الطبية)');
expect(target, isNotNull);
expect(target!.destination.latitude, closeTo(31.97869, 0.0001));
expect(target.destination.longitude, closeTo(35.83426, 0.0001));
expect(target.title, equals('المدينة الطبية'));
});
test('Parses geo:0,0 query format used by Android apps', () {
final target = DeepLinkService.instance.parseUri('geo:0,0?q=31.9539,35.9106(سيتي%20مول)');
expect(target, isNotNull);
expect(target!.destination.latitude, closeTo(31.9539, 0.0001));
expect(target.destination.longitude, closeTo(35.9106, 0.0001));
expect(target.title, equals('سيتي مول'));
});
test('Parses custom siromaps://navigate with autoStartNavigation', () {
final target = DeepLinkService.instance.parseUri('siromaps://navigate?lat=31.97869&lng=35.83426&title=مدينة_الحسين_الطبية');
expect(target, isNotNull);
expect(target!.destination.latitude, closeTo(31.97869, 0.0001));
expect(target.destination.longitude, closeTo(35.83426, 0.0001));
expect(target.title, equals('مدينة_الحسين_الطبية'));
expect(target.autoStartNavigation, isTrue);
});
test('Parses custom siromaps://route with preview mode', () {
final target = DeepLinkService.instance.parseUri('siromaps://route?dlat=32.01&dlng=35.86&dname=جامعة_اليرموك');
expect(target, isNotNull);
expect(target!.destination.latitude, closeTo(32.01, 0.0001));
expect(target.destination.longitude, closeTo(35.86, 0.0001));
expect(target.title, equals('جامعة_اليرموك'));
expect(target.autoStartNavigation, isFalse);
});
test('Parses google.navigation URI intent', () {
final target = DeepLinkService.instance.parseUri('google.navigation:q=31.97869,35.83426&mode=d');
expect(target, isNotNull);
expect(target!.destination.latitude, closeTo(31.97869, 0.0001));
expect(target.destination.longitude, closeTo(35.83426, 0.0001));
expect(target.autoStartNavigation, isTrue);
});
test('Parses Google Maps URL', () {
final target = DeepLinkService.instance.parseUri('https://www.google.com/maps/dir/?api=1&destination=31.97869,35.83426');
expect(target, isNotNull);
expect(target!.destination.latitude, closeTo(31.97869, 0.0001));
expect(target.destination.longitude, closeTo(35.83426, 0.0001));
});
test('Parses Universal Siro Web Link', () {
final target = DeepLinkService.instance.parseUri('https://maps.siro.app/navigate?lat=31.97869&lng=35.83426&title=المدينة%20الطبية');
expect(target, isNotNull);
expect(target!.destination.latitude, closeTo(31.97869, 0.0001));
expect(target.destination.longitude, closeTo(35.83426, 0.0001));
expect(target.title, equals('المدينة الطبية'));
expect(target.autoStartNavigation, isTrue);
});
test('Returns null on invalid or empty URIs', () {
expect(DeepLinkService.instance.parseUri(''), isNull);
expect(DeepLinkService.instance.parseUri('invalid_link_without_coords'), isNull);
expect(DeepLinkService.instance.parseUri('geo:invalid,coords'), isNull);
});
});
group('PipService Tests', () {
test('PipService initializes and reports supported', () async {
final pip = PipService.instance;
pip.init();
final supported = await pip.isPipSupported();
expect(supported, isTrue);
});
test('PipService toggles and enters/exits PiP mode correctly', () async {
final pip = PipService.instance;
await pip.exitPictureInPicture();
expect(pip.isInPipMode.value, isFalse);
await pip.enterPictureInPicture();
expect(pip.isInPipMode.value, isTrue);
await pip.exitPictureInPicture();
expect(pip.isInPipMode.value, isFalse);
await pip.togglePip();
expect(pip.isInPipMode.value, isTrue);
await pip.togglePip();
expect(pip.isInPipMode.value, isFalse);
});
});
}