From 0ccd1068f03c28b886717c71baf10b8aa337a103 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 17 Apr 2026 06:43:51 +0000 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=A7=AA=20Add=20tests=20for=20ProfileC?= =?UTF-8?q?ard=20component?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: is0692vs <135803462+is0692vs@users.noreply.github.com> --- src/components/__tests__/ProfileCard.test.tsx | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 src/components/__tests__/ProfileCard.test.tsx diff --git a/src/components/__tests__/ProfileCard.test.tsx b/src/components/__tests__/ProfileCard.test.tsx new file mode 100644 index 0000000..88152b8 --- /dev/null +++ b/src/components/__tests__/ProfileCard.test.tsx @@ -0,0 +1,126 @@ +// @vitest-environment jsdom +import { describe, it, expect } from "vitest"; +import { render, screen } from "@testing-library/react"; +import "@testing-library/jest-dom"; +import ProfileCard from "../ProfileCard"; +import type { UserProfile } from "@/lib/types"; + +const mockProfile: UserProfile = { + login: "octocat", + avatar_url: "https://github.com/images/error/octocat_happy.gif", + name: "The Octocat", + bio: "I'm a GitHub mascot.", + company: "@github", + location: "San Francisco", + blog: "https://github.blog", + twitter_username: "github", + created_at: "2011-01-25T18:44:36Z", + followers: 1000, + following: 50, + public_repos: 100, + orgs: [ + { login: "github", avatar_url: "https://avatars.githubusercontent.com/u/9919?v=4" } + ], + pinnedRepos: [ + { + name: "Spoon-Knife", + description: "This repo is for demonstration purposes only.", + url: "https://github.com/octocat/Spoon-Knife", + stargazerCount: 15000, + primaryLanguage: { name: "HTML", color: "#e34c26" } + } + ] +}; + +describe("ProfileCard", () => { + it("renders basic profile information correctly", () => { + render(); + + // Name and login + expect(screen.getByText("The Octocat")).toBeInTheDocument(); + expect(screen.getByText("@octocat")).toBeInTheDocument(); + + // Stats + expect(screen.getByText("1,000")).toBeInTheDocument(); + expect(screen.getByText("50")).toBeInTheDocument(); + expect(screen.getByText("100")).toBeInTheDocument(); + + // Join date - "Joined January 2011" + expect(screen.getByText(/Joined January 2011/)).toBeInTheDocument(); + }); + + it("falls back to login when name is null", () => { + const profileWithoutName = { ...mockProfile, name: null }; + render(); + + // First heading is the fallback name, and then the paragraph is @login + const headings = screen.getAllByText("octocat"); + expect(headings.length).toBeGreaterThan(0); + }); + + it("renders optional fields when provided", () => { + render(); + + expect(screen.getByText("I'm a GitHub mascot.")).toBeInTheDocument(); + expect(screen.getByText("@github")).toBeInTheDocument(); + expect(screen.getByText("San Francisco")).toBeInTheDocument(); + expect(screen.getByText("github.blog")).toBeInTheDocument(); + }); + + it("does not render optional fields when null", () => { + const minimalProfile = { + ...mockProfile, + bio: null, + company: null, + location: null, + blog: null, + orgs: [], + pinnedRepos: [] + }; + render(); + + expect(screen.queryByText("I'm a GitHub mascot.")).not.toBeInTheDocument(); + expect(screen.queryByText("@github")).not.toBeInTheDocument(); + expect(screen.queryByText("San Francisco")).not.toBeInTheDocument(); + expect(screen.queryByText("github.blog")).not.toBeInTheDocument(); + expect(screen.queryByText("Organizations")).not.toBeInTheDocument(); + expect(screen.queryByText("Pinned Repositories")).not.toBeInTheDocument(); + }); + + it("renders organizations correctly", () => { + render(); + expect(screen.getByText("Organizations")).toBeInTheDocument(); + // Org name should be a span or text + const orgElement = screen.getByText("github"); + expect(orgElement).toBeInTheDocument(); + }); + + it("renders pinned repositories correctly", () => { + render(); + expect(screen.getByText("Pinned Repositories")).toBeInTheDocument(); + expect(screen.getByText("Spoon-Knife")).toBeInTheDocument(); + expect(screen.getByText("This repo is for demonstration purposes only.")).toBeInTheDocument(); + expect(screen.getByText("HTML")).toBeInTheDocument(); + expect(screen.getByText("15,000")).toBeInTheDocument(); + }); + + it("handles pinned repos without description or language", () => { + const profileWithMinimalRepo = { + ...mockProfile, + pinnedRepos: [ + { + name: "Empty-Repo", + description: null, + url: "https://github.com/octocat/Empty-Repo", + stargazerCount: 0, + primaryLanguage: null + } + ] + }; + render(); + + expect(screen.getByText("Pinned Repositories")).toBeInTheDocument(); + expect(screen.getByText("Empty-Repo")).toBeInTheDocument(); + expect(screen.getByText("0")).toBeInTheDocument(); + }); +}); From c2061c7b5a69fdde4395148519981f0ab9e224b6 Mon Sep 17 00:00:00 2001 From: is0692vs Date: Fri, 17 Apr 2026 17:07:54 +0900 Subject: [PATCH 2/2] test: make ProfileCard tests more robust Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/components/__tests__/ProfileCard.test.tsx | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/components/__tests__/ProfileCard.test.tsx b/src/components/__tests__/ProfileCard.test.tsx index 88152b8..9a049ae 100644 --- a/src/components/__tests__/ProfileCard.test.tsx +++ b/src/components/__tests__/ProfileCard.test.tsx @@ -41,9 +41,9 @@ describe("ProfileCard", () => { expect(screen.getByText("@octocat")).toBeInTheDocument(); // Stats - expect(screen.getByText("1,000")).toBeInTheDocument(); - expect(screen.getByText("50")).toBeInTheDocument(); - expect(screen.getByText("100")).toBeInTheDocument(); + expect(screen.getByText(mockProfile.followers.toLocaleString())).toBeInTheDocument(); + expect(screen.getByText(mockProfile.following.toLocaleString())).toBeInTheDocument(); + expect(screen.getByText(mockProfile.public_repos.toLocaleString())).toBeInTheDocument(); // Join date - "Joined January 2011" expect(screen.getByText(/Joined January 2011/)).toBeInTheDocument(); @@ -53,9 +53,8 @@ describe("ProfileCard", () => { const profileWithoutName = { ...mockProfile, name: null }; render(); - // First heading is the fallback name, and then the paragraph is @login - const headings = screen.getAllByText("octocat"); - expect(headings.length).toBeGreaterThan(0); + expect(screen.getByRole("heading", { level: 2, name: "octocat" })).toBeInTheDocument(); + expect(screen.getByText("@octocat")).toBeInTheDocument(); }); it("renders optional fields when provided", () => { @@ -89,10 +88,8 @@ describe("ProfileCard", () => { it("renders organizations correctly", () => { render(); - expect(screen.getByText("Organizations")).toBeInTheDocument(); - // Org name should be a span or text - const orgElement = screen.getByText("github"); - expect(orgElement).toBeInTheDocument(); + screen.getByText("Organizations"); + screen.getByText("github"); }); it("renders pinned repositories correctly", () => { @@ -101,7 +98,7 @@ describe("ProfileCard", () => { expect(screen.getByText("Spoon-Knife")).toBeInTheDocument(); expect(screen.getByText("This repo is for demonstration purposes only.")).toBeInTheDocument(); expect(screen.getByText("HTML")).toBeInTheDocument(); - expect(screen.getByText("15,000")).toBeInTheDocument(); + expect(screen.getByText(mockProfile.pinnedRepos[0].stargazerCount.toLocaleString())).toBeInTheDocument(); }); it("handles pinned repos without description or language", () => {