tv-anarchy/Tests/TVAnarchyCoreTests/MediaKeyForwardingTests.swift
Natalie 4a2ceb9781 feat(offline): inline star-to-keep and trash-to-cull on cache rows
Surface the existing pin (keep-from-cull) and per-file delete actions as
visible inline buttons on each offline cache row instead of context-menu-only:
a star toggles protection from auto-cull (and restore-if-missing), a trash
culls that file early. Aligns wording/icons to the star metaphor.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 00:12:41 -04:00

138 lines
No EOL
5.3 KiB
Swift

import XCTest
@testable import TVAnarchyCore
/// Integration coverage for `PlayerController.applyMediaKeyForwarding()` each
/// persisted setting should register only its half of `NowPlayingController`.
@MainActor
final class MediaKeyForwardingTests: XCTestCase {
private var tmp: URL!
override func setUpWithError() throws {
tmp = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
.appendingPathComponent("media-keys-\(UUID().uuidString)", isDirectory: true)
try FileManager.default.createDirectory(at: tmp, withIntermediateDirectories: true)
setenv("TV_ANARCHY_STATE_DIR", tmp.path, 1)
}
override func tearDownWithError() throws {
unsetenv("TV_ANARCHY_STATE_DIR")
try? FileManager.default.removeItem(at: tmp)
}
private func makeStack() -> (PlayerController, LibraryController) {
let library = LibraryController(watchHistory: WatchHistoryController())
let player = PlayerController()
player.attach(library: library)
let pl = PlaylistController(library: library)
player.attach(playlist: pl)
return (player, library)
}
private func saveSettings(forwardMediaKeys: Bool, forwardVolumeKeys: Bool) {
var s = SettingsStore.load()
s.forwardMediaKeys = forwardMediaKeys
s.forwardVolumeKeys = forwardVolumeKeys
SettingsStore.save(s)
}
// MARK: settings matrix
func testApplyBothOnByDefault() {
let (player, _) = makeStack()
player.applyMediaKeyForwarding()
XCTAssertEqual(player.mediaKeyForwardingState.transport, true)
XCTAssertEqual(player.mediaKeyForwardingState.volume, true)
}
func testApplyTransportOnly() {
saveSettings(forwardMediaKeys: true, forwardVolumeKeys: false)
let (player, _) = makeStack()
player.applyMediaKeyForwarding()
XCTAssertEqual(player.mediaKeyForwardingState.transport, true)
XCTAssertEqual(player.mediaKeyForwardingState.volume, false)
}
func testApplyVolumeOnly() {
saveSettings(forwardMediaKeys: false, forwardVolumeKeys: true)
let (player, _) = makeStack()
player.applyMediaKeyForwarding()
XCTAssertEqual(player.mediaKeyForwardingState.transport, false)
XCTAssertEqual(player.mediaKeyForwardingState.volume, true)
}
func testApplyBothOff() {
saveSettings(forwardMediaKeys: false, forwardVolumeKeys: false)
let (player, _) = makeStack()
player.applyMediaKeyForwarding()
XCTAssertEqual(player.mediaKeyForwardingState.transport, false)
XCTAssertEqual(player.mediaKeyForwardingState.volume, false)
}
// MARK: live toggles (DeviceView path)
func testDisableVolumeLeavesTransportRegistered() {
let (player, library) = makeStack()
player.applyMediaKeyForwarding()
library.forwardVolumeKeys = false
player.applyMediaKeyForwarding()
XCTAssertEqual(player.mediaKeyForwardingState.transport, true)
XCTAssertEqual(player.mediaKeyForwardingState.volume, false)
}
func testDisableTransportLeavesVolumeRegistered() {
let (player, library) = makeStack()
player.applyMediaKeyForwarding()
library.forwardMediaKeys = false
player.applyMediaKeyForwarding()
XCTAssertEqual(player.mediaKeyForwardingState.transport, false)
XCTAssertEqual(player.mediaKeyForwardingState.volume, true)
}
func testReenableVolumeAfterTransportStillOn() {
let (player, library) = makeStack()
player.applyMediaKeyForwarding()
library.forwardVolumeKeys = false
player.applyMediaKeyForwarding()
XCTAssertFalse(player.mediaKeyForwardingState.volume)
library.forwardVolumeKeys = true
player.applyMediaKeyForwarding()
XCTAssertTrue(player.mediaKeyForwardingState.transport)
XCTAssertTrue(player.mediaKeyForwardingState.volume)
}
// MARK: AppLocalAPI patch path
func testAppLocalAPIPatchReconfiguresIndependently() throws {
let library = LibraryController(watchHistory: WatchHistoryController())
let player = PlayerController()
player.attach(library: library)
let pl = PlaylistController(library: library)
player.attach(playlist: pl)
let offline = OfflineCacheController(library: library)
let playlist = PlaylistController(library: library)
let api = AppLocalAPI()
api.attach(offline: offline, player: player, library: library, playlist: playlist)
player.applyMediaKeyForwarding()
XCTAssertTrue(player.mediaKeyForwardingState.transport)
XCTAssertTrue(player.mediaKeyForwardingState.volume)
_ = try api.patchSettings(Data(#"{"forwardVolumeKeys":false}"#.utf8))
XCTAssertTrue(player.mediaKeyForwardingState.transport)
XCTAssertFalse(player.mediaKeyForwardingState.volume)
_ = try api.patchSettings(Data(#"{"forwardMediaKeys":false}"#.utf8))
XCTAssertFalse(player.mediaKeyForwardingState.transport)
XCTAssertFalse(player.mediaKeyForwardingState.volume)
_ = try api.patchSettings(Data(#"{"forwardVolumeKeys":true}"#.utf8))
XCTAssertFalse(player.mediaKeyForwardingState.transport)
XCTAssertTrue(player.mediaKeyForwardingState.volume)
}
}