refine optional API mocking

This commit is contained in:
Felix Staud 2024-08-02 14:49:14 -07:00
parent 018a628e6d
commit f133a8f1d9
12 changed files with 162 additions and 79 deletions

View File

@ -5,4 +5,4 @@ VITE_DISCORD_CLIENT_ID=1234567890
VITE_GOOGLE_CLIENT_ID=1234567890
VITE_I18N_DEBUG=1
VITE_PORT=8000
VITE_MOCK_API=1
VITE_MOCK_API=0

8
package-lock.json generated
View File

@ -21,6 +21,7 @@
"@eslint/js": "^9.3.0",
"@hpcc-js/wasm": "^2.18.0",
"@stylistic/eslint-plugin-ts": "^2.6.0-beta.0",
"@types/crypto-js": "^4.2.2",
"@types/jsdom": "^21.1.7",
"@types/node": "^20.12.13",
"@typescript-eslint/eslint-plugin": "^8.0.0-alpha.54",
@ -1763,6 +1764,13 @@
"integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==",
"dev": true
},
"node_modules/@types/crypto-js": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.2.2.tgz",
"integrity": "sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/eslint": {
"version": "8.56.11",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.11.tgz",

View File

@ -23,6 +23,7 @@
"@eslint/js": "^9.3.0",
"@hpcc-js/wasm": "^2.18.0",
"@stylistic/eslint-plugin-ts": "^2.6.0-beta.0",
"@types/crypto-js": "^4.2.2",
"@types/jsdom": "^21.1.7",
"@types/node": "^20.12.13",
"@typescript-eslint/eslint-plugin": "^8.0.0-alpha.54",
@ -32,7 +33,7 @@
"eslint": "^9.7.0",
"jsdom": "^24.0.0",
"lefthook": "^1.6.12",
"msw": "^2.3.1",
"msw": "^2.3.1",
"phaser3spectorjs": "^0.0.8",
"typedoc": "^0.26.4",
"typescript": "^5.5.3",
@ -61,9 +62,9 @@
"#app/*": "./src/*",
"#test/*": "./src/test/*"
},
"msw": {
"workerDirectory": [
"public"
]
}
}
"msw": {
"workerDirectory": [
"public"
]
}
}

View File

@ -13,7 +13,7 @@ async function enableApiMocking(): Promise<ServiceWorkerRegistration | void> {
const { worker } = await import("./mocks/msw/msw-browser");
return worker.start({ onUnhandledRequest: "bypass" });
}
console.log("API Mocking disabled.");
return Promise.resolve();
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,38 @@
import { http, HttpResponse } from "msw";
/**
* Api mock handlers for `/account` path
*/
export const mswAccountHandlers = (baseUrl: string) => [
/**
* Account Info
*/
http.get(`${baseUrl}/account/info`, async () => {
return HttpResponse.json({
username: "Guest",
});
}),
/**
* Account login
*/
http.post(`${baseUrl}/account/login`, async () => {
return HttpResponse.json({
token: "this-is-your-session-token",
});
}),
/**
* Account logout
*/
http.get(`${baseUrl}/account/logout`, async () => {
return HttpResponse.text();
}),
/**
* Account register
*/
http.post(`${baseUrl}/account/register`, async ({ request }) => {
return new HttpResponse("This is just a mocked API. Registration not possible!", {
status: 500,
statusText: "Internal Server Error",
});
}),
];

View File

@ -0,0 +1,28 @@
import { randInt } from "#app/utils.js";
import { http, HttpResponse } from "msw";
/**
* Api mock handlers for `/daily` path
*/
export const mswDailyHandlers = (baseUrl: string) => [
/**
* Daily rankingpagecount
*/
http.get(`${baseUrl}/daily/rankingpagecount`, async () => {
return HttpResponse.text("1");
}),
/**
* Daily rankings
*/
http.get(`${baseUrl}/daily/rankings`, async () => {
const rankings = Array.from({ length: 9 })
.map((n: number) => ({
username: `Player ${n + 1}`,
score: randInt(99999),
wave: randInt(99),
}))
.sort((a, b) => (a.score > b.score ? -1 : 1))
.map((rank, i) => ({ ...rank, rank: i + 1 }));
return HttpResponse.json(rankings);
}),
];

View File

@ -0,0 +1,18 @@
import { randInt } from "#app/utils.js";
import { http, HttpResponse } from "msw";
/**
* Api mock handlers for `/game` path
*/
export const mswGameHandlers = (baseUrl: string) => [
/**
* Game titlestats
*/
http.get(`${baseUrl}/game/titlestats`, async () => {
const playerCount = randInt(999999);
return HttpResponse.json({
playerCount,
battleCount: randInt(999999, playerCount),
});
}),
];

