luminate/Tests/LuminateCoreTests/JellyfinModelTests.swift

101 lines
4.2 KiB
Swift

//
// JellyfinModelTests.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 Testing
@testable import LuminateCore
/// Guards the wire spellings Luminate's domain enums promise the service layer.
///
/// These raw values are the entire contract between ``LuminateCore`` and the generated Jellyfin
/// client: mapping is a `rawValue` round trip, so a typo here silently drops data at runtime rather
/// than failing to compile.
@Suite struct JellyfinModelTests {
@Test("Media kind raw values match the server spellings")
func mediaKindRawValues() {
#expect(JellyfinMediaKind.movie.rawValue == "Movie")
#expect(JellyfinMediaKind.boxSet.rawValue == "BoxSet")
#expect(JellyfinMediaKind.collectionFolder.rawValue == "CollectionFolder")
#expect(JellyfinMediaKind(rawValue: "Episode") == .episode)
#expect(JellyfinMediaKind(rawValue: "MusicAlbum") == nil)
}
@Test("Collection type raw values are lowercase, as the server sends them")
func collectionTypeRawValues() {
#expect(JellyfinCollectionType(rawValue: "tvshows") == .tvShows)
#expect(JellyfinCollectionType(rawValue: "movies") == .movies)
#expect(JellyfinCollectionType(rawValue: "boxsets") == .boxSets)
#expect(JellyfinCollectionType(rawValue: "TvShows") == nil)
#expect(JellyfinCollectionType(rawValue: "music") == nil)
}
@Test("Sort field and item field keep their irregular server spellings")
func irregularRawValues() {
#expect(JellyfinSortField.defaultOrder.rawValue == "Default")
#expect(JellyfinSortField.airedEpisodeOrder.rawValue == "AiredEpisodeOrder")
#expect(JellyfinItemField.isHighDefinition.rawValue == "IsHD")
#expect(JellyfinItemField.providerIDs.rawValue == "ProviderIds")
#expect(JellyfinItemField.parentID.rawValue == "ParentId")
}
@Test("Image type and format raw values match the server spellings")
func imageRawValues() {
#expect(JellyfinImageType.primary.rawValue == "Primary")
#expect(JellyfinImageType.boxRear.rawValue == "BoxRear")
#expect(JellyfinImageFormat.jpg.rawValue == "Jpg")
#expect(JellyfinSortOrder.descending.rawValue == "Descending")
}
@Test("An empty query sends nothing, so the server applies its own defaults")
func emptyQueryIsFullyUnset() {
let query = JellyfinMediaQuery()
#expect(query.userID == nil)
#expect(query.parentID == nil)
#expect(query.includeItemKinds == nil)
#expect(query.sortBy == nil)
#expect(query.limit == nil)
#expect(query.recursive == nil)
#expect(query.enableImageTypes == nil)
}
@Test("Empty list options send nothing")
func emptyListOptionsAreFullyUnset() {
let options = JellyfinListOptions()
#expect(options.userID == nil)
#expect(options.parentID == nil)
#expect(options.seasonID == nil)
#expect(options.season == nil)
#expect(options.limit == nil)
#expect(options.fields == nil)
#expect(options.includeItemKinds == nil)
#expect(options.includeHidden == nil)
#expect(options.groupItems == nil)
}
@Test("Collection defaults are empty rather than nil")
func collectionDefaults() {
#expect(JellyfinMediaPage().items.isEmpty)
#expect(JellyfinMediaPage().totalRecordCount == nil)
#expect(JellyfinMediaItem().imageTags.isEmpty)
#expect(JellyfinMediaItem().backdropImageTags.isEmpty)
#expect(JellyfinLibrary().backdropImageTags.isEmpty)
}
}