Repository: anuraghazra/github-readme-stats
Pull request #3234 (2023-09-15 11:12:32)

infra: enable no-use-before-define eslint rule
https://eslint.org/docs/latest/rules/no-use-before-define

vercel[bot]: [vc]: #Qimq2SiTBmaWmpvUqMfmFadjJ6FwMmdpxgS2ss3IUA8=:eyJpc01vbm9yZXBvIjp0cnVlLCJ0eXBlIjoiZ2l0aHViIiwicHJvamVjdHMiOlt7Im5hbWUiOiJnaXRodWItcmVhZG1lLXN0YXRzIiwiaW5zcGVjdG9yVXJsIjoiaHR0cHM6Ly92ZXJjZWwuY29tL2dpdGh1Yi1yZWFkbWUtc3RhdHMtdGVhbS9naXRodWItcmVhZG1lLXN0YXRzLzJxRU1hRmQ2ZTJtRk5RZ1ZVY3B6ZFZ3YkhUWFgiLCJwcmV2aWV3VXJsIjoiZ2l0aHViLXJlYWRtZS1zdGF0cy1naXQtaW5mcmFlbi03OTRiZjItZ2l0aHViLXJlYWRtZS1zdGF0cy10ZWFtLnZlcmNlbC5hcHAiLCJuZXh0Q29tbWl0U3RhdHVzIjoiREVQTE9ZRUQifV19
**The latest updates on your projects**. Learn more about [Vercel for Git ↗︎](https://vercel.link/github-learn-more)

| Name | Status | Preview | Updated (UTC) |
| :--- | :----- | :------ | :------ |
| **github-readme-stats** | ✅ Ready ([Inspect](https://vercel.com/github-readme-stats-team/github-readme-stats/2qEMaFd6e2mFNQgVUcpzdVwbHTXX)) | [Visit Preview](https://github-readme-stats-git-infraen-794bf2-github-readme-stats-team.vercel.app) | Sep 15, 2023 11:12am |


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/anuraghazra/github-readme-stats/pull/3234?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Anurag+Hazra) Report
Patch coverage: **`100.00%`** and no project coverage change.
> Comparison is base [(`6370d0c`)](https://app.codecov.io/gh/anuraghazra/github-readme-stats/commit/6370d0c44d5574c449ee70f62dd18a835434f8ab?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Anurag+Hazra) 98.38% compared to head [(`612f6ba`)](https://app.codecov.io/gh/anuraghazra/github-readme-stats/pull/3234?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Anurag+Hazra) 98.38%.

<details><summary>Additional details and impacted files</summary>


```diff
@@           Coverage Diff           @@
##           master    #3234   +/-   ##
=======================================
  Coverage   98.38%   98.38%           
=======================================
  Files          27       27           
  Lines        5884     5884           
  Branches      525      525           
=======================================
  Hits         5789     5789           
  Misses         92       92           
  Partials        3        3           
```


| [Files Changed](https://app.codecov.io/gh/anuraghazra/github-readme-stats/pull/3234?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Anurag+Hazra) | Coverage Δ | |
|---|---|---|
| [src/common/utils.js](https://app.codecov.io/gh/anuraghazra/github-readme-stats/pull/3234?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Anurag+Hazra#diff-c3JjL2NvbW1vbi91dGlscy5qcw==) | `98.93% <100.00%> (ø)` | |
| [src/fetchers/gist-fetcher.js](https://app.codecov.io/gh/anuraghazra/github-readme-stats/pull/3234?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Anurag+Hazra#diff-c3JjL2ZldGNoZXJzL2dpc3QtZmV0Y2hlci5qcw==) | `100.00% <100.00%> (ø)` | |


</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/anuraghazra/github-readme-stats/pull/3234?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Anurag+Hazra).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Anurag+Hazra).


Patch:
diff --git a/.eslintrc.json b/.eslintrc.json
index 88030d9..7b2160f 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -128,7 +128,7 @@
 
         // Disallow hoisting - let & const don't allow hoisting anyhow
 
-        // "no-use-before-define": "error",
+        "no-use-before-define": "error",
 
         // Node.js and CommonJS
 
diff --git a/api/gist.js b/api/gist.js
index 3134bb5..3e7dca0 100644
--- a/api/gist.js
+++ b/api/gist.js
@@ -77,7 +77,12 @@ export default async (req, res) => {
       }),
     );
   } catch (err) {
-    res.setHeader("Cache-Control", `no-cache, no-store, must-revalidate`); // Don't cache error responses.
+    res.setHeader(
+      "Cache-Control",
+      `max-age=${CONSTANTS.ERROR_CACHE_SECONDS / 2}, s-maxage=${
+        CONSTANTS.ERROR_CACHE_SECONDS
+      }, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
+    ); // Use lower cache period for errors.
     return res.send(renderError(err.message, err.secondaryMessage));
   }
 };
diff --git a/api/index.js b/api/index.js
index d171c80..c513f7c 100644
--- a/api/index.js
+++ b/api/index.js
@@ -57,7 +57,7 @@ export default async (req, res) => {
     );
 
     let cacheSeconds = clampValue(
-      parseInt(cache_seconds || CONSTANTS.FOUR_HOURS, 10),
+      parseInt(cache_seconds || CONSTANTS.CARD_CACHE_SECONDS, 10),
       CONSTANTS.FOUR_HOURS,
       CONSTANTS.ONE_DAY,
     );
@@ -100,7 +100,12 @@ export default async (req, res) => {
       }),
     );
   } catch (err) {
-    res.setHeader("Cache-Control", `no-cache, no-store, must-revalidate`); // Don't cache error responses.
+    res.setHeader(
+      "Cache-Control",
+      `max-age=${CONSTANTS.ERROR_CACHE_SECONDS / 2}, s-maxage=${
+        CONSTANTS.ERROR_CACHE_SECONDS
+      }, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
+    ); // Use lower cache period for errors.
     return res.send(renderError(err.message, err.secondaryMessage));
   }
 };
