project-nomad/admin/tests/unit/validators/common.test.ts
LuisMIguelFurlanettoSousa 7e0ae3ea83 test: adicionar suite inicial de testes unitários com Vitest
Adiciona 81 testes unitários cobrindo backend e frontend:

Backend (50 testes):
- utils/version: isNewerVersion, parseMajorVersion (14 testes)
- utils/misc: formatSpeed, toTitleCase, parseBoolean (17 testes)
- utils/fs: determineFileType, matchesDevice, sanitizeFilename (14 testes)
- validators/common: assertNotPrivateUrl - proteção SSRF (9 testes)

Frontend (27 testes):
- lib/classNames: concatenação condicional de classes (5 testes)
- lib/util: capitalizeFirstLetter, formatBytes, extractFileName (12 testes)
- hooks/useDiskDisplayData: getAllDiskDisplayItems, getPrimaryDiskInfo (6 testes)

Infraestrutura:
- Instala vitest, @testing-library/react, jsdom
- Configura vitest.config.ts com aliases para ~ e #app
- Script npm test:unit para rodar todos os testes

Closes #491
2026-03-23 11:53:55 -03:00

57 lines
1.6 KiB
TypeScript

import { describe, it, expect } from 'vitest'
import { assertNotPrivateUrl } from '#app/validators/common'
describe('assertNotPrivateUrl', () => {
it('permite URL pública HTTPS', () => {
// Cenário
const url = 'https://example.com/file.zim'
// Ação / Validação
expect(() => assertNotPrivateUrl(url)).not.toThrow()
})
it('permite URL RFC1918 192.168.x.x (LAN appliance)', () => {
// Cenário
const url = 'http://192.168.1.100:8080/file.zim'
// Ação / Validação
expect(() => assertNotPrivateUrl(url)).not.toThrow()
})
it('permite URL RFC1918 10.x.x.x (LAN appliance)', () => {
// Cenário
const url = 'http://10.0.0.1/file.zim'
// Ação / Validação
expect(() => assertNotPrivateUrl(url)).not.toThrow()
})
it('bloqueia localhost', () => {
// Cenário
const url = 'http://localhost/file'
// Ação / Validação
expect(() => assertNotPrivateUrl(url)).toThrow()
})
it('bloqueia 127.0.0.1 (loopback)', () => {
expect(() => assertNotPrivateUrl('http://127.0.0.1/file')).toThrow()
})
it('bloqueia 127.0.0.2 (loopback alternativo)', () => {
expect(() => assertNotPrivateUrl('http://127.0.0.2/file')).toThrow()
})
it('bloqueia 0.0.0.0', () => {
expect(() => assertNotPrivateUrl('http://0.0.0.0/file')).toThrow()
})
it('bloqueia endereço de metadados cloud 169.254.169.254', () => {
expect(() => assertNotPrivateUrl('http://169.254.169.254/metadata')).toThrow()
})
it('bloqueia IPv6 loopback [::1]', () => {
expect(() => assertNotPrivateUrl('http://[::1]/file')).toThrow()
})
})