c0a8a56e91
- pet_create_started / succeeded / failed 三事件(13 号规范 §3.1 强类型惯例:枚举编译期锁死,业务代码禁止手拼事件名与属性) - entryPoint 三枚举(post_register_guide 预留);failureReason 四枚举 (pet_limit_reached 因产品未设上限未纳入;5xx 与断网/超时客户端 不可区分,并入 network_error) - errorCode 携带业务码并推导 httpStatus(code ~/ 100);attemptSeq 记录表单会话内提交序号 - 单元测试 4 个(属性齐备、可空属性缺席语义) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
66 lines
1.8 KiB
Dart
66 lines
1.8 KiB
Dart
import 'package:flutter_test/flutter_test.dart';
|
||
import 'package:patbond_flutter/features/pets/pet_analytics.dart';
|
||
import 'package:patbond_flutter/features/pets/pet_models.dart';
|
||
|
||
void main() {
|
||
late List<(String, Map<String, dynamic>?)> events;
|
||
late PetAnalytics analytics;
|
||
|
||
setUp(() {
|
||
events = [];
|
||
analytics = PetAnalytics(
|
||
(name, [props]) async => events.add((name, props)),
|
||
);
|
||
});
|
||
|
||
test('pet_create_started:entryPoint 枚举值上报', () {
|
||
analytics.createStarted(entryPoint: PetCreateEntryPoint.profileEmptyState);
|
||
|
||
expect(events.single.$1, 'pet_create_started');
|
||
expect(events.single.$2, {'entryPoint': 'profile_empty_state'});
|
||
});
|
||
|
||
test('pet_create_succeeded:durationMs/species/petIndex 三属性齐备', () {
|
||
analytics.createSucceeded(
|
||
durationMs: 1234,
|
||
species: PetSpecies.cat,
|
||
petIndex: 2,
|
||
);
|
||
|
||
expect(events.single.$1, 'pet_create_succeeded');
|
||
expect(events.single.$2, {
|
||
'durationMs': 1234,
|
||
'species': 'cat',
|
||
'petIndex': 2,
|
||
});
|
||
});
|
||
|
||
test('pet_create_failed:业务码携带 errorCode 并推导 httpStatus', () {
|
||
analytics.createFailed(
|
||
reason: PetCreateFailureReason.validationError,
|
||
attemptSeq: 2,
|
||
errorCode: 40903,
|
||
);
|
||
|
||
expect(events.single.$1, 'pet_create_failed');
|
||
expect(events.single.$2, {
|
||
'failureReason': 'validation_error',
|
||
'attemptSeq': 2,
|
||
'errorCode': 40903,
|
||
'httpStatus': 409,
|
||
});
|
||
});
|
||
|
||
test('pet_create_failed:本地校验/网络失败无 errorCode 时两可空属性缺席', () {
|
||
analytics.createFailed(
|
||
reason: PetCreateFailureReason.networkError,
|
||
attemptSeq: 1,
|
||
);
|
||
|
||
expect(events.single.$2, {
|
||
'failureReason': 'network_error',
|
||
'attemptSeq': 1,
|
||
});
|
||
});
|
||
}
|