174 lines
4.6 KiB
Go
174 lines
4.6 KiB
Go
package internal
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func facturaValida() *InvoiceInput {
|
|
return &InvoiceInput{
|
|
Tipo: "alta",
|
|
Factura: FacturaInput{
|
|
EmisorNIF: "A1234567B", // [A-Z0-9] + 7 dígitos + [A-Z]
|
|
EmisorNombre: "Empresa Test SL",
|
|
NumSerie: "INV-2026-001",
|
|
FechaExpedicion: "28-05-2026",
|
|
TipoFactura: "F1",
|
|
Descripcion: "Servicios",
|
|
IVA: []IVAInput{{Base: 100, Cuota: 21, Tipo: 21}},
|
|
ImporteTotal: 121.0,
|
|
},
|
|
Sistema: SistemaInput{
|
|
Nombre: "MiSistema",
|
|
NIFProveedor: "B9876543C",
|
|
Version: "1.0",
|
|
},
|
|
}
|
|
}
|
|
|
|
func TestValidateInvoiceInput_EntradaValida(t *testing.T) {
|
|
errs := ValidateInvoiceInput(facturaValida())
|
|
if len(errs) != 0 {
|
|
t.Errorf("entrada válida no debería tener errores, obtuvo: %v", errs)
|
|
}
|
|
}
|
|
|
|
func TestValidateInvoiceInput_TipoVacio(t *testing.T) {
|
|
in := facturaValida()
|
|
in.Tipo = ""
|
|
errs := ValidateInvoiceInput(in)
|
|
if !contieneError(errs, "tipo") {
|
|
t.Error("debería fallar con tipo vacío")
|
|
}
|
|
}
|
|
|
|
func TestValidateInvoiceInput_TipoInvalido(t *testing.T) {
|
|
in := facturaValida()
|
|
in.Tipo = "modificacion"
|
|
errs := ValidateInvoiceInput(in)
|
|
if !contieneError(errs, "tipo") {
|
|
t.Error("debería fallar con tipo inválido")
|
|
}
|
|
}
|
|
|
|
func TestValidateInvoiceInput_NIFVacio(t *testing.T) {
|
|
in := facturaValida()
|
|
in.Factura.EmisorNIF = ""
|
|
errs := ValidateInvoiceInput(in)
|
|
if !contieneError(errs, "emisor_nif") {
|
|
t.Error("debería fallar con NIF vacío")
|
|
}
|
|
}
|
|
|
|
func TestValidateInvoiceInput_NIFFormatoInvalido(t *testing.T) {
|
|
casos := []string{
|
|
"12345678", // 8 dígitos sin letra final
|
|
"ABCDEFGHI", // todo letras
|
|
"A1234567", // empresa sin último carácter
|
|
"123456789", // 9 dígitos sin letra
|
|
"1234567R", // 7 dígitos + letra (autónomo necesita 8 dígitos)
|
|
"A123456BC", // empresa con dos letras al final
|
|
"",
|
|
}
|
|
for _, nif := range casos {
|
|
in := facturaValida()
|
|
in.Factura.EmisorNIF = nif
|
|
errs := ValidateInvoiceInput(in)
|
|
if !contieneError(errs, "emisor_nif") {
|
|
t.Errorf("NIF %q debería ser inválido", nif)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestValidateInvoiceInput_NIFFormatos_Validos(t *testing.T) {
|
|
casos := []string{
|
|
"A1234567B", // empresa, letra final letra
|
|
"B9876543C", // empresa, letra final letra
|
|
"A12345678", // empresa, letra final dígito
|
|
"53950250R", // autónomo (8 dígitos + letra)
|
|
"12345678Z", // autónomo genérico
|
|
"X1234567L", // NIE (letra inicial + 7 dígitos + letra)
|
|
}
|
|
for _, nif := range casos {
|
|
in := facturaValida()
|
|
in.Factura.EmisorNIF = nif
|
|
errs := ValidateInvoiceInput(in)
|
|
if contieneError(errs, "emisor_nif") {
|
|
t.Errorf("NIF %q debería ser válido", nif)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestValidateInvoiceInput_FechaFormatoInvalido(t *testing.T) {
|
|
casos := []string{"2026-05-28", "28/05/2026", "2026/05/28", "28-5-2026"}
|
|
for _, fecha := range casos {
|
|
in := facturaValida()
|
|
in.Factura.FechaExpedicion = fecha
|
|
errs := ValidateInvoiceInput(in)
|
|
if !contieneError(errs, "fecha_expedicion") {
|
|
t.Errorf("fecha %q debería ser inválida (esperado dd-mm-yyyy)", fecha)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestValidateInvoiceInput_TipoFacturaInvalido(t *testing.T) {
|
|
in := facturaValida()
|
|
in.Factura.TipoFactura = "X9"
|
|
errs := ValidateInvoiceInput(in)
|
|
if !contieneError(errs, "tipo_factura") {
|
|
t.Error("debería fallar con tipo de factura inválido")
|
|
}
|
|
}
|
|
|
|
func TestValidateInvoiceInput_TiposFacturaValidos(t *testing.T) {
|
|
for _, tipo := range []string{"F1", "F2", "R1", "R2", "R3", "R4", "R5"} {
|
|
in := facturaValida()
|
|
in.Factura.TipoFactura = tipo
|
|
errs := ValidateInvoiceInput(in)
|
|
if contieneError(errs, "tipo_factura") {
|
|
t.Errorf("tipo de factura %q debería ser válido", tipo)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestValidateInvoiceInput_IVAVacio(t *testing.T) {
|
|
in := facturaValida()
|
|
in.Factura.IVA = nil
|
|
errs := ValidateInvoiceInput(in)
|
|
if !contieneError(errs, "iva") {
|
|
t.Error("debería fallar sin líneas de IVA")
|
|
}
|
|
}
|
|
|
|
func TestValidateInvoiceInput_ImporteNegativo(t *testing.T) {
|
|
in := facturaValida()
|
|
in.Factura.ImporteTotal = -1.0
|
|
errs := ValidateInvoiceInput(in)
|
|
if !contieneError(errs, "importe_total") {
|
|
t.Error("debería fallar con importe negativo")
|
|
}
|
|
}
|
|
|
|
func TestValidateInvoiceInput_SistemaVacio(t *testing.T) {
|
|
in := facturaValida()
|
|
in.Sistema = SistemaInput{}
|
|
errs := ValidateInvoiceInput(in)
|
|
if len(errs) < 3 {
|
|
t.Errorf("debería fallar con sistema vacío, obtuvo %d errores", len(errs))
|
|
}
|
|
}
|
|
|
|
func contieneError(errs []error, campo string) bool {
|
|
for _, e := range errs {
|
|
if ve, ok := e.(*ValidationError); ok && ve.Field != "" {
|
|
if len(ve.Field) >= len(campo) {
|
|
for i := 0; i <= len(ve.Field)-len(campo); i++ {
|
|
if ve.Field[i:i+len(campo)] == campo {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false
|
|
}
|