O lugar passa a ser da contagem de projetos desenvolvidos do GitHub. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
121 lines
3.9 KiB
TypeScript
121 lines
3.9 KiB
TypeScript
import { fireEvent, render, screen } from "@testing-library/react";
|
|
import type { ReactNode } from "react";
|
|
|
|
import Hero, { roundedRepoFloor } from "./Hero";
|
|
|
|
jest.mock("motion/react", () => {
|
|
const React = require("react");
|
|
|
|
const motion = new Proxy(
|
|
{},
|
|
{
|
|
get: (_, tag: string) => {
|
|
const Component = ({
|
|
children,
|
|
initial: _initial,
|
|
animate: _animate,
|
|
transition: _transition,
|
|
...props
|
|
}: { children?: ReactNode } & Record<string, unknown>) =>
|
|
React.createElement(tag, props, children);
|
|
Component.displayName = `motion.${tag}`;
|
|
return Component;
|
|
},
|
|
},
|
|
);
|
|
|
|
return { motion, useReducedMotion: () => false };
|
|
});
|
|
|
|
describe("Hero", () => {
|
|
beforeEach(() => {
|
|
jest.spyOn(window, "open").mockImplementation(() => null);
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.restoreAllMocks();
|
|
});
|
|
|
|
it("routes project conversations to contact without opening an external service", () => {
|
|
render(<Hero />);
|
|
|
|
const contactLink = screen.getByRole("link", {
|
|
name: /conversar/i,
|
|
});
|
|
expect(contactLink).toHaveAttribute("href", "/#contact");
|
|
expect(contactLink).not.toHaveAttribute("target", "_blank");
|
|
fireEvent.click(contactLink);
|
|
expect(window.open).not.toHaveBeenCalled();
|
|
expect(screen.getByRole("link", { name: /ver projetos/i })).toHaveAttribute(
|
|
"href",
|
|
"/cases",
|
|
);
|
|
});
|
|
|
|
it("keeps the headline as one readable sentence despite the per-word animation", () => {
|
|
render(<Hero />);
|
|
|
|
expect(screen.getByRole("heading", { level: 1 })).toHaveTextContent(
|
|
"Sistemas sob medida para operações que não cabem em soluções prontas.",
|
|
);
|
|
});
|
|
|
|
it("keeps social destinations with isolated external tabs", () => {
|
|
render(<Hero />);
|
|
|
|
expect(screen.getByRole("link", { name: "GitHub" })).toHaveAttribute(
|
|
"href",
|
|
"https://github.com/evandrodevbr",
|
|
);
|
|
expect(screen.getByRole("link", { name: "LinkedIn" })).toHaveAttribute(
|
|
"href",
|
|
"https://www.linkedin.com/in/evandro-fonseca-junior-0969aa1b0/",
|
|
);
|
|
expect(screen.getByRole("link", { name: "Email" })).toHaveAttribute(
|
|
"href",
|
|
"mailto:[email protected]",
|
|
);
|
|
for (const name of ["GitHub", "LinkedIn"]) {
|
|
const link = screen.getByRole("link", { name });
|
|
expect(link).toHaveAttribute("target", "_blank");
|
|
expect(link).toHaveAttribute("rel", "noopener noreferrer");
|
|
}
|
|
});
|
|
|
|
it("shows the real GitHub repo count with the public/private breakdown", () => {
|
|
render(<Hero stats={{ repos: { total: 68, public: 25, private: 43 } }} />);
|
|
|
|
expect(screen.getByText("projetos desenvolvidos")).toBeInTheDocument();
|
|
expect(screen.getByText("Mais de")).toBeInTheDocument();
|
|
expect(screen.getByText("65")).toBeInTheDocument();
|
|
expect(screen.getByText("25 públicos · 43 privados")).toBeInTheDocument();
|
|
expect(screen.queryByText(/projetos publicados/i)).not.toBeInTheDocument();
|
|
expect(screen.queryByText(/demonstração online/i)).not.toBeInTheDocument();
|
|
});
|
|
|
|
it("rounds the repo count down so 'mais de' is always true", () => {
|
|
expect(roundedRepoFloor(68)).toBe(65);
|
|
expect(roundedRepoFloor(66)).toBe(65);
|
|
expect(roundedRepoFloor(65)).toBe(60);
|
|
expect(roundedRepoFloor(6)).toBe(5);
|
|
expect(roundedRepoFloor(5)).toBe(0);
|
|
});
|
|
|
|
it("hides the repo count while the total is too small to round", () => {
|
|
render(<Hero stats={{ repos: { total: 4, public: 2, private: 2 } }} />);
|
|
|
|
expect(
|
|
screen.queryByText(/projetos desenvolvidos/i),
|
|
).not.toBeInTheDocument();
|
|
});
|
|
|
|
it("omits the repo count when the GitHub lookup is unavailable", () => {
|
|
render(<Hero stats={{ years: 5 }} />);
|
|
|
|
expect(screen.getByText("anos de experiência")).toBeInTheDocument();
|
|
expect(
|
|
screen.queryByText(/projetos desenvolvidos/i),
|
|
).not.toBeInTheDocument();
|
|
});
|
|
});
|