View File

@ -0,0 +1,47 @@
import { http, HttpResponse } from "msw";
import everythingJson from "../data/everything.json";
/**
* Api mock handlers for `/savedata` path
*/
export const mswSavedataHandlers = (baseUrl: string) => [
/**
* Savedata system
*/
http.get(`${baseUrl}/savedata/system/get`, async () => {
try {
const lsData = localStorage.getItem("data_Guest");
const data = atob(lsData);
const json = JSON.parse(data);
return HttpResponse.json(json);
} catch (e) {
console.warn("Failed to load localStorage data. Falling back to everything.json", e);
return HttpResponse.json(everythingJson); // make sure that the localhost data is loaded
}
}),
/**
* Savedata session
*/
http.get(`${baseUrl}/savedata/session/get`, async ({ request }) => {
console.log(`${baseUrl}/savedata/session/get`, request);
const { searchParams } = new URL(request.url);
const slot = searchParams.get("slot");
const lsData = localStorage.getItem(`sessionData${slot}_Guest`);
return HttpResponse.text(lsData ?? null);
}),
/**
* Savedata update
*/
http.post(`${baseUrl}/savedata/updateAll`, async () => {
return HttpResponse.text(); // right?
}),
/**
* Savedata verify
*/
http.get(`${baseUrl}/savedata/system/verify`, async () => {
return HttpResponse.json({
valid: true,
});
}),
];

View File

@ -1,43 +0,0 @@
import { randInt } from "#app/utils.js";
import { http, HttpResponse } from "msw";
import everythingPrsv from "../test/utils/saves/everything.prsv?raw";
const baseUrl = import.meta.env.VITE_SERVER_URL ?? "https://api.pokerogue.net";
export const getHandlers = [
http.get(`${baseUrl}/account/info`, async () => {
return HttpResponse.json({
username: "guest",
});
}),
http.get(`${baseUrl}/savedata/system`, async () => {
return HttpResponse.text(everythingPrsv);
}),
http.get(`${baseUrl}/savedata/session`, async () => {
return HttpResponse.text();
}),
http.get(`${baseUrl}/daily/rankingpagecount`, async () => {
return HttpResponse.text("1");
}),
http.get(`${baseUrl}/daily/rankings`, async () => {
const rankings = [...Array(9)]
.map((_, i) => ({
username: `Player ${i + 1}`,
score: randInt(99999),
wave: randInt(99),
}))
.sort((a, b) => (a.score > b.score ? -1 : 1))
.map((rank, i) => ({ ...rank, rank: i + 1 }));
return HttpResponse.json(rankings);
}),
http.get(`${baseUrl}/game/titlestats`, async () => {
const playerCount = randInt(999999);
return HttpResponse.json({
playerCount,
battleCount: randInt(999999, playerCount),
});
}),
http.get(`${baseUrl}/account/logout`, async () => {
return HttpResponse.text();
}),
];

View File

@ -1,24 +0,0 @@
import { http, HttpResponse } from "msw";
const baseUrl = import.meta.env.VITE_SERVER_URL ?? "https://api.pokerogue.net";
export const postHandlers = [
http.post(`${baseUrl}/account/login`, async () => {
return HttpResponse.json({
token: "this-is-your-session-token",
});
}),
http.post(
`${baseUrl}/account/register`,
async ({ request }) => {
console.log(request);
return new HttpResponse("This is just localhost!", {
status: 500,
statusText: "Internal Server Error",
});
}
),
http.post(`${baseUrl}/savedata/update`, async () => {
return HttpResponse.text(); // right?
}),
];

View File

@ -1,5 +1,14 @@
import { setupWorker } from "msw/browser";
import { getHandlers } from "./handlers/get-handlers";
import { postHandlers } from "./handlers/post-handlers";
import { mswAccountHandlers } from "./api/handlers/msw-account-handlers";
import { mswDailyHandlers } from "./api/handlers/msw-daily-handlers";
import { mswGameHandlers } from "./api/handlers/msw-game-handlers";
import { mswSavedataHandlers } from "./api/handlers/msw-savedata-handlers";
export const worker = setupWorker(...getHandlers, ...postHandlers);
const mswApiBase = import.meta.env.VITE_SERVER_URL ?? "http://localhost:8001";
export const worker = setupWorker(
...mswAccountHandlers(mswApiBase),
...mswDailyHandlers(mswApiBase),
...mswSavedataHandlers(mswApiBase),
...mswGameHandlers(mswApiBase)
);