diff --git a/.eslintrc.json b/.eslintrc.json index 255e9fc57a574..367f484a665f5 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -16,7 +16,7 @@ // Possible Errors (overrides from recommended set) // "no-extra-parens": "error", - // "no-unexpected-multiline": "error", + "no-unexpected-multiline": "error", // All JSDoc comments must be valid diff --git a/.github/labeler.yml b/.github/labeler.yml index 9708a97ab35c4..c8da8cff7608f 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -17,18 +17,21 @@ lang-card: - src/fetchers/top-languages-fetcher.js - tests/fetchTopLanguages.test.js - tests/renderTopLanguagesCard.test.js + - tests/top-langs.test.js repo-card: - api/pin.js - src/cards/repo-card.js - src/fetchers/repo-fetcher.js - tests/fetchRepo.test.js - tests/renderRepoCard.test.js + - tests/pin.test.js stats-card: - api/index.js - src/cards/stats-card.js - src/fetchers/stats-fetcher.js - tests/fetchStats.test.js - tests/renderStatsCard.test.js + - tests/api.test.js wakatime-card: - api/wakatime.js - src/cards/wakatime-card.js @@ -41,6 +44,7 @@ gist-card: - src/fetchers/gist-fetcher.js - tests/fetchGist.test.js - tests/renderGistCard.test.js + - tests/gist.test.js ranks: src/calculateRank.js ci: - .github/workflows/* diff --git a/src/fetchers/top-languages-fetcher.js b/src/fetchers/top-languages-fetcher.js index 1f386c1df682a..26e99e619ddb3 100644 --- a/src/fetchers/top-languages-fetcher.js +++ b/src/fetchers/top-languages-fetcher.js @@ -75,12 +75,6 @@ const fetchTopLanguages = async ( const res = await retryer(fetcher, { login: username }); - if (res.data.errors) { - logger.error(res.data.errors); - throw Error(res.data.errors[0].message || "Could not fetch user"); - } - - // Catch GraphQL errors. if (res.data.errors) { logger.error(res.data.errors); if (res.data.errors[0].type === "NOT_FOUND") { diff --git a/tests/api.test.js b/tests/api.test.js index 567d2c12fd7de..d29db222b9516 100644 --- a/tests/api.test.js +++ b/tests/api.test.js @@ -276,4 +276,24 @@ describe("Test /api/", () => { }), ); }); + + it("should render error card if username in blacklist", async () => { + const { req, res } = faker({ username: "renovate-bot" }, data_stats); + + await api(req, res); + + expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml"); + expect(res.send).toBeCalledWith(renderError("Something went wrong")); + }); + + it("should render error card when wrong locale is provided", async () => { + const { req, res } = faker({ locale: "asdf" }, data_stats); + + await api(req, res); + + expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml"); + expect(res.send).toBeCalledWith( + renderError("Something went wrong", "Language not found"), + ); + }); }); diff --git a/tests/fetchTopLanguages.test.js b/tests/fetchTopLanguages.test.js index 9a48a1620f8dc..90648c3198dd9 100644 --- a/tests/fetchTopLanguages.test.js +++ b/tests/fetchTopLanguages.test.js @@ -141,11 +141,31 @@ describe("FetchTopLanguages", () => { }); }); - it("should throw error", async () => { + it("should throw specific error when user not found", async () => { mock.onPost("https://api.github.com/graphql").reply(200, error); await expect(fetchTopLanguages("anuraghazra")).rejects.toThrow( "Could not resolve to a User with the login of 'noname'.", ); }); + + it("should throw other errors with their message", async () => { + mock.onPost("https://api.github.com/graphql").reply(200, { + errors: [{ message: "Some test GraphQL error" }], + }); + + await expect(fetchTopLanguages("anuraghazra")).rejects.toThrow( + "Some test GraphQL error", + ); + }); + + it("should throw error with specific message when error does not contain message property", async () => { + mock.onPost("https://api.github.com/graphql").reply(200, { + errors: [{ type: "TEST" }], + }); + + await expect(fetchTopLanguages("anuraghazra")).rejects.toThrow( + "Something went while trying to retrieve the language data using the GraphQL API.", + ); + }); }); diff --git a/tests/fetchWakatime.test.js b/tests/fetchWakatime.test.js index fb337345bef0b..1636114ee5404 100644 --- a/tests/fetchWakatime.test.js +++ b/tests/fetchWakatime.test.js @@ -112,97 +112,7 @@ describe("Wakatime fetcher", () => { .reply(200, wakaTimeData); const repo = await fetchWakatimeStats({ username }); - expect(repo).toMatchInlineSnapshot(` - { - "categories": [ - { - "digital": "22:40", - "hours": 22, - "minutes": 40, - "name": "Coding", - "percent": 100, - "text": "22 hrs 40 mins", - "total_seconds": 81643.570077, - }, - ], - "daily_average": 16095, - "daily_average_including_other_language": 16329, - "days_including_holidays": 7, - "days_minus_holidays": 5, - "editors": [ - { - "digital": "22:40", - "hours": 22, - "minutes": 40, - "name": "VS Code", - "percent": 100, - "text": "22 hrs 40 mins", - "total_seconds": 81643.570077, - }, - ], - "holidays": 2, - "human_readable_daily_average": "4 hrs 28 mins", - "human_readable_daily_average_including_other_language": "4 hrs 32 mins", - "human_readable_total": "22 hrs 21 mins", - "human_readable_total_including_other_language": "22 hrs 40 mins", - "id": "random hash", - "is_already_updating": false, - "is_coding_activity_visible": true, - "is_including_today": false, - "is_other_usage_visible": true, - "is_stuck": false, - "is_up_to_date": true, - "languages": [ - { - "digital": "0:19", - "hours": 0, - "minutes": 19, - "name": "Other", - "percent": 1.43, - "text": "19 mins", - "total_seconds": 1170.434361, - }, - { - "digital": "0:01", - "hours": 0, - "minutes": 1, - "name": "TypeScript", - "percent": 0.1, - "text": "1 min", - "total_seconds": 83.293809, - }, - { - "digital": "0:00", - "hours": 0, - "minutes": 0, - "name": "YAML", - "percent": 0.07, - "text": "0 secs", - "total_seconds": 54.975151, - }, - ], - "operating_systems": [ - { - "digital": "22:40", - "hours": 22, - "minutes": 40, - "name": "Mac", - "percent": 100, - "text": "22 hrs 40 mins", - "total_seconds": 81643.570077, - }, - ], - "percent_calculated": 100, - "range": "last_7_days", - "status": "ok", - "timeout": 15, - "total_seconds": 80473.135716, - "total_seconds_including_other_language": 81643.570077, - "user_id": "random hash", - "username": "anuraghazra", - "writes_only": false, - } - `); + expect(repo).toStrictEqual(wakaTimeData.data); }); it("should throw error if username param missing", async () => { diff --git a/tests/gist.test.js b/tests/gist.test.js index b7c348411820b..bdf95156d5f44 100644 --- a/tests/gist.test.js +++ b/tests/gist.test.js @@ -150,4 +150,24 @@ describe("Test /api/gist", () => { expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml"); expect(res.send).toBeCalledWith(renderError("Gist not found")); }); + + it("should render error if wrong locale is provided", async () => { + const req = { + query: { + id: "bbfce31e0217a3689c8d961a356cb10d", + locale: "asdf", + }, + }; + const res = { + setHeader: jest.fn(), + send: jest.fn(), + }; + + await gist(req, res); + + expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml"); + expect(res.send).toBeCalledWith( + renderError("Something went wrong", "Language not found"), + ); + }); }); diff --git a/tests/pin.test.js b/tests/pin.test.js index ad63fe01d6815..cff0bbd41af4a 100644 --- a/tests/pin.test.js +++ b/tests/pin.test.js @@ -138,4 +138,45 @@ describe("Test /api/pin", () => { renderError("Organization Repository Not found"), ); }); + + it("should render error card if username in blacklist", async () => { + const req = { + query: { + username: "renovate-bot", + repo: "convoychat", + }, + }; + const res = { + setHeader: jest.fn(), + send: jest.fn(), + }; + mock.onPost("https://api.github.com/graphql").reply(200, data_user); + + await pin(req, res); + + expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml"); + expect(res.send).toBeCalledWith(renderError("Something went wrong")); + }); + + it("should render error card if wrong locale provided", async () => { + const req = { + query: { + username: "anuraghazra", + repo: "convoychat", + locale: "asdf", + }, + }; + const res = { + setHeader: jest.fn(), + send: jest.fn(), + }; + mock.onPost("https://api.github.com/graphql").reply(200, data_user); + + await pin(req, res); + + expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml"); + expect(res.send).toBeCalledWith( + renderError("Something went wrong", "Language not found"), + ); + }); }); diff --git a/tests/top-langs.test.js b/tests/top-langs.test.js index f0ce0b55bb51b..36a8586028e94 100644 --- a/tests/top-langs.test.js +++ b/tests/top-langs.test.js @@ -139,7 +139,12 @@ describe("Test /api/top-langs", () => { await topLangs(req, res); expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml"); - expect(res.send).toBeCalledWith(renderError(error.errors[0].message)); + expect(res.send).toBeCalledWith( + renderError( + error.errors[0].message, + "Make sure the provided username is not an organization", + ), + ); }); it("should render error card on incorrect layout input", async () => { @@ -162,4 +167,43 @@ describe("Test /api/top-langs", () => { renderError("Something went wrong", "Incorrect layout input"), ); }); + + it("should render error card if username in blacklist", async () => { + const req = { + query: { + username: "renovate-bot", + }, + }; + const res = { + setHeader: jest.fn(), + send: jest.fn(), + }; + mock.onPost("https://api.github.com/graphql").reply(200, data_langs); + + await topLangs(req, res); + + expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml"); + expect(res.send).toBeCalledWith(renderError("Something went wrong")); + }); + + it("should render error card if wrong locale provided", async () => { + const req = { + query: { + username: "anuraghazra", + locale: "asdf", + }, + }; + const res = { + setHeader: jest.fn(), + send: jest.fn(), + }; + mock.onPost("https://api.github.com/graphql").reply(200, data_langs); + + await topLangs(req, res); + + expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml"); + expect(res.send).toBeCalledWith( + renderError("Something went wrong", "Locale not found"), + ); + }); });