feat: added isTemplate badge & refactored console.logs (#146)

* feat: template option added husky added for same commit disable console in test \
logger utils added env checked for log modified git ignore

* changed are done as per the suggesstion

* changed style and font

* text color dynamic

* fix border and using .bagde class as common

* simplified the badge svg code through a common method

* chore: updated css & fixed tests

Co-authored-by: anuraghazra <hazru.anurag@gmail.com>
This commit is contained in:
Joydip Roy 2020-07-23 13:05:50 +05:30 committed by GitHub
parent 03f55e809e
commit 5ed75e11be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 78 additions and 33 deletions

2
.gitignore vendored
View File

@ -2,4 +2,6 @@
.env
node_modules
package-lock.json
*.lock
.vscode/
coverage

View File

@ -4,6 +4,7 @@ const {
parseBoolean,
clampValue,
CONSTANTS,
logger,
} = require("../src/utils");
const fetchRepo = require("../src/fetchRepo");
const renderRepoCard = require("../src/renderRepoCard");
@ -28,7 +29,7 @@ module.exports = async (req, res) => {
try {
repoData = await fetchRepo(username, repo);
} catch (err) {
console.log(err);
logger.error(err);
return res.send(renderError(err.message));
}
@ -52,7 +53,7 @@ module.exports = async (req, res) => {
}
res.setHeader("Cache-Control", `public, max-age=${cacheSeconds}`);
res.send(
renderRepoCard(repoData, {
title_color,

View File

@ -15,9 +15,15 @@
"axios": "^0.19.2",
"axios-mock-adapter": "^1.18.1",
"css-to-object": "^1.1.0",
"husky": "^4.2.5",
"jest": "^26.1.0"
},
"dependencies": {
"dotenv": "^8.2.0"
},
"husky": {
"hooks": {
"pre-commit": "npm test"
}
}
}

View File

@ -10,6 +10,7 @@ const fetcher = (variables, token) => {
nameWithOwner
isPrivate
isArchived
isTemplate
stargazers {
totalCount
}

View File

@ -1,4 +1,4 @@
const { request } = require("./utils");
const { request, logger } = require("./utils");
const retryer = require("./retryer");
const calculateRank = require("./calculateRank");
require("dotenv").config();
@ -61,7 +61,7 @@ async function fetchStats(username) {
let res = await retryer(fetcher, { login: username });
if (res.data.errors) {
console.log(res.data.errors);
logger.error(res.data.errors);
throw Error(res.data.errors[0].message || "Could not fetch user");
}

View File

@ -1,4 +1,4 @@
const { request } = require("./utils");
const { request, logger } = require("./utils");
const retryer = require("./retryer");
require("dotenv").config();
@ -38,7 +38,7 @@ async function fetchTopLanguages(username) {
let res = await retryer(fetcher, { login: username });
if (res.data.errors) {
console.log(res.data.errors);
logger.error(res.data.errors);
throw Error(res.data.errors[0].message || "Could not fetch user");
}

View File

@ -14,6 +14,7 @@ const renderRepoCard = (repo, options = {}) => {
primaryLanguage,
stargazers,
isArchived,
isTemplate,
forkCount,
} = repo;
const {
@ -49,14 +50,20 @@ const renderRepoCard = (repo, options = {}) => {
const totalStars = kFormatter(stargazers.totalCount);
const totalForks = kFormatter(forkCount);
const archiveBadge = isArchived
? `
<g data-testid="archive-badge" class="archive-badge" transform="translate(320, 38)">
const getBadgeSVG = (label) => `
<g data-testid="badge" class="badge" transform="translate(320, 38)">
<rect stroke="${textColor}" stroke-width="1" width="70" height="20" x="-12" y="-14" ry="10" rx="10"></rect>
<text fill="${textColor}">Archived</text>
<text
x="23" y="-5"
alignment-baseline="central"
dominant-baseline="central"
text-anchor="middle"
fill="${textColor}"
>
${label}
</text>
</g>
`
: "";
`;
const svgLanguage = `
<g transform="translate(30, 100)">
@ -90,17 +97,25 @@ const renderRepoCard = (repo, options = {}) => {
.description { font: 400 13px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor} }
.gray { font: 400 12px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor} }
.icon { fill: ${iconColor} }
.archive-badge { font: 600 12px 'Segoe UI', Ubuntu, Sans-Serif; }
.archive-badge rect { opacity: 0.2 }
.badge { font: 600 11px 'Segoe UI', Ubuntu, Sans-Serif; }
.badge rect { opacity: 0.2 }
</style>
<rect data-testid="card-bg" x="0.5" y="0.5" width="399" height="99%" rx="4.5" fill="${bgColor}" stroke="#E4E2E2"/>
<svg class="icon" x="25" y="25" viewBox="0 0 16 16" version="1.1" width="16" height="16">
${icons.contribs}
</svg>
${archiveBadge}
<text x="50" y="38" class="header">${header}</text>
${
isTemplate
? getBadgeSVG("Template")
: isArchived
? getBadgeSVG("Archived")
: ""
}
<text class="description" x="25" y="70">${encodeHTML(desc)}</text>
${svgLanguage}

View File

@ -1,9 +1,11 @@
const { logger } = require("./utils");
const retryer = async (fetcher, variables, retries = 0) => {
if (retries > 7) {
throw new Error("Maximum retries exceeded");
}
try {
console.log(`Trying PAT_${retries + 1}`);
logger.log(`Trying PAT_${retries + 1}`);
// try to fetch with the first token since RETRIES is 0 index i'm adding +1
let response = await fetcher(
@ -18,7 +20,7 @@ const retryer = async (fetcher, variables, retries = 0) => {
// if rate limit is hit increase the RETRIES and recursively call the retryer
// with username, and current RETRIES
if (isRateExceeded) {
console.log(`PAT_${retries + 1} Failed`);
logger.log(`PAT_${retries + 1} Failed`);
retries++;
// directly return from the function
return retryer(fetcher, variables, retries);
@ -32,7 +34,7 @@ const retryer = async (fetcher, variables, retries = 0) => {
const isBadCredential = err.response.data && err.response.data.message === "Bad credentials";
if (isBadCredential) {
console.log(`PAT_${retries + 1} Failed`);
logger.log(`PAT_${retries + 1} Failed`);
retries++;
// directly return from the function
return retryer(fetcher, variables, retries);

View File

@ -116,6 +116,10 @@ function getCardColors({
return { titleColor, iconColor, textColor, bgColor };
}
const fn = () => {};
// return console instance based on the environment
const logger = process.env.NODE_ENV !== "test" ? console : { log: fn, error: fn };
const CONSTANTS = {
THIRTY_MINUTES: 1800,
TWO_HOURS: 7200,
@ -133,5 +137,6 @@ module.exports = {
FlexLayout,
getCardColors,
clampValue,
logger,
CONSTANTS,
};

View File

@ -17,6 +17,7 @@ const data_repo = {
name: "TypeScript",
},
forkCount: 100,
isTemplate: false
},
};

View File

@ -217,17 +217,6 @@ describe("Test renderRepoCard", () => {
);
});
it("should render archive badge if repo is archived", () => {
document.body.innerHTML = renderRepoCard({
...data_repo.repository,
isArchived: true,
});
expect(queryByTestId(document.body, "archive-badge")).toHaveTextContent(
"Archived"
);
});
it("should not render star count or fork count if either of the are zero", () => {
document.body.innerHTML = renderRepoCard({
...data_repo.repository,
@ -235,7 +224,7 @@ describe("Test renderRepoCard", () => {
});
expect(queryByTestId(document.body, "stargazers")).toBeNull();
expect(queryByTestId(document.body, "forkcount")).toBeDefined();
expect(queryByTestId(document.body, "forkcount")).toBeInTheDocument();
document.body.innerHTML = renderRepoCard({
...data_repo.repository,
@ -243,7 +232,7 @@ describe("Test renderRepoCard", () => {
forkCount: 0,
});
expect(queryByTestId(document.body, "stargazers")).toBeDefined();
expect(queryByTestId(document.body, "stargazers")).toBeInTheDocument();
expect(queryByTestId(document.body, "forkcount")).toBeNull();
document.body.innerHTML = renderRepoCard({
@ -255,4 +244,26 @@ describe("Test renderRepoCard", () => {
expect(queryByTestId(document.body, "stargazers")).toBeNull();
expect(queryByTestId(document.body, "forkcount")).toBeNull();
});
it("should render badges", () => {
document.body.innerHTML = renderRepoCard({
...data_repo.repository,
isArchived: true,
});
expect(queryByTestId(document.body, "badge")).toHaveTextContent("Archived");
document.body.innerHTML = renderRepoCard({
...data_repo.repository,
isTemplate: true,
});
expect(queryByTestId(document.body, "badge")).toHaveTextContent("Template");
});
it("should not render template", () => {
document.body.innerHTML = renderRepoCard({
...data_repo.repository,
});
expect(queryByTestId(document.body, "badge")).toBeNull();
});
});

View File

@ -1,8 +1,9 @@
require("@testing-library/jest-dom");
const retryer = require("../src/retryer");
const { logger } = require("../src/utils");
const fetcher = jest.fn((variables, token) => {
console.log(variables, token);
logger.log(variables, token);
return new Promise((res, rej) => res({ data: "ok" }));
});