feat(pasarela): datos inferidos juntos en una pantalla "Datos del local"
deploy-branch / deploy (push) Successful in 2m18s
deploy-branch / teardown (push) Skipped
tests / Unitarias + componente + build (pull_request) Successful in 2m23s
tests / Integración (Nominatim real, opt-in) (pull_request) Skipped
tests / Unitarias + componente + build (push) Successful in 2m30s
tests / Integración (Nominatim real, opt-in) (push) Skipped

- Nuevo PasoDatosLocal con nombre, provincia y dirección (ahora editable)
  en la misma pantalla, con aviso cuando vienen de la inferencia
- El wizard pasa de 6 a 5 pasos: Ubicación → Datos del local → Categoría
  → Tipo específico → Resumen
- Eliminados PasoNombre y PasoProvincia (absorbidos)
- Spec principal actualizada al nuevo orden de pantallas
This commit is contained in:
2026-09-12 19:00:33 +02:00
parent 30b7cc884e
commit 49e965b248
7 changed files with 117 additions and 95 deletions
+26 -25
View File
@@ -2,8 +2,7 @@
import { afterEach, describe, expect, it } from "vitest";
import { useState } from "react";
import { cleanup, fireEvent, render, screen } from "@testing-library/react";
import PasoNombre from "../../src/components/PasoNombre.jsx";
import PasoProvincia from "../../src/components/PasoProvincia.jsx";
import PasoDatosLocal from "../../src/components/PasoDatosLocal.jsx";
import PasoCategoria from "../../src/components/PasoCategoria.jsx";
import PasoSubcategoria from "../../src/components/PasoSubcategoria.jsx";
import { PROVINCIAS } from "../../src/constants/provincias.js";
@@ -12,8 +11,7 @@ import { CATEGORIAS, NOMBRES_CATEGORIAS } from "../../src/constants/categorias.j
afterEach(cleanup);
// Harness con useState real: los pasos escriben a través de setForm y el
// estado resultante se lee desde fuera (más fiel que espiar el updater,
// cuya evaluación diferida pierde el valor del evento en React 18).
// estado resultante se lee desde fuera (más fiel que espiar el updater).
function renderPaso(Componente, inicial) {
const estado = { form: inicial };
function Wrapper() {
@@ -25,35 +23,38 @@ function renderPaso(Componente, inicial) {
return estado;
}
describe("PasoNombre", () => {
it("muestra el nombre inferido y es editable", () => {
const estado = renderPaso(PasoNombre, { nombre: "Bar El Olivo" });
const input = screen.getByLabelText(/nombre del local/i);
expect(input.value).toBe("Bar El Olivo");
fireEvent.change(input, { target: { value: "Bar La Plaza" } });
describe("PasoDatosLocal (datos inferidos en una pantalla)", () => {
it("muestra los tres campos pre-rellenados con lo inferido, en la misma pantalla", () => {
renderPaso(PasoDatosLocal, { nombre: "Puerta del Sol", provincia: "Madrid", direccion: "Puerta del Sol, 28013 Madrid" });
expect(screen.getByLabelText(/nombre del local/i).value).toBe("Puerta del Sol");
expect(screen.getByLabelText(/provincia/i).value).toBe("Madrid");
expect(screen.getByLabelText(/^dirección/i).value).toBe("Puerta del Sol, 28013 Madrid");
// aviso de que vienen de la inferencia
expect(screen.getByText(/Rellenados automáticamente desde la ubicación/i)).toBeTruthy();
});
it("todos editables: nombre (input), provincia (select PROVINCIAS), dirección (input)", () => {
const estado = renderPaso(PasoDatosLocal, { nombre: "Bar X", provincia: "Barcelona", direccion: "Calle 1" });
fireEvent.change(screen.getByLabelText(/nombre del local/i), { target: { value: "Bar La Plaza" } });
expect(estado.form.nombre).toBe("Bar La Plaza");
});
it("vacío si la inferencia falló", () => {
renderPaso(PasoNombre, { nombre: "" });
expect(screen.getByLabelText(/nombre del local/i).value).toBe("");
});
});
describe("PasoProvincia", () => {
it("es un select con el listado PROVINCIAS y la provincia pre-rellenada", () => {
renderPaso(PasoProvincia, { provincia: "La Coruña" });
const select = screen.getByLabelText(/provincia/i);
expect(select.value).toBe("La Coruña");
const opciones = [...select.options].map((o) => o.value);
expect(opciones).toEqual(["", ...PROVINCIAS]);
fireEvent.change(select, { target: { value: "Madrid" } });
// (la aserción de estado se cubre con el harness en el resto de pasos)
fireEvent.change(select, { target: { value: "Gerona" } });
expect(estado.form.provincia).toBe("Gerona");
fireEvent.change(screen.getByLabelText(/^dirección/i), { target: { value: "Calle Nueva 2" } });
expect(estado.form.direccion).toBe("Calle Nueva 2");
});
it("sin coincidencia queda vacío (selección manual)", () => {
renderPaso(PasoProvincia, { provincia: "" });
it("vacíos y sin aviso de inferencia cuando la inferencia falló", () => {
renderPaso(PasoDatosLocal, { nombre: "", provincia: "", direccion: "" });
expect(screen.getByLabelText(/nombre del local/i).value).toBe("");
expect(screen.getByLabelText(/provincia/i).value).toBe("");
expect(screen.getByLabelText(/^dirección/i).value).toBe("");
expect(screen.queryByText(/Rellenados automáticamente/i)).toBeNull();
});
});