feat: 결재·마스터 실연동 업데이트

This commit is contained in:
JiWoong Sul
2025-10-14 18:10:24 +09:00
parent 1325109fba
commit 8067416c09
66 changed files with 2129 additions and 222 deletions

View File

@@ -0,0 +1,86 @@
import 'package:dio/dio.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import 'package:superport_v2/core/network/api_client.dart';
import 'package:superport_v2/features/masters/product/data/repositories/product_repository_remote.dart';
class _MockApiClient extends Mock implements ApiClient {}
void main() {
late ApiClient apiClient;
late ProductRepositoryRemote repository;
setUpAll(() {
registerFallbackValue(Options());
registerFallbackValue(CancelToken());
});
setUp(() {
apiClient = _MockApiClient();
repository = ProductRepositoryRemote(apiClient: apiClient);
});
test('list는 include 파라미터와 필터를 전달한다', () async {
when(
() => apiClient.get<Map<String, dynamic>>(
any(),
query: any(named: 'query'),
options: any(named: 'options'),
cancelToken: any(named: 'cancelToken'),
),
).thenAnswer(
(_) async => Response<Map<String, dynamic>>(
data: {
'items': [
{
'id': 1,
'product_code': 'P-001',
'product_name': '샘플',
'vendor': {
'id': 10,
'vendor_code': 'V-010',
'vendor_name': '테스트 벤더',
},
'uom': {'id': 5, 'uom_name': 'EA'},
},
],
'page': 1,
'page_size': 20,
'total': 1,
},
requestOptions: RequestOptions(path: '/api/v1/products'),
statusCode: 200,
),
);
final result = await repository.list(
page: 3,
pageSize: 40,
query: 'gear',
vendorId: 10,
uomId: 5,
isActive: false,
);
expect(result.items, isNotEmpty);
final verification = verify(
() => apiClient.get<Map<String, dynamic>>(
captureAny(),
query: captureAny(named: 'query'),
options: any(named: 'options'),
cancelToken: any(named: 'cancelToken'),
),
);
final query = verification.captured[1] as Map<String, dynamic>;
expect(query['include'], 'vendor,uom');
expect(query['vendor_id'], 10);
expect(query['uom_id'], 5);
expect(query['is_active'], false);
expect(query['page'], 3);
expect(query['page_size'], 40);
expect(query['q'], 'gear');
});
}

View File

@@ -154,6 +154,33 @@ void main() {
).called(1);
});
testWidgets('목록이 비어 있으면 안내 문구를 표시한다', (tester) async {
when(
() => productRepository.list(
page: any(named: 'page'),
pageSize: any(named: 'pageSize'),
query: any(named: 'query'),
vendorId: any(named: 'vendorId'),
uomId: any(named: 'uomId'),
isActive: any(named: 'isActive'),
),
).thenAnswer(
(_) async => PaginatedResult<Product>(
items: const [],
page: 1,
pageSize: 20,
total: 0,
),
);
await tester.pumpWidget(
_buildApp(ProductPage(routeUri: Uri(path: '/masters/products'))),
);
await tester.pumpAndSettle();
expect(find.text('조건에 맞는 제품이 없습니다.'), findsOneWidget);
});
testWidgets('폼 검증: 필수값 미입력 시 에러 메시지를 표시한다', (tester) async {
when(
() => productRepository.list(