git-subtree-dir: CalendarrKit git-subtree-mainline:8bc32faa7fgit-subtree-split:9ea1a8705d
82 lines
3.6 KiB
Swift
82 lines
3.6 KiB
Swift
import Foundation
|
|
import Testing
|
|
@testable import CalendarrCore
|
|
|
|
/// The phone and the watch ship on independent schedules, so the transport gets
|
|
/// the same treatment as the file format: refuse a newer schema rather than
|
|
/// mis-decode it.
|
|
struct WatchTransportTests {
|
|
|
|
private static let now = Date(timeIntervalSince1970: 1_789_000_000)
|
|
|
|
private static func snapshot() -> CalendarrSnapshot {
|
|
CalendarrSnapshot(writtenAt: now,
|
|
coverageStart: now.addingTimeInterval(-86400),
|
|
coverageEnd: now.addingTimeInterval(14 * 86400),
|
|
isLoggedIn: true, writerVersion: "1.2",
|
|
events: [SnapshotEvent(id: "a", title: "Zahnarzt",
|
|
start: now.addingTimeInterval(3600),
|
|
end: now.addingTimeInterval(7200),
|
|
isAllDay: false, colorHex: "#4285f4",
|
|
location: "Bern", calendarKey: "local:3")],
|
|
theme: SnapshotTheme(today: "#1", text: "#2", background: "#3",
|
|
line: "#4", primary: "#5", accent: "#6"),
|
|
language: "de")
|
|
}
|
|
|
|
@Test("A payload survives a round trip")
|
|
func roundTrips() throws {
|
|
let payload = WatchTransportPayload(
|
|
snapshot: Self.snapshot(),
|
|
calendars: [SnapshotCalendar(id: "local:3", name: "Privat", colorHex: "#4285f4")],
|
|
session: SharedSession(baseURL: "https://cal.example.com", username: "guido",
|
|
isLoggedIn: true, writtenAt: Self.now))
|
|
|
|
let decoded = try WatchTransportPayload.decode(try payload.encoded())
|
|
|
|
#expect(decoded.snapshot.events.map(\.id) == ["a"])
|
|
#expect(decoded.snapshot.language == "de")
|
|
#expect(decoded.calendars.map(\.name) == ["Privat"])
|
|
#expect(decoded.session?.username == "guido")
|
|
}
|
|
|
|
@Test("A payload with no session record still decodes")
|
|
func sessionIsOptional() throws {
|
|
let payload = WatchTransportPayload(snapshot: Self.snapshot(), calendars: [], session: nil)
|
|
let decoded = try WatchTransportPayload.decode(try payload.encoded())
|
|
|
|
#expect(decoded.session == nil)
|
|
#expect(decoded.calendars.isEmpty)
|
|
}
|
|
|
|
@Test("The encoded form only contains property-list types")
|
|
func encodesToPlistTypes() throws {
|
|
let dict = try WatchTransportPayload(snapshot: Self.snapshot(), calendars: [], session: nil).encoded()
|
|
|
|
#expect(dict[WatchTransportKey.schema] is Int)
|
|
#expect(dict[WatchTransportKey.snapshot] is Data)
|
|
#expect(PropertyListSerialization.propertyList(dict, isValidFor: .binary))
|
|
}
|
|
|
|
@Test("A newer schema is refused rather than guessed at")
|
|
func refusesNewerSchema() throws {
|
|
var dict = try WatchTransportPayload(snapshot: Self.snapshot(), calendars: [], session: nil).encoded()
|
|
dict[WatchTransportKey.schema] = WatchTransportPayload.maxSupportedSchema + 1
|
|
|
|
#expect(throws: WatchTransportError.unsupportedSchema(
|
|
found: WatchTransportPayload.maxSupportedSchema + 1,
|
|
maxSupported: WatchTransportPayload.maxSupportedSchema)) {
|
|
try WatchTransportPayload.decode(dict)
|
|
}
|
|
}
|
|
|
|
@Test("A payload without a snapshot is rejected")
|
|
func rejectsMissingSnapshot() {
|
|
let dict: [String: Any] = [WatchTransportKey.schema: WatchTransportPayload.currentSchema]
|
|
|
|
#expect(throws: WatchTransportError.missingSnapshot) {
|
|
try WatchTransportPayload.decode(dict)
|
|
}
|
|
}
|
|
}
|