diff --git a/api/pin.js b/api/pin.js
index 3383b00..d505746 100644
--- a/api/pin.js
+++ b/api/pin.js
@@ -40,7 +40,7 @@ export default async (req, res) => {
     const repoData = await fetchRepo(username, repo);
 
     let cacheSeconds = clampValue(
-      parseInt(cache_seconds || CONSTANTS.FOUR_HOURS, 10),
+      parseInt(cache_seconds || CONSTANTS.CARD_CACHE_SECONDS, 10),
       CONSTANTS.FOUR_HOURS,
       CONSTANTS.ONE_DAY,
     );
@@ -83,7 +83,12 @@ export default async (req, res) => {
       }),
     );
   } catch (err) {
-    res.setHeader("Cache-Control", `no-cache, no-store, must-revalidate`); // Don't cache error responses.
+    res.setHeader(
+      "Cache-Control",
+      `max-age=${CONSTANTS.ERROR_CACHE_SECONDS / 2}, s-maxage=${
+        CONSTANTS.ERROR_CACHE_SECONDS
+      }, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
+    ); // Use lower cache period for errors.
     return res.send(renderError(err.message, err.secondaryMessage));
   }
 };
diff --git a/api/top-langs.js b/api/top-langs.js
index fdb6702..5596751 100644
--- a/api/top-langs.js
+++ b/api/top-langs.js
@@ -63,7 +63,7 @@ export default async (req, res) => {
     );
 
     let cacheSeconds = clampValue(
-      parseInt(cache_seconds || CONSTANTS.FOUR_HOURS, 10),
+      parseInt(cache_seconds || CONSTANTS.CARD_CACHE_SECONDS, 10),
       CONSTANTS.FOUR_HOURS,
       CONSTANTS.ONE_DAY,
     );
@@ -99,7 +99,12 @@ export default async (req, res) => {
       }),
     );
   } catch (err) {
-    res.setHeader("Cache-Control", `no-cache, no-store, must-revalidate`); // Don't cache error responses.
+    res.setHeader(
+      "Cache-Control",
+      `max-age=${CONSTANTS.ERROR_CACHE_SECONDS / 2}, s-maxage=${
+        CONSTANTS.ERROR_CACHE_SECONDS
+      }, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
+    ); // Use lower cache period for errors.
     return res.send(renderError(err.message, err.secondaryMessage));
   }
 };
