ProyectoGrupal/VerifactuMidAPI/internal/models_test.go

174 lines
4.6 KiB
Go
Raw Permalink Normal View History

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
}