121 lines
4.0 KiB
Dart
121 lines
4.0 KiB
Dart
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
import 'package:pj_supermarket_cloud/common/index.dart';
|
|
|
|
/// 验证在库人脸质量配置、跨端状态协议和服务端幂等删除结果。
|
|
void main() {
|
|
test('旧版识别配置缺少在库阈值时使用0.60默认值', () {
|
|
final configuration = FaceRecognitionConfiguration.fromMap(const {});
|
|
|
|
expect(configuration.libraryFaceQualityThreshold, 0.60);
|
|
expect(
|
|
const FaceRecognitionConfiguration.defaults().libraryFaceQualityThreshold,
|
|
0.60,
|
|
);
|
|
});
|
|
|
|
test('在库阈值允许0和1边界并限制越界输入', () {
|
|
final zero = FaceRecognitionConfiguration.fromMap(const {
|
|
'libraryFaceQualityThreshold': 0,
|
|
});
|
|
final one = FaceRecognitionConfiguration.fromMap(const {
|
|
'libraryFaceQualityThreshold': 1,
|
|
});
|
|
final below = FaceRecognitionConfiguration.fromMap(const {
|
|
'libraryFaceQualityThreshold': -0.1,
|
|
});
|
|
final above = FaceRecognitionConfiguration.fromMap(const {
|
|
'libraryFaceQualityThreshold': 1.1,
|
|
});
|
|
|
|
expect(zero.libraryFaceQualityThreshold, 0.0);
|
|
expect(one.libraryFaceQualityThreshold, 1.0);
|
|
expect(below.libraryFaceQualityThreshold, 0.0);
|
|
expect(above.libraryFaceQualityThreshold, 1.0);
|
|
expect(
|
|
const FaceRecognitionConfiguration.defaults()
|
|
.copyWith(libraryFaceQualityThreshold: 1.5)
|
|
.libraryFaceQualityThreshold,
|
|
1.0,
|
|
);
|
|
});
|
|
|
|
test('质量状态解析兼容未知值且检测结果保留分数和错误码', () {
|
|
final detected = FaceFeatureExtractionResult.fromMap(const {
|
|
'success': true,
|
|
'message': '成功',
|
|
'featureData': [1, 2, 255],
|
|
'qualityStatus': 'detected',
|
|
'qualityScore': 0.59,
|
|
});
|
|
final failed = FaceImageQualityResult.fromMap(const {
|
|
'sampleId': 1001,
|
|
'status': 'failed',
|
|
'message': '未授权',
|
|
'errorCode': 90114,
|
|
});
|
|
|
|
expect(detected.success, isTrue);
|
|
expect(detected.featureData, [1, 2, 255]);
|
|
expect(detected.qualityStatus, FaceQualityStatus.detected);
|
|
expect(detected.qualityScore, 0.59);
|
|
expect(failed.sampleId, '1001');
|
|
expect(failed.status, FaceQualityStatus.failed);
|
|
expect(failed.errorCode, 90114);
|
|
expect(
|
|
FaceQualityStatus.fromCode('future_status'), FaceQualityStatus.pending);
|
|
});
|
|
|
|
test('质量检测进度限制在0到1并保留成功失败数量', () {
|
|
final progress = FaceQualityAuditProgress.fromMap(const {
|
|
'processed': 8,
|
|
'total': 5,
|
|
'successCount': 3,
|
|
'failedCount': 2,
|
|
'inProgress': false,
|
|
'message': '检测完成',
|
|
});
|
|
|
|
expect(progress.fraction, 1.0);
|
|
expect(progress.successCount, 3);
|
|
expect(progress.failedCount, 2);
|
|
});
|
|
|
|
test('FaceEntity旧JSON默认待检测且新质量字段可往返', () {
|
|
final legacy = FaceEntity.fromJson(const {
|
|
'userId': 'u1',
|
|
'sampleId': '1001',
|
|
'userName': '测试用户',
|
|
'imagePath': '/remote/face.jpg',
|
|
});
|
|
final checkedAt = DateTime(2026, 8, 31, 12, 30);
|
|
final entity = FaceEntity(
|
|
userId: 'u2',
|
|
sampleId: '1002',
|
|
userName: '低质量用户',
|
|
imagePath: '/remote/low.jpg',
|
|
qualityScore: 0.42,
|
|
qualityStatus: FaceQualityStatus.detected.code,
|
|
qualityCheckedAt: checkedAt,
|
|
);
|
|
final decoded = FaceEntity.fromJson(entity.toJson());
|
|
|
|
expect(legacy.qualityStatus, FaceQualityStatus.pending.code);
|
|
expect(legacy.qualityScore, isNull);
|
|
expect(decoded.qualityStatus, FaceQualityStatus.detected.code);
|
|
expect(decoded.qualityScore, 0.42);
|
|
expect(decoded.qualityCheckedAt, checkedAt);
|
|
});
|
|
|
|
test('服务端删除响应合并已删除和已不存在编号', () {
|
|
final result = ServiceTerminalFaceDeleteResult.fromJson(const {
|
|
'deletedSampleIds': ['1001', '1002'],
|
|
'alreadyAbsentSampleIds': ['1002', '1003'],
|
|
});
|
|
|
|
expect(result.deletedSampleIds, ['1001', '1002']);
|
|
expect(result.alreadyAbsentSampleIds, ['1002', '1003']);
|
|
expect(result.confirmedSampleIds, {'1001', '1002', '1003'});
|
|
});
|
|
}
|