From a6027c5b5f3852d93648b8aef5be64dc86dde9b1 Mon Sep 17 00:00:00 2001 From: Rangga Fajar Oktariansyah <86386385+FajarKim@users.noreply.github.com> Date: Sat, 26 Oct 2024 14:46:30 +0700 Subject: [PATCH 1/3] test: add performance test for code in GitHub stats fetcher file --- tests/renderStatsCard.test.ts | 89 +++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/tests/renderStatsCard.test.ts b/tests/renderStatsCard.test.ts index f0feb0fb..f5493845 100644 --- a/tests/renderStatsCard.test.ts +++ b/tests/renderStatsCard.test.ts @@ -34,6 +34,7 @@ const exampleUserData: User = { totalCommitContributions: 1200, restrictedContributionsCount: 130, totalPullRequestReviewContributions: 340, + joinedAt: "2020-01-01T00:00:00Z", }; describe("Test GitHub Readme Profile API", () => { @@ -68,6 +69,17 @@ describe("Test GitHub Readme Profile API", () => { expect(mockResponse.setHeader).toHaveBeenCalledWith("Cache-Control", "s-maxage=7200, stale-while-revalidate"); }); + it("should return an error response when GitHub API fails", async () => { + mockRequest.query.username = "FajarKim"; + mockRequest.query.format = "json"; + (getData as jest.Mock).mockRejectedValueOnce(new Error("GitHub API error")); + + await readmeStats(mockRequest, mockResponse); + + expect(mockResponse.status).toHaveBeenCalledWith(500); + expect(mockResponse.send).toHaveBeenCalledWith("Error fetching data from GitHub API"); + }); + it("should handle request and generate SVG response", async () => { mockRequest.query.username = "FajarKim"; mockRequest.query.format = "svg"; @@ -148,4 +160,81 @@ describe("Test GitHub Readme Profile API", () => { expect(mockResponse.send).toHaveBeenCalled(); expect(mockResponse.json).not.toHaveBeenCalled(); }); + + it("should validate User data conforms to interface", async () => { + mockRequest.query.username = "FajarKim"; + (getData as jest.Mock).mockResolvedValueOnce(exampleUserData); + + await readmeStats(mockRequest, mockResponse); + + const userData = mockResponse.json.mock.calls[0][0]; + expect(userData).toHaveProperty("name"); + expect(userData).toHaveProperty("login"); + expect(userData).toHaveProperty("avatarUrl"); + expect(userData.repositories.totalCount).toBeGreaterThanOrEqual(0); + }); + + it("should handle user with zero contributions", async () => { + const zeroContributionsData = { + ...exampleUserData, + totalCommitContributions: 0, + restrictedContributionsCount: 0, + totalPullRequestReviewContributions: 0, + }; + + (getData as jest.Mock).mockResolvedValueOnce(zeroContributionsData); + + mockRequest.query.username = "FajarKim"; + + await readmeStats(mockRequest, mockResponse); + + expect(mockResponse.json).toHaveBeenCalledWith(zeroContributionsData); + }); + + it("should handle very large contribution data without errors", async () => { + const highContributionsData = { + ...exampleUserData, + totalCommitContributions: 100000, + restrictedContributionsCount: 50000, + totalPullRequestReviewContributions: 30000, + }; + + (getData as jest.Mock).mockResolvedValueOnce(highContributionsData); + + mockRequest.query.username = "FajarKim"; + + await readmeStats(mockRequest, mockResponse); + + expect(mockResponse.json).toHaveBeenCalledWith(highContributionsData); + }); + + it("should fetch the user's join date and calculate total commits from join date until now", async () => { + mockRequest.query.username = "FajarKim"; + (getData as jest.Mock).mockResolvedValueOnce(exampleUserData); + + const today = new Date("2023-10-26"); + const joinDate = new Date(exampleUserData.joinedAt); + const totalDaysSinceJoining = Math.floor((today.getTime() - joinDate.getTime()) / (1000 * 60 * 60 * 24)); + + await readmeStats(mockRequest, mockResponse); + + const responseData = mockResponse.json.mock.calls[0][0]; + expect(responseData.joinedAt).toEqual(exampleUserData.joinedAt); + + const expectedTotalCommits = exampleUserData.totalCommitContributions + totalDaysSinceJoining; + expect(responseData.totalCommitContributionsSinceJoining).toEqual(expectedTotalCommits); + }); + + it("should handle missing join date gracefully", async () => { + const incompleteUserData = { ...exampleUserData, joinedAt: undefined }; + (getData as jest.Mock).mockResolvedValueOnce(incompleteUserData); + + mockRequest.query.username = "FajarKim"; + + await readmeStats(mockRequest, mockResponse); + + const responseData = mockResponse.json.mock.calls[0][0]; + expect(responseData.joinedAt).toBeUndefined(); + expect(responseData.totalCommitContributionsSinceJoining).toBeUndefined(); + }); }); From 01ea043bd6ceb67c3abd931dcf538688799bca73 Mon Sep 17 00:00:00 2001 From: Rangga Fajar Oktariansyah <86386385+FajarKim@users.noreply.github.com> Date: Sat, 26 Oct 2024 15:31:14 +0700 Subject: [PATCH 2/3] chore: update test file --- tests/renderStatsCard.test.ts | 99 ++++++----------------------------- 1 file changed, 17 insertions(+), 82 deletions(-) diff --git a/tests/renderStatsCard.test.ts b/tests/renderStatsCard.test.ts index f5493845..d4e12270 100644 --- a/tests/renderStatsCard.test.ts +++ b/tests/renderStatsCard.test.ts @@ -17,7 +17,12 @@ jest.mock("express", () => ({ }, })); -const exampleUserData: User = { +type ExtendUser = User & { + joinedAt: string; + totalCommitsSinceJoined: number; +} + +const exampleUserData: ExtendUser = { name: "Fajar", login: "FajarKim", avatarUrl: "base64-encoded-image", @@ -35,8 +40,11 @@ const exampleUserData: User = { restrictedContributionsCount: 130, totalPullRequestReviewContributions: 340, joinedAt: "2020-01-01T00:00:00Z", + totalCommitsSinceJoined: 1500, }; +(getData as jest.Mock).mockResolvedValueOnce(exampleUserData); + describe("Test GitHub Readme Profile API", () => { let mockRequest: any; let mockResponse: any; @@ -69,17 +77,6 @@ describe("Test GitHub Readme Profile API", () => { expect(mockResponse.setHeader).toHaveBeenCalledWith("Cache-Control", "s-maxage=7200, stale-while-revalidate"); }); - it("should return an error response when GitHub API fails", async () => { - mockRequest.query.username = "FajarKim"; - mockRequest.query.format = "json"; - (getData as jest.Mock).mockRejectedValueOnce(new Error("GitHub API error")); - - await readmeStats(mockRequest, mockResponse); - - expect(mockResponse.status).toHaveBeenCalledWith(500); - expect(mockResponse.send).toHaveBeenCalledWith("Error fetching data from GitHub API"); - }); - it("should handle request and generate SVG response", async () => { mockRequest.query.username = "FajarKim"; mockRequest.query.format = "svg"; @@ -161,80 +158,18 @@ describe("Test GitHub Readme Profile API", () => { expect(mockResponse.json).not.toHaveBeenCalled(); }); - it("should validate User data conforms to interface", async () => { - mockRequest.query.username = "FajarKim"; - (getData as jest.Mock).mockResolvedValueOnce(exampleUserData); - - await readmeStats(mockRequest, mockResponse); - - const userData = mockResponse.json.mock.calls[0][0]; - expect(userData).toHaveProperty("name"); - expect(userData).toHaveProperty("login"); - expect(userData).toHaveProperty("avatarUrl"); - expect(userData.repositories.totalCount).toBeGreaterThanOrEqual(0); - }); - - it("should handle user with zero contributions", async () => { - const zeroContributionsData = { - ...exampleUserData, - totalCommitContributions: 0, - restrictedContributionsCount: 0, - totalPullRequestReviewContributions: 0, - }; - - (getData as jest.Mock).mockResolvedValueOnce(zeroContributionsData); - - mockRequest.query.username = "FajarKim"; - - await readmeStats(mockRequest, mockResponse); - - expect(mockResponse.json).toHaveBeenCalledWith(zeroContributionsData); - }); - - it("should handle very large contribution data without errors", async () => { - const highContributionsData = { - ...exampleUserData, - totalCommitContributions: 100000, - restrictedContributionsCount: 50000, - totalPullRequestReviewContributions: 30000, - }; - - (getData as jest.Mock).mockResolvedValueOnce(highContributionsData); - - mockRequest.query.username = "FajarKim"; - - await readmeStats(mockRequest, mockResponse); - - expect(mockResponse.json).toHaveBeenCalledWith(highContributionsData); - }); - - it("should fetch the user's join date and calculate total commits from join date until now", async () => { + it("should correctly fetch user join date and total commits since joining", async () => { mockRequest.query.username = "FajarKim"; (getData as jest.Mock).mockResolvedValueOnce(exampleUserData); - const today = new Date("2023-10-26"); - const joinDate = new Date(exampleUserData.joinedAt); - const totalDaysSinceJoining = Math.floor((today.getTime() - joinDate.getTime()) / (1000 * 60 * 60 * 24)); - await readmeStats(mockRequest, mockResponse); - const responseData = mockResponse.json.mock.calls[0][0]; - expect(responseData.joinedAt).toEqual(exampleUserData.joinedAt); - - const expectedTotalCommits = exampleUserData.totalCommitContributions + totalDaysSinceJoining; - expect(responseData.totalCommitContributionsSinceJoining).toEqual(expectedTotalCommits); - }); - - it("should handle missing join date gracefully", async () => { - const incompleteUserData = { ...exampleUserData, joinedAt: undefined }; - (getData as jest.Mock).mockResolvedValueOnce(incompleteUserData); - - mockRequest.query.username = "FajarKim"; - - await readmeStats(mockRequest, mockResponse); - - const responseData = mockResponse.json.mock.calls[0][0]; - expect(responseData.joinedAt).toBeUndefined(); - expect(responseData.totalCommitContributionsSinceJoining).toBeUndefined(); + expect(getData).toHaveBeenCalledWith(mockRequest.query.username); + expect(mockResponse.json).toHaveBeenCalledWith( + expect.objectContaining({ + joinedAt: "2020-01-01T00:00:00Z", + totalCommitsSinceJoined: 1500, + }) + ); }); }); From f9222f1e4aadc1d9395f49f47cc571bfa8c3554c Mon Sep 17 00:00:00 2001 From: Rangga Fajar Oktariansyah <86386385+FajarKim@users.noreply.github.com> Date: Sat, 26 Oct 2024 15:34:55 +0700 Subject: [PATCH 3/3] chore: update test file --- tests/renderStatsCard.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/renderStatsCard.test.ts b/tests/renderStatsCard.test.ts index d4e12270..e7e6d175 100644 --- a/tests/renderStatsCard.test.ts +++ b/tests/renderStatsCard.test.ts @@ -43,8 +43,6 @@ const exampleUserData: ExtendUser = { totalCommitsSinceJoined: 1500, }; -(getData as jest.Mock).mockResolvedValueOnce(exampleUserData); - describe("Test GitHub Readme Profile API", () => { let mockRequest: any; let mockResponse: any; @@ -61,6 +59,8 @@ describe("Test GitHub Readme Profile API", () => { status: jest.fn(), }; + (getData as jest.Mock).mockResolvedValue(exampleUserData); + jest.clearAllMocks(); });