Fiel der Server aus, endete der Start bei einem Fehlerbildschirm mit zwei Knöpfen: „Erneut versuchen" und „Abmelden". Beide nützen im Flugzeug nichts — und dahinter lagen die Dateien, die man genau für diesen Fall heruntergeladen hatte. Jetzt geht die App trotzdem auf: Token und Konto liegen auf dem Gerät, die Mediathekenliste auch, und die Startseite kommt neuerdings aus demselben Speicher. Oben die Downloads, darunter der Stand vom letzten Mal, ausgegraut, mit einem Satz, der sagt warum. Die Detailseite nimmt den Titel vom Gerät, wenn der Server schweigt, und der Abspielknopf bleibt an, weil die Datei ja da ist. Und was man offline geschaut hat, zählt: Fortschritt, den der Server nicht annimmt, wird zurückgelegt und nachgereicht, sobald er wieder antwortet. Dafür sagt `reportProgress` jetzt, ob die Meldung ankam. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
118 lines
3.8 KiB
Swift
118 lines
3.8 KiB
Swift
import Foundation
|
|
import Testing
|
|
@testable import MediaKit
|
|
|
|
/// Ein Server, der auf Ansage annimmt oder nicht.
|
|
private final class Briefkasten: Fortschrittsempfaenger, @unchecked Sendable {
|
|
nonisolated let identity: String
|
|
/// Ob Meldungen angenommen werden.
|
|
var nimmtAn: Bool
|
|
private(set) var angekommen: [PlaybackReport] = []
|
|
|
|
init(identity: String = "server-a", nimmtAn: Bool = true) {
|
|
self.identity = identity
|
|
self.nimmtAn = nimmtAn
|
|
}
|
|
|
|
func reportProgress(_ report: PlaybackReport) async -> Bool {
|
|
guard nimmtAn else { return false }
|
|
angekommen.append(report)
|
|
return true
|
|
}
|
|
}
|
|
|
|
private func bericht(_ titel: String, sekunden: Double) -> PlaybackReport {
|
|
PlaybackReport(
|
|
itemID: titel,
|
|
state: .stopped,
|
|
time: .seconds(sekunden),
|
|
duration: .seconds(3600)
|
|
)
|
|
}
|
|
|
|
@Suite("Nachgereichter Fortschritt")
|
|
@MainActor
|
|
struct FortschrittspostTests {
|
|
/// Eine eigene Datei je Prüfung — sonst sähe die zweite, was die erste
|
|
/// liegen gelassen hat.
|
|
private func ablage() -> URL {
|
|
FileManager.default.temporaryDirectory
|
|
.appending(path: "post-\(UUID().uuidString).json")
|
|
}
|
|
|
|
@Test("Was ankam, wird nicht aufgehoben")
|
|
func nichtsLiegenLassen() async {
|
|
let post = Fortschrittspost(ablage: ablage())
|
|
let server = Briefkasten()
|
|
|
|
post.zuruecklegen(bericht("film", sekunden: 600), server: server.identity)
|
|
#expect(post.wartend == 1)
|
|
|
|
await post.zustellen(über: server)
|
|
#expect(post.wartend == 0)
|
|
#expect(server.angekommen.count == 1)
|
|
#expect(server.angekommen.first?.itemID == "film")
|
|
}
|
|
|
|
@Test("Was nicht ankommt, bleibt liegen")
|
|
func liegenbleiben() async {
|
|
let post = Fortschrittspost(ablage: ablage())
|
|
let server = Briefkasten(nimmtAn: false)
|
|
|
|
post.zuruecklegen(bericht("film", sekunden: 600), server: server.identity)
|
|
await post.zustellen(über: server)
|
|
#expect(post.wartend == 1)
|
|
|
|
server.nimmtAn = true
|
|
await post.zustellen(über: server)
|
|
#expect(post.wartend == 0)
|
|
}
|
|
|
|
@Test("Je Titel nur der letzte Stand")
|
|
func nurDerLetzteStand() async {
|
|
let post = Fortschrittspost(ablage: ablage())
|
|
let server = Briefkasten()
|
|
|
|
post.zuruecklegen(bericht("film", sekunden: 60), server: server.identity)
|
|
post.zuruecklegen(bericht("film", sekunden: 1800), server: server.identity)
|
|
#expect(post.wartend == 1)
|
|
|
|
await post.zustellen(über: server)
|
|
#expect(server.angekommen.count == 1)
|
|
#expect(server.angekommen.first?.time == .seconds(1800))
|
|
}
|
|
|
|
@Test("Ein fremder Server bekommt nichts")
|
|
func nichtAnDenFalschen() async {
|
|
let post = Fortschrittspost(ablage: ablage())
|
|
post.zuruecklegen(bericht("film", sekunden: 600), server: "server-a")
|
|
|
|
let anderer = Briefkasten(identity: "server-b")
|
|
await post.zustellen(über: anderer)
|
|
#expect(anderer.angekommen.isEmpty)
|
|
#expect(post.wartend == 1)
|
|
}
|
|
|
|
@Test("Der Briefkasten überlebt den Neustart")
|
|
func aufDerPlatte() async {
|
|
let datei = ablage()
|
|
let erste = Fortschrittspost(ablage: datei)
|
|
erste.zuruecklegen(bericht("folge", sekunden: 900), server: "server-a")
|
|
|
|
let zweite = Fortschrittspost(ablage: datei)
|
|
#expect(zweite.wartend == 1)
|
|
|
|
let server = Briefkasten()
|
|
await zweite.zustellen(über: server)
|
|
#expect(server.angekommen.first?.time == .seconds(900))
|
|
}
|
|
|
|
@Test("Leeren wirft alles weg")
|
|
func leeren() async {
|
|
let post = Fortschrittspost(ablage: ablage())
|
|
post.zuruecklegen(bericht("film", sekunden: 600), server: "server-a")
|
|
post.leeren()
|
|
#expect(post.wartend == 0)
|
|
}
|
|
}
|