// @vitest-environment jsdom import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { cleanup, fireEvent, render, screen } from "@testing-library/react"; import BotonProponerArriba from "../../src/components/BotonProponerArriba.jsx"; const matchMediaMock = (esMovil) => (_query) => ({ matches: esMovil, media: _query, addEventListener: () => {}, removeEventListener: () => {}, addListener: () => {}, removeListener: () => {}, }); beforeEach(() => { // por defecto PC; cada prueba que lo necesite lo sobreescribe vi.stubGlobal("matchMedia", matchMediaMock(false)); }); afterEach(() => { vi.unstubAllGlobals(); cleanup(); }); describe("BotonProponerArriba (solo PC)", () => { it("en PC: píldora arriba a la derecha, alineada con el borde del cuerpo, que abre la pasarela", () => { const onClick = vi.fn(); render(); const boton = screen.getByRole("button", { name: /añade un nuevo local al directorio/i }); expect(boton.textContent).toContain("Proponer local"); expect(boton.style.position).toBe("fixed"); expect(boton.style.top).toBe("20px"); // alineado al borde derecho de la columna de 720px; mínimo 16px. // (la serialización exacta de max()/calc() varía entre versiones de jsdom) const right = (boton.getAttribute("style").match(/right:\s*([^;]+)/) || [])[1]; expect(right).toMatch(/max\(/); expect(right).toContain("100vw"); expect(right).toContain("720px"); expect(right).toContain("16px"); fireEvent.click(boton); expect(onClick).toHaveBeenCalledTimes(1); }); it("en móvil no se renderiza", () => { vi.stubGlobal("matchMedia", matchMediaMock(true)); render( {}} />); expect(screen.queryByRole("button")).toBeNull(); }); });