104 lines
4.6 KiB
Swift
104 lines
4.6 KiB
Swift
//
|
|
// ClientEnvironmentKeyTests.swift
|
|
//
|
|
// Copyright 2026 Brendan Szymanski <hello@bscubed.dev>
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
//
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
//
|
|
|
|
import Foundation
|
|
import LuminateCore
|
|
@_spi(Portico) import Portico
|
|
import Testing
|
|
|
|
@testable import LuminateUI
|
|
|
|
/// A ``JellyfinService`` that exists only to be told apart from the default.
|
|
private final class StubJellyfinService: JellyfinService {
|
|
var isAuthenticated: Bool { true }
|
|
|
|
func publicServerInfo() async throws -> JellyfinServerInfo { JellyfinServerInfo() }
|
|
func serverInfo() async throws -> JellyfinServerInfo { JellyfinServerInfo() }
|
|
func publicUsers() async throws -> [JellyfinUser] { [] }
|
|
func currentUser() async throws -> JellyfinUser { JellyfinUser() }
|
|
func authenticate(username: String, password: String) async throws -> JellyfinAuthentication {
|
|
JellyfinAuthentication(accessToken: "stub")
|
|
}
|
|
func quickConnectEnabled() async throws -> Bool { false }
|
|
func initiateQuickConnect() async throws -> JellyfinQuickConnectState { JellyfinQuickConnectState() }
|
|
func quickConnectState(secret: String) async throws -> JellyfinQuickConnectState { JellyfinQuickConnectState() }
|
|
func authenticateWithQuickConnect(secret: String) async throws -> JellyfinAuthentication {
|
|
JellyfinAuthentication(accessToken: "stub")
|
|
}
|
|
func updateUserPassword(
|
|
userID: String?,
|
|
currentPassword: String?,
|
|
currentPIN: String?,
|
|
newPassword: String?,
|
|
resetPassword: Bool?
|
|
) async throws {}
|
|
func libraries(_ options: JellyfinListOptions) async throws -> [JellyfinLibrary] { [] }
|
|
func items(_ query: JellyfinMediaQuery) async throws -> JellyfinMediaPage { JellyfinMediaPage() }
|
|
func item(id: String, userID: String?) async throws -> JellyfinMediaItem { JellyfinMediaItem() }
|
|
func resumeItems(_ options: JellyfinListOptions) async throws -> JellyfinMediaPage { JellyfinMediaPage() }
|
|
func nextUp(seriesID: String?, options: JellyfinListOptions) async throws -> JellyfinMediaPage {
|
|
JellyfinMediaPage()
|
|
}
|
|
func latestMedia(_ options: JellyfinListOptions) async throws -> [JellyfinMediaItem] { [] }
|
|
func seasons(seriesID: String, options: JellyfinListOptions) async throws -> JellyfinMediaPage {
|
|
JellyfinMediaPage()
|
|
}
|
|
func episodes(seriesID: String, options: JellyfinListOptions) async throws -> JellyfinMediaPage {
|
|
JellyfinMediaPage()
|
|
}
|
|
func searchHints(term: String, options: JellyfinListOptions) async throws -> [JellyfinSearchHint] { [] }
|
|
func image(
|
|
itemID: String,
|
|
type: JellyfinImageType,
|
|
index: Int32?,
|
|
request: JellyfinImageRequest
|
|
) async throws -> Data {
|
|
Data()
|
|
}
|
|
func markPlayed(itemID: String, userID: String?, datePlayed: Date?) async throws -> JellyfinUserData {
|
|
JellyfinUserData()
|
|
}
|
|
func markUnplayed(itemID: String, userID: String?) async throws -> JellyfinUserData { JellyfinUserData() }
|
|
func markFavorite(itemID: String, userID: String?) async throws -> JellyfinUserData { JellyfinUserData() }
|
|
func unmarkFavorite(itemID: String, userID: String?) async throws -> JellyfinUserData { JellyfinUserData() }
|
|
}
|
|
|
|
/// Guards the `\\.client` environment slot itself.
|
|
///
|
|
/// No widgets are constructed, so these run on a headless machine without `Gtk.initCheck()`.
|
|
@MainActor @Suite struct ClientEnvironmentKeyTests {
|
|
@Test("An unresolved slot falls back to the unconfigured service")
|
|
func defaultIsUnconfigured() {
|
|
#expect(EnvironmentValues().client is UnconfiguredJellyfinService)
|
|
}
|
|
|
|
@Test("The key path routes through the environment subscript")
|
|
func keyPathResolvesToABox() {
|
|
#expect(EnvironmentValues()._box(for: \.client) != nil)
|
|
}
|
|
|
|
@Test("An injected service replaces the default")
|
|
func injectionOverridesDefault() {
|
|
var values = EnvironmentValues()
|
|
values.client = StubJellyfinService()
|
|
#expect(values.client is StubJellyfinService)
|
|
}
|
|
}
|