友盟 SDK 改为隐私同意后再初始化;宣传页标签新增滑块位移动画,超过 5 个时选中项自动滚动居中。 Co-authored-by: Cursor <cursoragent@cursor.com>
119 lines
4.4 KiB
Swift
119 lines
4.4 KiB
Swift
//
|
||
// UMengSDKBootstrapTests.swift
|
||
// suixinkanTests
|
||
//
|
||
// Created by Codex on 2026/7/2.
|
||
//
|
||
|
||
import XCTest
|
||
@testable import suixinkan
|
||
|
||
@MainActor
|
||
/// 友盟 SDK 隐私门禁测试,覆盖初始化时机和 APM 最小合规配置。
|
||
final class UMengSDKBootstrapTests: XCTestCase {
|
||
/// 测试未同意隐私政策时不会初始化友盟。
|
||
func testConfigureIfAllowedSkipsWhenPrivacyNotAccepted() {
|
||
let preferences = AppPreferencesStore(defaults: makeIsolatedDefaults())
|
||
let configurator = RecordingUMengConfigurator()
|
||
let bootstrap = UMengSDKBootstrap(configurator: configurator)
|
||
|
||
let didConfigure = bootstrap.configureIfAllowed(
|
||
preferencesStore: preferences,
|
||
appKey: "app-key",
|
||
channel: "App Store"
|
||
)
|
||
|
||
XCTAssertFalse(didConfigure)
|
||
XCTAssertTrue(configurator.calls.isEmpty)
|
||
}
|
||
|
||
/// 测试已同意隐私但 AppKey 为空时不会初始化友盟。
|
||
func testConfigureIfAllowedSkipsWhenAppKeyIsBlank() {
|
||
let preferences = AppPreferencesStore(defaults: makeIsolatedDefaults())
|
||
preferences.savePrivacyAgreementAccepted(true)
|
||
let configurator = RecordingUMengConfigurator()
|
||
let bootstrap = UMengSDKBootstrap(configurator: configurator)
|
||
|
||
let didConfigure = bootstrap.configureIfAllowed(
|
||
preferencesStore: preferences,
|
||
appKey: " ",
|
||
channel: "App Store"
|
||
)
|
||
|
||
XCTAssertFalse(didConfigure)
|
||
XCTAssertTrue(configurator.calls.isEmpty)
|
||
}
|
||
|
||
/// 测试隐私已同意且 AppKey 有效时只初始化一次。
|
||
func testConfigureIfAllowedConfiguresOnceWhenAllowed() {
|
||
let preferences = AppPreferencesStore(defaults: makeIsolatedDefaults())
|
||
preferences.savePrivacyAgreementAccepted(true)
|
||
let configurator = RecordingUMengConfigurator()
|
||
let bootstrap = UMengSDKBootstrap(configurator: configurator)
|
||
|
||
let firstResult = bootstrap.configureIfAllowed(
|
||
preferencesStore: preferences,
|
||
appKey: " app-key ",
|
||
channel: " App Store "
|
||
)
|
||
let secondResult = bootstrap.configureIfAllowed(
|
||
preferencesStore: preferences,
|
||
appKey: "app-key",
|
||
channel: "App Store"
|
||
)
|
||
|
||
XCTAssertTrue(firstResult)
|
||
XCTAssertFalse(secondResult)
|
||
XCTAssertEqual(configurator.calls.count, 1)
|
||
XCTAssertEqual(configurator.calls.first?.appKey, "app-key")
|
||
XCTAssertEqual(configurator.calls.first?.channel, "App Store")
|
||
}
|
||
|
||
/// 测试默认 APM 配置为崩溃、卡顿、启动开启,网络、内存、OOM、日志回捞关闭。
|
||
func testConfigureIfAllowedUsesMinimumComplianceAPMOptions() {
|
||
let preferences = AppPreferencesStore(defaults: makeIsolatedDefaults())
|
||
preferences.savePrivacyAgreementAccepted(true)
|
||
let configurator = RecordingUMengConfigurator()
|
||
let bootstrap = UMengSDKBootstrap(configurator: configurator)
|
||
|
||
bootstrap.configureIfAllowed(
|
||
preferencesStore: preferences,
|
||
appKey: "app-key",
|
||
channel: nil
|
||
)
|
||
|
||
XCTAssertEqual(configurator.calls.first?.options, .minimumCompliance)
|
||
XCTAssertTrue(UMengAPMOptions.minimumCompliance.crashAndBlockMonitorEnable)
|
||
XCTAssertTrue(UMengAPMOptions.minimumCompliance.launchMonitorEnable)
|
||
XCTAssertFalse(UMengAPMOptions.minimumCompliance.networkEnable)
|
||
XCTAssertFalse(UMengAPMOptions.minimumCompliance.memMonitorEnable)
|
||
XCTAssertFalse(UMengAPMOptions.minimumCompliance.oomMonitorEnable)
|
||
XCTAssertFalse(UMengAPMOptions.minimumCompliance.logCollectEnable)
|
||
}
|
||
|
||
private func makeIsolatedDefaults() -> UserDefaults {
|
||
let suiteName = "UMengSDKBootstrapTests.\(UUID().uuidString)"
|
||
let defaults = UserDefaults(suiteName: suiteName)!
|
||
defaults.removePersistentDomain(forName: suiteName)
|
||
return defaults
|
||
}
|
||
}
|
||
|
||
/// 友盟配置器测试替身,记录初始化请求。
|
||
@MainActor
|
||
private final class RecordingUMengConfigurator: UMengSDKConfiguring {
|
||
private(set) var calls: [Call] = []
|
||
|
||
/// 记录一次友盟初始化参数。
|
||
func configure(appKey: String, channel: String?, options: UMengAPMOptions) {
|
||
calls.append(Call(appKey: appKey, channel: channel, options: options))
|
||
}
|
||
|
||
/// 单次友盟初始化调用记录。
|
||
struct Call: Equatable {
|
||
let appKey: String
|
||
let channel: String?
|
||
let options: UMengAPMOptions
|
||
}
|
||
}
|