refactor: named arguments for render error function (#4537)

* refactor: named arguments for render error function

* Update tests/api.test.js

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Alexandr <qwerty541zxc@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Ophelia Goldstein
2025-10-07 23:21:18 +03:00
committed by GitHub
co-authored by Copilot Alexandr
parent f7920901b6
commit e9d0e8fd17
12 changed files with 222 additions and 125 deletions
+20 -12
View File
@@ -47,12 +47,16 @@ export default async (req, res) => {
if (locale && !isLocaleAvailable(locale)) {
return res.send(
renderError("Something went wrong", "Language not found", {
title_color,
text_color,
bg_color,
border_color,
theme,
renderError({
message: "Something went wrong",
secondaryMessage: "Language not found",
renderOptions: {
title_color,
text_color,
bg_color,
border_color,
theme,
},
}),
);
}
@@ -85,12 +89,16 @@ export default async (req, res) => {
} catch (err) {
setErrorCacheHeaders(res);
return res.send(
renderError(err.message, err.secondaryMessage, {
title_color,
text_color,
bg_color,
border_color,
theme,
renderError({
message: err.message,
secondaryMessage: err.secondaryMessage,
renderOptions: {
title_color,
text_color,
bg_color,
border_color,
theme,
},
}),
);
}
+20 -12
View File
@@ -66,12 +66,16 @@ export default async (req, res) => {
if (locale && !isLocaleAvailable(locale)) {
return res.send(
renderError("Something went wrong", "Language not found", {
title_color,
text_color,
bg_color,
border_color,
theme,
renderError({
message: "Something went wrong",
secondaryMessage: "Language not found",
renderOptions: {
title_color,
text_color,
bg_color,
border_color,
theme,
},
}),
);
}
@@ -128,12 +132,16 @@ export default async (req, res) => {
} catch (err) {
setErrorCacheHeaders(res);
return res.send(
renderError(err.message, err.secondaryMessage, {
title_color,
text_color,
bg_color,
border_color,
theme,
renderError({
message: err.message,
secondaryMessage: err.secondaryMessage,
renderOptions: {
title_color,
text_color,
bg_color,
border_color,
theme,
},
}),
);
}
+20 -12
View File
@@ -49,12 +49,16 @@ export default async (req, res) => {
if (locale && !isLocaleAvailable(locale)) {
return res.send(
renderError("Something went wrong", "Language not found", {
title_color,
text_color,
bg_color,
border_color,
theme,
renderError({
message: "Something went wrong",
secondaryMessage: "Language not found",
renderOptions: {
title_color,
text_color,
bg_color,
border_color,
theme,
},
}),
);
}
@@ -88,12 +92,16 @@ export default async (req, res) => {
} catch (err) {
setErrorCacheHeaders(res);
return res.send(
renderError(err.message, err.secondaryMessage, {
title_color,
text_color,
bg_color,
border_color,
theme,
renderError({
message: err.message,
secondaryMessage: err.secondaryMessage,
renderOptions: {
title_color,
text_color,
bg_color,
border_color,
theme,
},
}),
);
}
+24 -9
View File
@@ -60,7 +60,12 @@ export default async (req, res) => {
}
if (locale && !isLocaleAvailable(locale)) {
return res.send(renderError("Something went wrong", "Locale not found"));
return res.send(
renderError({
message: "Something went wrong",
secondaryMessage: "Locale not found",
}),
);
}
if (
@@ -69,7 +74,10 @@ export default async (req, res) => {
!["compact", "normal", "donut", "donut-vertical", "pie"].includes(layout))
) {
return res.send(
renderError("Something went wrong", "Incorrect layout input"),
renderError({
message: "Something went wrong",
secondaryMessage: "Incorrect layout input",
}),
);
}
@@ -79,7 +87,10 @@ export default async (req, res) => {
!["bytes", "percentages"].includes(stats_format))
) {
return res.send(
renderError("Something went wrong", "Incorrect stats_format input"),
renderError({
message: "Something went wrong",
secondaryMessage: "Incorrect stats_format input",
}),
);
}
@@ -123,12 +134,16 @@ export default async (req, res) => {
} catch (err) {
setErrorCacheHeaders(res);
return res.send(
renderError(err.message, err.secondaryMessage, {
title_color,
text_color,
bg_color,
border_color,
theme,
renderError({
message: err.message,
secondaryMessage: err.secondaryMessage,
renderOptions: {
title_color,
text_color,
bg_color,
border_color,
theme,
},
}),
);
}
+20 -12
View File
@@ -62,12 +62,16 @@ export default async (req, res) => {
if (locale && !isLocaleAvailable(locale)) {
return res.send(
renderError("Something went wrong", "Language not found", {
title_color,
text_color,
bg_color,
border_color,
theme,
renderError({
message: "Something went wrong",
secondaryMessage: "Language not found",
renderOptions: {
title_color,
text_color,
bg_color,
border_color,
theme,
},
}),
);
}
@@ -109,12 +113,16 @@ export default async (req, res) => {
} catch (err) {
setErrorCacheHeaders(res);
return res.send(
renderError(err.message, err.secondaryMessage, {
title_color,
text_color,
bg_color,
border_color,
theme,
renderError({
message: err.message,
secondaryMessage: err.secondaryMessage,
renderOptions: {
title_color,
text_color,
bg_color,
border_color,
theme,
},
}),
);
}
+14 -6
View File
@@ -33,9 +33,13 @@ const guardAccess = ({ res, id, type, colors }) => {
if (Array.isArray(currentWhitelist) && !currentWhitelist.includes(id)) {
const result = res.send(
renderError(notWhitelistedMsg, "Please deploy your own instance", {
...colors,
show_repo_link: false,
renderError({
message: notWhitelistedMsg,
secondaryMessage: "Please deploy your own instance",
renderOptions: {
...colors,
show_repo_link: false,
},
}),
);
return { isPassed: false, result };
@@ -47,9 +51,13 @@ const guardAccess = ({ res, id, type, colors }) => {
blacklist.includes(id)
) {
const result = res.send(
renderError(BLACKLISTED_MESSAGE, "Please deploy your own instance", {
...colors,
show_repo_link: false,
renderError({
message: BLACKLISTED_MESSAGE,
secondaryMessage: "Please deploy your own instance",
renderOptions: {
...colors,
show_repo_link: false,
},
}),
);
return { isPassed: false, result };
+16 -11
View File
@@ -352,18 +352,23 @@ const UPSTREAM_API_ERRORS = [
/**
* Renders error message on the card.
*
* @param {string} message Main error message.
* @param {string} secondaryMessage The secondary error message.
* @param {object} options Function options.
* @param {string=} options.title_color Card title color.
* @param {string=} options.text_color Card text color.
* @param {string=} options.bg_color Card background color.
* @param {string=} options.border_color Card border color.
* @param {string=} options.theme Card theme.
* @param {boolean=} options.show_repo_link Whether to show repo link or not.
* @param {object} args Function arguments.
* @param {string} args.message Main error message.
* @param {string} [args.secondaryMessage=""] The secondary error message.
* @param {object} [args.renderOptions={}] Render options.
* @param {string=} args.renderOptions.title_color Card title color.
* @param {string=} args.renderOptions.text_color Card text color.
* @param {string=} args.renderOptions.bg_color Card background color.
* @param {string=} args.renderOptions.border_color Card border color.
* @param {string=} args.renderOptions.theme Card theme.
* @param {boolean=} args.renderOptions.show_repo_link Whether to show repo link or not.
* @returns {string} The SVG markup.
*/
const renderError = (message, secondaryMessage = "", options = {}) => {
const renderError = ({
message,
secondaryMessage = "",
renderOptions = {},
}) => {
const {
title_color,
text_color,
@@ -371,7 +376,7 @@ const renderError = (message, secondaryMessage = "", options = {}) => {
border_color,
theme = "default",
show_repo_link = true,
} = options;
} = renderOptions;
// returns theme based colors with proper overrides and defaults
const { titleColor, textColor, bgColor, borderColor } = getCardColors({
+30 -17
View File
@@ -1,3 +1,5 @@
// @ts-check
import { jest } from "@jest/globals";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
@@ -7,6 +9,9 @@ import { renderStatsCard } from "../src/cards/stats.js";
import { CONSTANTS, renderError } from "../src/common/utils.js";
import { expect, it, describe, afterEach } from "@jest/globals";
/**
* @type {import("../src/fetchers/stats").StatsData}
*/
const stats = {
name: "Anurag Hazra",
totalStars: 100,
@@ -19,7 +24,7 @@ const stats = {
totalDiscussionsStarted: 10,
totalDiscussionsAnswered: 40,
contributedTo: 50,
rank: null,
rank: { level: "DEV", percentile: 0 },
};
stats.rank = calculateRank({
@@ -115,10 +120,11 @@ describe("Test /api/", () => {
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
expect(res.send).toBeCalledWith(
renderError(
error.errors[0].message,
"Make sure the provided username is not an organization",
),
renderError({
message: error.errors[0].message,
secondaryMessage:
"Make sure the provided username is not an organization",
}),
);
});
@@ -129,11 +135,12 @@ describe("Test /api/", () => {
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
expect(res.send).toBeCalledWith(
renderError(
error.errors[0].message,
"Make sure the provided username is not an organization",
{ theme: "merko" },
),
renderError({
message: error.errors[0].message,
secondaryMessage:
"Make sure the provided username is not an organization",
renderOptions: { theme: "merko" },
}),
);
});
@@ -307,11 +314,11 @@ describe("Test /api/", () => {
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
expect(res.send).toBeCalledWith(
renderError(
"This username is blacklisted",
"Please deploy your own instance",
{ show_repo_link: false },
),
renderError({
message: "This username is blacklisted",
secondaryMessage: "Please deploy your own instance",
renderOptions: { show_repo_link: false },
}),
);
});
@@ -322,7 +329,10 @@ describe("Test /api/", () => {
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
expect(res.send).toBeCalledWith(
renderError("Something went wrong", "Language not found"),
renderError({
message: "Something went wrong",
secondaryMessage: "Language not found",
}),
);
});
@@ -340,7 +350,10 @@ describe("Test /api/", () => {
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
expect(res.send).toBeCalledWith(
renderError("Could not fetch total commits.", "Please try again later"),
renderError({
message: "Could not fetch total commits.",
secondaryMessage: "Please try again later",
}),
);
// Received SVG output should not contain string "https://tiny.one/readme-stats"
expect(res.send.mock.calls[0][0]).not.toContain(
+11 -6
View File
@@ -1,3 +1,5 @@
// @ts-check
import { jest } from "@jest/globals";
import "@testing-library/jest-dom";
import axios from "axios";
@@ -124,10 +126,10 @@ describe("Test /api/gist", () => {
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
expect(res.send).toBeCalledWith(
renderError(
'Missing params "id" make sure you pass the parameters in URL',
"/api/gist?id=GIST_ID",
),
renderError({
message: 'Missing params "id" make sure you pass the parameters in URL',
secondaryMessage: "/api/gist?id=GIST_ID",
}),
);
});
@@ -148,7 +150,7 @@ describe("Test /api/gist", () => {
await gist(req, res);
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
expect(res.send).toBeCalledWith(renderError("Gist not found"));
expect(res.send).toBeCalledWith(renderError({ message: "Gist not found" }));
});
it("should render error if wrong locale is provided", async () => {
@@ -167,7 +169,10 @@ describe("Test /api/gist", () => {
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
expect(res.send).toBeCalledWith(
renderError("Something went wrong", "Language not found"),
renderError({
message: "Something went wrong",
secondaryMessage: "Language not found",
}),
);
});
+22 -12
View File
@@ -1,3 +1,5 @@
// @ts-check
import { jest } from "@jest/globals";
import "@testing-library/jest-dom";
import axios from "axios";
@@ -56,6 +58,7 @@ describe("Test /api/pin", () => {
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
expect(res.send).toBeCalledWith(
// @ts-ignore
renderRepoCard({
...data_repo.repository,
starCount: data_repo.repository.stargazers.totalCount,
@@ -86,6 +89,7 @@ describe("Test /api/pin", () => {
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
expect(res.send).toBeCalledWith(
renderRepoCard(
// @ts-ignore
{
...data_repo.repository,
starCount: data_repo.repository.stargazers.totalCount,
@@ -113,7 +117,9 @@ describe("Test /api/pin", () => {
await pin(req, res);
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
expect(res.send).toBeCalledWith(renderError("User Repository Not found"));
expect(res.send).toBeCalledWith(
renderError({ message: "User Repository Not found" }),
);
});
it("should render error card if org repo not found", async () => {
@@ -135,7 +141,7 @@ describe("Test /api/pin", () => {
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
expect(res.send).toBeCalledWith(
renderError("Organization Repository Not found"),
renderError({ message: "Organization Repository Not found" }),
);
});
@@ -156,11 +162,11 @@ describe("Test /api/pin", () => {
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
expect(res.send).toBeCalledWith(
renderError(
"This username is blacklisted",
"Please deploy your own instance",
{ show_repo_link: false },
),
renderError({
message: "This username is blacklisted",
secondaryMessage: "Please deploy your own instance",
renderOptions: { show_repo_link: false },
}),
);
});
@@ -182,7 +188,10 @@ describe("Test /api/pin", () => {
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
expect(res.send).toBeCalledWith(
renderError("Something went wrong", "Language not found"),
renderError({
message: "Something went wrong",
secondaryMessage: "Language not found",
}),
);
});
@@ -199,10 +208,11 @@ describe("Test /api/pin", () => {
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
expect(res.send).toBeCalledWith(
renderError(
'Missing params "username", "repo" make sure you pass the parameters in URL',
"/api/pin?username=USERNAME&amp;repo=REPO_NAME",
),
renderError({
message:
'Missing params "username", "repo" make sure you pass the parameters in URL',
secondaryMessage: "/api/pin?username=USERNAME&amp;repo=REPO_NAME",
}),
);
});
+20 -11
View File
@@ -1,3 +1,5 @@
// @ts-check
import { jest } from "@jest/globals";
import "@testing-library/jest-dom";
import axios from "axios";
@@ -140,10 +142,11 @@ describe("Test /api/top-langs", () => {
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
expect(res.send).toBeCalledWith(
renderError(
error.errors[0].message,
"Make sure the provided username is not an organization",
),
renderError({
message: error.errors[0].message,
secondaryMessage:
"Make sure the provided username is not an organization",
}),
);
});
@@ -164,7 +167,10 @@ describe("Test /api/top-langs", () => {
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
expect(res.send).toBeCalledWith(
renderError("Something went wrong", "Incorrect layout input"),
renderError({
message: "Something went wrong",
secondaryMessage: "Incorrect layout input",
}),
);
});
@@ -184,11 +190,11 @@ describe("Test /api/top-langs", () => {
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
expect(res.send).toBeCalledWith(
renderError(
"This username is blacklisted",
"Please deploy your own instance",
{ show_repo_link: false },
),
renderError({
message: "This username is blacklisted",
secondaryMessage: "Please deploy your own instance",
renderOptions: { show_repo_link: false },
}),
);
});
@@ -209,7 +215,10 @@ describe("Test /api/top-langs", () => {
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
expect(res.send).toBeCalledWith(
renderError("Something went wrong", "Locale not found"),
renderError({
message: "Something went wrong",
secondaryMessage: "Locale not found",
}),
);
});
+5 -5
View File
@@ -46,7 +46,7 @@ describe("Test utils.js", () => {
});
it("should test renderError", () => {
document.body.innerHTML = renderError("Something went wrong");
document.body.innerHTML = renderError({ message: "Something went wrong" });
expect(
queryByTestId(document.body, "message").children[0],
).toHaveTextContent(/Something went wrong/gim);
@@ -55,10 +55,10 @@ describe("Test utils.js", () => {
).toBeEmptyDOMElement(2);
// Secondary message
document.body.innerHTML = renderError(
"Something went wrong",
"Secondary Message",
);
document.body.innerHTML = renderError({
message: "Something went wrong",
secondaryMessage: "Secondary Message",
});
expect(
queryByTestId(document.body, "message").children[1],
).toHaveTextContent(/Secondary Message/gim);