tftsr-devops_investigation/tests/unit/selectDropdownViewport.test.tsx

125 lines
4.0 KiB
TypeScript
Raw Permalink Normal View History

import { describe, it, expect, beforeEach, afterEach } from "vitest";
import { render, screen } from "@testing-library/react";
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from "@/components/ui";
describe("Select Dropdown - Viewport Awareness", () => {
let originalInnerHeight: number;
beforeEach(() => {
originalInnerHeight = window.innerHeight;
});
afterEach(() => {
// Restore original window height
Object.defineProperty(window, "innerHeight", {
writable: true,
configurable: true,
value: originalInnerHeight,
});
});
it("should render Select component with trigger and content", () => {
render(
<Select value="" onValueChange={() => {}}>
<SelectTrigger>
<SelectValue placeholder="Select..." />
</SelectTrigger>
<SelectContent>
<SelectItem value="option1">Option 1</SelectItem>
<SelectItem value="option2">Option 2</SelectItem>
</SelectContent>
</Select>
);
// Trigger should be visible
expect(screen.getByRole("button")).toBeInTheDocument();
});
it("should apply bottom-full class when flipped upward", () => {
// Test verifies the flip logic when dropdown is near bottom of viewport
// Simulating a dropdown positioned 10px from viewport bottom
const dropdownBottom = window.innerHeight - 10;
const spaceBelow = window.innerHeight - dropdownBottom;
const shouldFlipUpward = spaceBelow < 20;
expect(shouldFlipUpward).toBe(true);
});
it("should apply top-full class when sufficient space below", () => {
const mockBottom = 300; // Plenty of space below
const viewportHeight = 1080;
const spaceBelow = viewportHeight - mockBottom;
const shouldFlipUpward = spaceBelow < 20;
expect(shouldFlipUpward).toBe(false);
});
it("should use 20px threshold for flip decision", () => {
const threshold = 20;
// Just above threshold - should not flip
const spaceBelowAbove = 21;
expect(spaceBelowAbove < threshold).toBe(false);
// Just below threshold - should flip
const spaceBelowBelow = 19;
expect(spaceBelowBelow < threshold).toBe(true);
// Exactly at threshold - should flip
const spaceBelowExact = 20;
expect(spaceBelowExact < threshold).toBe(false);
});
it("should calculate space below correctly", () => {
const viewportHeight = 1080;
const dropdownBottom = 950;
const expectedSpaceBelow = viewportHeight - dropdownBottom;
expect(expectedSpaceBelow).toBe(130);
expect(expectedSpaceBelow < 20).toBe(false); // Should not flip
});
it("should handle edge case at exact viewport bottom", () => {
const viewportHeight = 1080;
const dropdownBottom = 1080; // Exactly at bottom
const spaceBelow = viewportHeight - dropdownBottom;
expect(spaceBelow).toBe(0);
expect(spaceBelow < 20).toBe(true); // Should flip
});
it("should handle edge case beyond viewport", () => {
const viewportHeight = 1080;
const dropdownBottom = 1100; // Beyond viewport
const spaceBelow = viewportHeight - dropdownBottom;
expect(spaceBelow).toBe(-20);
expect(spaceBelow < 20).toBe(true); // Should flip
});
});
describe("Select Dropdown - CSS Classes", () => {
it("should use correct classes for downward expansion", () => {
const flipUpward = false;
const classes = flipUpward ? "bottom-full mb-1" : "top-full mt-1";
expect(classes).toBe("top-full mt-1");
});
it("should use correct classes for upward expansion", () => {
const flipUpward = true;
const classes = flipUpward ? "bottom-full mb-1" : "top-full mt-1";
expect(classes).toBe("bottom-full mb-1");
});
it("should include common classes regardless of flip direction", () => {
const commonClasses = "absolute z-50 max-h-60 w-full overflow-auto rounded-md border bg-card p-1 shadow-md";
// These classes should always be present
expect(commonClasses).toContain("absolute");
expect(commonClasses).toContain("z-50");
expect(commonClasses).toContain("max-h-60");
});
});