tv-anarchy/Tests/TVAnarchyCoreTests/LibraryConfigTests.swift

104 lines
4.4 KiB
Swift
Raw Permalink Normal View History

import XCTest
@testable import TVAnarchyCore
/// The configurable foldertype mapping, the editable type catalog, and the
/// derived adult-set. `LibraryConfig` is a process-global cache (written by
/// SettingsStore), so every test resets it to the defaults in tearDown so it
/// can't leak into HomeGatingTests or others.
final class LibraryConfigTests: XCTestCase {
private var tmp: URL!
private func reset(_ folderTypes: [String: String] = [:],
_ types: [LibraryType] = LibraryTypes.defaults) {
LibraryConfig.update(folderTypes: folderTypes, types: types)
}
override func setUpWithError() throws {
tmp = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
.appendingPathComponent("libcfg-\(UUID().uuidString)", isDirectory: true)
try FileManager.default.createDirectory(at: tmp, withIntermediateDirectories: true)
setenv("TV_ANARCHY_STATE_DIR", tmp.path, 1)
reset()
}
override func tearDownWithError() throws {
reset() // never leak a mapping/catalog into other suites
unsetenv("TV_ANARCHY_STATE_DIR")
try? FileManager.default.removeItem(at: tmp)
}
// MARK: catalog
func testDefaultCatalogLabelsAndAdultFlag() {
XCTAssertTrue(LibraryConfig.isAdultType("porn"))
XCTAssertFalse(LibraryConfig.isAdultType("tv"))
XCTAssertEqual(LibraryConfig.label("tv"), "TV")
XCTAssertEqual(LibraryConfig.label("custom"), "Custom") // capitalized fallback
}
func testSlug() {
XCTAssertEqual(LibraryTypes.slug("Music Videos"), "music-videos")
XCTAssertEqual(LibraryTypes.slug("Stand-Up!"), "stand-up")
}
// MARK: default (empty config) == old hardcoded behaviour
func testDefaultMatchesLegacyPornBehaviour() {
XCTAssertTrue(LibraryConfig.isAdult(category: "porn"))
XCTAssertFalse(LibraryConfig.isAdult(category: "tv"))
XCTAssertTrue(LibraryConfig.isAdult(path: "/bigdisk/_/media/porn/hentai/x.mp4"))
XCTAssertFalse(LibraryConfig.isAdult(path: "/Users/q/media/tv/Psych/S01E01.mkv"))
XCTAssertEqual(LibraryConfig.type(of: "tv"), "tv") // identity when unmapped
}
// MARK: mark an arbitrarily-named folder adult
func testMappingFolderToPornMakesItAdult() {
reset(["xxx": "porn", "kids": "cartoons"])
XCTAssertTrue(LibraryConfig.isAdult(category: "xxx"))
XCTAssertTrue(LibraryConfig.isAdult(path: "/media/xxx/clip.mp4"))
XCTAssertEqual(LibraryConfig.type(of: "xxx"), "porn")
XCTAssertEqual(LibraryConfig.type(of: "kids"), "cartoons")
XCTAssertFalse(LibraryConfig.isAdult(category: "kids"))
XCTAssertTrue(LibraryConfig.isAdult(category: "porn")) // literal porn still adult
}
func testRetypingPornFolderClearsAdult() {
reset(["porn": "movies"])
XCTAssertFalse(LibraryConfig.isAdult(category: "porn"))
XCTAssertFalse(LibraryConfig.isAdult(path: "/media/porn/x.mp4"))
XCTAssertEqual(LibraryConfig.type(of: "porn"), "movies")
}
// MARK: editable / expandable catalog
func testCustomAdultTypeDrivesGating() {
// Add a custom adult type and map a folder to it no "porn" involved.
var types = LibraryTypes.defaults
types.append(LibraryType(id: "fetish", label: "Fetish", adult: true))
reset(["dungeon": "fetish"], types)
XCTAssertTrue(LibraryConfig.isAdultType("fetish"))
XCTAssertEqual(LibraryConfig.label("fetish"), "Fetish")
XCTAssertTrue(LibraryConfig.isAdult(category: "dungeon"))
XCTAssertTrue(LibraryConfig.isAdult(path: "/media/dungeon/x.mp4"))
}
func testEmptyCatalogFallsBackToDefaults() {
reset([:], [])
XCTAssertEqual(LibraryConfig.types.map(\.id), LibraryTypes.defaults.map(\.id))
}
// MARK: the cache is owned by SettingsStore
func testSaveAndLoadSyncTheCache() {
var types = LibraryTypes.defaults
types.append(LibraryType(id: "asmr", label: "ASMR", adult: true))
SettingsStore.save(AppSettings(folderTypes: ["whispers": "asmr"], libraryTypes: types))
XCTAssertTrue(LibraryConfig.isAdult(category: "whispers"))
XCTAssertEqual(LibraryConfig.label("asmr"), "ASMR")
// load() re-syncs from disk (a fresh launch).
reset()
_ = SettingsStore.load()
XCTAssertTrue(LibraryConfig.isAdult(category: "whispers"))
}
}