You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
101 lines
4.2 KiB
101 lines
4.2 KiB
import Foundation
|
|
import Testing
|
|
import GRDB
|
|
@testable import Music
|
|
|
|
struct DatabaseServiceTests {
|
|
// Creates an in-memory DatabaseService, inserts a track, and fetches it back.
|
|
@Test func insertAndFetchTrack() throws {
|
|
let db = try DatabaseService(inMemory: true)
|
|
var track = Track.fixture(title: "Test Song", artist: "Test Artist")
|
|
try db.insert(&track)
|
|
|
|
let tracks = try db.fetchTracks(search: "", sortColumn: "title", ascending: true)
|
|
#expect(tracks.count == 1)
|
|
#expect(tracks[0].title == "Test Song")
|
|
}
|
|
|
|
// Inserts multiple tracks and verifies sorting by different columns.
|
|
@Test func fetchTracksSortedByArtist() throws {
|
|
let db = try DatabaseService(inMemory: true)
|
|
var t1 = Track.fixture(fileURL: "/a.mp3", title: "Zebra", artist: "Alpha")
|
|
var t2 = Track.fixture(fileURL: "/b.mp3", title: "Alpha", artist: "Zebra")
|
|
try db.insert(&t1)
|
|
try db.insert(&t2)
|
|
|
|
let ascending = try db.fetchTracks(search: "", sortColumn: "artist", ascending: true)
|
|
#expect(ascending[0].artist == "Alpha")
|
|
#expect(ascending[1].artist == "Zebra")
|
|
|
|
let descending = try db.fetchTracks(search: "", sortColumn: "artist", ascending: false)
|
|
#expect(descending[0].artist == "Zebra")
|
|
}
|
|
|
|
// Searches using FTS5 and verifies only matching tracks are returned.
|
|
@Test func fts5Search() throws {
|
|
let db = try DatabaseService(inMemory: true)
|
|
var t1 = Track.fixture(fileURL: "/a.mp3", title: "Bohemian Rhapsody", artist: "Queen")
|
|
var t2 = Track.fixture(fileURL: "/b.mp3", title: "Hotel California", artist: "Eagles")
|
|
var t3 = Track.fixture(fileURL: "/c.mp3", title: "Stairway to Heaven", artist: "Led Zeppelin")
|
|
try db.insert(&t1)
|
|
try db.insert(&t2)
|
|
try db.insert(&t3)
|
|
|
|
let results = try db.fetchTracks(search: "queen", sortColumn: "title", ascending: true)
|
|
#expect(results.count == 1)
|
|
#expect(results[0].title == "Bohemian Rhapsody")
|
|
}
|
|
|
|
// Searches with a prefix to verify autocomplete-style matching.
|
|
@Test func fts5PrefixSearch() throws {
|
|
let db = try DatabaseService(inMemory: true)
|
|
var t1 = Track.fixture(fileURL: "/a.mp3", title: "Bohemian Rhapsody", artist: "Queen")
|
|
var t2 = Track.fixture(fileURL: "/b.mp3", title: "Hotel California", artist: "Eagles")
|
|
try db.insert(&t1)
|
|
try db.insert(&t2)
|
|
|
|
let results = try db.fetchTracks(search: "boh", sortColumn: "title", ascending: true)
|
|
#expect(results.count == 1)
|
|
#expect(results[0].title == "Bohemian Rhapsody")
|
|
}
|
|
|
|
// Inserts a batch of tracks and verifies duplicates are silently ignored.
|
|
@Test func batchInsertIgnoresDuplicates() throws {
|
|
let db = try DatabaseService(inMemory: true)
|
|
let tracks = [
|
|
Track.fixture(fileURL: "/a.mp3", title: "Song A"),
|
|
Track.fixture(fileURL: "/b.mp3", title: "Song B"),
|
|
Track.fixture(fileURL: "/a.mp3", title: "Song A Duplicate"),
|
|
]
|
|
try db.insertBatch(tracks)
|
|
|
|
let all = try db.fetchTracks(search: "", sortColumn: "title", ascending: true)
|
|
#expect(all.count == 2)
|
|
}
|
|
|
|
// Updates play stats and verifies they persist.
|
|
@Test func updatePlayStats() throws {
|
|
let db = try DatabaseService(inMemory: true)
|
|
var track = Track.fixture()
|
|
try db.insert(&track)
|
|
|
|
let now = Date()
|
|
try db.updatePlayStats(trackId: track.id!, playCount: 5, lastPlayedAt: now)
|
|
|
|
let fetched = try db.fetchTracks(search: "", sortColumn: "title", ascending: true)
|
|
#expect(fetched[0].playCount == 5)
|
|
#expect(fetched[0].lastPlayedAt != nil)
|
|
}
|
|
|
|
// Validates that an invalid sort column falls back to "title".
|
|
@Test func invalidSortColumnFallsBackToTitle() throws {
|
|
let db = try DatabaseService(inMemory: true)
|
|
var t1 = Track.fixture(fileURL: "/a.mp3", title: "Zebra")
|
|
var t2 = Track.fixture(fileURL: "/b.mp3", title: "Alpha")
|
|
try db.insert(&t1)
|
|
try db.insert(&t2)
|
|
|
|
let result = try db.fetchTracks(search: "", sortColumn: "DROP TABLE tracks", ascending: true)
|
|
#expect(result[0].title == "Alpha")
|
|
}
|
|
}
|
|
|