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", () => {