import 'package:afterwork/data/models/user_model.dart'; import 'package:afterwork/domain/entities/user.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { group('UserModel', () { const tUserModel = UserModel( userId: '123', userLastName: 'Doe', userFirstName: 'John', email: 'john.doe@example.com', motDePasse: 'hashedPassword123', profileImageUrl: 'https://example.com/profile.jpg', ); final tUserModelJson = { 'userId': '123', 'nom': 'Doe', 'prenoms': 'John', 'email': 'john.doe@example.com', 'motDePasse': 'hashedPassword123', 'profileImageUrl': 'https://example.com/profile.jpg', }; test('should be a subclass of User entity', () { // Assert expect(tUserModel, isA()); }); test('should extend User with all its properties', () { // Assert expect(tUserModel.userId, '123'); expect(tUserModel.userLastName, 'Doe'); expect(tUserModel.userFirstName, 'John'); expect(tUserModel.email, 'john.doe@example.com'); expect(tUserModel.motDePasse, 'hashedPassword123'); expect(tUserModel.profileImageUrl, 'https://example.com/profile.jpg'); }); group('fromJson', () { test('should return a valid UserModel from JSON', () { // Act final result = UserModel.fromJson(tUserModelJson); // Assert expect(result, isA()); expect(result.userId, '123'); expect(result.userLastName, 'Doe'); expect(result.userFirstName, 'John'); expect(result.email, 'john.doe@example.com'); expect(result.motDePasse, 'hashedPassword123'); expect(result.profileImageUrl, 'https://example.com/profile.jpg'); }); test('should use default values for missing fields', () { // Arrange final minimalJson = {}; // Act final result = UserModel.fromJson(minimalJson); // Assert expect(result.userId, ''); expect(result.userLastName, 'Inconnu'); expect(result.userFirstName, 'Inconnu'); expect(result.email, 'inconnu@example.com'); expect(result.motDePasse, ''); expect(result.profileImageUrl, ''); }); test('should handle partial JSON data', () { // Arrange final partialJson = { 'userId': '456', 'email': 'partial@example.com', }; // Act final result = UserModel.fromJson(partialJson); // Assert expect(result.userId, '456'); expect(result.email, 'partial@example.com'); expect(result.userLastName, 'Inconnu'); // Default expect(result.userFirstName, 'Inconnu'); // Default expect(result.motDePasse, ''); // Default }); test('should handle null values in JSON', () { // Arrange final jsonWithNulls = { 'userId': null, 'nom': null, 'prenoms': null, 'email': null, 'motDePasse': null, 'profileImageUrl': null, }; // Act final result = UserModel.fromJson(jsonWithNulls); // Assert expect(result.userId, ''); expect(result.userLastName, 'Inconnu'); expect(result.userFirstName, 'Inconnu'); expect(result.email, 'inconnu@example.com'); expect(result.motDePasse, ''); expect(result.profileImageUrl, ''); }); }); group('toJson', () { test('should return a JSON map containing proper data', () { // Act final result = tUserModel.toJson(); // Assert expect(result, isA>()); expect(result['id'], '123'); expect(result['nom'], 'Doe'); expect(result['prenoms'], 'John'); expect(result['email'], 'john.doe@example.com'); expect(result['motDePasse'], 'hashedPassword123'); expect(result['profileImageUrl'], 'https://example.com/profile.jpg'); }); test('should map field names correctly (userId -> id, etc.)', () { // Act final result = tUserModel.toJson(); // Assert // Vérifie que le mapping des champs est correct expect(result.containsKey('id'), isTrue); expect(result.containsKey('nom'), isTrue); expect(result.containsKey('prenoms'), isTrue); // Ne doit PAS contenir les noms de propriétés Dart expect(result.containsKey('userId'), isFalse); expect(result.containsKey('userLastName'), isFalse); expect(result.containsKey('userFirstName'), isFalse); }); test('should be reversible (fromJson -> toJson)', () { // Act final json = tUserModel.toJson(); // Adapter le JSON pour fromJson (id -> userId) json['userId'] = json['id']; final model = UserModel.fromJson(json); // Assert expect(model.userId, tUserModel.userId); expect(model.userLastName, tUserModel.userLastName); expect(model.userFirstName, tUserModel.userFirstName); expect(model.email, tUserModel.email); expect(model.motDePasse, tUserModel.motDePasse); }); }); group('Equality', () { test('should support value equality (from Equatable)', () { // Arrange const user1 = UserModel( userId: '123', userLastName: 'Doe', userFirstName: 'John', email: 'john@example.com', motDePasse: 'password', profileImageUrl: 'profile.jpg', ); const user2 = UserModel( userId: '123', userLastName: 'Doe', userFirstName: 'John', email: 'john@example.com', motDePasse: 'password', profileImageUrl: 'profile.jpg', ); // Assert expect(user1, equals(user2)); expect(user1.hashCode, equals(user2.hashCode)); }); test('should not be equal when fields are different', () { // Arrange const user1 = UserModel( userId: '123', userLastName: 'Doe', userFirstName: 'John', email: 'john@example.com', motDePasse: 'password', profileImageUrl: 'profile.jpg', ); const user2 = UserModel( userId: '456', // Different ID userLastName: 'Doe', userFirstName: 'John', email: 'john@example.com', motDePasse: 'password', profileImageUrl: 'profile.jpg', ); // Assert expect(user1, isNot(equals(user2))); }); }); group('API Integration', () { test('should correctly map API field names', () { // Arrange final apiResponse = { 'userId': 'api-123', 'nom': 'APILastName', 'prenoms': 'APIFirstName', 'email': 'api@example.com', 'motDePasse': 'api-password', 'profileImageUrl': 'https://api.com/profile.jpg', }; // Act final user = UserModel.fromJson(apiResponse); final jsonForApi = user.toJson(); // Assert expect(user.userId, 'api-123'); expect(user.userLastName, 'APILastName'); expect(user.userFirstName, 'APIFirstName'); expect(jsonForApi['id'], 'api-123'); expect(jsonForApi['nom'], 'APILastName'); expect(jsonForApi['prenoms'], 'APIFirstName'); }); test('should handle empty strings from API', () { // Arrange final apiResponse = { 'userId': '', 'nom': '', 'prenoms': '', 'email': '', 'motDePasse': '', 'profileImageUrl': '', }; // Act final user = UserModel.fromJson(apiResponse); // Assert expect(user.userId, ''); expect(user.userLastName, ''); // Utilise la valeur vide, pas le défaut expect(user.userFirstName, ''); expect(user.email, ''); }); }); group('Edge Cases', () { test('should handle very long strings', () { // Arrange final longString = 'A' * 1000; final jsonWithLongStrings = { 'userId': longString, 'nom': longString, 'prenoms': longString, 'email': '$longString@example.com', 'motDePasse': longString, 'profileImageUrl': 'https://example.com/$longString.jpg', }; // Act final user = UserModel.fromJson(jsonWithLongStrings); // Assert expect(user.userId.length, 1000); expect(user.userLastName.length, 1000); expect(user.userFirstName.length, 1000); }); test('should handle special characters', () { // Arrange final jsonWithSpecialChars = { 'userId': '123', 'nom': 'Dôe-Smîth', 'prenoms': 'Jöhn', 'email': 'john+test@example.com', 'motDePasse': 'P@ssw0rd!#\$', 'profileImageUrl': 'https://example.com/profile.jpg', }; // Act final user = UserModel.fromJson(jsonWithSpecialChars); // Assert expect(user.userLastName, 'Dôe-Smîth'); expect(user.userFirstName, 'Jöhn'); expect(user.email, 'john+test@example.com'); expect(user.motDePasse, 'P@ssw0rd!#\$'); }); test('should handle unicode characters', () { // Arrange final jsonWithUnicode = { 'userId': '123', 'nom': '山田', 'prenoms': '太郎', 'email': 'yamada@example.jp', 'motDePasse': 'パスワード', 'profileImageUrl': 'https://example.jp/山田.jpg', }; // Act final user = UserModel.fromJson(jsonWithUnicode); // Assert expect(user.userLastName, '山田'); expect(user.userFirstName, '太郎'); expect(user.motDePasse, 'パスワード'); }); }); }); }