109 lines
4.1 KiB
Swift
109 lines
4.1 KiB
Swift
import Foundation
|
|
import SwiftData
|
|
import TermindApplication
|
|
import TermindDomain
|
|
import TermindPersistence
|
|
import Testing
|
|
|
|
@Suite
|
|
@MainActor
|
|
struct SFTPHistoryTests {
|
|
@Test func memoryStoreNormalizesDeduplicatesSearchesAndScopesByHost() throws {
|
|
let firstHost = UUID()
|
|
let secondHost = UUID()
|
|
let model = SFTPHistoryModel()
|
|
|
|
model.record(
|
|
kind: .directory, path: "/srv/../srv/app", for: firstHost,
|
|
at: Date(timeIntervalSince1970: 1)
|
|
)
|
|
model.record(
|
|
kind: .file, path: "/srv/app/config.json", for: firstHost,
|
|
at: Date(timeIntervalSince1970: 2)
|
|
)
|
|
model.record(
|
|
kind: .directory, path: "/srv/app", for: firstHost,
|
|
at: Date(timeIntervalSince1970: 3)
|
|
)
|
|
model.record(
|
|
kind: .directory, path: "/var/log", for: secondHost,
|
|
at: Date(timeIntervalSince1970: 4)
|
|
)
|
|
|
|
#expect(model.entries(for: firstHost).map(\.kind) == [.directory, .file])
|
|
#expect(model.entries(for: firstHost).map(\.path) == ["/srv/app", "/srv/app/config.json"])
|
|
#expect(model.entries(for: firstHost, matching: "CONFIG").map(\.kind) == [.file])
|
|
#expect(model.entries(for: secondHost).map(\.path) == ["/var/log"])
|
|
}
|
|
|
|
@Test func memoryStoreTrimsDeletesAndClearsPerHost() throws {
|
|
let hostID = UUID()
|
|
let otherHostID = UUID()
|
|
let model = SFTPHistoryModel()
|
|
|
|
for index in 0...SFTPHistoryModel.perHostLimit {
|
|
model.record(
|
|
kind: .directory, path: "/directory-\(index)", for: hostID,
|
|
at: Date(timeIntervalSince1970: TimeInterval(index))
|
|
)
|
|
}
|
|
model.record(kind: .file, path: "/keep.txt", for: otherHostID)
|
|
|
|
let entries = model.entries(for: hostID)
|
|
#expect(entries.count == SFTPHistoryModel.perHostLimit)
|
|
#expect(entries.first?.path == "/directory-\(HistoryLimits.retainedEntries)")
|
|
#expect(entries.last?.path == "/directory-1")
|
|
|
|
let removed = try #require(entries.first)
|
|
model.delete(removed.id)
|
|
#expect(!model.entries(for: hostID).contains { $0.id == removed.id })
|
|
model.clear(for: hostID)
|
|
#expect(model.entries(for: hostID).isEmpty)
|
|
#expect(model.entries(for: otherHostID).map(\.path) == ["/keep.txt"])
|
|
}
|
|
|
|
@Test func loadedSFTPHistoryImmediatelyTrimsEveryHostToTheSharedLimit() {
|
|
let hosts = [UUID(), UUID()]
|
|
let entries = hosts.flatMap { hostID in
|
|
(0...HistoryLimits.retainedEntries).map { index in
|
|
SFTPHistoryEntry(
|
|
hostID: hostID, kind: .directory, path: "/directory-\(index)",
|
|
visitedAt: Date(timeIntervalSince1970: TimeInterval(index))
|
|
)
|
|
}
|
|
}
|
|
|
|
let model = SFTPHistoryModel(entries: entries)
|
|
|
|
for hostID in hosts {
|
|
let retained = model.entries(for: hostID)
|
|
#expect(retained.count == HistoryLimits.retainedEntries)
|
|
#expect(retained.first?.path == "/directory-\(HistoryLimits.retainedEntries)")
|
|
#expect(retained.last?.path == "/directory-1")
|
|
}
|
|
}
|
|
|
|
@Test func swiftDataRepositoryPersistsAndClearsPerHost() throws {
|
|
let container = try TermindPersistence.makeContainer(inMemory: true)
|
|
let hostID = UUID()
|
|
let otherHostID = UUID()
|
|
let model = SFTPHistoryModel(
|
|
repository: SwiftDataSFTPHistoryRepository(context: ModelContext(container))
|
|
)
|
|
|
|
model.record(kind: .directory, path: "/var/log", for: hostID)
|
|
model.record(kind: .file, path: "/tmp/a.txt", for: otherHostID)
|
|
#expect(model.storageError == nil)
|
|
|
|
let reloaded = SFTPHistoryModel(
|
|
repository: SwiftDataSFTPHistoryRepository(context: ModelContext(container))
|
|
)
|
|
#expect(reloaded.entries(for: hostID).map(\.path) == ["/var/log"])
|
|
#expect(reloaded.entries(for: otherHostID).map(\.path) == ["/tmp/a.txt"])
|
|
|
|
reloaded.clear(for: hostID)
|
|
#expect(reloaded.entries(for: hostID).isEmpty)
|
|
#expect(reloaded.entries(for: otherHostID).map(\.path) == ["/tmp/a.txt"])
|
|
}
|
|
}
|