diff --git a/api/wakatime.js b/api/wakatime.js
index ec0c813..65f026e 100644
--- a/api/wakatime.js
+++ b/api/wakatime.js
@@ -42,7 +42,7 @@ export default async (req, res) => {
     const stats = await fetchWakatimeStats({ username, api_domain });
 
     let cacheSeconds = clampValue(
-      parseInt(cache_seconds || CONSTANTS.FOUR_HOURS, 10),
+      parseInt(cache_seconds || CONSTANTS.CARD_CACHE_SECONDS, 10),
       CONSTANTS.FOUR_HOURS,
       CONSTANTS.ONE_DAY,
     );
@@ -50,10 +50,6 @@ export default async (req, res) => {
       ? parseInt(process.env.CACHE_SECONDS, 10) || cacheSeconds
       : cacheSeconds;
 
-    if (!cache_seconds) {
-      cacheSeconds = CONSTANTS.FOUR_HOURS;
-    }
-
     res.setHeader(
       "Cache-Control",
       `max-age=${
@@ -82,7 +78,12 @@ export default async (req, res) => {
       }),
     );
   } catch (err) {
-    res.setHeader("Cache-Control", `no-cache, no-store, must-revalidate`); // Don't cache error responses.
+    res.setHeader(
+      "Cache-Control",
+      `max-age=${CONSTANTS.ERROR_CACHE_SECONDS / 2}, s-maxage=${
+        CONSTANTS.ERROR_CACHE_SECONDS
+      }, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
+    ); // Use lower cache period for errors.
     return res.send(renderError(err.message, err.secondaryMessage));
   }
 };
diff --git a/docs/readme_cn.md b/docs/readme_cn.md
index 386f904..f33f98d 100644
--- a/docs/readme_cn.md
+++ b/docs/readme_cn.md
@@ -189,7 +189,7 @@ dark, radical, merko, gruvbox, tokyonight, onedark, cobalt, synthwave, highcontr
 
 - `hide` - 从卡片中隐藏指定语言 _(Comma seperated values)_
 - `hide_title` - _(boolean)_
-- `layout` - 提供五種佈局 `normal` & `compact` & `donut` & `donut-vertical` & `pie` 间切换
+- `layout` - 提供五种布局 `normal` & `compact` & `donut` & `donut-vertical` & `pie` 间切换
 - `card_width` - 手动设置卡片的宽度 _(number)_
 
 > :warning: **重要:**
@@ -321,7 +321,7 @@ _注意：热门语言并不表示我的技能水平或类似的水平，它是
 
 ## 自己部署
 
-#### [Check Out Step By Step Video Tutorial By @codeSTACKr](https://youtu.be/n6d4KHSKqGk?t=107)
+#### [查看分步视频教程 作者：@codeSTACKr](https://youtu.be/n6d4KHSKqGk?t=107)
 
 因为 GitHub 的 API 每个小时只允许 5 千次请求，我的 `https://github-readme-stats.vercel.app/api` 很有可能会触发限制。如果你将其托管在自己的 Vercel 服务器上，那么你就不必为此担心。点击 deploy 按钮来开始你的部署！
 
diff --git a/src/common/retryer.js b/src/common/retryer.js
index 74f9a0f..3f294d3 100644
--- a/src/common/retryer.js
+++ b/src/common/retryer.js
@@ -72,5 +72,5 @@ const retryer = async (fetcher, variables, retries = 0) => {
   }
 };
 
-export { retryer };
+export { retryer, RETRIES };
 export default retryer;
diff --git a/src/common/utils.js b/src/common/utils.js
index 871c493..f1f74b6 100644
--- a/src/common/utils.js
+++ b/src/common/utils.js
@@ -7,6 +7,22 @@ import { themes } from "../../themes/index.js";
 // Script parameters.
 const ERROR_CARD_LENGTH = 576.5;
 
