Files
MobileMusicAssistant/MobileMusicAssistantTests/MALibraryManagerTests.swift
T
2026-04-20 11:10:53 +02:00

150 lines
5.0 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import Testing
import Foundation
@testable import Mobile_Music_Assistant
// MARK: - Pagination Threshold
@Suite("MALibraryManager Pagination Threshold")
struct PaginationThresholdTests {
/// Replicates the "load more if needed" threshold logic.
/// Returns true if a load should be triggered for the given currentIndex.
private func shouldLoadMore(currentIndex: Int, totalLoaded: Int, threshold: Int = 10) -> Bool {
guard totalLoaded > 0 else { return false }
return currentIndex >= totalLoaded - threshold
}
@Test("Triggers load when item is within 10 of the end")
func triggersNearEnd() {
#expect(shouldLoadMore(currentIndex: 91, totalLoaded: 100))
#expect(shouldLoadMore(currentIndex: 95, totalLoaded: 100))
#expect(shouldLoadMore(currentIndex: 99, totalLoaded: 100))
}
@Test("Does not trigger load when item is far from the end")
func noTriggerFarFromEnd() {
#expect(!shouldLoadMore(currentIndex: 50, totalLoaded: 100))
#expect(!shouldLoadMore(currentIndex: 0, totalLoaded: 100))
#expect(!shouldLoadMore(currentIndex: 89, totalLoaded: 100))
}
@Test("Boundary: triggers exactly at threshold position")
func triggersAtExactThreshold() {
// With 100 items and threshold 10, position 90 is the boundary (100 - 10 = 90)
#expect(shouldLoadMore(currentIndex: 90, totalLoaded: 100))
#expect(!shouldLoadMore(currentIndex: 89, totalLoaded: 100))
}
@Test("Does not trigger with empty list")
func noTriggerWithEmptyList() {
#expect(!shouldLoadMore(currentIndex: 0, totalLoaded: 0))
}
@Test("Always triggers with a single-item list")
func alwaysTriggersForSingleItem() {
#expect(shouldLoadMore(currentIndex: 0, totalLoaded: 1))
}
}
// MARK: - Page hasMore Detection
@Suite("MALibraryManager hasMore Detection")
struct HasMoreDetectionTests {
/// Returns false (no more pages) if returned count < pageSize.
private func hasMorePages(returned: Int, pageSize: Int) -> Bool {
returned >= pageSize
}
@Test("No more pages when returned count equals pageSize")
func exactPageSizeHasMore() {
#expect(hasMorePages(returned: 50, pageSize: 50))
}
@Test("No more pages when returned count is less than pageSize")
func partialPageMeansNoMore() {
#expect(!hasMorePages(returned: 25, pageSize: 50))
#expect(!hasMorePages(returned: 0, pageSize: 50))
#expect(!hasMorePages(returned: 49, pageSize: 50))
}
@Test("Has more pages when returned count is greater than pageSize (e.g. over-fetch)")
func overFetchHasMore() {
#expect(hasMorePages(returned: 51, pageSize: 50))
}
}
// MARK: - Favorite URI Collection
@Suite("MALibraryManager Favorite URI Collection")
struct FavoriteURICollectionTests {
@Test("Collects URIs of items marked as favorite")
func collectsFavoriteURIs() throws {
let items: [MAMediaItem] = try [
"""{"uri":"spotify://1","name":"A","favorite":true}""",
"""{"uri":"spotify://2","name":"B","favorite":false}""",
"""{"uri":"spotify://3","name":"C","favorite":true}""",
].map {
try JSONDecoder().decode(MAMediaItem.self, from: Data($0.utf8))
}
let favorites = Set(items.filter(\.favorite).map(\.uri))
#expect(favorites == Set(["spotify://1", "spotify://3"]))
}
@Test("Returns empty set when no items are favorite")
func emptyWhenNoFavorites() throws {
let items: [MAMediaItem] = try [
"""{"uri":"x://1","name":"A","favorite":false}""",
"""{"uri":"x://2","name":"B"}""",
].map {
try JSONDecoder().decode(MAMediaItem.self, from: Data($0.utf8))
}
let favorites = Set(items.filter(\.favorite).map(\.uri))
#expect(favorites.isEmpty)
}
@Test("isFavorite check on MALibraryManager respects favoriteURIs set")
func isFavoriteCheck() {
let manager = MALibraryManager()
// Initially no favorites
#expect(manager.isFavorite(uri: "spotify://track/1") == false)
}
}
// MARK: - MALibraryManager Initial State
@Suite("MALibraryManager Initial State")
struct LibraryManagerInitialStateTests {
@Test("Artists collection starts empty")
func artistsStartEmpty() {
#expect(MALibraryManager().artists.isEmpty)
}
@Test("Albums collection starts empty")
func albumsStartEmpty() {
#expect(MALibraryManager().albums.isEmpty)
}
@Test("Playlists collection starts empty")
func playlistsStartEmpty() {
#expect(MALibraryManager().playlists.isEmpty)
}
@Test("Loading flags start as false")
func loadingFlagsStartFalse() {
let m = MALibraryManager()
#expect(m.isLoadingArtists == false)
#expect(m.isLoadingAlbums == false)
#expect(m.isLoadingPlaylists == false)
}
@Test("favoriteURIs starts empty")
func favoriteURIsStartEmpty() {
#expect(MALibraryManager().favoriteURIs.isEmpty)
}
}