feat(playlist): 歌单数据层 + 加入歌单入口
数据层: - PlaylistSummary(歌单名/歌曲数/封面),DB 用一条 SQL 取摘要, 封面取歌单内第一首有封面的歌 - PlaylistRepository.getSummaries() / addSongs()(批量加入并去重) - 修复 AudioService.playPlaylist:之前把文件路径直接当 URL, 歌单播放必然失败;现在用 WebDAVService.getFileUrl 构造 入口(视觉为临时实现,等设计稿替换): - 文件列表长按 -> "加入歌单" 底部弹层 - 可在弹层里新建歌单并直接加入 真机验证:长按歌曲 -> 新建 "TL" -> 数据库 playlists/playlist_songs 均有记录。 测试:新增 playlist_summary 4 个用例,累计 29 个全绿。
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
// test/playlist_summary_test.dart
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:qingting_player/models/playlist_summary.dart';
|
||||
|
||||
void main() {
|
||||
group('PlaylistSummary.fromRow', () {
|
||||
test('完整行解析', () {
|
||||
final s = PlaylistSummary.fromRow({
|
||||
'id': 'abc',
|
||||
'name': '随手',
|
||||
'song_count': 12,
|
||||
'cover_path': '/data/artworks/x.jpg',
|
||||
'updated_at': 1700000000,
|
||||
});
|
||||
expect(s.id, 'abc');
|
||||
expect(s.name, '随手');
|
||||
expect(s.songCount, 12);
|
||||
expect(s.coverPath, '/data/artworks/x.jpg');
|
||||
expect(s.isEmpty, isFalse);
|
||||
});
|
||||
|
||||
test('没有封面时 coverPath 为 null', () {
|
||||
final s = PlaylistSummary.fromRow({
|
||||
'id': 'abc',
|
||||
'name': '车用',
|
||||
'song_count': 3,
|
||||
'cover_path': '',
|
||||
});
|
||||
expect(s.coverPath, isNull);
|
||||
expect(s.songCount, 3);
|
||||
});
|
||||
|
||||
test('空歌单 isEmpty', () {
|
||||
final s = PlaylistSummary.fromRow({
|
||||
'id': 'x',
|
||||
'name': '空',
|
||||
'song_count': 0,
|
||||
});
|
||||
expect(s.isEmpty, isTrue);
|
||||
expect(s.coverPath, isNull);
|
||||
});
|
||||
|
||||
test('字段缺失时不崩', () {
|
||||
final s = PlaylistSummary.fromRow({});
|
||||
expect(s.id, '');
|
||||
expect(s.name, '');
|
||||
expect(s.songCount, 0);
|
||||
expect(s.isEmpty, isTrue);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user