import { describe, expect, it, vi } from "vitest"; import ProveedorUbicacion from "../../src/utils/ubicacion/ProveedorUbicacion.js"; describe("ProveedorUbicacion (clase base)", () => { it("normaliza: minúsculas, sin tildes, sin espacios extremos", () => { const p = new ProveedorUbicacion(); expect(p.normalizar(" ÁLAVA ")).toBe("alava"); expect(p.normalizar("Guipúzcoa")).toBe("guipuzcoa"); expect(ProveedorUbicacion.normalizar("MA DRID")).toBe("ma drid"); expect(p.normalizar(null)).toBe(""); }); describe("emparejarProvincia", () => { const p = new ProveedorUbicacion(); it("coincidencia exacta insensible a acentos y mayúsculas", () => { expect(p.emparejarProvincia("ALAVA")).toBe("Álava"); expect(p.emparejarProvincia("Guipuzcoa")).toBe("Guipúzcoa"); }); it("coincidencia parcial dentro de un texto (Comunidad de Madrid)", () => { expect(p.emparejarProvincia("Comunidad de Madrid")).toBe("Madrid"); expect(p.emparejarProvincia("Santiago, A Coruña, Galicia")).toBe("La Coruña"); }); it("tolera artículos anteuestos (A Coruña → La Coruña)", () => { expect(p.emparejarProvincia("A Coruña")).toBe("La Coruña"); expect(p.emparejarProvincia("Ourense")).toBe("Orense"); }); it("alias de nombres cooficiales (D12)", () => { expect(p.emparejarProvincia("Bizkaia")).toBe("Vizcaya"); expect(p.emparejarProvincia("Gipuzkoa")).toBe("Guipúzcoa"); expect(p.emparejarProvincia("Girona")).toBe("Gerona"); expect(p.emparejarProvincia("Lleida")).toBe("Lérida"); expect(p.emparejarProvincia("Illes Balears")).toBe("Islas Baleares"); expect(p.emparejarProvincia("Asturies")).toBe("Asturias"); }); it("devuelve \"\" cuando no casa con ninguna provincia", () => { expect(p.emparejarProvincia("Île-de-France")).toBe(""); expect(p.emparejarProvincia("")).toBe(""); expect(p.emparejarProvincia("Lisboa")).toBe(""); }); }); it("el contrato base no acepta ninguna entrada", () => { const p = new ProveedorUbicacion(); expect(p.detecta("41.38, 2.17")).toBe(false); expect(p.detecta("https://maps.google.com")).toBe(false); }); it("extrae() de la base lanza \"sin implementar\" (método abstracto)", async () => { const p = new ProveedorUbicacion(); await expect(p.extrae("x")).rejects.toThrow("sin implementar"); }); describe("fetchNominatim degrada errores a null", () => { it("devuelve null si fetch lanza (sin red)", async () => { const p = new ProveedorUbicacion(); vi.stubGlobal("fetch", vi.fn(() => Promise.reject(new Error("sin red")))); expect(await p.fetchNominatim("https://nominatim.openstreetmap.org/x")).toBeNull(); vi.unstubAllGlobals(); }); it("devuelve null si la respuesta HTTP no es ok", async () => { const p = new ProveedorUbicacion(); vi.stubGlobal("fetch", vi.fn(() => Promise.resolve({ ok: false, status: 503 }))); expect(await p.fetchNominatim("https://nominatim.openstreetmap.org/x")).toBeNull(); vi.unstubAllGlobals(); }); it("devuelve el JSON cuando todo va bien y manda cabeceras", async () => { const p = new ProveedorUbicacion(); const fetchMock = vi.fn(() => Promise.resolve({ ok: true, json: () => Promise.resolve([{ lat: "1" }]) })); vi.stubGlobal("fetch", fetchMock); expect(await p.fetchNominatim("https://nominatim.openstreetmap.org/x")).toEqual([{ lat: "1" }]); const [, init] = fetchMock.mock.calls[0]; expect(init.headers["Accept-Language"]).toBe("es"); expect(init.headers["User-Agent"]).toBe("LocalesEspanoles/1.0"); vi.unstubAllGlobals(); }); }); });