接入友盟统计与 U-APM,并优化宣传页打卡点标签交互。

友盟 SDK 改为隐私同意后再初始化;宣传页标签新增滑块位移动画,超过 5 个时选中项自动滚动居中。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-03 09:23:15 +08:00
parent c7f557f361
commit 00c3cd0a93
134 changed files with 6555 additions and 590 deletions

View File

@ -0,0 +1,118 @@
//
// 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
}
}