+/**
+ * Encode string as HTML.
+ *
+ * @see https://stackoverflow.com/a/48073476/10629172
+ *
+ * @param {string} str String to encode.
+ * @returns {string} Encoded string.
+ */
+const encodeHTML = (str) => {
+  return str
+    .replace(/[\u00A0-\u9999<>&](?!#)/gim, (i) => {
+      return "&#" + i.charCodeAt(0) + ";";
+    })
+    .replace(/\u0008/gim, "");
+};
+
 /**
  * Renders error message on the card.
  *
@@ -34,6 +50,31 @@ const renderError = (message, secondaryMessage = "") => {
   `;
 };
 
+/**
+ * Auto layout utility, allows us to layout things vertically or horizontally with
+ * proper gaping.
+ *
+ * @param {object} props Function properties.
+ * @param {string[]} props.items Array of items to layout.
+ * @param {number} props.gap Gap between items.
+ * @param {"column" | "row"=} props.direction Direction to layout items.
+ * @param {number[]=} props.sizes Array of sizes for each item.
+ * @returns {string[]} Array of items with proper layout.
+ */
+const flexLayout = ({ items, gap, direction, sizes = [] }) => {
+  let lastSize = 0;
+  // filter() for filtering out empty strings
+  return items.filter(Boolean).map((item, i) => {
+    const size = sizes[i] || 0;
+    let transform = `translate(${lastSize}, 0)`;
+    if (direction === "column") {
+      transform = `translate(0, ${lastSize})`;
+    }
+    lastSize += size + gap;
+    return `<g transform="${transform}">${item}</g>`;
+  });
+};
+
 /**
  * Creates a node to display the primary programming language of the repository/gist.
  *
@@ -79,22 +120,6 @@ const iconWithLabel = (icon, label, testid, iconSize) => {
   return flexLayout({ items: [iconSvg, text], gap: 20 }).join("");
 };
 
-/**
- * Encode string as HTML.
- *
- * @see https://stackoverflow.com/a/48073476/10629172
- *
- * @param {string} str String to encode.
- * @returns {string} Encoded string.
- */
-const encodeHTML = (str) => {
-  return str
-    .replace(/[\u00A0-\u9999<>&](?!#)/gim, (i) => {
-      return "&#" + i.charCodeAt(0) + ";";
-    })
-    .replace(/\u0008/gim, "");
-};
-
 /**
  * Retrieves num with suffix k(thousands) precise to 1 decimal if greater than 999.
  *
@@ -221,31 +246,6 @@ const request = (data, headers) => {
   });
 };
 
-/**
- * Auto layout utility, allows us to layout things vertically or horizontally with
- * proper gaping.
- *
- * @param {object} props Function properties.
- * @param {string[]} props.items Array of items to layout.
- * @param {number} props.gap Gap between items.
- * @param {"column" | "row"=} props.direction Direction to layout items.
- * @param {number[]=} props.sizes Array of sizes for each item.
- * @returns {string[]} Array of items with proper layout.
- */
-const flexLayout = ({ items, gap, direction, sizes = [] }) => {
-  let lastSize = 0;
-  // filter() for filtering out empty strings
-  return items.filter(Boolean).map((item, i) => {
-    const size = sizes[i] || 0;
-    let transform = `translate(${lastSize}, 0)`;
-    if (direction === "column") {
-      transform = `translate(0, ${lastSize})`;
-    }
-    lastSize += size + gap;
-    return `<g transform="${transform}">${item}</g>`;
-  });
-};
-
 /**
  * Object containing card colors.
  * @typedef {{
@@ -373,11 +373,21 @@ const noop = () => {};
 const logger =
   process.env.NODE_ENV !== "test" ? console : { log: noop, error: noop };
 
+// Cache settings.
+const CARD_CACHE_SECONDS = 14400;
+const ERROR_CACHE_SECONDS = 600;
+
 const CONSTANTS = {
+  ONE_MINUTE: 60,
+  FIVE_MINUTES: 300,
+  TEN_MINUTES: 600,
+  FIFTEEN_MINUTES: 900,
   THIRTY_MINUTES: 1800,
   TWO_HOURS: 7200,
   FOUR_HOURS: 14400,
   ONE_DAY: 86400,
+  CARD_CACHE_SECONDS,
+  ERROR_CACHE_SECONDS,
 };
 
 const SECONDARY_ERROR_MESSAGES = {
diff --git a/src/fetchers/gist-fetcher.js b/src/fetchers/gist-fetcher.js
index ebf5819..4e0e0f5 100644
--- a/src/fetchers/gist-fetcher.js
+++ b/src/fetchers/gist-fetcher.js
@@ -46,6 +46,36 @@ const fetcher = async (variables, token) => {
   );
 };
 
+/**
+ * @typedef {{ name: string; language: { name: string; }, size: number }} GistFile Gist file.
+ */
+
+/**
+ * This function calculates the primary language of a gist by files size.
+ *
+ * @param {GistFile[]} files Files.
+ * @returns {string} Primary language.
+ */
+const calculatePrimaryLanguage = (files) => {
+  const languages = {};
+  for (const file of files) {
+    if (file.language) {
+      if (languages[file.language.name]) {
+        languages[file.language.name] += file.size;
+      } else {
+        languages[file.language.name] = file.size;
+      }
+    }
+  }
+  let primaryLanguage = Object.keys(languages)[0];
+  for (const language in languages) {
+    if (languages[language] > languages[primaryLanguage]) {
+      primaryLanguage = language;
+    }
+  }
+  return primaryLanguage;
+};
+
 /**
  * @typedef {import('./types').GistData} GistData Gist data.
  */
