Unit tests und nudging screen

This commit is contained in:
2026-04-20 11:10:53 +02:00
parent e1aebdb916
commit 3858500a45
8 changed files with 1223 additions and 0 deletions
@@ -0,0 +1,149 @@
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)
}
}