tv-anarchy/Tests/TVAnarchyCoreTests/NowPlayingTests.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

72 lines
3.3 KiB
Swift

import XCTest
@testable import TVAnarchyCore
@MainActor
final class NowPlayingTests: XCTestCase {
// MARK: pure decisions
func testIsActivelyPlaying() {
XCTAssertTrue(NowPlayingController.isActivelyPlaying(
PlaybackStatus(playing: true, paused: false)))
XCTAssertFalse(NowPlayingController.isActivelyPlaying(
PlaybackStatus(playing: true, paused: true))) // paused not active
XCTAssertFalse(NowPlayingController.isActivelyPlaying(
PlaybackStatus(playing: false)))
// hosts that don't report `paused` (nil) count as playing when playing.
XCTAssertTrue(NowPlayingController.isActivelyPlaying(
PlaybackStatus(playing: true, paused: nil)))
}
func testCanStep() {
XCTAssertTrue(NowPlayingController.canStep(playlistCount: 5, isEnqueueable: false))
XCTAssertTrue(NowPlayingController.canStep(playlistCount: 1, isEnqueueable: true))
XCTAssertFalse(NowPlayingController.canStep(playlistCount: 1, isEnqueueable: false))
XCTAssertFalse(NowPlayingController.canStep(playlistCount: nil, isEnqueueable: false))
}
func testVolumeStepAndAdjust() {
XCTAssertEqual(NowPlayingController.volumeStep(scale: 125), 5)
XCTAssertEqual(NowPlayingController.adjustedVolume(current: 50, delta: 5, scale: 125), 55)
XCTAssertEqual(NowPlayingController.adjustedVolume(current: 2, delta: -5, scale: 125), 0)
XCTAssertEqual(NowPlayingController.adjustedVolume(current: 122, delta: 5, scale: 125), 125)
XCTAssertEqual(NowPlayingController.adjustedVolume(current: nil, delta: -5, scale: 125), 95)
}
// MARK: registration is idempotent + safe
func testEnableDisableIdempotent() {
let np = NowPlayingController()
XCTAssertFalse(np.isEnabled)
XCTAssertFalse(np.volumeKeysEnabled)
let h = NowPlayingController.Handlers(toggle: {}, play: {}, pause: {},
next: {}, previous: {}, seek: { _ in },
volumeUp: { false }, volumeDown: { false })
np.enable(h)
XCTAssertTrue(np.isEnabled)
XCTAssertTrue(np.volumeKeysEnabled)
np.enable(h) // second enable is a no-op
np.update(title: "Ep 1", posterPath: nil, position: 10, duration: 100,
playing: true, canStep: true) // must not crash
np.disable()
XCTAssertFalse(np.isEnabled)
XCTAssertFalse(np.volumeKeysEnabled)
np.disable() // second disable is a no-op
}
func testTransportAndVolumeIndependent() {
let np = NowPlayingController()
let h = NowPlayingController.Handlers(toggle: {}, play: {}, pause: {},
next: {}, previous: {}, seek: { _ in },
volumeUp: { false }, volumeDown: { false })
np.enableTransport(h)
XCTAssertTrue(np.isEnabled)
XCTAssertFalse(np.volumeKeysEnabled)
np.enableVolumeKeys(h)
XCTAssertTrue(np.volumeKeysEnabled)
np.disableVolumeKeys()
XCTAssertTrue(np.isEnabled)
XCTAssertFalse(np.volumeKeysEnabled)
np.disableTransport()
XCTAssertFalse(np.isEnabled)
}
}