fix: type error

This commit is contained in:
imeepos
2026-01-29 18:46:34 +08:00
parent 5a4d1ac1bd
commit 8f33ade8df
13 changed files with 102 additions and 163 deletions

View File

@@ -1,14 +1,7 @@
import { renderHook, act } from '@testing-library/react-native'
import { useDownloadMedia } from './use-download-media'
import * as FileSystem from 'expo-file-system'
import * as MediaLibrary from 'expo-media-library'
jest.mock('expo-file-system', () => ({
documentDirectory: 'file:///mock/document/',
createDownloadResumable: jest.fn(),
deleteAsync: jest.fn(),
}))
jest.mock('expo-media-library', () => ({
requestPermissionsAsync: jest.fn(),
saveToLibraryAsync: jest.fn(),
@@ -56,13 +49,7 @@ describe('useDownloadMedia', () => {
;(MediaLibrary.requestPermissionsAsync as jest.Mock).mockResolvedValue({
status: 'granted',
})
const mockDownloadAsync = jest.fn().mockResolvedValue({ uri: 'file:///mock/document/download_123.jpg' })
;(FileSystem.createDownloadResumable as jest.Mock).mockReturnValue({
downloadAsync: mockDownloadAsync,
})
;(MediaLibrary.saveToLibraryAsync as jest.Mock).mockResolvedValue(undefined)
;(FileSystem.deleteAsync as jest.Mock).mockResolvedValue(undefined)
const { result } = renderHook(() => useDownloadMedia())
@@ -84,12 +71,7 @@ describe('useDownloadMedia', () => {
})
it('should download image successfully', async () => {
const mockDownloadAsync = jest.fn().mockResolvedValue({ uri: 'file:///mock/document/download_123.jpg' })
;(FileSystem.createDownloadResumable as jest.Mock).mockReturnValue({
downloadAsync: mockDownloadAsync,
})
;(MediaLibrary.saveToLibraryAsync as jest.Mock).mockResolvedValue(undefined)
;(FileSystem.deleteAsync as jest.Mock).mockResolvedValue(undefined)
const { result } = renderHook(() => useDownloadMedia())
@@ -99,26 +81,11 @@ describe('useDownloadMedia', () => {
})
expect(response).toEqual({ success: true })
expect(FileSystem.createDownloadResumable).toHaveBeenCalledWith(
'https://example.com/image.jpg',
expect.stringMatching(/^file:\/\/\/mock\/document\/download_\d+\.jpg$/),
{},
expect.any(Function)
)
expect(MediaLibrary.saveToLibraryAsync).toHaveBeenCalled()
expect(FileSystem.deleteAsync).toHaveBeenCalledWith(
expect.stringMatching(/^file:\/\/\/mock\/document\/download_\d+\.jpg$/),
{ idempotent: true }
)
expect(MediaLibrary.saveToLibraryAsync).toHaveBeenCalledWith('https://example.com/image.jpg')
})
it('should download video successfully', async () => {
const mockDownloadAsync = jest.fn().mockResolvedValue({ uri: 'file:///mock/document/download_123.mp4' })
;(FileSystem.createDownloadResumable as jest.Mock).mockReturnValue({
downloadAsync: mockDownloadAsync,
})
;(MediaLibrary.saveToLibraryAsync as jest.Mock).mockResolvedValue(undefined)
;(FileSystem.deleteAsync as jest.Mock).mockResolvedValue(undefined)
const { result } = renderHook(() => useDownloadMedia())
@@ -128,19 +95,11 @@ describe('useDownloadMedia', () => {
})
expect(response).toEqual({ success: true })
expect(FileSystem.createDownloadResumable).toHaveBeenCalledWith(
'https://example.com/video.mp4',
expect.stringMatching(/^file:\/\/\/mock\/document\/download_\d+\.mp4$/),
{},
expect.any(Function)
)
expect(MediaLibrary.saveToLibraryAsync).toHaveBeenCalledWith('https://example.com/video.mp4')
})
it('should handle download failure', async () => {
const mockDownloadAsync = jest.fn().mockRejectedValue(new Error('Network error'))
;(FileSystem.createDownloadResumable as jest.Mock).mockReturnValue({
downloadAsync: mockDownloadAsync,
})
;(MediaLibrary.saveToLibraryAsync as jest.Mock).mockRejectedValue(new Error('Network error'))
const { result } = renderHook(() => useDownloadMedia())
@@ -154,12 +113,7 @@ describe('useDownloadMedia', () => {
})
it('should handle save to library failure', async () => {
const mockDownloadAsync = jest.fn().mockResolvedValue({ uri: 'file:///mock/document/download_123.jpg' })
;(FileSystem.createDownloadResumable as jest.Mock).mockReturnValue({
downloadAsync: mockDownloadAsync,
})
;(MediaLibrary.saveToLibraryAsync as jest.Mock).mockRejectedValue(new Error('Save failed'))
;(FileSystem.deleteAsync as jest.Mock).mockResolvedValue(undefined)
const { result } = renderHook(() => useDownloadMedia())
@@ -170,8 +124,6 @@ describe('useDownloadMedia', () => {
expect(response).toEqual({ success: false, error: 'Save failed' })
expect(result.current.error).toBe('Save failed')
// Should still attempt to clean up temp file
expect(FileSystem.deleteAsync).toHaveBeenCalled()
})
})
@@ -183,17 +135,12 @@ describe('useDownloadMedia', () => {
})
it('should set loading to true during download', async () => {
let resolveDownload: (value: any) => void
const downloadPromise = new Promise((resolve) => {
resolveDownload = resolve
let resolveSave: (value: any) => void
const savePromise = new Promise((resolve) => {
resolveSave = resolve
})
const mockDownloadAsync = jest.fn().mockReturnValue(downloadPromise)
;(FileSystem.createDownloadResumable as jest.Mock).mockReturnValue({
downloadAsync: mockDownloadAsync,
})
;(MediaLibrary.saveToLibraryAsync as jest.Mock).mockResolvedValue(undefined)
;(FileSystem.deleteAsync as jest.Mock).mockResolvedValue(undefined)
;(MediaLibrary.saveToLibraryAsync as jest.Mock).mockReturnValue(savePromise)
const { result } = renderHook(() => useDownloadMedia())
@@ -204,18 +151,15 @@ describe('useDownloadMedia', () => {
expect(result.current.loading).toBe(true)
await act(async () => {
resolveDownload!({ uri: 'file:///mock/document/download_123.jpg' })
await downloadPromise
resolveSave!(undefined)
await savePromise
})
expect(result.current.loading).toBe(false)
})
it('should set loading to false after error', async () => {
const mockDownloadAsync = jest.fn().mockRejectedValue(new Error('Error'))
;(FileSystem.createDownloadResumable as jest.Mock).mockReturnValue({
downloadAsync: mockDownloadAsync,
})
;(MediaLibrary.saveToLibraryAsync as jest.Mock).mockRejectedValue(new Error('Error'))
const { result } = renderHook(() => useDownloadMedia())
@@ -234,23 +178,8 @@ describe('useDownloadMedia', () => {
})
})
it('should update progress during download', async () => {
let progressCallback: (progress: { totalBytesWritten: number; totalBytesExpectedToWrite: number }) => void
const mockDownloadAsync = jest.fn().mockImplementation(async () => {
// Simulate progress updates
progressCallback({ totalBytesWritten: 50, totalBytesExpectedToWrite: 100 })
return { uri: 'file:///mock/document/download_123.jpg' }
})
;(FileSystem.createDownloadResumable as jest.Mock).mockImplementation(
(url, fileUri, options, callback) => {
progressCallback = callback
return { downloadAsync: mockDownloadAsync }
}
)
it('should reset progress after completion', async () => {
;(MediaLibrary.saveToLibraryAsync as jest.Mock).mockResolvedValue(undefined)
;(FileSystem.deleteAsync as jest.Mock).mockResolvedValue(undefined)
const { result } = renderHook(() => useDownloadMedia())
@@ -263,12 +192,7 @@ describe('useDownloadMedia', () => {
})
it('should reset progress on new download', async () => {
const mockDownloadAsync = jest.fn().mockResolvedValue({ uri: 'file:///mock/document/download_123.jpg' })
;(FileSystem.createDownloadResumable as jest.Mock).mockReturnValue({
downloadAsync: mockDownloadAsync,
})
;(MediaLibrary.saveToLibraryAsync as jest.Mock).mockResolvedValue(undefined)
;(FileSystem.deleteAsync as jest.Mock).mockResolvedValue(undefined)
const { result } = renderHook(() => useDownloadMedia())
@@ -292,12 +216,7 @@ describe('useDownloadMedia', () => {
.mockResolvedValueOnce({ status: 'denied' })
.mockResolvedValueOnce({ status: 'granted' })
const mockDownloadAsync = jest.fn().mockResolvedValue({ uri: 'file:///mock/document/download_123.jpg' })
;(FileSystem.createDownloadResumable as jest.Mock).mockReturnValue({
downloadAsync: mockDownloadAsync,
})
;(MediaLibrary.saveToLibraryAsync as jest.Mock).mockResolvedValue(undefined)
;(FileSystem.deleteAsync as jest.Mock).mockResolvedValue(undefined)
const { result } = renderHook(() => useDownloadMedia())
@@ -319,10 +238,7 @@ describe('useDownloadMedia', () => {
status: 'granted',
})
const mockDownloadAsync = jest.fn().mockRejectedValue('Unknown error')
;(FileSystem.createDownloadResumable as jest.Mock).mockReturnValue({
downloadAsync: mockDownloadAsync,
})
;(MediaLibrary.saveToLibraryAsync as jest.Mock).mockRejectedValue('Unknown error')
const { result } = renderHook(() => useDownloadMedia())