refactor(web): sidebar app list to scroll area component (#33733)

This commit is contained in:
yyh
2026-03-19 14:33:55 +08:00
committed by GitHub
parent 942087cbdb
commit 79e5253410
7 changed files with 192 additions and 82 deletions

View File

@ -7,17 +7,21 @@
*/
import type { InstalledApp } from '@/models/explore'
import { fireEvent, render, screen, waitFor } from '@testing-library/react'
import Toast from '@/app/components/base/toast'
import SideBar from '@/app/components/explore/sidebar'
import { MediaType } from '@/hooks/use-breakpoints'
import { AppModeEnum } from '@/types/app'
const { mockToastAdd } = vi.hoisted(() => ({
mockToastAdd: vi.fn(),
}))
let mockMediaType: string = MediaType.pc
const mockSegments = ['apps']
const mockPush = vi.fn()
const mockUninstall = vi.fn()
const mockUpdatePinStatus = vi.fn()
let mockInstalledApps: InstalledApp[] = []
let mockIsUninstallPending = false
vi.mock('@/next/navigation', () => ({
useSelectedLayoutSegments: () => mockSegments,
@ -42,12 +46,22 @@ vi.mock('@/service/use-explore', () => ({
}),
useUninstallApp: () => ({
mutateAsync: mockUninstall,
isPending: mockIsUninstallPending,
}),
useUpdateAppPinStatus: () => ({
mutateAsync: mockUpdatePinStatus,
}),
}))
vi.mock('@/app/components/base/ui/toast', () => ({
toast: {
add: mockToastAdd,
close: vi.fn(),
update: vi.fn(),
promise: vi.fn(),
},
}))
const createInstalledApp = (overrides: Partial<InstalledApp> = {}): InstalledApp => ({
id: overrides.id ?? 'app-1',
uninstallable: overrides.uninstallable ?? false,
@ -74,7 +88,7 @@ describe('Sidebar Lifecycle Flow', () => {
vi.clearAllMocks()
mockMediaType = MediaType.pc
mockInstalledApps = []
vi.spyOn(Toast, 'notify').mockImplementation(() => ({ clear: vi.fn() }))
mockIsUninstallPending = false
})
describe('Pin / Unpin / Delete Flow', () => {
@ -91,7 +105,7 @@ describe('Sidebar Lifecycle Flow', () => {
await waitFor(() => {
expect(mockUpdatePinStatus).toHaveBeenCalledWith({ appId: 'app-1', isPinned: true })
expect(Toast.notify).toHaveBeenCalledWith(expect.objectContaining({
expect(mockToastAdd).toHaveBeenCalledWith(expect.objectContaining({
type: 'success',
}))
})
@ -110,7 +124,7 @@ describe('Sidebar Lifecycle Flow', () => {
await waitFor(() => {
expect(mockUpdatePinStatus).toHaveBeenCalledWith({ appId: 'app-1', isPinned: false })
expect(Toast.notify).toHaveBeenCalledWith(expect.objectContaining({
expect(mockToastAdd).toHaveBeenCalledWith(expect.objectContaining({
type: 'success',
}))
})
@ -136,9 +150,9 @@ describe('Sidebar Lifecycle Flow', () => {
// Step 4: Uninstall API called and success toast shown
await waitFor(() => {
expect(mockUninstall).toHaveBeenCalledWith('app-1')
expect(Toast.notify).toHaveBeenCalledWith(expect.objectContaining({
expect(mockToastAdd).toHaveBeenCalledWith(expect.objectContaining({
type: 'success',
message: 'common.api.remove',
title: 'common.api.remove',
}))
})
})