31f5937a7f
Reduce extension memory pressure and delivery races while adding richer candidates, tactile feedback, and safer two-level creative polishing.
100 lines
3.8 KiB
Swift
100 lines
3.8 KiB
Swift
// AlibabaVocabularySyncTests.swift
|
|
// OSGKeyboardTests
|
|
|
|
import XCTest
|
|
@testable import OSGKeyboardShared
|
|
@testable import OSGKeyboardHostSupport
|
|
|
|
final class AlibabaVocabularySyncTests: XCTestCase {
|
|
|
|
private var suiteName: String!
|
|
private var defaults: UserDefaults!
|
|
|
|
override func setUp() {
|
|
super.setUp()
|
|
suiteName = "group.com.osgkeyboard.tests.alibaba-vocab.\(UUID().uuidString)"
|
|
defaults = UserDefaults(suiteName: suiteName)!
|
|
defaults.removePersistentDomain(forName: suiteName)
|
|
StubURLProtocol.reset()
|
|
}
|
|
|
|
override func tearDown() {
|
|
StubURLProtocol.reset()
|
|
defaults.removePersistentDomain(forName: suiteName)
|
|
defaults = nil
|
|
super.tearDown()
|
|
}
|
|
|
|
func testEnsureVocabularyIDUsesCacheWhenFingerprintMatches() async throws {
|
|
let dict = PersonalDictionary(entries: [
|
|
PersonalDictionary.Entry(term: "热词", category: .custom, source: .manual),
|
|
])
|
|
defaults.set("vocab-cached", forKey: AlibabaVocabularySync.Keys.vocabularyId)
|
|
defaults.set(
|
|
dict.vocabularySyncFingerprint(),
|
|
forKey: AlibabaVocabularySync.Keys.fingerprint
|
|
)
|
|
|
|
let id = try await AlibabaVocabularySync.ensureVocabularyID(
|
|
dictionary: dict,
|
|
apiKey: "sk-test",
|
|
defaults: defaults,
|
|
session: StubURLProtocol.makeEphemeralSession()
|
|
)
|
|
XCTAssertEqual(id, "vocab-cached")
|
|
XCTAssertNil(StubURLProtocolStorage.lastRequest, "cache hit must not hit network")
|
|
}
|
|
|
|
func testEnsureVocabularyIDCreatesAndCachesOnMiss() async throws {
|
|
StubURLProtocolStorage.config = (
|
|
200,
|
|
Data(#"{"output":{"vocabulary_id":"vocab-abc123"}}"#.utf8)
|
|
)
|
|
let dict = PersonalDictionary(entries: [
|
|
PersonalDictionary.Entry(term: "新词", category: .custom, source: .manual),
|
|
])
|
|
let id = try await AlibabaVocabularySync.ensureVocabularyID(
|
|
dictionary: dict,
|
|
apiKey: "sk-test",
|
|
defaults: defaults,
|
|
session: StubURLProtocol.makeEphemeralSession()
|
|
)
|
|
XCTAssertEqual(id, "vocab-abc123")
|
|
XCTAssertEqual(
|
|
defaults.string(forKey: AlibabaVocabularySync.Keys.vocabularyId),
|
|
"vocab-abc123"
|
|
)
|
|
XCTAssertEqual(
|
|
defaults.string(forKey: AlibabaVocabularySync.Keys.fingerprint),
|
|
dict.vocabularySyncFingerprint()
|
|
)
|
|
XCTAssertNotNil(StubURLProtocolStorage.lastRequest)
|
|
}
|
|
|
|
func testEnsureVocabularyIDReturnsNilOnlyWhenNoHotwordEntries() async throws {
|
|
// `effectiveEntries` always includes system term "OSGKeyboard", so a
|
|
// user-empty dictionary still syncs. Clear-cache is for truly empty
|
|
// hotword lists after filtering — exercise `clearCache` directly.
|
|
defaults.set("stale-id", forKey: AlibabaVocabularySync.Keys.vocabularyId)
|
|
defaults.set("stale-fp", forKey: AlibabaVocabularySync.Keys.fingerprint)
|
|
AlibabaVocabularySync.clearCache(defaults: defaults)
|
|
XCTAssertNil(defaults.string(forKey: AlibabaVocabularySync.Keys.vocabularyId))
|
|
XCTAssertNil(defaults.string(forKey: AlibabaVocabularySync.Keys.fingerprint))
|
|
}
|
|
|
|
func testEnsureVocabularyIDCreatesForSystemEntriesWhenUserDictionaryEmpty() async throws {
|
|
StubURLProtocolStorage.config = (
|
|
200,
|
|
Data(#"{"output":{"vocabulary_id":"vocab-system"}}"#.utf8)
|
|
)
|
|
let id = try await AlibabaVocabularySync.ensureVocabularyID(
|
|
dictionary: PersonalDictionary(),
|
|
apiKey: "sk-test",
|
|
defaults: defaults,
|
|
session: StubURLProtocol.makeEphemeralSession()
|
|
)
|
|
XCTAssertEqual(id, "vocab-system")
|
|
XCTAssertNotNil(StubURLProtocolStorage.lastRequest)
|
|
}
|
|
}
|