@@ -80,35 +110,5 @@ const fetchGist = async (id) => {
   };
 };
 
-/**
- * @typedef {{ name: string; language: { name: string; }, size: number }} GistFile Gist file.
- */
-
-/**
- * This function calculates the primary language of a gist by files size.
- *
- * @param {GistFile[]} files Files.
- * @returns {string} Primary language.
- */
-const calculatePrimaryLanguage = (files) => {
-  const languages = {};
-  for (const file of files) {
-    if (file.language) {
-      if (languages[file.language.name]) {
-        languages[file.language.name] += file.size;
-      } else {
-        languages[file.language.name] = file.size;
-      }
-    }
-  }
-  let primaryLanguage = Object.keys(languages)[0];
-  for (const language in languages) {
-    if (languages[language] > languages[primaryLanguage]) {
-      primaryLanguage = language;
-    }
-  }
-  return primaryLanguage;
-};
-
 export { fetchGist };
 export default fetchGist;
diff --git a/src/fetchers/stats-fetcher.js b/src/fetchers/stats-fetcher.js
index dd62b46..f021a72 100644
--- a/src/fetchers/stats-fetcher.js
+++ b/src/fetchers/stats-fetcher.js
@@ -153,8 +153,8 @@ const statsFetcher = async (username) => {
  */
 const totalCommitsFetcher = async (username) => {
   if (!githubUsernameRegex.test(username)) {
-    logger.log("Invalid username");
-    return 0;
+    logger.log("Invalid username provided.");
+    throw new Error("Invalid username provided.");
   }
 
   // https://developer.github.com/v3/search/#search-commits
@@ -170,18 +170,19 @@ const totalCommitsFetcher = async (username) => {
     });
   };
 
+  let res;
   try {
-    let res = await retryer(fetchTotalCommits, { login: username });
-    let total_count = res.data.total_count;
-    if (!!total_count && !isNaN(total_count)) {
-      return res.data.total_count;
-    }
+    res = await retryer(fetchTotalCommits, { login: username });
   } catch (err) {
     logger.log(err);
+    throw new Error(err);
+  }
+
+  const totalCount = res.data.total_count;
+  if (!totalCount || isNaN(totalCount)) {
+    throw new Error("Could not fetch total commits.");
   }
