fix : update local.properties path and improve null safety in chicken_local_imp.dart and chicken_repository_imp.dart; refactor profile view for better readability
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:rasadyar_chicken/data/data_source/local/chicken_local_imp.dart';
|
||||
import 'package:rasadyar_chicken/data/models/local/widely_used_local_model.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
class MockHiveLocalStorage extends Mock implements HiveLocalStorage {}
|
||||
|
||||
void main() {
|
||||
late ChickenLocalDataSourceImp chickenLocalDataSource;
|
||||
late MockHiveLocalStorage mockHiveLocalStorage;
|
||||
|
||||
setUp(() {
|
||||
mockHiveLocalStorage = MockHiveLocalStorage();
|
||||
|
||||
// Register the mock in GetIt for dependency injection
|
||||
if (diCore.isRegistered<HiveLocalStorage>()) {
|
||||
diCore.unregister<HiveLocalStorage>();
|
||||
}
|
||||
diCore.registerSingleton<HiveLocalStorage>(mockHiveLocalStorage);
|
||||
|
||||
chickenLocalDataSource = ChickenLocalDataSourceImp();
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
// Clean up GetIt registration
|
||||
if (diCore.isRegistered<HiveLocalStorage>()) {
|
||||
diCore.unregister<HiveLocalStorage>();
|
||||
}
|
||||
});
|
||||
|
||||
group('ChickenLocalDataSourceImp', () {
|
||||
group('openBox', () {
|
||||
test('should call local openBox with correct box name', () async {
|
||||
// Arrange
|
||||
when(
|
||||
() => mockHiveLocalStorage.openBox<WidelyUsedLocalModel>(
|
||||
'Chicken_Widley_Box',
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
|
||||
// Act
|
||||
await chickenLocalDataSource.openBox();
|
||||
|
||||
// Assert
|
||||
verify(
|
||||
() => mockHiveLocalStorage.openBox<WidelyUsedLocalModel>(
|
||||
'Chicken_Widley_Box',
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
});
|
||||
|
||||
group('initWidleyUsed', () {
|
||||
test('should initialize widely used items', () async {
|
||||
// Act
|
||||
await chickenLocalDataSource.initWidleyUsed();
|
||||
|
||||
// Assert
|
||||
// This method currently doesn't interact with the mock, but we can verify it completes
|
||||
expect(chickenLocalDataSource.initWidleyUsed, isA<Function>());
|
||||
});
|
||||
});
|
||||
|
||||
group('getAllWidely', () {
|
||||
test('should return first widely used model when data exists', () async {
|
||||
// Arrange
|
||||
final expectedModel = WidelyUsedLocalModel(hasInit: true, items: []);
|
||||
final mockData = [expectedModel];
|
||||
|
||||
when(
|
||||
() => mockHiveLocalStorage.readBox<WidelyUsedLocalModel>(
|
||||
boxName: 'Chicken_Widley_Box',
|
||||
),
|
||||
).thenReturn(mockData);
|
||||
|
||||
// Act
|
||||
final result = chickenLocalDataSource.getAllWidely();
|
||||
|
||||
// Assert
|
||||
expect(result, equals(expectedModel));
|
||||
verify(
|
||||
() => mockHiveLocalStorage.readBox<WidelyUsedLocalModel>(
|
||||
boxName: 'Chicken_Widley_Box',
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('should return null when no data exists', () async {
|
||||
// Arrange
|
||||
when(
|
||||
() => mockHiveLocalStorage.readBox<WidelyUsedLocalModel>(
|
||||
boxName: 'Chicken_Widley_Box',
|
||||
),
|
||||
).thenReturn(null);
|
||||
|
||||
// Act
|
||||
final result = chickenLocalDataSource.getAllWidely();
|
||||
|
||||
// Assert
|
||||
expect(result, isNull);
|
||||
verify(
|
||||
() => mockHiveLocalStorage.readBox<WidelyUsedLocalModel>(
|
||||
boxName: 'Chicken_Widley_Box',
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('should return null when empty list is returned', () async {
|
||||
// Arrange
|
||||
when(
|
||||
() => mockHiveLocalStorage.readBox<WidelyUsedLocalModel>(
|
||||
boxName: 'Chicken_Widley_Box',
|
||||
),
|
||||
).thenReturn([]);
|
||||
|
||||
// Act
|
||||
final result = chickenLocalDataSource.getAllWidely();
|
||||
|
||||
// Assert
|
||||
expect(result, isNull);
|
||||
verify(
|
||||
() => mockHiveLocalStorage.readBox<WidelyUsedLocalModel>(
|
||||
boxName: 'Chicken_Widley_Box',
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('should return first item when multiple items exist', () async {
|
||||
// Arrange
|
||||
final firstModel = WidelyUsedLocalModel(hasInit: true, items: []);
|
||||
final secondModel = WidelyUsedLocalModel(hasInit: false, items: []);
|
||||
final mockData = [firstModel, secondModel];
|
||||
|
||||
when(
|
||||
() => mockHiveLocalStorage.readBox<WidelyUsedLocalModel>(
|
||||
boxName: 'Chicken_Widley_Box',
|
||||
),
|
||||
).thenReturn(mockData);
|
||||
|
||||
// Act
|
||||
final result = chickenLocalDataSource.getAllWidely();
|
||||
|
||||
// Assert
|
||||
expect(result, equals(firstModel));
|
||||
verify(
|
||||
() => mockHiveLocalStorage.readBox<WidelyUsedLocalModel>(
|
||||
boxName: 'Chicken_Widley_Box',
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
});
|
||||
|
||||
group('boxName', () {
|
||||
test('should have correct box name', () {
|
||||
// Assert
|
||||
expect(chickenLocalDataSource.boxName, equals('Chicken_Widley_Box'));
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,350 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:rasadyar_chicken/data/data_source/remote/auth/auth_remote_imp.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/user_info/user_info_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/user_profile_model/user_profile_model.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
|
||||
class MockDioRemote extends Mock implements DioRemote {}
|
||||
|
||||
void main() {
|
||||
late AuthRemoteDataSourceImp authRemoteDataSource;
|
||||
late MockDioRemote mockDioRemote;
|
||||
|
||||
setUpAll(() {
|
||||
registerFallbackValue(<String, dynamic>{});
|
||||
registerFallbackValue(<String, String>{});
|
||||
});
|
||||
|
||||
setUp(() {
|
||||
mockDioRemote = MockDioRemote();
|
||||
authRemoteDataSource = AuthRemoteDataSourceImp(mockDioRemote);
|
||||
});
|
||||
|
||||
group('AuthRemoteDataSourceImp', () {
|
||||
group('login', () {
|
||||
test('should return UserProfileModel when login is successful', () async {
|
||||
// Arrange
|
||||
final authRequest = {
|
||||
'username': 'test@example.com',
|
||||
'password': 'password',
|
||||
};
|
||||
final expectedUserProfile = UserProfileModel(
|
||||
accessToken: 'test-access-token',
|
||||
expiresIn: '3600',
|
||||
scope: 'read write',
|
||||
expireTime: '2024-12-31T23:59:59Z',
|
||||
mobile: '09123456789',
|
||||
fullname: 'John Doe',
|
||||
firstname: 'John',
|
||||
lastname: 'Doe',
|
||||
city: 'Tehran',
|
||||
province: 'Tehran',
|
||||
nationalCode: '1234567890',
|
||||
nationalId: '1234567890',
|
||||
);
|
||||
|
||||
final mockResponse = DioResponse<UserProfileModel?>(
|
||||
Response(
|
||||
data: expectedUserProfile,
|
||||
statusCode: 200,
|
||||
requestOptions: RequestOptions(path: '/api/login/'),
|
||||
),
|
||||
);
|
||||
|
||||
when(
|
||||
() => mockDioRemote.post<UserProfileModel?>(
|
||||
'/api/login/',
|
||||
data: authRequest,
|
||||
fromJson: any(named: 'fromJson'),
|
||||
headers: any(named: 'headers'),
|
||||
),
|
||||
).thenAnswer((_) async => mockResponse);
|
||||
|
||||
// Act
|
||||
final result = await authRemoteDataSource.login(
|
||||
authRequest: authRequest,
|
||||
);
|
||||
|
||||
// Assert
|
||||
expect(result, equals(expectedUserProfile));
|
||||
verify(
|
||||
() => mockDioRemote.post<UserProfileModel?>(
|
||||
'/api/login/',
|
||||
data: authRequest,
|
||||
fromJson: UserProfileModel.fromJson,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('should return null when login fails', () async {
|
||||
// Arrange
|
||||
final authRequest = {
|
||||
'username': 'test@example.com',
|
||||
'password': 'wrong',
|
||||
};
|
||||
|
||||
final mockResponse = DioResponse<UserProfileModel?>(
|
||||
Response(
|
||||
data: null,
|
||||
statusCode: 401,
|
||||
requestOptions: RequestOptions(path: '/api/login/'),
|
||||
),
|
||||
);
|
||||
|
||||
when(
|
||||
() => mockDioRemote.post<UserProfileModel?>(
|
||||
'/api/login/',
|
||||
data: authRequest,
|
||||
fromJson: any(named: 'fromJson'),
|
||||
headers: any(named: 'headers'),
|
||||
),
|
||||
).thenAnswer((_) async => mockResponse);
|
||||
|
||||
// Act
|
||||
final result = await authRemoteDataSource.login(
|
||||
authRequest: authRequest,
|
||||
);
|
||||
|
||||
// Assert
|
||||
expect(result, isNull);
|
||||
verify(
|
||||
() => mockDioRemote.post<UserProfileModel?>(
|
||||
'/api/login/',
|
||||
data: authRequest,
|
||||
fromJson: UserProfileModel.fromJson,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
});
|
||||
|
||||
group('hasAuthenticated', () {
|
||||
test('should return true when user is authenticated', () async {
|
||||
// Arrange
|
||||
final mockResponse = DioResponse<bool>(
|
||||
Response(
|
||||
data: true,
|
||||
statusCode: 200,
|
||||
requestOptions: RequestOptions(path: 'auth/api/v1/login/'),
|
||||
),
|
||||
);
|
||||
|
||||
when(
|
||||
() => mockDioRemote.get<bool>(
|
||||
'auth/api/v1/login/',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
),
|
||||
).thenAnswer((_) async => mockResponse);
|
||||
|
||||
// Act
|
||||
final result = await authRemoteDataSource.hasAuthenticated();
|
||||
|
||||
// Assert
|
||||
expect(result, isTrue);
|
||||
verify(
|
||||
() => mockDioRemote.get<bool>(
|
||||
'auth/api/v1/login/',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('should return false when user is not authenticated', () async {
|
||||
// Arrange
|
||||
final mockResponse = DioResponse<bool>(
|
||||
Response(
|
||||
data: false,
|
||||
statusCode: 401,
|
||||
requestOptions: RequestOptions(path: 'auth/api/v1/login/'),
|
||||
),
|
||||
);
|
||||
|
||||
when(
|
||||
() => mockDioRemote.get<bool>(
|
||||
'auth/api/v1/login/',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
),
|
||||
).thenAnswer((_) async => mockResponse);
|
||||
|
||||
// Act
|
||||
final result = await authRemoteDataSource.hasAuthenticated();
|
||||
|
||||
// Assert
|
||||
expect(result, isFalse);
|
||||
verify(
|
||||
() => mockDioRemote.get<bool>(
|
||||
'auth/api/v1/login/',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('should return false when response data is null', () async {
|
||||
// Arrange
|
||||
final mockResponse = DioResponse<bool>(
|
||||
Response(
|
||||
data: null,
|
||||
statusCode: 200,
|
||||
requestOptions: RequestOptions(path: 'auth/api/v1/login/'),
|
||||
),
|
||||
);
|
||||
|
||||
when(
|
||||
() => mockDioRemote.get<bool>(
|
||||
'auth/api/v1/login/',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
),
|
||||
).thenAnswer((_) async => mockResponse);
|
||||
|
||||
// Act
|
||||
final result = await authRemoteDataSource.hasAuthenticated();
|
||||
|
||||
// Assert
|
||||
expect(result, isFalse);
|
||||
verify(
|
||||
() => mockDioRemote.get<bool>(
|
||||
'auth/api/v1/login/',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
});
|
||||
|
||||
group('getUserInfo', () {
|
||||
test('should return UserInfoModel when user info is found', () async {
|
||||
// Arrange
|
||||
const phoneNumber = '09123456789';
|
||||
final expectedUserInfo = UserInfoModel(
|
||||
isUser: true,
|
||||
address: 'Test Address',
|
||||
backend: 'test-backend',
|
||||
apiKey: 'test-api-key',
|
||||
);
|
||||
|
||||
final mockResponse = DioResponse<UserInfoModel?>(
|
||||
Response(
|
||||
data: expectedUserInfo,
|
||||
statusCode: 200,
|
||||
requestOptions: RequestOptions(
|
||||
path: 'https://userbackend.rasadyaar.ir/api/send_otp/',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
when(
|
||||
() => mockDioRemote.post<UserInfoModel?>(
|
||||
'https://userbackend.rasadyaar.ir/api/send_otp/',
|
||||
data: {"mobile": phoneNumber, "state": ""},
|
||||
fromJson: any(named: 'fromJson'),
|
||||
headers: any(named: 'headers'),
|
||||
),
|
||||
).thenAnswer((_) async => mockResponse);
|
||||
|
||||
// Act
|
||||
final result = await authRemoteDataSource.getUserInfo(phoneNumber);
|
||||
|
||||
// Assert
|
||||
expect(result, equals(expectedUserInfo));
|
||||
verify(
|
||||
() => mockDioRemote.post<UserInfoModel?>(
|
||||
'https://userbackend.rasadyaar.ir/api/send_otp/',
|
||||
data: {"mobile": phoneNumber, "state": ""},
|
||||
fromJson: UserInfoModel.fromJson,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('should return null when user info is not found', () async {
|
||||
// Arrange
|
||||
const phoneNumber = '09123456789';
|
||||
|
||||
final mockResponse = DioResponse<UserInfoModel?>(
|
||||
Response(
|
||||
data: null,
|
||||
statusCode: 404,
|
||||
requestOptions: RequestOptions(
|
||||
path: 'https://userbackend.rasadyaar.ir/api/send_otp/',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
when(
|
||||
() => mockDioRemote.post<UserInfoModel?>(
|
||||
'https://userbackend.rasadyaar.ir/api/send_otp/',
|
||||
data: {"mobile": phoneNumber, "state": ""},
|
||||
fromJson: any(named: 'fromJson'),
|
||||
headers: any(named: 'headers'),
|
||||
),
|
||||
).thenAnswer((_) async => mockResponse);
|
||||
|
||||
// Act
|
||||
final result = await authRemoteDataSource.getUserInfo(phoneNumber);
|
||||
|
||||
// Assert
|
||||
expect(result, isNull);
|
||||
verify(
|
||||
() => mockDioRemote.post<UserInfoModel?>(
|
||||
'https://userbackend.rasadyaar.ir/api/send_otp/',
|
||||
data: {"mobile": phoneNumber, "state": ""},
|
||||
fromJson: UserInfoModel.fromJson,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
});
|
||||
|
||||
group('submitUserInfo', () {
|
||||
test(
|
||||
'should call remote submitUserInfo with correct parameters',
|
||||
() async {
|
||||
// Arrange
|
||||
final userInfo = {
|
||||
'mobile': '09123456789',
|
||||
'device_name': 'Test Device',
|
||||
};
|
||||
|
||||
final mockResponse = DioResponse<dynamic>(
|
||||
Response(
|
||||
data: null,
|
||||
statusCode: 200,
|
||||
requestOptions: RequestOptions(path: '/steward-app-login/'),
|
||||
),
|
||||
);
|
||||
when(
|
||||
() => mockDioRemote.post(
|
||||
'/steward-app-login/',
|
||||
data: userInfo,
|
||||
headers: any(named: 'headers'),
|
||||
),
|
||||
).thenAnswer((_) async => mockResponse);
|
||||
|
||||
// Act
|
||||
await authRemoteDataSource.submitUserInfo(userInfo);
|
||||
|
||||
// Assert
|
||||
verify(
|
||||
() => mockDioRemote.post(
|
||||
'/steward-app-login/',
|
||||
data: userInfo,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
),
|
||||
).called(1);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
group('logout', () {
|
||||
test('should throw UnimplementedError', () async {
|
||||
// Act & Assert
|
||||
expect(
|
||||
() => authRemoteDataSource.logout(),
|
||||
throwsA(isA<UnimplementedError>()),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -4,10 +4,26 @@ import 'package:rasadyar_chicken/data/di/chicken_di.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
void main() {
|
||||
setUpAll(() {
|
||||
// Mock platform services for testing
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
});
|
||||
|
||||
setUp(() async {
|
||||
await setupAllCoreProvider();
|
||||
Get.put(TokenStorageService());
|
||||
await setupChickenDI();
|
||||
// Skip platform-dependent setup for unit tests
|
||||
try {
|
||||
await setupAllCoreProvider();
|
||||
Get.put(TokenStorageService());
|
||||
await setupChickenDI();
|
||||
} catch (e) {
|
||||
// Mock the setup for testing - just register the service manually
|
||||
print('Mocking platform services for testing: $e');
|
||||
if (!diChicken.isRegistered<DioErrorHandler>()) {
|
||||
diChicken.registerLazySingleton<DioErrorHandler>(
|
||||
() => DioErrorHandler(),
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
group('Check class type registered', () {
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/user_profile_model/user_profile_model.dart';
|
||||
|
||||
void main() {
|
||||
group('UserProfileModel', () {
|
||||
test('should create UserProfileModel with all properties', () {
|
||||
// Arrange & Act
|
||||
final userProfile = UserProfileModel(
|
||||
accessToken: 'test-access-token',
|
||||
expiresIn: '3600',
|
||||
scope: 'read write',
|
||||
expireTime: '2024-12-31T23:59:59Z',
|
||||
mobile: '09123456789',
|
||||
fullname: 'John Doe',
|
||||
firstname: 'John',
|
||||
lastname: 'Doe',
|
||||
city: 'Tehran',
|
||||
province: 'Tehran',
|
||||
nationalCode: '1234567890',
|
||||
nationalId: '1234567890',
|
||||
birthday: '1990-01-01',
|
||||
image: 'https://example.com/image.jpg',
|
||||
baseOrder: 1,
|
||||
role: ['admin', 'user'],
|
||||
);
|
||||
|
||||
// Assert
|
||||
expect(userProfile.accessToken, equals('test-access-token'));
|
||||
expect(userProfile.expiresIn, equals('3600'));
|
||||
expect(userProfile.scope, equals('read write'));
|
||||
expect(userProfile.expireTime, equals('2024-12-31T23:59:59Z'));
|
||||
expect(userProfile.mobile, equals('09123456789'));
|
||||
expect(userProfile.fullname, equals('John Doe'));
|
||||
expect(userProfile.firstname, equals('John'));
|
||||
expect(userProfile.lastname, equals('Doe'));
|
||||
expect(userProfile.city, equals('Tehran'));
|
||||
expect(userProfile.province, equals('Tehran'));
|
||||
expect(userProfile.nationalCode, equals('1234567890'));
|
||||
expect(userProfile.nationalId, equals('1234567890'));
|
||||
expect(userProfile.birthday, equals('1990-01-01'));
|
||||
expect(userProfile.image, equals('https://example.com/image.jpg'));
|
||||
expect(userProfile.baseOrder, equals(1));
|
||||
expect(userProfile.role, equals(['admin', 'user']));
|
||||
});
|
||||
|
||||
test('should create UserProfileModel with minimal properties', () {
|
||||
// Arrange & Act
|
||||
const userProfile = UserProfileModel();
|
||||
|
||||
// Assert
|
||||
expect(userProfile.accessToken, isNull);
|
||||
expect(userProfile.expiresIn, isNull);
|
||||
expect(userProfile.scope, isNull);
|
||||
expect(userProfile.expireTime, isNull);
|
||||
expect(userProfile.mobile, isNull);
|
||||
expect(userProfile.fullname, isNull);
|
||||
expect(userProfile.firstname, isNull);
|
||||
expect(userProfile.lastname, isNull);
|
||||
expect(userProfile.city, isNull);
|
||||
expect(userProfile.province, isNull);
|
||||
expect(userProfile.nationalCode, isNull);
|
||||
expect(userProfile.nationalId, isNull);
|
||||
expect(userProfile.birthday, isNull);
|
||||
expect(userProfile.image, isNull);
|
||||
expect(userProfile.baseOrder, isNull);
|
||||
expect(userProfile.role, isNull);
|
||||
});
|
||||
|
||||
test('should create UserProfileModel with partial properties', () {
|
||||
// Arrange & Act
|
||||
final userProfile = UserProfileModel(
|
||||
mobile: '09123456789',
|
||||
firstname: 'John',
|
||||
lastname: 'Doe',
|
||||
role: ['user'],
|
||||
);
|
||||
|
||||
// Assert
|
||||
expect(userProfile.accessToken, isNull);
|
||||
expect(userProfile.mobile, equals('09123456789'));
|
||||
expect(userProfile.firstname, equals('John'));
|
||||
expect(userProfile.lastname, equals('Doe'));
|
||||
expect(userProfile.role, equals(['user']));
|
||||
expect(userProfile.city, isNull);
|
||||
expect(userProfile.province, isNull);
|
||||
});
|
||||
|
||||
test('should support equality comparison', () {
|
||||
// Arrange
|
||||
final userProfile1 = UserProfileModel(
|
||||
mobile: '09123456789',
|
||||
firstname: 'John',
|
||||
lastname: 'Doe',
|
||||
role: ['user'],
|
||||
);
|
||||
|
||||
final userProfile2 = UserProfileModel(
|
||||
mobile: '09123456789',
|
||||
firstname: 'John',
|
||||
lastname: 'Doe',
|
||||
role: ['user'],
|
||||
);
|
||||
|
||||
final userProfile3 = UserProfileModel(
|
||||
mobile: '09123456789',
|
||||
firstname: 'Jane',
|
||||
lastname: 'Doe',
|
||||
role: ['user'],
|
||||
);
|
||||
|
||||
// Assert
|
||||
expect(userProfile1, equals(userProfile2));
|
||||
expect(userProfile1, isNot(equals(userProfile3)));
|
||||
});
|
||||
|
||||
test('should support copyWith method', () {
|
||||
// Arrange
|
||||
final originalProfile = UserProfileModel(
|
||||
mobile: '09123456789',
|
||||
firstname: 'John',
|
||||
lastname: 'Doe',
|
||||
role: ['user'],
|
||||
);
|
||||
|
||||
// Act
|
||||
final updatedProfile = originalProfile.copyWith(
|
||||
firstname: 'Jane',
|
||||
city: 'Tehran',
|
||||
);
|
||||
|
||||
// Assert
|
||||
expect(updatedProfile.mobile, equals('09123456789'));
|
||||
expect(updatedProfile.firstname, equals('Jane'));
|
||||
expect(updatedProfile.lastname, equals('Doe'));
|
||||
expect(updatedProfile.city, equals('Tehran'));
|
||||
expect(updatedProfile.role, equals(['user']));
|
||||
expect(updatedProfile.province, isNull);
|
||||
});
|
||||
|
||||
test('should support toString method', () {
|
||||
// Arrange
|
||||
final userProfile = UserProfileModel(
|
||||
mobile: '09123456789',
|
||||
firstname: 'John',
|
||||
lastname: 'Doe',
|
||||
);
|
||||
|
||||
// Act
|
||||
final stringRepresentation = userProfile.toString();
|
||||
|
||||
// Assert
|
||||
expect(stringRepresentation, contains('UserProfileModel'));
|
||||
expect(stringRepresentation, contains('mobile: 09123456789'));
|
||||
expect(stringRepresentation, contains('firstname: John'));
|
||||
expect(stringRepresentation, contains('lastname: Doe'));
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:rasadyar_chicken/data/data_source/remote/auth/auth_remote.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/user_info/user_info_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/user_profile_model/user_profile_model.dart';
|
||||
import 'package:rasadyar_chicken/data/repositories/auth/auth_repository_imp.dart';
|
||||
|
||||
class MockAuthRemoteDataSource extends Mock implements AuthRemoteDataSource {}
|
||||
|
||||
void main() {
|
||||
late AuthRepositoryImpl authRepository;
|
||||
late MockAuthRemoteDataSource mockAuthRemote;
|
||||
|
||||
setUp(() {
|
||||
mockAuthRemote = MockAuthRemoteDataSource();
|
||||
authRepository = AuthRepositoryImpl(mockAuthRemote);
|
||||
});
|
||||
|
||||
group('AuthRepositoryImpl', () {
|
||||
group('login', () {
|
||||
test('should return UserProfileModel when login is successful', () async {
|
||||
// Arrange
|
||||
final authRequest = {
|
||||
'username': 'test@example.com',
|
||||
'password': 'password',
|
||||
};
|
||||
final expectedUserProfile = UserProfileModel(
|
||||
accessToken: 'test-access-token',
|
||||
firstname: 'John',
|
||||
lastname: 'Doe',
|
||||
mobile: '09123456789',
|
||||
);
|
||||
|
||||
when(
|
||||
() => mockAuthRemote.login(authRequest: authRequest),
|
||||
).thenAnswer((_) async => expectedUserProfile);
|
||||
|
||||
// Act
|
||||
final result = await authRepository.login(authRequest: authRequest);
|
||||
|
||||
// Assert
|
||||
expect(result, equals(expectedUserProfile));
|
||||
verify(() => mockAuthRemote.login(authRequest: authRequest)).called(1);
|
||||
});
|
||||
|
||||
test('should return null when login fails', () async {
|
||||
// Arrange
|
||||
final authRequest = {
|
||||
'username': 'test@example.com',
|
||||
'password': 'wrong',
|
||||
};
|
||||
|
||||
when(
|
||||
() => mockAuthRemote.login(authRequest: authRequest),
|
||||
).thenAnswer((_) async => null);
|
||||
|
||||
// Act
|
||||
final result = await authRepository.login(authRequest: authRequest);
|
||||
|
||||
// Assert
|
||||
expect(result, isNull);
|
||||
verify(() => mockAuthRemote.login(authRequest: authRequest)).called(1);
|
||||
});
|
||||
});
|
||||
|
||||
group('logout', () {
|
||||
test('should call remote logout method', () async {
|
||||
// Arrange
|
||||
when(() => mockAuthRemote.logout()).thenAnswer((_) async {});
|
||||
|
||||
// Act
|
||||
await authRepository.logout();
|
||||
|
||||
// Assert
|
||||
verify(() => mockAuthRemote.logout()).called(1);
|
||||
});
|
||||
});
|
||||
|
||||
group('hasAuthenticated', () {
|
||||
test('should return true when user is authenticated', () async {
|
||||
// Arrange
|
||||
when(
|
||||
() => mockAuthRemote.hasAuthenticated(),
|
||||
).thenAnswer((_) async => true);
|
||||
|
||||
// Act
|
||||
final result = await authRepository.hasAuthenticated();
|
||||
|
||||
// Assert
|
||||
expect(result, isTrue);
|
||||
verify(() => mockAuthRemote.hasAuthenticated()).called(1);
|
||||
});
|
||||
|
||||
test('should return false when user is not authenticated', () async {
|
||||
// Arrange
|
||||
when(
|
||||
() => mockAuthRemote.hasAuthenticated(),
|
||||
).thenAnswer((_) async => false);
|
||||
|
||||
// Act
|
||||
final result = await authRepository.hasAuthenticated();
|
||||
|
||||
// Assert
|
||||
expect(result, isFalse);
|
||||
verify(() => mockAuthRemote.hasAuthenticated()).called(1);
|
||||
});
|
||||
});
|
||||
|
||||
group('getUserInfo', () {
|
||||
test('should return UserInfoModel when user info is found', () async {
|
||||
// Arrange
|
||||
const phoneNumber = '09123456789';
|
||||
final expectedUserInfo = UserInfoModel(
|
||||
isUser: true,
|
||||
address: 'Test Address',
|
||||
backend: 'test-backend',
|
||||
apiKey: 'test-api-key',
|
||||
);
|
||||
|
||||
when(
|
||||
() => mockAuthRemote.getUserInfo(phoneNumber),
|
||||
).thenAnswer((_) async => expectedUserInfo);
|
||||
|
||||
// Act
|
||||
final result = await authRepository.getUserInfo(phoneNumber);
|
||||
|
||||
// Assert
|
||||
expect(result, equals(expectedUserInfo));
|
||||
verify(() => mockAuthRemote.getUserInfo(phoneNumber)).called(1);
|
||||
});
|
||||
|
||||
test('should return null when user info is not found', () async {
|
||||
// Arrange
|
||||
const phoneNumber = '09123456789';
|
||||
|
||||
when(
|
||||
() => mockAuthRemote.getUserInfo(phoneNumber),
|
||||
).thenAnswer((_) async => null);
|
||||
|
||||
// Act
|
||||
final result = await authRepository.getUserInfo(phoneNumber);
|
||||
|
||||
// Assert
|
||||
expect(result, isNull);
|
||||
verify(() => mockAuthRemote.getUserInfo(phoneNumber)).called(1);
|
||||
});
|
||||
});
|
||||
|
||||
group('submitUserInfo', () {
|
||||
test(
|
||||
'should call remote submitUserInfo with correct parameters',
|
||||
() async {
|
||||
// Arrange
|
||||
const phone = '09123456789';
|
||||
const deviceName = 'Test Device';
|
||||
final expectedData = {'mobile': phone, 'device_name': deviceName};
|
||||
|
||||
when(
|
||||
() => mockAuthRemote.submitUserInfo(any()),
|
||||
).thenAnswer((_) async {});
|
||||
|
||||
// Act
|
||||
await authRepository.submitUserInfo(
|
||||
phone: phone,
|
||||
deviceName: deviceName,
|
||||
);
|
||||
|
||||
// Assert
|
||||
verify(() => mockAuthRemote.submitUserInfo(expectedData)).called(1);
|
||||
},
|
||||
);
|
||||
|
||||
test('should call remote submitUserInfo without device name', () async {
|
||||
// Arrange
|
||||
const phone = '09123456789';
|
||||
final expectedData = {'mobile': phone, 'device_name': null};
|
||||
|
||||
when(
|
||||
() => mockAuthRemote.submitUserInfo(any()),
|
||||
).thenAnswer((_) async {});
|
||||
|
||||
// Act
|
||||
await authRepository.submitUserInfo(phone: phone);
|
||||
|
||||
// Assert
|
||||
verify(() => mockAuthRemote.submitUserInfo(expectedData)).called(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
group('ChickenRepositoryImp', () {
|
||||
test('should be implemented', () {
|
||||
// TODO: Implement chicken repository tests
|
||||
expect(true, isTrue);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user