Skip to content

Commit 8f38c83

Browse files
committed
fix: address user center review feedback
1 parent b306aa2 commit 8f38c83

8 files changed

Lines changed: 103 additions & 3 deletions

File tree

src/components/user/AlbumDetailPanel.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ const emit = defineEmits<{
7171
</div>
7272

7373
<SongDetailList
74+
v-else-if="!props.loading && props.songs.length > 0"
7475
:songs="props.songs"
7576
:fallback-cover="props.album?.picUrl ?? ''"
7677
@play-song="emit('play-song', $event)"

src/components/user/PlaylistDetailPanel.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,11 @@ const emit = defineEmits<{
6060
<p>当前歌单暂无可播放歌曲。</p>
6161
</div>
6262

63-
<SongDetailList :songs="props.songs" @play-song="emit('play-song', $event)" />
63+
<SongDetailList
64+
v-else-if="!props.loading && props.songs.length > 0"
65+
:songs="props.songs"
66+
@play-song="emit('play-song', $event)"
67+
/>
6468
</section>
6569
</template>
6670

src/composables/useFavoriteAlbums.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ export function useFavoriteAlbums(): UseFavoriteAlbumsReturn {
269269
.filter((track): track is Song => Boolean(track))
270270
} catch (requestError) {
271271
console.error('Failed to load album detail:', requestError)
272-
return []
272+
throw requestError
273273
}
274274
}
275275

src/composables/useUserPlaylists.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ export function useUserPlaylists(): UseUserPlaylistsReturn {
213213
.filter((track): track is Song => Boolean(track))
214214
} catch (requestError) {
215215
console.error('Failed to load playlist detail:', requestError)
216-
return []
216+
throw requestError
217217
}
218218
}
219219

tests/components/user/AlbumDetailPanel.test.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,42 @@ describe('AlbumDetailPanel', () => {
3232
const cover = wrapper.get('img.detail-song-cover')
3333
expect(cover.attributes('src')).toBe('album-cover.jpg')
3434
})
35+
36+
it('does not render stale song rows while the next album detail is loading', () => {
37+
const wrapper = mount(AlbumDetailPanel, {
38+
props: {
39+
album: {
40+
id: 'album-1',
41+
name: 'Album 1',
42+
picUrl: 'album-cover.jpg',
43+
size: 1,
44+
artistName: 'Artist 1'
45+
},
46+
songs: [createMockSong({ id: 'song-1', name: 'Stale Song' })],
47+
loading: true
48+
}
49+
})
50+
51+
expect(wrapper.text()).toContain('专辑详情加载中...')
52+
expect(wrapper.find('.detail-song').exists()).toBe(false)
53+
})
54+
55+
it('does not render stale song rows when detail loading fails', () => {
56+
const wrapper = mount(AlbumDetailPanel, {
57+
props: {
58+
album: {
59+
id: 'album-1',
60+
name: 'Album 1',
61+
picUrl: 'album-cover.jpg',
62+
size: 1,
63+
artistName: 'Artist 1'
64+
},
65+
songs: [createMockSong({ id: 'song-1', name: 'Stale Song' })],
66+
error: new Error('load failed')
67+
}
68+
})
69+
70+
expect(wrapper.text()).toContain('专辑详情加载失败')
71+
expect(wrapper.find('.detail-song').exists()).toBe(false)
72+
})
3573
})
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { mount } from '@vue/test-utils'
2+
import { describe, expect, it } from 'vitest'
3+
4+
import PlaylistDetailPanel from '@/components/user/PlaylistDetailPanel.vue'
5+
import { createMockSong } from '../../utils/test-utils'
6+
7+
describe('PlaylistDetailPanel', () => {
8+
it('does not render stale song rows while the next playlist detail is loading', () => {
9+
const wrapper = mount(PlaylistDetailPanel, {
10+
props: {
11+
playlist: {
12+
id: 'playlist-1',
13+
name: 'Playlist 1',
14+
trackCount: 10
15+
},
16+
songs: [createMockSong({ id: 'song-1', name: 'Stale Song' })],
17+
loading: true
18+
}
19+
})
20+
21+
expect(wrapper.text()).toContain('歌单详情加载中...')
22+
expect(wrapper.find('.detail-song').exists()).toBe(false)
23+
})
24+
25+
it('does not render stale song rows when detail loading fails', () => {
26+
const wrapper = mount(PlaylistDetailPanel, {
27+
props: {
28+
playlist: {
29+
id: 'playlist-1',
30+
name: 'Playlist 1',
31+
trackCount: 10
32+
},
33+
songs: [createMockSong({ id: 'song-1', name: 'Stale Song' })],
34+
error: new Error('load failed')
35+
}
36+
})
37+
38+
expect(wrapper.text()).toContain('歌单详情加载失败')
39+
expect(wrapper.find('.detail-song').exists()).toBe(false)
40+
})
41+
})

tests/composables/useFavoriteAlbums.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,4 +144,12 @@ describe('useFavoriteAlbums', () => {
144144
platform: 'netease'
145145
})
146146
})
147+
148+
it('surfaces album detail failures instead of silently returning an empty song list', async () => {
149+
getAlbumDetailMock.mockRejectedValue(new Error('album detail failed'))
150+
151+
const viewModel = mountUseFavoriteAlbums()
152+
153+
await expect(viewModel.loadAlbumSongs(88)).rejects.toThrow('album detail failed')
154+
})
147155
})

tests/composables/useUserPlaylists.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,4 +141,12 @@ describe('useUserPlaylists', () => {
141141
])
142142
expect(viewModel.count.value).toBe(1)
143143
})
144+
145+
it('surfaces playlist detail failures instead of silently returning an empty song list', async () => {
146+
getPlaylistTracksMock.mockRejectedValue(new Error('playlist detail failed'))
147+
148+
const viewModel = mountUseUserPlaylists()
149+
150+
await expect(viewModel.loadPlaylistSongs(3)).rejects.toThrow('playlist detail failed')
151+
})
144152
})

0 commit comments

Comments
 (0)