mirror of
https://github.com/langgenius/dify.git
synced 2026-05-06 02:18:08 +08:00
test: adding some web tests (#27792)
This commit is contained in:
@ -759,4 +759,104 @@ export default translation`
|
||||
expect(result).not.toContain('Zbuduj inteligentnego agenta')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Performance and Scalability', () => {
|
||||
it('should handle large translation files efficiently', async () => {
|
||||
// Create a large translation file with 1000 keys
|
||||
const largeContent = `const translation = {
|
||||
${Array.from({ length: 1000 }, (_, i) => ` key${i}: 'value${i}',`).join('\n')}
|
||||
}
|
||||
|
||||
export default translation`
|
||||
|
||||
fs.writeFileSync(path.join(testEnDir, 'large.ts'), largeContent)
|
||||
|
||||
const startTime = Date.now()
|
||||
const keys = await getKeysFromLanguage('en-US')
|
||||
const endTime = Date.now()
|
||||
|
||||
expect(keys.length).toBe(1000)
|
||||
expect(endTime - startTime).toBeLessThan(1000) // Should complete in under 1 second
|
||||
})
|
||||
|
||||
it('should handle multiple translation files concurrently', async () => {
|
||||
// Create multiple files
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const content = `const translation = {
|
||||
key${i}: 'value${i}',
|
||||
nested${i}: {
|
||||
subkey: 'subvalue'
|
||||
}
|
||||
}
|
||||
|
||||
export default translation`
|
||||
fs.writeFileSync(path.join(testEnDir, `file${i}.ts`), content)
|
||||
}
|
||||
|
||||
const startTime = Date.now()
|
||||
const keys = await getKeysFromLanguage('en-US')
|
||||
const endTime = Date.now()
|
||||
|
||||
expect(keys.length).toBe(20) // 10 files * 2 keys each
|
||||
expect(endTime - startTime).toBeLessThan(500)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Unicode and Internationalization', () => {
|
||||
it('should handle Unicode characters in keys and values', async () => {
|
||||
const unicodeContent = `const translation = {
|
||||
'中文键': '中文值',
|
||||
'العربية': 'قيمة',
|
||||
'emoji_😀': 'value with emoji 🎉',
|
||||
'mixed_中文_English': 'mixed value'
|
||||
}
|
||||
|
||||
export default translation`
|
||||
|
||||
fs.writeFileSync(path.join(testEnDir, 'unicode.ts'), unicodeContent)
|
||||
|
||||
const keys = await getKeysFromLanguage('en-US')
|
||||
|
||||
expect(keys).toContain('unicode.中文键')
|
||||
expect(keys).toContain('unicode.العربية')
|
||||
expect(keys).toContain('unicode.emoji_😀')
|
||||
expect(keys).toContain('unicode.mixed_中文_English')
|
||||
})
|
||||
|
||||
it('should handle RTL language files', async () => {
|
||||
const rtlContent = `const translation = {
|
||||
مرحبا: 'Hello',
|
||||
العالم: 'World',
|
||||
nested: {
|
||||
مفتاح: 'key'
|
||||
}
|
||||
}
|
||||
|
||||
export default translation`
|
||||
|
||||
fs.writeFileSync(path.join(testEnDir, 'rtl.ts'), rtlContent)
|
||||
|
||||
const keys = await getKeysFromLanguage('en-US')
|
||||
|
||||
expect(keys).toContain('rtl.مرحبا')
|
||||
expect(keys).toContain('rtl.العالم')
|
||||
expect(keys).toContain('rtl.nested.مفتاح')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Error Recovery', () => {
|
||||
it('should handle syntax errors in translation files gracefully', async () => {
|
||||
const invalidContent = `const translation = {
|
||||
validKey: 'valid value',
|
||||
invalidKey: 'missing quote,
|
||||
anotherKey: 'another value'
|
||||
}
|
||||
|
||||
export default translation`
|
||||
|
||||
fs.writeFileSync(path.join(testEnDir, 'invalid.ts'), invalidContent)
|
||||
|
||||
await expect(getKeysFromLanguage('en-US')).rejects.toThrow()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -286,4 +286,116 @@ describe('Navigation Utilities', () => {
|
||||
expect(mockPush).toHaveBeenCalledWith('/datasets/filtered-set/documents?page=1&limit=50&status=active&type=pdf&sort=created_at&order=desc')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Edge Cases and Error Handling', () => {
|
||||
test('handles special characters in query parameters', () => {
|
||||
Object.defineProperty(window, 'location', {
|
||||
value: { search: '?keyword=hello%20world&filter=type%3Apdf&tag=%E4%B8%AD%E6%96%87' },
|
||||
writable: true,
|
||||
})
|
||||
|
||||
const path = createNavigationPath('/datasets/123/documents')
|
||||
expect(path).toContain('hello+world')
|
||||
expect(path).toContain('type%3Apdf')
|
||||
expect(path).toContain('%E4%B8%AD%E6%96%87')
|
||||
})
|
||||
|
||||
test('handles duplicate query parameters', () => {
|
||||
Object.defineProperty(window, 'location', {
|
||||
value: { search: '?tag=tag1&tag=tag2&tag=tag3' },
|
||||
writable: true,
|
||||
})
|
||||
|
||||
const params = extractQueryParams(['tag'])
|
||||
// URLSearchParams.get() returns the first value
|
||||
expect(params.tag).toBe('tag1')
|
||||
})
|
||||
|
||||
test('handles very long query strings', () => {
|
||||
const longValue = 'a'.repeat(1000)
|
||||
Object.defineProperty(window, 'location', {
|
||||
value: { search: `?data=${longValue}` },
|
||||
writable: true,
|
||||
})
|
||||
|
||||
const path = createNavigationPath('/datasets/123/documents')
|
||||
expect(path).toContain(longValue)
|
||||
expect(path.length).toBeGreaterThan(1000)
|
||||
})
|
||||
|
||||
test('handles empty string values in query parameters', () => {
|
||||
const path = createNavigationPathWithParams('/datasets/123/documents', {
|
||||
page: 1,
|
||||
keyword: '',
|
||||
filter: '',
|
||||
sort: 'name',
|
||||
})
|
||||
|
||||
expect(path).toBe('/datasets/123/documents?page=1&sort=name')
|
||||
expect(path).not.toContain('keyword=')
|
||||
expect(path).not.toContain('filter=')
|
||||
})
|
||||
|
||||
test('handles null and undefined values in mergeQueryParams', () => {
|
||||
Object.defineProperty(window, 'location', {
|
||||
value: { search: '?page=1&limit=10&keyword=test' },
|
||||
writable: true,
|
||||
})
|
||||
|
||||
const merged = mergeQueryParams({
|
||||
keyword: null,
|
||||
filter: undefined,
|
||||
sort: 'name',
|
||||
})
|
||||
const result = merged.toString()
|
||||
|
||||
expect(result).toContain('page=1')
|
||||
expect(result).toContain('limit=10')
|
||||
expect(result).not.toContain('keyword')
|
||||
expect(result).toContain('sort=name')
|
||||
})
|
||||
|
||||
test('handles navigation with hash fragments', () => {
|
||||
Object.defineProperty(window, 'location', {
|
||||
value: { search: '?page=1', hash: '#section-2' },
|
||||
writable: true,
|
||||
})
|
||||
|
||||
const path = createNavigationPath('/datasets/123/documents')
|
||||
// Should preserve query params but not hash
|
||||
expect(path).toBe('/datasets/123/documents?page=1')
|
||||
})
|
||||
|
||||
test('handles malformed query strings gracefully', () => {
|
||||
Object.defineProperty(window, 'location', {
|
||||
value: { search: '?page=1&invalid&limit=10&=value&key=' },
|
||||
writable: true,
|
||||
})
|
||||
|
||||
const params = extractQueryParams(['page', 'limit', 'invalid', 'key'])
|
||||
expect(params.page).toBe('1')
|
||||
expect(params.limit).toBe('10')
|
||||
// Malformed params should be handled by URLSearchParams
|
||||
expect(params.invalid).toBe('') // for `&invalid`
|
||||
expect(params.key).toBe('') // for `&key=`
|
||||
})
|
||||
})
|
||||
|
||||
describe('Performance Tests', () => {
|
||||
test('handles large number of query parameters efficiently', () => {
|
||||
const manyParams = Array.from({ length: 50 }, (_, i) => `param${i}=value${i}`).join('&')
|
||||
Object.defineProperty(window, 'location', {
|
||||
value: { search: `?${manyParams}` },
|
||||
writable: true,
|
||||
})
|
||||
|
||||
const startTime = Date.now()
|
||||
const path = createNavigationPath('/datasets/123/documents')
|
||||
const endTime = Date.now()
|
||||
|
||||
expect(endTime - startTime).toBeLessThan(50) // Should be fast
|
||||
expect(path).toContain('param0=value0')
|
||||
expect(path).toContain('param49=value49')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user