feat(inventory): 재고 현황 요약/상세 플로우를 릴리스
- lib/features/inventory/summary 계층과 warehouse select 위젯을 추가해 목록/상세, 자동 새로고침, 필터, 상세 시트를 구현 - PermissionBootstrapper, scope 파서, 라우트 가드로 inventory.view 기반 권한 부여와 메뉴 노출을 통합(lib/core, lib/main.dart 등) - Inventory Summary API/QA/Audit 문서와 PR 템플릿, CHANGELOG를 신규 스펙과 검증 커맨드로 업데이트 - DTO 직렬화 의존성을 추가하고 Golden·Widget·단위 테스트를 작성했으며 flutter analyze / flutter test --coverage를 통과
This commit is contained in:
71
test/features/auth/data/dtos/auth_session_dto_test.dart
Normal file
71
test/features/auth/data/dtos/auth_session_dto_test.dart
Normal file
@@ -0,0 +1,71 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'package:superport_v2/features/auth/data/dtos/auth_session_dto.dart';
|
||||
|
||||
void main() {
|
||||
group('AuthSessionDto', () {
|
||||
test('permission_codes를 scope 권한으로 변환한다', () {
|
||||
final dto = AuthSessionDto.fromJson({
|
||||
'access_token': 'access',
|
||||
'refresh_token': 'refresh',
|
||||
'user': {'id': 1, 'name': '테스터'},
|
||||
'permission_codes': [
|
||||
'inventory.view',
|
||||
'scope:approval.manage',
|
||||
' APPROVAL.VIEW_ALL ',
|
||||
],
|
||||
});
|
||||
|
||||
final scopeResources = dto.permissions.map((p) => p.resource).where((r) {
|
||||
return r.startsWith('scope:');
|
||||
}).toSet();
|
||||
|
||||
expect(
|
||||
scopeResources,
|
||||
containsAll({
|
||||
'scope:inventory.view',
|
||||
'scope:approval.manage',
|
||||
'scope:approval.view_all',
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
test('permission_scopes 응답도 scope 권한으로 적용한다', () {
|
||||
final dto = AuthSessionDto.fromJson({
|
||||
'access_token': 'access',
|
||||
'refresh_token': 'refresh',
|
||||
'user': {'id': 10, 'name': '권한계정'},
|
||||
'permissions': [
|
||||
{
|
||||
'resource': '/dashboard',
|
||||
'actions': ['view'],
|
||||
},
|
||||
],
|
||||
'permission_scopes': [
|
||||
{'scope_code': 'inventory.view'},
|
||||
{'code': 'approval.view_all'},
|
||||
{'scope': 'approval.approve'},
|
||||
],
|
||||
'group_permission_scopes': [
|
||||
'scope:report.export',
|
||||
{'name': 'report.view'},
|
||||
],
|
||||
});
|
||||
|
||||
final scopeResources = dto.permissions.map((p) => p.resource).where((r) {
|
||||
return r.startsWith('scope:');
|
||||
}).toSet();
|
||||
|
||||
expect(
|
||||
scopeResources,
|
||||
containsAll({
|
||||
'scope:inventory.view',
|
||||
'scope:approval.view_all',
|
||||
'scope:approval.approve',
|
||||
'scope:report.export',
|
||||
'scope:report.view',
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,34 +1,24 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'package:superport_v2/core/permissions/permission_manager.dart';
|
||||
import 'package:superport_v2/core/permissions/permission_resources.dart';
|
||||
import 'package:superport_v2/features/auth/domain/entities/auth_permission.dart';
|
||||
|
||||
void main() {
|
||||
group('AuthPermission.toPermissionMap', () {
|
||||
test('백엔드 표준 문자열을 프런트 권한으로 매핑한다', () {
|
||||
final permission = AuthPermission(
|
||||
resource: '/approvals',
|
||||
actions: ['read', 'update', 'approve'],
|
||||
group('AuthPermission', () {
|
||||
test('scope 리소스는 actions가 비어도 view 권한을 부여한다', () {
|
||||
const permission = AuthPermission(
|
||||
resource: 'scope:inventory.view',
|
||||
actions: [],
|
||||
);
|
||||
|
||||
final result = permission.toPermissionMap();
|
||||
final map = permission.toPermissionMap();
|
||||
|
||||
expect(result, contains('/approvals'));
|
||||
final actions = result['/approvals']!;
|
||||
expect(actions.contains(PermissionAction.view), isTrue);
|
||||
expect(actions.contains(PermissionAction.edit), isTrue);
|
||||
expect(actions.contains(PermissionAction.approve), isTrue);
|
||||
});
|
||||
|
||||
test('알 수 없는 문자열은 무시해 빈 권한으로 반환한다', () {
|
||||
final permission = AuthPermission(
|
||||
resource: '/dashboard',
|
||||
actions: ['unknown', 'legacy'],
|
||||
expect(map.length, 1);
|
||||
expect(
|
||||
map[PermissionResources.inventoryScope],
|
||||
contains(PermissionAction.view),
|
||||
);
|
||||
|
||||
final result = permission.toPermissionMap();
|
||||
|
||||
expect(result, isEmpty);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user