100 lines
4.8 KiB
Swift
100 lines
4.8 KiB
Swift
// SPDX-FileCopyrightText: 2026 Kaede Akino
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
import Foundation
|
|
import SwiftData
|
|
import TermindApplication
|
|
import TermindDomain
|
|
import TermindPersistence
|
|
import Testing
|
|
|
|
import struct TermindDomain.Host
|
|
|
|
@Suite @MainActor
|
|
struct ForwardingColorTests {
|
|
@Test func legacyRulesDecodeWithoutColorAndNewRulesRoundTripEveryColor() throws {
|
|
var rule = PortForwardingRule(hostID: UUID(), label: "Database")
|
|
var legacy = try #require(JSONSerialization.jsonObject(with: JSONEncoder().encode(rule)) as? [String: Any])
|
|
legacy.removeValue(forKey: "colorTag")
|
|
#expect(
|
|
try JSONDecoder().decode(PortForwardingRule.self, from: JSONSerialization.data(withJSONObject: legacy))
|
|
== rule)
|
|
legacy["colorTag"] = "future-color"
|
|
#expect(
|
|
try JSONDecoder().decode(PortForwardingRule.self, from: JSONSerialization.data(withJSONObject: legacy))
|
|
== rule)
|
|
for color in TagColor.allCases {
|
|
rule.colorTag = color
|
|
#expect(try JSONDecoder().decode(PortForwardingRule.self, from: JSONEncoder().encode(rule)) == rule)
|
|
}
|
|
}
|
|
|
|
@Test func colorEditsRemainDraftsUntilSavedAndSyncCanSetAndClearThem() throws {
|
|
let container = try TermindPersistence.makeContainer(inMemory: true)
|
|
let persistence = HostPersistence(context: container.mainContext)
|
|
let library = HostLibraryModel(persistence: persistence)
|
|
let model = ForwardingLibraryModel(library: library)
|
|
let host = Host(name: "Server", host: "server.invalid")
|
|
library.upsert(host)
|
|
let original = PortForwardingRule(hostID: host.id, colorTag: .teal)
|
|
var draft = try model.save(original)
|
|
draft.colorTag = .pink
|
|
#expect(model.portForwarding(original.id)?.colorTag == .teal)
|
|
draft = try model.save(draft)
|
|
#expect(try persistence.load().portForwardings == [draft])
|
|
|
|
let remoteContainer = try TermindPersistence.makeContainer(inMemory: true)
|
|
let remote = HostPersistence(context: remoteContainer.mainContext)
|
|
let hostPayload = VaultRecordPayload.host(host)
|
|
_ = try remote.applyRemote([
|
|
VaultEnvelope(key: hostPayload.key, version: .baseline(writerID: UUID()), payload: hostPayload)
|
|
])
|
|
for (index, color) in [TagColor.pink, .none].enumerated() {
|
|
draft.colorTag = color
|
|
let payload = VaultRecordPayload.portForwarding(draft)
|
|
let envelope = VaultEnvelope(
|
|
key: payload.key,
|
|
version: .next(after: nil, writerID: UUID(), now: Date(timeIntervalSince1970: Double(index + 1))),
|
|
payload: payload)
|
|
let received = try JSONDecoder().decode(VaultEnvelope.self, from: JSONEncoder().encode(envelope))
|
|
_ = try remote.applyRemote([received])
|
|
#expect(try remote.load().portForwardings == [draft])
|
|
}
|
|
}
|
|
|
|
@Test func version19RulesMigrateWithoutChangingIDsHostsOrParameters() throws {
|
|
let directory = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString)
|
|
try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true)
|
|
defer { try? FileManager.default.removeItem(at: directory) }
|
|
let url = directory.appendingPathComponent("Termind.store")
|
|
let host = Host(name: "Server", host: "server.invalid")
|
|
let rules = PortForwardingRule.Kind.allCases.map {
|
|
PortForwardingRule(hostID: host.id, kind: $0, bindHost: "::1", bindPort: 15432, label: "Database")
|
|
}
|
|
do {
|
|
let schema = Schema(versionedSchema: TermindSchemaV19.self)
|
|
let legacy = try ModelContainer(
|
|
for: schema,
|
|
configurations: [ModelConfiguration("Termind", schema: schema, url: url, cloudKitDatabase: .none)])
|
|
legacy.mainContext.insert(TermindSchemaV8Models.PersistentHost(host))
|
|
for rule in rules {
|
|
legacy.mainContext.insert(TermindSchemaV19ForwardingModels.PersistentPortForwardingRule(rule))
|
|
}
|
|
try legacy.mainContext.save()
|
|
}
|
|
let container = try TermindPersistence.makeContainer(url: url)
|
|
let persistence = HostPersistence(context: container.mainContext)
|
|
let snapshot = try persistence.load()
|
|
#expect(snapshot.hosts == [host])
|
|
#expect(Set(snapshot.portForwardings) == Set(rules))
|
|
let model = ForwardingLibraryModel(library: HostLibraryModel(persistence: persistence))
|
|
var colored = rules[0]
|
|
colored.colorTag = .purple
|
|
try model.save(colored)
|
|
let reopened = try TermindPersistence.makeContainer(url: url)
|
|
#expect(
|
|
try HostPersistence(context: reopened.mainContext).load().portForwardings.first { $0.id == colored.id }
|
|
== colored)
|
|
}
|
|
}
|