Skip to content

Commit

Permalink
Merge pull request #27 from sametcodes/develop
Browse files Browse the repository at this point in the history
Passport.js, supports Public APIs and unit tests
  • Loading branch information
sametcodes authored Mar 7, 2023
2 parents c36a771 + 81c3b1d commit 09bb4f1
Show file tree
Hide file tree
Showing 47 changed files with 8,334 additions and 7,701 deletions.
3 changes: 2 additions & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx lint-staged
npx lint-staged
npm run lint
53 changes: 53 additions & 0 deletions __tests__/pages/platform/codewars.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { testApiHandler } from "next-test-api-route-handler";
import handlePlatformAPI from "@/services/api/handler";

import { encode } from "querystring";

import * as services from "@/services/platform/codewars";
import * as templates from "@/components/svgs/codewars";

const handler = handlePlatformAPI("codewars", services, templates);
const methods = Object.keys(services);

describe("Codewars Platform APIs", () => {
methods.forEach((method) => {
test(`/api/platform/codewars?method=${method}`, async () => {
await testApiHandler({
handler,
requestPatcher: (req) => {
req.url = `/api/platform/codewars?${encode({
method,
uid: "6405534466df6b87ed0adb53",
})}`;
},
test: async ({ fetch }) => {
const res = await fetch({ method: "GET" });
expect(res.status).toBe(200);

const xml = await res.text();
expect(xml.indexOf("<svg")).toBe(0);
},
});
});

test(`/api/platform/codewars?method=${method}&returnType=json`, async () => {
await testApiHandler({
handler,
requestPatcher: (req) => {
req.url = `/api/platform/codewars?${encode({
method,
uid: "6405534466df6b87ed0adb53",
returnType: "json",
})}`;
},
test: async ({ fetch }) => {
const res = await fetch({ method: "GET" });
expect(res.headers.get("content-type")).toContain("application/json");
expect(res.status).toBe(200);
},
});
});
});
});

export {};
56 changes: 56 additions & 0 deletions __tests__/pages/platform/github.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { testApiHandler } from "next-test-api-route-handler";
import handlePlatformAPI from "@/services/api/handler";

import { encode } from "querystring";

import * as services from "@/services/platform/github";
import * as templates from "@/components/svgs/github";

const handler = handlePlatformAPI("github", services, templates);
const methods = Object.keys(services);

describe("Github Platform APIs", () => {
methods.forEach((method) => {
test(`/api/platform/github?method=${method}`, async () => {
await testApiHandler({
handler,
requestPatcher: (req) => {
req.url = `/api/platform/github?${encode({
method,
uid: "6405534466df6b87ed0adb53",
})}`;
},
test: async ({ fetch }) => {
const res = await fetch({ method: "GET" });
expect(res.status).toBe(200);

const xml = await res.text();
expect(xml.indexOf("<svg")).toBe(0);
},
});
});

test(`/api/platform/github?method=${method}&returnType=json`, async () => {
await testApiHandler({
handler,
requestPatcher: (req) => {
req.url = `/api/platform/github?${encode({
method,
uid: "6405534466df6b87ed0adb53",
returnType: "json",
})}`;
},
test: async ({ fetch }) => {
const res = await fetch({ method: "GET" });
expect(res.headers.get("content-type")).toContain("application/json");
expect(res.status).toBe(200);

const json = await res.json();
expect(json).toHaveProperty("data");
},
});
});
});
});

export {};
53 changes: 53 additions & 0 deletions __tests__/pages/platform/stackoverflow.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { testApiHandler } from "next-test-api-route-handler";
import handlePlatformAPI from "@/services/api/handler";

import { encode } from "querystring";

import * as services from "@/services/platform/stackoverflow";
import * as templates from "@/components/svgs/stackoverflow";

const handler = handlePlatformAPI("stackoverflow", services, templates);
const methods = Object.keys(services);

