feat(propuesta): pasarela paso a paso con autodetección de ubicación y FAB
- Campo universal de ubicación (Google Maps/Waze/OSM/coordenadas/dirección) sobre proveedores extensibles (src/utils/ubicacion) con resolver e inferencia inversa Nominatim (nombre/provincia pre-rellenados, alias cooficiales) - FAB flotante abajo a la derecha que abre la pasarela en un modal accesible (Escape, foco contenido, responsive); sin descripción ni puntuación; avisos de duplicado y filtro de palabras dentro del modal - Aviso PWA reposicionado: tarjeta abajo a la izquierda en móvil, botón compacto arriba a la izquierda en PC (no tapa el FAB) - Suite de pruebas: 88 unitarias/componente (vitest + RTL, offline) y 10 de integración (supertest + SQLite :memory: y Nominatim real opt-in) - CI: workflow de Gitea Actions con npm test + build en push/PR e integración manual
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
// @vitest-environment jsdom
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { cleanup, fireEvent, render, screen } from "@testing-library/react";
|
||||
import BotonFlotante from "../../src/components/BotonFlotante.jsx";
|
||||
|
||||
afterEach(cleanup);
|
||||
|
||||
describe("BotonFlotante", () => {
|
||||
it("expone su propósito con aria-label (accesible sin hover)", () => {
|
||||
render(<BotonFlotante onClick={() => {}} />);
|
||||
expect(screen.getByRole("button", { name: "Añade un nuevo local al directorio" })).toBeTruthy();
|
||||
});
|
||||
|
||||
it("tooltip oculto por defecto y visible al recibir foco", () => {
|
||||
render(<BotonFlotante onClick={() => {}} />);
|
||||
expect(screen.queryByRole("tooltip")).toBeNull();
|
||||
|
||||
fireEvent.focus(screen.getByRole("button"));
|
||||
expect(screen.getByRole("tooltip").textContent).toBe("Añade un nuevo local al directorio");
|
||||
|
||||
fireEvent.blur(screen.getByRole("button"));
|
||||
expect(screen.queryByRole("tooltip")).toBeNull();
|
||||
});
|
||||
|
||||
it("tooltip también en hover", () => {
|
||||
render(<BotonFlotante onClick={() => {}} />);
|
||||
fireEvent.mouseEnter(screen.getByRole("button"));
|
||||
expect(screen.getByRole("tooltip")).toBeTruthy();
|
||||
fireEvent.mouseLeave(screen.getByRole("button"));
|
||||
expect(screen.queryByRole("tooltip")).toBeNull();
|
||||
});
|
||||
|
||||
it("al pulsarlo abre la pasarela (onClick)", () => {
|
||||
const onClick = vi.fn();
|
||||
render(<BotonFlotante onClick={onClick} />);
|
||||
fireEvent.click(screen.getByRole("button"));
|
||||
expect(onClick).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user