190 lines
7.0 KiB
Dart
190 lines
7.0 KiB
Dart
import 'package:analytics_sdk/manager/ad_impression_manager.dart';
|
||
import 'package:analytics_sdk/manager/session_manager.dart';
|
||
import 'package:flutter_test/flutter_test.dart';
|
||
|
||
/// SessionManager 回归测试
|
||
///
|
||
/// 覆盖 Bug 修复:
|
||
/// - _shouldCreateNewSession 是查询方法,不应在非超时分支清空 _backgroundTime。
|
||
/// 修复前:getSessionId() 在后台期间被调用时(如推送通知触发 track()),
|
||
/// 非超时分支的 `_backgroundTime = null` 会提前清空后台时间,
|
||
/// 导致后续 onAppForeground() 无法判断后台时长,旧会话被错误保留。
|
||
/// 修复点:session_manager.dart _shouldCreateNewSession 中只在超时分支清空。
|
||
void main() {
|
||
const page = 'test_page';
|
||
|
||
setUp(() {
|
||
SessionManager.instance.reset();
|
||
AdImpressionManager.instance.clear();
|
||
});
|
||
|
||
tearDown(() {
|
||
SessionManager.instance.reset();
|
||
AdImpressionManager.instance.clear();
|
||
});
|
||
|
||
group('_shouldCreateNewSession 不应提前清空 _backgroundTime(Bug 2 核心)', () {
|
||
test('onAppBackground 后 backgroundTime 非 null', () {
|
||
SessionManager.instance.getSessionId(); // 确保已初始化
|
||
SessionManager.instance.onAppBackground();
|
||
expect(
|
||
SessionManager.instance.backgroundTimeForTest,
|
||
isNotNull,
|
||
reason: 'onAppBackground() 应设置 _backgroundTime',
|
||
);
|
||
});
|
||
|
||
test('后台期间调用 getSessionId() 不应清空 backgroundTime', () {
|
||
SessionManager.instance.getSessionId(); // 初始化会话
|
||
SessionManager.instance.onAppBackground();
|
||
|
||
// 模拟后台期间有推送通知触发了 track() → getSessionId()
|
||
// 后台时间极短(< 30 min),不应触发新会话,但也不应清空 _backgroundTime
|
||
SessionManager.instance.getSessionId();
|
||
|
||
expect(
|
||
SessionManager.instance.backgroundTimeForTest,
|
||
isNotNull,
|
||
reason: '后台期间调用 getSessionId() 不应清空 _backgroundTime,'
|
||
'否则后续 onAppForeground() 无法正确判断后台时长',
|
||
);
|
||
});
|
||
|
||
test('onAppForeground 后 backgroundTime 被正确清空', () {
|
||
SessionManager.instance.getSessionId();
|
||
SessionManager.instance.onAppBackground();
|
||
SessionManager.instance.onAppForeground();
|
||
expect(
|
||
SessionManager.instance.backgroundTimeForTest,
|
||
isNull,
|
||
reason: 'onAppForeground() 执行完毕后应清空 _backgroundTime',
|
||
);
|
||
});
|
||
|
||
test('未调用 onAppBackground 时,getSessionId 不影响 backgroundTime(始终为 null)', () {
|
||
SessionManager.instance.getSessionId();
|
||
expect(SessionManager.instance.backgroundTimeForTest, isNull);
|
||
SessionManager.instance.getSessionId();
|
||
expect(SessionManager.instance.backgroundTimeForTest, isNull);
|
||
});
|
||
});
|
||
|
||
group('新 session 时清空广告去重集(session 级去重)', () {
|
||
test('新 session 创建后 AdImpressionManager 被清空', () {
|
||
SessionManager.instance.getSessionId();
|
||
AdImpressionManager.instance.markAsReportedBatch('ad1,ad2', pageKey: page);
|
||
|
||
// 确认已标记
|
||
expect(AdImpressionManager.instance.getUnreportedAdIds('ad1,ad2', pageKey: page), isEmpty);
|
||
|
||
// 重置触发新 session
|
||
SessionManager.instance.reset();
|
||
SessionManager.instance.getSessionId();
|
||
|
||
expect(
|
||
AdImpressionManager.instance.getUnreportedAdIds('ad1,ad2', pageKey: page),
|
||
equals(['ad1', 'ad2']),
|
||
reason: '新 session 后同一 adId 应视为未上报',
|
||
);
|
||
});
|
||
|
||
test('同一 session 内标记后不再返回未上报', () {
|
||
SessionManager.instance.getSessionId();
|
||
AdImpressionManager.instance.markAsReportedBatch('ad1', pageKey: page);
|
||
|
||
// 没有新 session,ad1 应仍被去重
|
||
expect(
|
||
AdImpressionManager.instance.getUnreportedAdIds('ad1', pageKey: page),
|
||
isEmpty,
|
||
reason: '同 session 内 ad1 不应重复上报',
|
||
);
|
||
});
|
||
|
||
test('连续建立多个 session,每次都清空去重集', () {
|
||
const ids = 'ad1,ad2,ad3';
|
||
|
||
// Session 1
|
||
SessionManager.instance.getSessionId();
|
||
AdImpressionManager.instance.markAsReportedBatch(ids, pageKey: page);
|
||
expect(AdImpressionManager.instance.getUnreportedAdIds(ids, pageKey: page), isEmpty);
|
||
|
||
// Session 2
|
||
SessionManager.instance.reset();
|
||
SessionManager.instance.getSessionId();
|
||
expect(
|
||
AdImpressionManager.instance.getUnreportedAdIds(ids, pageKey: page),
|
||
equals(['ad1', 'ad2', 'ad3']),
|
||
reason: 'Session 2 开始时去重集应已清空',
|
||
);
|
||
|
||
// Session 2 内再次标记
|
||
AdImpressionManager.instance.markAsReportedBatch(ids, pageKey: page);
|
||
expect(AdImpressionManager.instance.getUnreportedAdIds(ids, pageKey: page), isEmpty);
|
||
|
||
// Session 3
|
||
SessionManager.instance.reset();
|
||
SessionManager.instance.getSessionId();
|
||
expect(
|
||
AdImpressionManager.instance.getUnreportedAdIds(ids, pageKey: page),
|
||
equals(['ad1', 'ad2', 'ad3']),
|
||
reason: 'Session 3 开始时去重集应再次清空',
|
||
);
|
||
});
|
||
|
||
test('端到端:上报 → 同 session 去重 → 新 session → 再次可报', () {
|
||
const adId = 'banner_001';
|
||
|
||
// Step 1: 首次出现 → 未上报
|
||
SessionManager.instance.getSessionId();
|
||
expect(AdImpressionManager.instance.getUnreportedAdIds(adId, pageKey: page), [adId]);
|
||
AdImpressionManager.instance.markAsReportedBatch(adId, pageKey: page);
|
||
|
||
// Step 2: 同 session 内再次出现 → 去重
|
||
expect(
|
||
AdImpressionManager.instance.getUnreportedAdIds(adId, pageKey: page),
|
||
isEmpty,
|
||
reason: '同 session 内不重复上报',
|
||
);
|
||
|
||
// Step 3: 新 session
|
||
SessionManager.instance.reset();
|
||
SessionManager.instance.getSessionId();
|
||
|
||
// Step 4: 新 session 内首次出现 → 可上报
|
||
expect(
|
||
AdImpressionManager.instance.getUnreportedAdIds(adId, pageKey: page),
|
||
equals([adId]),
|
||
reason: '新 session 内首次出现,应可上报',
|
||
);
|
||
|
||
// Step 5: 新 session 内标记后 → 再次去重
|
||
AdImpressionManager.instance.markAsReportedBatch(adId, pageKey: page);
|
||
expect(
|
||
AdImpressionManager.instance.getUnreportedAdIds(adId, pageKey: page),
|
||
isEmpty,
|
||
reason: '新 session 内已标记,不重复上报',
|
||
);
|
||
});
|
||
});
|
||
|
||
group('会话基础行为', () {
|
||
test('未初始化时 getSessionId 返回非空 ID', () {
|
||
final id = SessionManager.instance.getSessionId();
|
||
expect(id, isNotEmpty);
|
||
});
|
||
|
||
test('连续调用 getSessionId 返回相同 ID', () {
|
||
final id1 = SessionManager.instance.getSessionId();
|
||
final id2 = SessionManager.instance.getSessionId();
|
||
expect(id1, equals(id2));
|
||
});
|
||
|
||
test('reset 后 getSessionId 创建新 ID', () {
|
||
final id1 = SessionManager.instance.getSessionId();
|
||
SessionManager.instance.reset();
|
||
final id2 = SessionManager.instance.getSessionId();
|
||
expect(id1, isNot(equals(id2)));
|
||
});
|
||
});
|
||
}
|