describe("Stackoverflow Platform APIs", () => {
methods.forEach((method) => {
test(`/api/platform/stackoverflow?method=${method}`, async () => {
await testApiHandler({
handler,
requestPatcher: (req) => {
req.url = `/api/platform/stackoverflow?${encode({
method,
uid: "6405534466df6b87ed0adb53",
})}`;
},
test: async ({ fetch }) => {
const res = await fetch({ method: "GET" });
expect(res.status).toBe(200);

const xml = await res.text();
expect(xml.indexOf("<svg")).toBe(0);
},
});
});

test(`/api/platform/stackoverflow?method=${method}&returnType=json`, async () => {
await testApiHandler({
handler,
requestPatcher: (req) => {
req.url = `/api/platform/stackoverflow?${encode({
method,
uid: "6405534466df6b87ed0adb53",
returnType: "json",
})}`;
},
test: async ({ fetch }) => {
const res = await fetch({ method: "GET" });
expect(res.headers.get("content-type")).toContain("application/json");
expect(res.status).toBe(200);
},
});
});
});
});

export {};
53 changes: 53 additions & 0 deletions __tests__/pages/platform/wakatime.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { testApiHandler } from "next-test-api-route-handler";
import handlePlatformAPI from "@/services/api/handler";

import { encode } from "querystring";

import * as services from "@/services/platform/wakatime";
import * as templates from "@/components/svgs/wakatime";

const handler = handlePlatformAPI("wakatime", services, templates);
const methods = Object.keys(services);

describe("Wakatime Platform APIs", () => {
methods.forEach((method) => {
test(`/api/platform/wakatime?method=${method}`, async () => {
await testApiHandler({
handler,
requestPatcher: (req) => {
req.url = `/api/platform/wakatime?${encode({
method,
uid: "6405534466df6b87ed0adb53",
})}`;
},
test: async ({ fetch }) => {
const res = await fetch({ method: "GET" });
expect(res.status).toBe(200);

const xml = await res.text();
expect(xml.indexOf("<svg")).toBe(0);
},
});
});

test(`/api/platform/wakatime?method=${method}&returnType=json`, async () => {
await testApiHandler({
handler,
requestPatcher: (req) => {
req.url = `/api/platform/wakatime?${encode({
method,
uid: "6405534466df6b87ed0adb53",
returnType: "json",
})}`;
},
test: async ({ fetch }) => {
const res = await fetch({ method: "GET" });
expect(res.headers.get("content-type")).toContain("application/json");
expect(res.status).toBe(200);
},
});
});
});
});

export {};
3 changes: 1 addition & 2 deletions app/account/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"use client";
import { useSession, signOut } from "next-auth/react";
import { useState } from "react";
import { FormEvent, ChangeEvent } from "react";
import { useState, FormEvent, ChangeEvent } from "react";

