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,53 @@
|
||||
import { beforeAll, describe, expect, it } from "vitest";
|
||||
import { inferirDesdeCoords, resolverUbicacion } from "../../src/utils/ubicacion/index.js";
|
||||
|
||||
// Integración real con Nominatim (OpenStreetMap). Suite opt-in
|
||||
// (`npm run test:integration`): se auto-salta sin conectividad y mantiene un
|
||||
// ritmo respetuoso con la política de uso (~1 req/s) esperando entre pruebas.
|
||||
const PAUSA_MS = 1100;
|
||||
const pausar = () => new Promise((r) => setTimeout(r, PAUSA_MS));
|
||||
|
||||
const conRed = await fetch("https://nominatim.openstreetmap.org/status", {
|
||||
headers: { "User-Agent": "LocalesEspanoles/1.0" },
|
||||
signal: AbortSignal.timeout(5000),
|
||||
})
|
||||
.then((r) => r.ok)
|
||||
.catch(() => false);
|
||||
|
||||
describe.skipIf(!conRed)("Integración Nominatim (red real)", () => {
|
||||
beforeAll(() => {
|
||||
if (!conRed) console.warn("Sin conectividad a Nominatim: suite saltada.");
|
||||
});
|
||||
|
||||
it("busca una dirección en texto y devuelve coordenadas + provincia canónica", async () => {
|
||||
const r = await resolverUbicacion("Calle Mayor 5, Alcalá de Henares");
|
||||
expect(r.proveedor).toBe("nominatim");
|
||||
expect(r.lat).toBeGreaterThan(40.4);
|
||||
expect(r.lat).toBeLessThan(40.6);
|
||||
expect(r.lng).toBeGreaterThan(-3.5);
|
||||
expect(r.lng).toBeLessThan(-3.2);
|
||||
expect(r.provincia).toBe("Madrid");
|
||||
});
|
||||
|
||||
it("geocodificación inversa de Madrid devuelve la provincia canónica", async () => {
|
||||
await pausar();
|
||||
const r = await inferirDesdeCoords(40.4168, -3.7038);
|
||||
expect(r).not.toBeNull();
|
||||
expect(r.provincia).toBe("Madrid");
|
||||
expect(r.nombre).toBeTruthy();
|
||||
expect(r.direccion).toBeTruthy();
|
||||
});
|
||||
|
||||
it("geocodificación inversa de Bilbao normaliza Bizkaia → Vizcaya (acentos/cooficial)", async () => {
|
||||
await pausar();
|
||||
const r = await inferirDesdeCoords(43.263, -2.935);
|
||||
expect(r.provincia).toBe("Vizcaya");
|
||||
});
|
||||
|
||||
it("geocodificación inversa fuera de España deja la provincia vacía (selección manual)", async () => {
|
||||
await pausar();
|
||||
const r = await inferirDesdeCoords(48.8584, 2.2945); // Torre Eiffel
|
||||
expect(r).not.toBeNull();
|
||||
expect(r.provincia).toBe("");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user