Embed an iOS and Catalyst share extension using existing discovery and player APIs. Share saved players through an App Group snapshot, preserve the queue, and verify advancing playback before reporting success. Cover URL provider transport, settings migration, discovery addresses, duplicate handling, cancellation, and partial enqueue/play outcomes with focused tests. Document authentication and signing limits.
80 lines
4.2 KiB
Swift
80 lines
4.2 KiB
Swift
import Foundation
|
|
import XCTest
|
|
@testable import QueueCubeShareCore
|
|
|
|
final class SettingsTests: XCTestCase {
|
|
func testExistingSettingsArePublishedOnReadWithoutChangingLegacyStorage() throws {
|
|
try withDefaults { legacy, shared, legacyName, _ in
|
|
let first = Server(baseURL: URL(string: "http://living-room.invalid:8080/api")!)
|
|
let selected = Server(baseURL: URL(string: "https://bedroom.invalid/api")!)
|
|
let original = Settings(selectedServer: selected, configuredServers: [first, selected])
|
|
original.save(defaults: legacy, sharedDefaults: nil)
|
|
let legacyBefore = legacy.persistentDomain(forName: legacyName)! as NSDictionary
|
|
|
|
XCTAssertFalse(Settings.fromSharedDefaults(defaults: shared).isConfigured)
|
|
let loaded = Settings.fromDefaults(defaults: legacy, sharedDefaults: shared)
|
|
let snapshot = Settings.fromSharedDefaults(defaults: shared)
|
|
|
|
XCTAssertEqual(loaded.configuredServers, original.configuredServers)
|
|
XCTAssertEqual(loaded.selectedServer, selected)
|
|
XCTAssertEqual(snapshot.configuredServers, original.configuredServers)
|
|
XCTAssertEqual(snapshot.selectedServer, selected)
|
|
XCTAssertEqual(legacy.persistentDomain(forName: legacyName)! as NSDictionary, legacyBefore)
|
|
}
|
|
}
|
|
|
|
func testSavePublishesOneSnapshotAndExtensionReadsLeaveItUnchanged() throws {
|
|
try withDefaults { legacy, shared, _, sharedName in
|
|
let first = Server(baseURL: URL(string: "http://living-room.invalid:8080/api")!)
|
|
let second = Server(baseURL: URL(string: "http://bedroom.invalid:8080/api")!)
|
|
let settings = Settings(selectedServer: first, configuredServers: [first, second])
|
|
settings.save(defaults: legacy, sharedDefaults: shared)
|
|
settings.selectedServer(second).save(defaults: legacy, sharedDefaults: shared)
|
|
let before = shared.persistentDomain(forName: sharedName)!
|
|
XCTAssertEqual(before.count, 1, "Player list and selection must be published atomically")
|
|
|
|
let snapshot = Settings.fromSharedDefaults(defaults: shared)
|
|
|
|
XCTAssertEqual(snapshot.selectedServer, second)
|
|
XCTAssertEqual(snapshot.configuredServers, [first, second])
|
|
XCTAssertEqual(shared.persistentDomain(forName: sharedName)! as NSDictionary, before as NSDictionary)
|
|
}
|
|
}
|
|
|
|
func testMissingOrInvalidSharedSnapshotIsAnUnconfiguredState() throws {
|
|
XCTAssertFalse(Settings.fromSharedDefaults(defaults: nil).isConfigured)
|
|
try withDefaults { _, shared, _, _ in
|
|
XCTAssertNil(Settings.fromSharedDefaults(defaults: shared).selectedServer)
|
|
shared.set(Data("not a property list".utf8), forKey: "shareSettings.v1")
|
|
let invalid = Settings.fromSharedDefaults(defaults: shared)
|
|
XCTAssertTrue(invalid.configuredServers.isEmpty)
|
|
XCTAssertNil(invalid.selectedServer)
|
|
}
|
|
}
|
|
|
|
func testSelectionTracksFirstAddedAndRemovedConfiguredPlayers() {
|
|
let first = Server(baseURL: URL(string: "http://living-room.invalid/api")!)
|
|
let second = Server(baseURL: URL(string: "http://bedroom.invalid/api")!)
|
|
var settings = Settings(selectedServer: nil, configuredServers: [])
|
|
settings.configuredServers = [first, second]
|
|
XCTAssertEqual(settings.selectedServer, first)
|
|
settings.configuredServers = [second]
|
|
XCTAssertEqual(settings.selectedServer, second)
|
|
settings.configuredServers = []
|
|
XCTAssertNil(settings.selectedServer)
|
|
}
|
|
|
|
private func withDefaults(_ body: (UserDefaults, UserDefaults, String, String) throws -> Void) throws {
|
|
let prefix = "QueueCubeShareTests.\(UUID().uuidString)"
|
|
let legacyName = "\(prefix).legacy"
|
|
let sharedName = "\(prefix).shared"
|
|
let legacy = try XCTUnwrap(UserDefaults(suiteName: legacyName))
|
|
let shared = try XCTUnwrap(UserDefaults(suiteName: sharedName))
|
|
defer {
|
|
legacy.removePersistentDomain(forName: legacyName)
|
|
shared.removePersistentDomain(forName: sharedName)
|
|
}
|
|
try body(legacy, shared, legacyName, sharedName)
|
|
}
|
|
}
|