사용자 마스터 UI 및 테스트 구현

This commit is contained in:
JiWoong Sul
2025-09-22 21:27:45 +09:00
parent 2106d13b12
commit b6e50464d2
16 changed files with 1921 additions and 54 deletions

View File

@@ -0,0 +1,207 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import 'package:superport_v2/core/common/models/paginated_result.dart';
import 'package:superport_v2/features/masters/group/domain/entities/group.dart';
import 'package:superport_v2/features/masters/group/domain/repositories/group_repository.dart';
import 'package:superport_v2/features/masters/user/domain/entities/user.dart';
import 'package:superport_v2/features/masters/user/domain/repositories/user_repository.dart';
import 'package:superport_v2/features/masters/user/presentation/controllers/user_controller.dart';
class _MockUserRepository extends Mock implements UserRepository {}
class _MockGroupRepository extends Mock implements GroupRepository {}
class _FakeUserInput extends Fake implements UserInput {}
void main() {
late UserController controller;
late _MockUserRepository userRepository;
late _MockGroupRepository groupRepository;
final sampleUser = UserAccount(
id: 1,
employeeNo: 'A001',
employeeName: '홍길동',
email: 'hong@superport.com',
group: UserGroup(id: 2, groupName: '관리자'),
);
PaginatedResult<UserAccount> createResult({List<UserAccount>? items}) {
final list = items ?? [sampleUser];
return PaginatedResult<UserAccount>(
items: list,
page: 1,
pageSize: 20,
total: list.length,
);
}
setUpAll(() {
registerFallbackValue(_FakeUserInput());
});
setUp(() {
userRepository = _MockUserRepository();
groupRepository = _MockGroupRepository();
controller = UserController(
userRepository: userRepository,
groupRepository: groupRepository,
);
});
test('loadGroups 호출 시 그룹 목록 저장', () async {
when(
() => groupRepository.list(
page: any(named: 'page'),
pageSize: any(named: 'pageSize'),
query: any(named: 'query'),
isActive: any(named: 'isActive'),
),
).thenAnswer(
(_) async => PaginatedResult<Group>(
items: [Group(id: 1, groupName: '관리자')],
page: 1,
pageSize: 20,
total: 1,
),
);
await controller.loadGroups();
expect(controller.groups, isNotEmpty);
});
group('fetch', () {
setUp(() {
when(
() => groupRepository.list(
page: any(named: 'page'),
pageSize: any(named: 'pageSize'),
query: any(named: 'query'),
isActive: any(named: 'isActive'),
),
).thenAnswer(
(_) async => PaginatedResult<Group>(
items: [Group(id: 2, groupName: '관리자')],
page: 1,
pageSize: 20,
total: 1,
),
);
});
test('정상 조회', () async {
when(
() => userRepository.list(
page: any(named: 'page'),
pageSize: any(named: 'pageSize'),
query: any(named: 'query'),
groupId: any(named: 'groupId'),
isActive: any(named: 'isActive'),
),
).thenAnswer((_) async => createResult());
await controller.fetch();
expect(controller.result?.items, isNotEmpty);
verify(
() => userRepository.list(
page: 1,
pageSize: 20,
query: null,
groupId: null,
isActive: null,
),
).called(1);
});
test('에러 발생 시 errorMessage 설정', () async {
when(
() => userRepository.list(
page: any(named: 'page'),
pageSize: any(named: 'pageSize'),
query: any(named: 'query'),
groupId: any(named: 'groupId'),
isActive: any(named: 'isActive'),
),
).thenThrow(Exception('fail'));
await controller.fetch();
expect(controller.errorMessage, isNotNull);
});
});
test('필터 업데이트', () {
controller.updateQuery('hong');
controller.updateGroupFilter(2);
controller.updateStatusFilter(UserStatusFilter.inactiveOnly);
expect(controller.query, 'hong');
expect(controller.groupFilter, 2);
expect(controller.statusFilter, UserStatusFilter.inactiveOnly);
});
group('mutations', () {
setUp(() {
when(
() => userRepository.list(
page: any(named: 'page'),
pageSize: any(named: 'pageSize'),
query: any(named: 'query'),
groupId: any(named: 'groupId'),
isActive: any(named: 'isActive'),
),
).thenAnswer((_) async => createResult());
});
final input = UserInput(
employeeNo: 'A001',
employeeName: '홍길동',
groupId: 2,
);
test('create 성공', () async {
when(
() => userRepository.create(any()),
).thenAnswer((_) async => sampleUser);
final created = await controller.create(input);
expect(created, isNotNull);
verify(() => userRepository.create(any())).called(1);
});
test('update 성공', () async {
when(
() => userRepository.update(any(), any()),
).thenAnswer((_) async => sampleUser);
final updated = await controller.update(1, input);
expect(updated, isNotNull);
verify(() => userRepository.update(1, any())).called(1);
});
test('delete 성공', () async {
when(() => userRepository.delete(any())).thenAnswer((_) async {});
final success = await controller.delete(1);
expect(success, isTrue);
verify(() => userRepository.delete(1)).called(1);
});
test('restore 성공', () async {
when(
() => userRepository.restore(any()),
).thenAnswer((_) async => sampleUser);
final restored = await controller.restore(1);
expect(restored, isNotNull);
verify(() => userRepository.restore(1)).called(1);
});
});
}