-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
487 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
import { getFileRenderType, FileRenderType } from './file-render-type'; | ||
import type { IFile } from '@putdotio/api-client'; | ||
|
||
const baseFile: IFile = { | ||
id: 1, | ||
parent_id: 1, | ||
name: 'test', | ||
size: 100, | ||
extension: 'txt', | ||
file_type: 'TEXT', | ||
content_type: 'text/plain', | ||
crc32: '1234567890', | ||
created_at: '2021-01-01T00:00:00Z', | ||
}; | ||
|
||
describe('getFileRenderType', () => { | ||
it('should return "folder" for directories', () => { | ||
const file: IFile = { | ||
...baseFile, | ||
content_type: 'application/x-directory', | ||
file_type: 'FOLDER', | ||
}; | ||
expect(getFileRenderType(file)).toBe('folder'); | ||
}); | ||
|
||
it('should return "audio" for audio files', () => { | ||
const file: IFile = { | ||
...baseFile, | ||
content_type: 'audio/mpeg', | ||
file_type: 'AUDIO', | ||
}; | ||
expect(getFileRenderType(file)).toBe('audio'); | ||
}); | ||
|
||
it('should return "video" for video files', () => { | ||
const file: IFile = { | ||
...baseFile, | ||
content_type: 'video/mp4', | ||
file_type: 'VIDEO', | ||
}; | ||
expect(getFileRenderType(file)).toBe('video'); | ||
}); | ||
|
||
it('should return "text/markdown" for markdown files', () => { | ||
const file: IFile = { | ||
...baseFile, | ||
content_type: 'text/markdown', | ||
extension: 'md', | ||
file_type: 'TEXT', | ||
}; | ||
expect(getFileRenderType(file)).toBe('text/markdown'); | ||
}); | ||
|
||
it('should return "text" for text files', () => { | ||
const file: IFile = { | ||
...baseFile, | ||
content_type: 'text/plain', | ||
file_type: 'TEXT', | ||
}; | ||
expect(getFileRenderType(file)).toBe('text'); | ||
}); | ||
|
||
it('should return "image" for image files', () => { | ||
const file: IFile = { | ||
...baseFile, | ||
content_type: 'image/jpeg', | ||
file_type: 'IMAGE', | ||
}; | ||
expect(getFileRenderType(file)).toBe('image'); | ||
}); | ||
|
||
it('should return "pdf" for PDF files', () => { | ||
const file: IFile = { | ||
...baseFile, | ||
content_type: 'application/pdf', | ||
file_type: 'PDF', | ||
}; | ||
expect(getFileRenderType(file)).toBe('pdf'); | ||
}); | ||
|
||
it('should return "archive" for archive files', () => { | ||
const file: IFile = { | ||
...baseFile, | ||
content_type: 'application/zip', | ||
file_type: 'ARCHIVE', | ||
}; | ||
expect(getFileRenderType(file)).toBe('archive'); | ||
}); | ||
|
||
it('should return "epub" for EPUB files', () => { | ||
const file: IFile = { | ||
...baseFile, | ||
content_type: 'application/epub+zip', | ||
}; | ||
expect(getFileRenderType(file)).toBe('epub'); | ||
}); | ||
|
||
it('should return "other" for unknown file types', () => { | ||
const file: IFile = { | ||
...baseFile, | ||
content_type: 'application/octet-stream', | ||
}; | ||
expect(getFileRenderType(file)).toBe('other'); | ||
}); | ||
|
||
it('should return "other" if content_type is not a string', () => { | ||
const file: IFile = { | ||
...baseFile, | ||
content_type: null as any, | ||
}; | ||
expect(getFileRenderType(file)).toBe('other'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import type { IFile } from '@putdotio/api-client'; | ||
|
||
export type FileRenderType = | ||
| 'archive' | ||
| 'audio' | ||
| 'epub' | ||
| 'folder' | ||
| 'image' | ||
| 'other' | ||
| 'pdf' | ||
| 'text' | ||
| 'text/markdown' | ||
| 'video'; | ||
|
||
export const getFileRenderType = (file: IFile): FileRenderType => { | ||
const { content_type, extension, file_type } = file; | ||
|
||
if (typeof content_type !== 'string') { | ||
return 'other'; | ||
} | ||
|
||
if (content_type === 'application/x-directory') { | ||
return 'folder'; | ||
} | ||
|
||
if (content_type.startsWith('audio') || file_type === 'AUDIO') { | ||
return 'audio'; | ||
} | ||
|
||
if (content_type.startsWith('video')) { | ||
return 'video'; | ||
} | ||
|
||
if (content_type.startsWith('text')) { | ||
if (content_type.endsWith('/markdown') || extension === 'md') { | ||
return 'text/markdown'; | ||
} | ||
return 'text'; | ||
} | ||
|
||
if (content_type.startsWith('image')) { | ||
return 'image'; | ||
} | ||
|
||
if (content_type === 'application/pdf') { | ||
return 'pdf'; | ||
} | ||
|
||
if (['application/x-rar', 'application/zip'].includes(content_type)) { | ||
return 'archive'; | ||
} | ||
|
||
if (content_type === 'application/epub+zip') { | ||
return 'epub'; | ||
} | ||
|
||
return 'other'; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
import type { IFile } from '@putdotio/api-client'; | ||
|
||
import { FileURLProvider } from './file-url-provider'; | ||
import { getFileRenderType } from './file-render-type'; | ||
|
||
jest.mock('./file-render-type'); | ||
|
||
const apiURL = 'https://api.example.com'; | ||
const token = 'test-token'; | ||
let provider: FileURLProvider; | ||
|
||
const baseFile: IFile = { | ||
id: 1, | ||
parent_id: 1, | ||
name: 'test', | ||
size: 100, | ||
extension: 'txt', | ||
file_type: 'TEXT', | ||
content_type: 'text/plain', | ||
crc32: '1234567890', | ||
created_at: '2021-01-01T00:00:00Z', | ||
}; | ||
|
||
beforeEach(() => { | ||
provider = new FileURLProvider(apiURL, token); | ||
}); | ||
|
||
const mockFileRenderType = (type: string) => { | ||
(getFileRenderType as jest.Mock).mockReturnValue(type); | ||
}; | ||
|
||
describe('FileURLProvider', () => { | ||
describe('getDownloadURL', () => { | ||
it('should return download URL for file ID', () => { | ||
const fileId = 123; | ||
const url = provider.getDownloadURL(fileId); | ||
expect(url).toMatchInlineSnapshot( | ||
`"https://api.example.com/v2/files/123/download?oauth_token=test-token"` | ||
); | ||
}); | ||
|
||
it('should return null for folder type', () => { | ||
const file: IFile = { | ||
...baseFile, | ||
file_type: 'FOLDER', | ||
}; | ||
const url = provider.getDownloadURL(file); | ||
expect(url).toBeNull(); | ||
}); | ||
|
||
it('should return download URL for file object', () => { | ||
const file: IFile = { | ||
...baseFile, | ||
file_type: 'VIDEO', | ||
}; | ||
const url = provider.getDownloadURL(file); | ||
expect(url).toMatchInlineSnapshot( | ||
`"https://api.example.com/v2/files/1/download?oauth_token=test-token"` | ||
); | ||
}); | ||
}); | ||
|
||
describe('getHLSStreamURL', () => { | ||
it('should return null if file is not a video', () => { | ||
mockFileRenderType('audio'); | ||
const file: IFile = { | ||
...baseFile, | ||
file_type: 'AUDIO', | ||
}; | ||
const url = provider.getHLSStreamURL(file, {}); | ||
expect(url).toBeNull(); | ||
}); | ||
|
||
it('should return HLS stream URL with parameters', () => { | ||
mockFileRenderType('video'); | ||
const file: IFile = { | ||
...baseFile, | ||
file_type: 'VIDEO', | ||
}; | ||
const params = { | ||
playOriginal: true, | ||
subtitleLanguages: ['en', 'es'], | ||
maxSubtitleCount: 2, | ||
}; | ||
const url = provider.getHLSStreamURL(file, params); | ||
expect(url).toMatchInlineSnapshot( | ||
`"https://api.example.com/v2/files/1/hls/media.m3u8?oauth_token=test-token&original=1&subtitle_languages=en%2Ces&max_subtitle_count=2"` | ||
); | ||
}); | ||
}); | ||
|
||
describe('getMP4DownloadURL', () => { | ||
it('should return null if file is not a video', () => { | ||
mockFileRenderType('audio'); | ||
const file: IFile = { | ||
...baseFile, | ||
file_type: 'AUDIO', | ||
}; | ||
const url = provider.getMP4DownloadURL(file); | ||
expect(url).toBeNull(); | ||
}); | ||
|
||
it('should return null if MP4 is not available', () => { | ||
mockFileRenderType('video'); | ||
const file: IFile = { | ||
...baseFile, | ||
file_type: 'VIDEO', | ||
is_mp4_available: false, | ||
parent_id: 0, | ||
name: 'test.mp4', | ||
size: 1024, | ||
content_type: 'video/mp4', | ||
}; | ||
const url = provider.getMP4DownloadURL(file); | ||
expect(url).toBeNull(); | ||
}); | ||
|
||
it('should return MP4 download URL if MP4 is available', () => { | ||
mockFileRenderType('video'); | ||
const file: IFile = { | ||
...baseFile, | ||
file_type: 'VIDEO', | ||
is_mp4_available: true, | ||
}; | ||
const url = provider.getMP4DownloadURL(file); | ||
expect(url).toMatchInlineSnapshot( | ||
`"https://api.example.com/v2/files/1/mp4/download?oauth_token=test-token"` | ||
); | ||
}); | ||
}); | ||
|
||
describe('getMP4StreamURL', () => { | ||
it('should return null if file is not a video', () => { | ||
mockFileRenderType('audio'); | ||
const file: IFile = { | ||
...baseFile, | ||
file_type: 'AUDIO', | ||
}; | ||
const url = provider.getMP4StreamURL(file); | ||
expect(url).toBeNull(); | ||
}); | ||
|
||
it('should return null if MP4 is not available', () => { | ||
mockFileRenderType('video'); | ||
const file: IFile = { | ||
...baseFile, | ||
file_type: 'VIDEO', | ||
is_mp4_available: false, | ||
}; | ||
const url = provider.getMP4StreamURL(file); | ||
expect(url).toBeNull(); | ||
}); | ||
|
||
it('should return MP4 stream URL if MP4 is available', () => { | ||
mockFileRenderType('video'); | ||
const file: IFile = { | ||
...baseFile, | ||
file_type: 'VIDEO', | ||
is_mp4_available: true, | ||
}; | ||
const url = provider.getMP4StreamURL(file); | ||
expect(url).toMatchInlineSnapshot( | ||
`"https://api.example.com/v2/files/1/mp4/stream?oauth_token=test-token"` | ||
); | ||
}); | ||
}); | ||
|
||
describe('getStreamURL', () => { | ||
it('should return audio stream URL for audio file', () => { | ||
mockFileRenderType('audio'); | ||
const file: IFile = { | ||
...baseFile, | ||
file_type: 'AUDIO', | ||
}; | ||
const url = provider.getStreamURL(file); | ||
expect(url).toMatchInlineSnapshot( | ||
`"https://api.example.com/v2/files/1/stream.mp3?oauth_token=test-token"` | ||
); | ||
}); | ||
|
||
it('should return video stream URL for video file', () => { | ||
mockFileRenderType('video'); | ||
const file: IFile = { | ||
...baseFile, | ||
file_type: 'VIDEO', | ||
}; | ||
const url = provider.getStreamURL(file); | ||
expect(url).toMatchInlineSnapshot( | ||
`"https://api.example.com/v2/files/1/stream?oauth_token=test-token"` | ||
); | ||
}); | ||
|
||
it('should return null for unsupported file type', () => { | ||
mockFileRenderType('archive'); | ||
const file: IFile = { | ||
...baseFile, | ||
file_type: 'ARCHIVE', | ||
}; | ||
const url = provider.getStreamURL(file); | ||
expect(url).toBeNull(); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.