export default function Account() {
const { data: session } = useSession({ required: true });
Expand Down
8 changes: 7 additions & 1 deletion app/login/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use client";
import { useSession, signIn, signOut } from "next-auth/react";
import Image from "next/image";

export default function LoginPage() {
const { data: session } = useSession();
Expand All @@ -8,7 +9,12 @@ export default function LoginPage() {
return (
<>
<p>Welcome, {session?.user?.name}</p>
<img src={session?.user?.image || ""} alt="photo" width={60} />
<Image
src={session?.user?.image || ""}
alt="photo"
width={60}
height={60}
/>
<p>
Signed in as {session?.user?.email} <br />
</p>
Expand Down
6 changes: 3 additions & 3 deletions components/svgs/codewars/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import * as Icons from "@components/icons";
import * as Icons from "@/components/icons";
import {
Document,
DocumentTitle,
List,
ListItem,
} from "@components/svgs/document";
import { ObjectEntries } from "@utils";
} from "@/components/svgs/document";
import { ObjectEntries } from "@/utils";

export const getUser = (result: any, platform: any) => {
const langs = ObjectEntries(result.ranks.languages).map(([key, value]) => ({
Expand Down
32 changes: 11 additions & 21 deletions components/svgs/document.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,29 +26,19 @@ export const getDocumentStyle = () => {
</style>`;
};

type IDocument = {
(props: {
width: number;
height: number;
children: JSX.Element | JSX.Element[];
}): JSX.Element;
};
type IDocument = (props: {
width: number;
height: number;
children: JSX.Element | Array<JSX.Element>;
}) => JSX.Element;

type IDocumentHeader = {
(props: { title: string; desc: string }): JSX.Element;
};
type IDocumentHeader = (props: { title: string; desc: string }) => JSX.Element;

type IDocumentTitle = {
(props: { children: string }): JSX.Element;
};
type IDocumentTitle = (props: { children: string }) => JSX.Element;

type IList = {
(props: { children: any }): JSX.Element;
};
type IList = (props: { children: any }) => JSX.Element;

export type IListItem = {
(props: IItem): JSX.Element;
};
export type IListItem = (props: IItem) => JSX.Element;

type IItem = {
icon: JSX.Element;
Expand Down Expand Up @@ -133,7 +123,7 @@ export const List: IList = ({ children }) => {
};
};

const calculateGap = (elements: ReactElement<IItem, IListItem>[]) => {
const calculateGap = (elements: Array<ReactElement<IItem, IListItem>>) => {
if (!children) {
return [];
}
Expand All @@ -143,7 +133,7 @@ export const List: IList = ({ children }) => {
.reduce((a, b) => Math.max(a, b), 0) + 45;
return elements.map((child, index) => ({
...child,
props: { ...child.props, index, gap: gap },
props: { ...child.props, index, gap },
}));
};

Expand Down
4 changes: 2 additions & 2 deletions components/svgs/github/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import * as Icons from "@components/icons";
import * as Icons from "@/components/icons";
import {
Document,
DocumentTitle,
List,
ListItem,
} from "@components/svgs/document";
} from "@/components/svgs/document";

export const getCurrentYearContributions = (result: any, platform: any) => {
const { totalContributions } =
Expand Down
4 changes: 2 additions & 2 deletions components/svgs/stackoverflow/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import {
DocumentTitle,
List,
ListItem,
} from "@components/svgs/document";
import * as Icons from "@components/icons";
} from "@/components/svgs/document";
import * as Icons from "@/components/icons";

export const getReputation = (result: any, platform: any) => {
return (
Expand Down
4 changes: 2 additions & 2 deletions components/svgs/wakatime/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import {
DocumentTitle,
List,
ListItem,
} from "@components/svgs/document";
import * as Icons from "@components/icons";
} from "@/components/svgs/document";
import * as Icons from "@/components/icons";

export const getAllTimeSinceToday = (result: any, platform: any) => {
return (
Expand Down
17 changes: 17 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const nextJest = require("next/jest");

const createJestConfig = nextJest({
dir: "./",
});

// Add any custom config to be passed to Jest
const customJestConfig = {
setupFilesAfterEnv: ["<rootDir>/jest.setup.js"],
moduleNameMapper: {
"^@/(.*)$": "<rootDir>/$1",
},
testEnvironment: "jest-environment-jsdom",
};

// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
module.exports = createJestConfig(customJestConfig);
8 changes: 8 additions & 0 deletions jest.setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import "@testing-library/jest-dom/extend-expect";

import { TextEncoder, TextDecoder } from "util";
import fetch from "node-fetch";

global.TextEncoder = TextEncoder;
global.TextDecoder = TextDecoder;
global.fetch = fetch;
Loading

1 comment on commit 09bb4f1

@vercel
Copy link

@vercel vercel bot commented on 09bb4f1 Mar 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

devstats – ./

devstats-sametcodes.vercel.app
devstats-git-main-sametcodes.vercel.app
devstats-app.vercel.app

Please sign in to comment.