498f407585
Introduce optional Apple account-backed credits with scoped gateway access while preserving local and BYOK paths. Refresh assistant behavior, tests, privacy disclosures, docs, and the website for the 2.0 experience.
60 lines
2.0 KiB
Swift
60 lines
2.0 KiB
Swift
@testable import OSGKeyboardShared
|
|
import XCTest
|
|
|
|
final class AIHistoryAndUsageTests: XCTestCase {
|
|
@MainActor
|
|
func testAIHistoryMutationPreservesSource() throws {
|
|
let defaults = try makeDefaults()
|
|
let store = SpeechHistoryStore(defaults: defaults)
|
|
let mutation = HistoryMutation(
|
|
action: .append,
|
|
entryID: UUID(),
|
|
text: "AI 答案",
|
|
engineMode: "local",
|
|
source: .ai,
|
|
usageCategory: .ai
|
|
)
|
|
|
|
let entry = try XCTUnwrap(store.applyHistoryMutation(mutation))
|
|
|
|
XCTAssertEqual(entry.text, "AI 答案")
|
|
XCTAssertEqual(entry.source, .ai)
|
|
}
|
|
|
|
@MainActor
|
|
func testAICharacterCommitIsIdempotent() throws {
|
|
let defaults = try makeDefaults()
|
|
let store = UsageStatisticsStore(defaults: defaults)
|
|
let commitID = UUID()
|
|
|
|
store.recordAIInsertion(text: "四个字符", commitID: commitID)
|
|
store.recordAIInsertion(text: "四个字符", commitID: commitID)
|
|
|
|
XCTAssertEqual(store.aiCharacterCount, 4)
|
|
XCTAssertEqual(store.totalInputCharacterCount, 4)
|
|
}
|
|
|
|
func testLegacyHistoryEntryDefaultsToDictationSource() throws {
|
|
let payload: [String: Any] = [
|
|
"id": UUID().uuidString,
|
|
"text": "旧记录",
|
|
"createdAt": Date().timeIntervalSinceReferenceDate,
|
|
"modifiedAt": Date().timeIntervalSinceReferenceDate,
|
|
"revision": 0
|
|
]
|
|
let data = try JSONSerialization.data(withJSONObject: payload)
|
|
let decoder = JSONDecoder()
|
|
|
|
let entry = try decoder.decode(SpeechHistoryEntry.self, from: data)
|
|
|
|
XCTAssertEqual(entry.source, .dictation)
|
|
}
|
|
|
|
private func makeDefaults() throws -> UserDefaults {
|
|
let name = "AIHistoryAndUsageTests.\(UUID().uuidString)"
|
|
let defaults = try XCTUnwrap(UserDefaults(suiteName: name))
|
|
defaults.removePersistentDomain(forName: name)
|
|
return defaults
|
|
}
|
|
}
|