@@ -34,6 +34,7 @@ const exampleUserData: User = {
34
34
totalCommitContributions : 1200 ,
35
35
restrictedContributionsCount : 130 ,
36
36
totalPullRequestReviewContributions : 340 ,
37
+ joinedAt : "2020-01-01T00:00:00Z" ,
37
38
} ;
38
39
39
40
describe ( "Test GitHub Readme Profile API" , ( ) => {
@@ -68,6 +69,17 @@ describe("Test GitHub Readme Profile API", () => {
68
69
expect ( mockResponse . setHeader ) . toHaveBeenCalledWith ( "Cache-Control" , "s-maxage=7200, stale-while-revalidate" ) ;
69
70
} ) ;
70
71
72
+ it ( "should return an error response when GitHub API fails" , async ( ) => {
73
+ mockRequest . query . username = "FajarKim" ;
74
+ mockRequest . query . format = "json" ;
75
+ ( getData as jest . Mock ) . mockRejectedValueOnce ( new Error ( "GitHub API error" ) ) ;
76
+
77
+ await readmeStats ( mockRequest , mockResponse ) ;
78
+
79
+ expect ( mockResponse . status ) . toHaveBeenCalledWith ( 500 ) ;
80
+ expect ( mockResponse . send ) . toHaveBeenCalledWith ( "Error fetching data from GitHub API" ) ;
81
+ } ) ;
82
+
71
83
it ( "should handle request and generate SVG response" , async ( ) => {
72
84
mockRequest . query . username = "FajarKim" ;
73
85
mockRequest . query . format = "svg" ;
@@ -148,4 +160,81 @@ describe("Test GitHub Readme Profile API", () => {
148
160
expect ( mockResponse . send ) . toHaveBeenCalled ( ) ;
149
161
expect ( mockResponse . json ) . not . toHaveBeenCalled ( ) ;
150
162
} ) ;
163
+
164
+ it ( "should validate User data conforms to interface" , async ( ) => {
165
+ mockRequest . query . username = "FajarKim" ;
166
+ ( getData as jest . Mock ) . mockResolvedValueOnce ( exampleUserData ) ;
167
+
168
+ await readmeStats ( mockRequest , mockResponse ) ;
169
+
170
+ const userData = mockResponse . json . mock . calls [ 0 ] [ 0 ] ;
171
+ expect ( userData ) . toHaveProperty ( "name" ) ;
172
+ expect ( userData ) . toHaveProperty ( "login" ) ;
173
+ expect ( userData ) . toHaveProperty ( "avatarUrl" ) ;
174
+ expect ( userData . repositories . totalCount ) . toBeGreaterThanOrEqual ( 0 ) ;
175
+ } ) ;
176
+
177
+ it ( "should handle user with zero contributions" , async ( ) => {
178
+ const zeroContributionsData = {
179
+ ...exampleUserData ,
180
+ totalCommitContributions : 0 ,
181
+ restrictedContributionsCount : 0 ,
182
+ totalPullRequestReviewContributions : 0 ,
183
+ } ;
184
+
185
+ ( getData as jest . Mock ) . mockResolvedValueOnce ( zeroContributionsData ) ;
186
+
187
+ mockRequest . query . username = "FajarKim" ;
188
+
189
+ await readmeStats ( mockRequest , mockResponse ) ;
190
+
191
+ expect ( mockResponse . json ) . toHaveBeenCalledWith ( zeroContributionsData ) ;
192
+ } ) ;
193
+
194
+ it ( "should handle very large contribution data without errors" , async ( ) => {
195
+ const highContributionsData = {
196
+ ...exampleUserData ,
197
+ totalCommitContributions : 100000 ,
198
+ restrictedContributionsCount : 50000 ,
199
+ totalPullRequestReviewContributions : 30000 ,
200
+ } ;
201
+
202
+ ( getData as jest . Mock ) . mockResolvedValueOnce ( highContributionsData ) ;
203
+
204
+ mockRequest . query . username = "FajarKim" ;
205
+
206
+ await readmeStats ( mockRequest , mockResponse ) ;
207
+
208
+ expect ( mockResponse . json ) . toHaveBeenCalledWith ( highContributionsData ) ;
209
+ } ) ;
210
+
211
+ it ( "should fetch the user's join date and calculate total commits from join date until now" , async ( ) => {
212
+ mockRequest . query . username = "FajarKim" ;
213
+ ( getData as jest . Mock ) . mockResolvedValueOnce ( exampleUserData ) ;
214
+
215
+ const today = new Date ( "2023-10-26" ) ;
216
+ const joinDate = new Date ( exampleUserData . joinedAt ) ;
217
+ const totalDaysSinceJoining = Math . floor ( ( today . getTime ( ) - joinDate . getTime ( ) ) / ( 1000 * 60 * 60 * 24 ) ) ;
218
+
219
+ await readmeStats ( mockRequest , mockResponse ) ;
220
+
221
+ const responseData = mockResponse . json . mock . calls [ 0 ] [ 0 ] ;
222
+ expect ( responseData . joinedAt ) . toEqual ( exampleUserData . joinedAt ) ;
223
+
224
+ const expectedTotalCommits = exampleUserData . totalCommitContributions + totalDaysSinceJoining ;
225
+ expect ( responseData . totalCommitContributionsSinceJoining ) . toEqual ( expectedTotalCommits ) ;
226
+ } ) ;
227
+
228
+ it ( "should handle missing join date gracefully" , async ( ) => {
229
+ const incompleteUserData = { ...exampleUserData , joinedAt : undefined } ;
230
+ ( getData as jest . Mock ) . mockResolvedValueOnce ( incompleteUserData ) ;
231
+
232
+ mockRequest . query . username = "FajarKim" ;
233
+
234
+ await readmeStats ( mockRequest , mockResponse ) ;
235
+
236
+ const responseData = mockResponse . json . mock . calls [ 0 ] [ 0 ] ;
237
+ expect ( responseData . joinedAt ) . toBeUndefined ( ) ;
238
+ expect ( responseData . totalCommitContributionsSinceJoining ) . toBeUndefined ( ) ;
239
+ } ) ;
151
240
} ) ;
0 commit comments