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'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); group('ArabicSearchNormalizer Tests', () { test('Normalizes diacritics and tashkeel', () { const input = 'مَدِينَةُ عَمَّانَ'; expect(ArabicSearchNormalizer.normalize(input), equals('مدينه عمان')); }); test('Normalizes various forms of Alef', () { expect(ArabicSearchNormalizer.normalize('أحمد'), equals('احمد')); expect(ArabicSearchNormalizer.normalize('إبراهيم'), equals('ابراهيم')); expect(ArabicSearchNormalizer.normalize('آلاء'), equals('الاء')); expect(ArabicSearchNormalizer.normalize('ٱستقبال'), equals('استقبال')); }); test('Normalizes Teh Marbuta and Alef Maqsura', () { expect(ArabicSearchNormalizer.normalize('مستشفى'), equals('مستشفي')); expect(ArabicSearchNormalizer.normalize('جامعة'), equals('جامعه')); expect(ArabicSearchNormalizer.normalize('صيدلية النهدي'), equals('صيدليه النهدي')); }); test('Matches normalized queries flexibly', () { expect( ArabicSearchNormalizer.matches('صيدلية النهدي الكبرى', 'نهدي'), isTrue, ); expect( ArabicSearchNormalizer.matches('مستشفى الجامعة الأردنية', 'جامعة'), isTrue, ); expect( ArabicSearchNormalizer.matches('مستشفى الجامعة الأردنية', 'جامعه'), isTrue, ); expect( ArabicSearchNormalizer.matches('مطعم القدس', 'القدس'), 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', () { test('Generates valid PNG bytes for modern sedan', () async { final bytes = await VehicleIconGenerator.generateVehicleIconBytes( styleId: 'car', primaryColor: const Color(0xFF007AFF), ); expect(bytes, isNotEmpty); // Valid PNG header starts with 0x89, 'P', 'N', 'G' (0x89, 0x50, 0x4E, 0x47) expect(bytes[0], equals(0x89)); expect(bytes[1], equals(0x50)); expect(bytes[2], equals(0x4E)); expect(bytes[3], equals(0x47)); }); test('Generates valid PNG bytes for SUV and Arrow styles', () async { final suvBytes = await VehicleIconGenerator.generateVehicleIconBytes( styleId: 'suv', primaryColor: const Color(0xFF00C853), ); expect(suvBytes, isNotEmpty); expect(suvBytes[0], equals(0x89)); final arrowBytes = await VehicleIconGenerator.generateVehicleIconBytes( styleId: 'arrow', primaryColor: const Color(0xFFFF3B30), ); expect(arrowBytes, isNotEmpty); expect(arrowBytes[0], equals(0x89)); }); test('Exposes predefined vehicle styles and colors', () { expect(VehicleIconGenerator.availableStyles, isNotEmpty); expect(VehicleIconGenerator.availableStyles.any((s) => s.id == 'car'), isTrue); expect(VehicleIconGenerator.availableStyles.any((s) => s.id == 'suv'), isTrue); expect(VehicleIconGenerator.availableStyles.any((s) => s.id == 'arrow'), isTrue); expect(VehicleIconGenerator.availableColors, isNotEmpty); 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); }); }); }