Files
maps-saas/apps/siro_maps/test/gates_and_fingerprint_test.dart
T

159 lines
5.5 KiB
Dart

import 'dart:convert';
import 'package:flutter_test/flutter_test.dart';
import 'package:http/http.dart' as http;
import 'package:http/testing.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:siro_maps/core/constants/api_constants.dart';
import 'package:siro_maps/core/services/device_fingerprint_service.dart';
import 'package:siro_maps/data/models/place_gate.dart';
import 'package:siro_maps/data/models/place_model.dart';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
group('PlaceGate & PlaceModel Tests', () {
test('PlaceGate parses json correctly', () {
final json = {
'name_ar': 'بوابة رقم 1 - كارفور',
'name_en': 'Gate 1 - Carrefour',
'latitude': 31.9712,
'longitude': 35.8456,
'is_main_gate': true,
};
final gate = PlaceGate.fromJson(json);
expect(gate.nameAr, equals('بوابة رقم 1 - كارفور'));
expect(gate.nameEn, equals('Gate 1 - Carrefour'));
expect(gate.latitude, equals(31.9712));
expect(gate.longitude, equals(35.8456));
expect(gate.isMainGate, isTrue);
final outJson = gate.toJson();
expect(outJson['name_ar'], equals('بوابة رقم 1 - كارفور'));
expect(outJson['is_main_gate'], isTrue);
});
test('PlaceModel parses gates array from API payload', () {
final rawPlace = {
'id': 'poi_city_mall',
'name': 'سيتي مول عمان',
'category': 'mall',
'latitude': 31.9823,
'longitude': 35.8344,
'elevation_meters': 980.5,
'gates': [
{
'name_ar': 'بوابة 1 - الطوارئ والخدمات',
'latitude': 31.9820,
'longitude': 35.8340,
'is_main_gate': false,
},
{
'name_ar': 'بوابة 2 - المدخل الرئيسي والزوار',
'latitude': 31.9825,
'longitude': 35.8346,
'is_main_gate': true,
}
]
};
final place = PlaceModel.fromJson(rawPlace);
expect(place.id, equals('poi_city_mall'));
expect(place.name, equals('سيتي مول عمان'));
expect(place.hasGates, isTrue);
expect(place.gates.length, equals(2));
expect(place.gates.first.nameAr, equals('بوابة 1 - الطوارئ والخدمات'));
expect(place.gates.last.isMainGate, isTrue);
});
test('PlaceModel handles empty or null gates gracefully', () {
final rawPlace = {
'name': 'كافيه عادي',
'category': 'cafe',
'latitude': 31.95,
'longitude': 35.91,
};
final place = PlaceModel.fromJson(rawPlace);
expect(place.hasGates, isFalse);
expect(place.gates, isEmpty);
});
});
group('DeviceFingerprintService Tests', () {
setUp(() {
SharedPreferences.setMockInitialValues({});
});
test('Generates deterministic hardware fingerprint and initializes headers', () async {
final service = DeviceFingerprintService.instance;
await service.init();
expect(service.fingerprintId, isNotEmpty);
expect(service.fingerprintId.startsWith('siro_'), isTrue);
expect(service.shortFingerprint.isNotEmpty, isTrue);
final headers = service.headers;
expect(headers.containsKey('x-device-fingerprint'), isTrue);
expect(headers['x-device-fingerprint'], equals(service.fingerprintId));
expect(headers.containsKey('x-client-version'), isTrue);
expect(headers.containsKey('x-device-platform'), isTrue);
expect(headers.containsKey('x-api-key'), isTrue);
expect(headers['x-api-key'], equals(ApiConstants.mapSaasKey));
});
test('Provisions dedicated consumer API key and switches activeApiKey', () async {
final service = DeviceFingerprintService.instance;
final mockClient = MockClient((request) async {
if (request.url.path.contains('/auth/device-provision')) {
return http.Response(
jsonEncode({
'apiKey': 'in_mob_unit_test_dedicated_key_998877',
'keyName': 'Siro Mobile - Unit Test Device',
'rateLimit': 60,
'plan': 'FREE',
'deviceFingerprint': service.fingerprintId,
'isNew': true,
}),
200,
headers: {'content-type': 'application/json'},
);
}
return http.Response('Not Found', 404);
});
final success = await service.provisionDedicatedApiKey(httpClient: mockClient);
expect(success, isTrue);
expect(service.activeApiKey, equals('in_mob_unit_test_dedicated_key_998877'));
expect(service.isDedicatedKeyActive, isTrue);
expect(service.rateLimit, equals(60));
expect(service.headers['x-api-key'], equals('in_mob_unit_test_dedicated_key_998877'));
});
test('Falls back gracefully to embedded key if provisioning fails or is offline', () async {
final service = DeviceFingerprintService.instance;
final offlineClient = MockClient((request) async {
return http.Response('Internal Server Error', 500);
});
service.setMockState(
fingerprint: 'siro_test_hw_offline_device',
clearApiKey: true,
);
final success = await service.provisionDedicatedApiKey(httpClient: offlineClient);
expect(success, isFalse);
// Falls back to master MapSaaS key without crashing
expect(service.activeApiKey, equals(ApiConstants.mapSaasKey));
expect(service.isDedicatedKeyActive, isFalse);
});
});
}