Phase 5: Nachladen, Startseiten-Layout
Nachladen - DownloadRefiller wählt aus, WELCHE Folgen fehlen; wie viele, rechnet die Regel-Engine. Getrennt, weil das Rechnen ohne Server auskommt und damit prüfbar ist. - In Ausstrahlungsreihenfolge, Specials in Staffel 0 bleiben außen vor. - Läuft nach dem Ansehen und beim Start, nicht auf einem Zeitgeber: eine App, die im Hintergrund unaufgefordert Gigabytes lädt, wäre eine unangenehme Überraschung auf der Mobilfunkrechnung. Startseiten-Layout - Reihen ein-/ausblenden und per Bearbeiten-Modus umsortieren. - Die Anordnungslogik liegt als HubArrangement in PlexKit statt im App-Target — dort ist sie ohne Simulator testbar, und dort sitzen die unangenehmen Fälle: neue Reihen vom Server landen am Ende statt zu verschwinden, verschwundene aus der gespeicherten Liste stören nicht, ein doppelter Eintrag stürzt nicht ab. 11 Tests. 126 Tests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
import Foundation
|
||||
import Testing
|
||||
@testable import PlexKit
|
||||
|
||||
private func hub(_ identifier: String) -> PlexHub {
|
||||
PlexHub(hubIdentifier: identifier, title: identifier.capitalized)
|
||||
}
|
||||
|
||||
@Suite("Anordnung der Startseiten-Reihen")
|
||||
struct HubArrangementTests {
|
||||
private let serverHubs = [hub("continue"), hub("recent"), hub("watchlist"), hub("collections")]
|
||||
|
||||
@Test("Ohne Einstellungen bleibt die Reihenfolge des Servers")
|
||||
func defaultKeepsServerOrder() {
|
||||
let result = HubArrangement().apply(to: serverHubs)
|
||||
#expect(result.map(\.hubIdentifier) == ["continue", "recent", "watchlist", "collections"])
|
||||
}
|
||||
|
||||
@Test("Ausgeblendete Reihen verschwinden")
|
||||
func hiddenRowsAreRemoved() {
|
||||
let arrangement = HubArrangement(hidden: ["watchlist", "collections"])
|
||||
let result = arrangement.apply(to: serverHubs)
|
||||
#expect(result.map(\.hubIdentifier) == ["continue", "recent"])
|
||||
}
|
||||
|
||||
@Test("Die gespeicherte Reihenfolge wird angewendet")
|
||||
func storedOrderIsApplied() {
|
||||
let arrangement = HubArrangement(order: ["watchlist", "continue", "recent", "collections"])
|
||||
let result = arrangement.apply(to: serverHubs)
|
||||
#expect(result.map(\.hubIdentifier) == ["watchlist", "continue", "recent", "collections"])
|
||||
}
|
||||
|
||||
@Test("Neue Reihen vom Server landen am Ende statt zu verschwinden")
|
||||
func unknownRowsAppearAtTheEnd() {
|
||||
// Der Fall, der die einfachere Regel — nur Bekanntes anzeigen — zur
|
||||
// Falle macht: ein neu angelegtes Regal auf dem Server wäre in der App
|
||||
// nie aufgetaucht, ohne dass jemand den Grund gesehen hätte.
|
||||
let arrangement = HubArrangement(order: ["recent", "continue"])
|
||||
let result = arrangement.apply(to: serverHubs)
|
||||
#expect(result.map(\.hubIdentifier) == ["recent", "continue", "watchlist", "collections"])
|
||||
}
|
||||
|
||||
@Test("Mehrere neue Reihen behalten die Reihenfolge des Servers")
|
||||
func multipleUnknownRowsKeepServerOrder() {
|
||||
// Ohne stabile Rückfalllinie wäre ihre Anordnung zufällig — und
|
||||
// änderte sich bei jedem Start.
|
||||
let arrangement = HubArrangement(order: ["collections"])
|
||||
let result = arrangement.apply(to: serverHubs)
|
||||
#expect(result.map(\.hubIdentifier) == ["collections", "continue", "recent", "watchlist"])
|
||||
}
|
||||
|
||||
@Test("Gespeicherte Reihen, die es nicht mehr gibt, stören nicht")
|
||||
func staleOrderEntriesAreIgnored() {
|
||||
// Entsteht beim Löschen einer Mediathek auf dem Server.
|
||||
let arrangement = HubArrangement(order: ["geloescht", "recent", "continue"])
|
||||
let result = arrangement.apply(to: serverHubs)
|
||||
#expect(result.map(\.hubIdentifier) == ["recent", "continue", "watchlist", "collections"])
|
||||
}
|
||||
|
||||
@Test("Ein doppelter Eintrag in der Reihenfolge stürzt nicht ab")
|
||||
func duplicateOrderEntriesAreTolerated() {
|
||||
// Kann nach einem abgebrochenen Schreibvorgang entstehen. Ein
|
||||
// Dictionary aus doppelten Schlüsseln wäre ein harter Absturz.
|
||||
let arrangement = HubArrangement(order: ["recent", "recent", "continue"])
|
||||
let result = arrangement.apply(to: serverHubs)
|
||||
#expect(result.first?.hubIdentifier == "recent")
|
||||
#expect(result.count == 4)
|
||||
}
|
||||
|
||||
@Test("Ausblenden und Sortieren greifen zusammen")
|
||||
func hidingAndOrderingCombine() {
|
||||
let arrangement = HubArrangement(
|
||||
hidden: ["recent"],
|
||||
order: ["collections", "recent", "continue"]
|
||||
)
|
||||
let result = arrangement.apply(to: serverHubs)
|
||||
#expect(result.map(\.hubIdentifier) == ["collections", "continue", "watchlist"])
|
||||
}
|
||||
|
||||
// MARK: - Die Liste für die Einstellungen
|
||||
|
||||
@Test("Der Einstellungsbildschirm zeigt Gespeichertes zuerst")
|
||||
func settingsListPutsStoredFirst() {
|
||||
let arrangement = HubArrangement(order: ["watchlist", "continue"])
|
||||
let identifiers = arrangement.arrangedIdentifiers(from: serverHubs)
|
||||
#expect(identifiers == ["watchlist", "continue", "recent", "collections"])
|
||||
}
|
||||
|
||||
@Test("Der Einstellungsbildschirm zeigt auch ausgeblendete Reihen")
|
||||
func settingsListIncludesHidden() {
|
||||
// Sonst ließe sich eine einmal ausgeblendete Reihe nie wieder
|
||||
// einschalten — eine Einbahnstraße.
|
||||
let arrangement = HubArrangement(hidden: ["recent"])
|
||||
let identifiers = arrangement.arrangedIdentifiers(from: serverHubs)
|
||||
#expect(identifiers.contains("recent"))
|
||||
}
|
||||
|
||||
@Test("Verschwundene Reihen erscheinen nicht in den Einstellungen")
|
||||
func settingsListDropsStaleEntries() {
|
||||
let arrangement = HubArrangement(order: ["geloescht", "recent"])
|
||||
let identifiers = arrangement.arrangedIdentifiers(from: serverHubs)
|
||||
#expect(!identifiers.contains("geloescht"))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user