-  // just return 0 if there is something wrong so that
-  // we don't break the whole app
-  return 0;
+  return totalCount;
 };
 
 /**


Test patch:
diff --git a/tests/api.test.js b/tests/api.test.js
index d29db22..1353f1f 100644
--- a/tests/api.test.js
+++ b/tests/api.test.js
@@ -184,13 +184,18 @@ describe("Test /api/", () => {
     ]);
   });
 
-  it("should not store cache when error", async () => {
+  it("should set shorter cache when error", async () => {
     const { req, res } = faker({}, error);
     await api(req, res);
 
     expect(res.setHeader.mock.calls).toEqual([
       ["Content-Type", "image/svg+xml"],
-      ["Cache-Control", `no-cache, no-store, must-revalidate`],
+      [
+        "Cache-Control",
+        `max-age=${CONSTANTS.ERROR_CACHE_SECONDS / 2}, s-maxage=${
+          CONSTANTS.ERROR_CACHE_SECONDS
+        }, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
+      ],
     ]);
   });
 
diff --git a/tests/fetchStats.test.js b/tests/fetchStats.test.js
index ac4d0a3..56125d8 100644
--- a/tests/fetchStats.test.js
+++ b/tests/fetchStats.test.js
@@ -210,62 +210,20 @@ describe("Test fetchStats", () => {
     });
   });
 
-  it("should return 0 commits when all_commits true and invalid username", async () => {
-    let stats = await fetchStats("asdf///---", true);
-    expect(stats).toStrictEqual({
-      contributedTo: 61,
-      name: "Anurag Hazra",
-      totalCommits: 0,
-      totalIssues: 200,
-      totalPRs: 300,
-      totalPRsMerged: 240,
-      mergedPRsPercentage: 80,
-      totalReviews: 50,
-      totalStars: 300,
-      totalDiscussionsStarted: 10,
-      totalDiscussionsAnswered: 40,
-      rank: calculateRank({
-        all_commits: true,
-        commits: 0,
-        prs: 300,
-        reviews: 50,
-        issues: 200,
-        repos: 5,
-        stars: 300,
-        followers: 100,
-      }),
-    });
+  it("should throw specific error when include_all_commits true and invalid username", async () => {
+    expect(fetchStats("asdf///---", true)).rejects.toThrow(
+      new Error("Invalid username provided."),
+    );
   });
 
-  it("should return 0 commits when all_commits true and API returns error", async () => {
+  it("should throw specific error when include_all_commits true and API returns error", async () => {
     mock
       .onGet("https://api.github.com/search/commits?q=author:anuraghazra")
       .reply(200, { error: "Some test error message" });
 
-    let stats = await fetchStats("anuraghazra", true);
-    expect(stats).toStrictEqual({
-      contributedTo: 61,
-      name: "Anurag Hazra",
-      totalCommits: 0,
-      totalIssues: 200,
-      totalPRs: 300,
-      totalPRsMerged: 240,
-      mergedPRsPercentage: 80,
-      totalReviews: 50,
-      totalStars: 300,
-      totalDiscussionsStarted: 10,
-      totalDiscussionsAnswered: 40,
-      rank: calculateRank({
-        all_commits: true,
-        commits: 0,
-        prs: 300,
-        reviews: 50,
-        issues: 200,
-        repos: 5,
-        stars: 300,
-        followers: 100,
-      }),
-    });
+    expect(fetchStats("anuraghazra", true)).rejects.toThrow(
+      new Error("Could not fetch total commits."),
+    );
   });
 
   it("should exclude stars of the `test-repo-1` repository", async () => {
diff --git a/tests/retryer.test.js b/tests/retryer.test.js
index 257a70d..b0b4bd7 100644
--- a/tests/retryer.test.js
+++ b/tests/retryer.test.js
@@ -1,6 +1,6 @@
 import { jest } from "@jest/globals";
 import "@testing-library/jest-dom";
-import { retryer } from "../src/common/retryer.js";
+import { retryer, RETRIES } from "../src/common/retryer.js";
 import { logger } from "../src/common/utils.js";
 import { expect, it, describe } from "@jest/globals";
 
@@ -44,7 +44,7 @@ describe("Test Retryer", () => {
     try {
       await retryer(fetcherFail, {});
     } catch (err) {
-      expect(fetcherFail).toBeCalledTimes(8);
+      expect(fetcherFail).toBeCalledTimes(RETRIES + 1);
       expect(err.message).toBe("Downtime due to GitHub API rate limiting");
     }
   });