mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-03-21 18:04:39 -05:00
useMyRouter + jest initial
This commit is contained in:
parent
2ccbfdf4e6
commit
80a7647f10
|
|
@ -1,12 +1,11 @@
|
|||
import { Playstyle } from "@prisma/client";
|
||||
import { countries } from "countries-list";
|
||||
import { useUser } from "hooks/common";
|
||||
import { useRouter } from "next/router";
|
||||
import { Dispatch, useMemo, useReducer } from "react";
|
||||
import { setManySearchParams, setSearchParams } from "utils/setSearchParams";
|
||||
import { getBooleanFromString, getWeaponFromString } from "utils/strings";
|
||||
import { trpc } from "utils/trpc";
|
||||
import { isFreeAgentPlaystyle, isFreeAgentRegion } from "utils/typeGuards";
|
||||
import { useMyRouter } from "./useMyRouter";
|
||||
|
||||
export type FreeAgentRegion = "EUROPE" | "AMERICAS" | "ASIA";
|
||||
|
||||
|
|
@ -48,7 +47,7 @@ export type UseFreeAgentsDispatch = Dispatch<Action>;
|
|||
const defaultState: UseFreeAgentsState = { xp: false, plusServer: false };
|
||||
|
||||
export function useFreeAgents() {
|
||||
const router = useRouter();
|
||||
const router = useMyRouter();
|
||||
const [user] = useUser();
|
||||
|
||||
const posts = trpc.useQuery(["freeAgents.posts"], {
|
||||
|
|
@ -67,27 +66,27 @@ export function useFreeAgents() {
|
|||
(oldState: UseFreeAgentsState, action: Action) => {
|
||||
switch (action.type) {
|
||||
case "SET_PLAYSTYLE":
|
||||
setSearchParams("playstyle", action.value);
|
||||
router.setSearchParams(["playstyle", action.value]);
|
||||
|
||||
return { ...oldState, playstyle: action.value };
|
||||
case "SET_XP_VALUE":
|
||||
setSearchParams("xp", "" + action.value);
|
||||
router.setSearchParams(["xp", action.value]);
|
||||
|
||||
return { ...oldState, xp: action.value };
|
||||
case "SET_PLUS_SERVER_VALUE":
|
||||
setSearchParams("plusServer", "" + action.value);
|
||||
router.setSearchParams(["plusServer", action.value]);
|
||||
|
||||
return { ...oldState, plusServer: action.value };
|
||||
case "SET_WEAPON":
|
||||
setSearchParams("weapon", action.value);
|
||||
router.setSearchParams(["weapon", action.value]);
|
||||
|
||||
return { ...oldState, weapon: action.value };
|
||||
case "SET_REGION":
|
||||
setSearchParams("region", action.value);
|
||||
router.setSearchParams(["region", action.value]);
|
||||
|
||||
return { ...oldState, region: action.value };
|
||||
case "RESET_FILTERS":
|
||||
setManySearchParams([], true);
|
||||
router.resetSearchParams();
|
||||
|
||||
return defaultState;
|
||||
default:
|
||||
|
|
|
|||
16
hooks/sr.ts
16
hooks/sr.ts
|
|
@ -1,11 +1,10 @@
|
|||
import { SalmonRunRecordCategory } from "@prisma/client";
|
||||
import { useRouter } from "next/router";
|
||||
import { salmonRunCategoryToNatural } from "pages/sr/leaderboards/new";
|
||||
import { GetAllSalmonRunRecordsData } from "prisma/queries/getAllSalmonRunRecords";
|
||||
import { useReducer } from "react";
|
||||
import useSWR from "swr";
|
||||
import { salmonRunStages } from "utils/lists/stages";
|
||||
import { setSearchParams } from "utils/setSearchParams";
|
||||
import { useMyRouter } from "./useMyRouter";
|
||||
|
||||
export type WeaponsFilter =
|
||||
| "NORMAL"
|
||||
|
|
@ -41,23 +40,22 @@ type Action =
|
|||
};
|
||||
|
||||
export function useSalmonRunRecords() {
|
||||
const router = useRouter();
|
||||
const { data: recordsData } = useSWR<GetAllSalmonRunRecordsData>(
|
||||
"/api/sr/records"
|
||||
);
|
||||
const router = useMyRouter();
|
||||
const { data: recordsData } =
|
||||
useSWR<GetAllSalmonRunRecordsData>("/api/sr/records");
|
||||
const [state, dispatch] = useReducer(
|
||||
(oldState: UseSalmonRunRecordsState, action: Action) => {
|
||||
switch (action.type) {
|
||||
case "SET_STAGE":
|
||||
setSearchParams("stage", action.stage);
|
||||
router.setSearchParams(["stage", action.stage]);
|
||||
|
||||
return { ...oldState, stage: action.stage };
|
||||
case "SET_CATEGORY":
|
||||
setSearchParams("category", action.category);
|
||||
router.setSearchParams(["category", action.category]);
|
||||
|
||||
return { ...oldState, category: action.category };
|
||||
case "SET_WEAPONS_FILTER":
|
||||
setSearchParams("filter", action.filter);
|
||||
router.setSearchParams(["filter", action.filter]);
|
||||
|
||||
return { ...oldState, weaponsFilter: action.filter };
|
||||
default:
|
||||
|
|
|
|||
45
hooks/useMyRouter.test.ts
Normal file
45
hooks/useMyRouter.test.ts
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import { adjustedSearchParams } from "./useMyRouter";
|
||||
|
||||
const TEST_URL = "https://sendou.ink/freeagents?xp=true&playstyle=MIDLINE";
|
||||
|
||||
describe("adjustedSearchParams", () => {
|
||||
test("no changes return search params unchanged", () => {
|
||||
const newParams = adjustedSearchParams(TEST_URL, []);
|
||||
const newParamsObj = Object.fromEntries(Array.from(newParams.entries()));
|
||||
|
||||
expect(newParamsObj.xp).toBe("true");
|
||||
expect(newParamsObj.playstyle).toBe("MIDLINE");
|
||||
expect(Object.keys(newParamsObj).length).toBe(2);
|
||||
});
|
||||
|
||||
test("adds search params while retaining old", () => {
|
||||
const newParams = adjustedSearchParams(TEST_URL, [["test", "works"]]);
|
||||
const newParamsObj = Object.fromEntries(Array.from(newParams.entries()));
|
||||
|
||||
expect(newParamsObj.xp).toBe("true");
|
||||
expect(newParamsObj.playstyle).toBe("MIDLINE");
|
||||
expect(newParamsObj.test).toBe("works");
|
||||
expect(Object.keys(newParamsObj).length).toBe(3);
|
||||
});
|
||||
|
||||
test("adds search params of number and boolean types", () => {
|
||||
const newParams = adjustedSearchParams(TEST_URL, [
|
||||
["number", 2],
|
||||
["boolean", true],
|
||||
]);
|
||||
const newParamsObj = Object.fromEntries(Array.from(newParams.entries()));
|
||||
|
||||
expect(newParamsObj.number).toBe("2");
|
||||
expect(newParamsObj.boolean).toBe("true");
|
||||
});
|
||||
|
||||
test("falsy value removes the key", () => {
|
||||
const newParams = adjustedSearchParams(TEST_URL, [
|
||||
["xp", ""],
|
||||
["playstyle", null],
|
||||
]);
|
||||
const newParamsObj = Object.fromEntries(Array.from(newParams.entries()));
|
||||
|
||||
expect(Object.keys(newParamsObj).length).toBe(0);
|
||||
});
|
||||
});
|
||||
84
hooks/useMyRouter.ts
Normal file
84
hooks/useMyRouter.ts
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
import { NextRouter, useRouter } from "next/router";
|
||||
import { URLSearchParams } from "url";
|
||||
|
||||
type SearchParamsTuple = [
|
||||
key: string,
|
||||
value:
|
||||
| string
|
||||
| string[]
|
||||
| number
|
||||
| number[]
|
||||
| boolean
|
||||
| boolean[]
|
||||
| null
|
||||
| undefined
|
||||
];
|
||||
|
||||
export const adjustedSearchParams = (
|
||||
url: string,
|
||||
newParams: SearchParamsTuple[]
|
||||
): URLSearchParams => {
|
||||
const result = new URL(url).searchParams;
|
||||
|
||||
for (const [key, value] of newParams) {
|
||||
if (!value && typeof value !== "boolean") {
|
||||
result.delete(key);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
result.delete(key);
|
||||
for (const element of value) {
|
||||
result.append(key, String(element));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
result.set(key, String(value));
|
||||
}
|
||||
|
||||
result.sort();
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
const isSearchParamsTuple = (
|
||||
newParams: SearchParamsTuple | SearchParamsTuple[]
|
||||
): newParams is SearchParamsTuple => {
|
||||
return !Array.isArray(newParams[0]);
|
||||
};
|
||||
|
||||
const setRouterSearchParams = (
|
||||
router: NextRouter,
|
||||
newParams: SearchParamsTuple | SearchParamsTuple[]
|
||||
) => {
|
||||
const newSearchParams = adjustedSearchParams(
|
||||
window.location.href,
|
||||
isSearchParamsTuple(newParams) ? [newParams] : newParams
|
||||
);
|
||||
|
||||
router.replace(
|
||||
`${router.pathname}?${newSearchParams.toString()}`,
|
||||
undefined,
|
||||
{
|
||||
shallow: true,
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const resetSearchParams = (router: NextRouter) =>
|
||||
router.replace(router.pathname, undefined, { shallow: true });
|
||||
|
||||
export const useMyRouter = (): NextRouter & {
|
||||
resetSearchParams: () => void;
|
||||
setSearchParams: (newParams: SearchParamsTuple | SearchParamsTuple[]) => void;
|
||||
} => {
|
||||
const router = useRouter();
|
||||
|
||||
return {
|
||||
...router,
|
||||
resetSearchParams: () => resetSearchParams(router),
|
||||
setSearchParams: (newParams: SearchParamsTuple | SearchParamsTuple[]) =>
|
||||
setRouterSearchParams(router, newParams),
|
||||
};
|
||||
};
|
||||
4
jest.config.js
Normal file
4
jest.config.js
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
module.exports = {
|
||||
preset: "ts-jest",
|
||||
testEnvironment: "node",
|
||||
};
|
||||
7959
package-lock.json
generated
7959
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
|
|
@ -3,6 +3,7 @@
|
|||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"test": "jest",
|
||||
"dev": "next dev",
|
||||
"build": "lingui compile && npm run prebuild && next build",
|
||||
"build:analyze": "lingui compile && npm run prebuild && ANALYZE=true next build",
|
||||
|
|
@ -68,6 +69,7 @@
|
|||
"@babel/core": "^7.14.5",
|
||||
"@lingui/cli": "^3.8.3",
|
||||
"@lingui/macro": "^3.8.3",
|
||||
"@types/jest": "^26.0.23",
|
||||
"@types/node": "^15.12.2",
|
||||
"@types/nprogress": "^0.2.0",
|
||||
"@types/react": "^17.0.11",
|
||||
|
|
@ -80,6 +82,7 @@
|
|||
"fishery": "^1.3.1",
|
||||
"prettier": "^2.3.1",
|
||||
"prisma": "^2.24.1",
|
||||
"ts-jest": "^27.0.3",
|
||||
"ts-node": "^10.0.0",
|
||||
"typescript": "^4.3.2"
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user