UNPKG

@lobehub/chat

Version:

Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.

165 lines (137 loc) 4.63 kB
// @vitest-environment node import qs from 'query-string'; import { describe, expect, it, vi } from 'vitest'; import { BRANDING_LOGO_URL } from '@/const/branding'; import { getCanonicalUrl } from '@/server/utils/url'; import { Manifest, manifestModule } from './manifest'; // Mock external dependencies vi.mock('@/const/branding', () => ({ BRANDING_LOGO_URL: 'https://example.com/logo.png', })); vi.mock('@/server/utils/url', () => ({ getCanonicalUrl: vi.fn().mockReturnValue('https://example.com/manifest.webmanifest'), })); describe('Manifest', () => { const manifest = new Manifest(); describe('generate', () => { it('should generate a valid manifest object', () => { const input = { color: '#FF0000', description: 'Test description', name: 'Test App', id: 'test-app', icons: [{ purpose: 'any' as const, sizes: '192x192', url: 'icon.png' }], screenshots: [{ form_factor: 'wide' as const, url: 'screenshot.png' }], }; const result = manifest.generate(input); expect(result).toMatchObject({ background_color: input.color, description: input.description, name: input.name, id: input.id, icons: expect.arrayContaining([ expect.objectContaining({ purpose: 'any', sizes: '192x192', }), ]), screenshots: expect.arrayContaining([ expect.objectContaining({ form_factor: 'wide', sizes: '1280x676', }), ]), }); }); it('should use default color if not provided', () => { const input = { description: 'Test description', name: 'Test App', id: 'test-app', icons: [], screenshots: [], }; const result = manifest.generate(input); expect(result.background_color).toBe('#000000'); expect(result.theme_color).toBe('#000000'); }); }); describe('_getImage', () => { it('should return correct image object', () => { const url = 'https://example.com/image.png'; const version = 2; // @ts-ignore - Accessing private method for testing const result = manifest._getImage(url, version); expect(result).toEqual({ cache_busting_mode: 'query', immutable: 'true', max_age: 31536000, src: qs.stringifyUrl({ query: { v: version }, url: BRANDING_LOGO_URL || url }), }); }); it('should use default version if not provided', () => { const url = 'https://example.com/image.png'; // @ts-ignore - Accessing private method for testing const result = manifest._getImage(url); expect(result.src).toContain('v=1'); }); }); describe('_getIcon', () => { it('should return correct icon object', () => { const icon = { url: 'https://example.com/icon.png', version: 3, sizes: '64x64', purpose: 'maskable' as const, }; // @ts-ignore - Accessing private method for testing const result = manifest._getIcon(icon); expect(result).toMatchObject({ purpose: 'maskable', sizes: '64x64', type: 'image/png', }); expect(result.src).toContain('v=3'); }); }); describe('_getScreenshot', () => { it('should return correct screenshot object for wide form factor', () => { const screenshot = { form_factor: 'wide' as const, url: 'https://example.com/screenshot.png', version: 4, }; // @ts-ignore - Accessing private method for testing const result = manifest._getScreenshot(screenshot); expect(result).toMatchObject({ form_factor: 'wide', sizes: '1280x676', type: 'image/png', }); expect(result.src).toContain('v=4'); }); it('should return correct screenshot object for narrow form factor', () => { const screenshot = { form_factor: 'narrow' as const, url: 'https://example.com/screenshot.png', sizes: '320x569', }; // @ts-ignore - Accessing private method for testing const result = manifest._getScreenshot(screenshot); expect(result).toMatchObject({ cache_busting_mode: 'query', form_factor: 'narrow', immutable: 'true', max_age: 31536000, sizes: '1280x676', src: 'https://example.com/logo.png?v=1', type: 'image/png', }); }); }); }); describe('manifestModule', () => { it('should be an instance of Manifest', () => { expect(manifestModule).toBeInstanceOf(Manifest); }); });