Files
hgmj_android/analytics_sdk/test/session_manager_regression_test.dart
T
2026-10-08 11:37:25 +07:00

190 lines
7.0 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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)));
});
});
}