From 0e3e1284949e858a670fd8c93465833832112d61 Mon Sep 17 00:00:00 2001 From: flx-sta <50131232+flx-sta@users.noreply.github.com> Date: Fri, 4 Oct 2024 15:50:28 -0700 Subject: [PATCH] chore: cleanup --- src/@types/PokerogueAccountApi.ts | 17 + .../PokerogueAdminApi.ts} | 0 .../TitleStats.ts => @types/PokerogueApi.ts} | 0 src/@types/PokerogueDailyApi.ts | 10 + .../PokerogueSavedataApi.ts} | 0 src/@types/PokerogueSessionSavedataApi.ts | 39 ++ src/@types/PokerogueSystemSavedataApi.ts | 20 + src/@types/pokerogue-api.ts | 9 - src/account.ts | 11 +- src/data/daily-run.ts | 4 +- src/phases/game-over-phase.ts | 4 +- src/plugins/api/{api.ts => api-base.ts} | 17 +- src/plugins/api/models/AccountInfo.ts | 4 - src/plugins/api/models/AccountLogin.ts | 10 - src/plugins/api/models/AccountRegister.ts | 4 - src/plugins/api/models/BaseApiResponse.ts | 6 - src/plugins/api/models/ClientSession.ts | 3 - src/plugins/api/models/ErrorResponse.ts | 4 - .../api/models/UpdateSessionSavedata.ts | 6 - .../api/models/UpdateSystemSavedata.ts | 5 - src/plugins/api/models/VerifySavedata.ts | 6 - src/plugins/api/pokerogue-account-api.ts | 101 +++++ src/plugins/api/pokerogue-admin-api.ts | 15 +- src/plugins/api/pokerogue-api.ts | 397 +----------------- src/plugins/api/pokerogue-daily-api.ts | 57 +++ src/plugins/api/pokerogue-savedata-api.ts | 41 ++ .../api/pokerogue-session-savedata-api.ts | 124 ++++++ .../api/pokerogue-system-savedata-api.ts | 78 ++++ src/system/game-data.ts | 25 +- src/test/account.test.ts | 33 +- src/test/daily_mode.test.ts | 15 +- src/test/reload.test.ts | 20 +- src/test/utils/gameWrapper.ts | 2 +- src/ui/admin-ui-handler.ts | 2 +- src/ui/daily-run-scoreboard.ts | 4 +- src/ui/login-form-ui-handler.ts | 2 +- src/ui/menu-ui-handler.ts | 2 +- src/ui/registration-form-ui-handler.ts | 4 +- 38 files changed, 588 insertions(+), 513 deletions(-) create mode 100644 src/@types/PokerogueAccountApi.ts rename src/{plugins/api/models/LinkAccountToDiscordId.ts => @types/PokerogueAdminApi.ts} (100%) rename src/{plugins/api/models/TitleStats.ts => @types/PokerogueApi.ts} (100%) create mode 100644 src/@types/PokerogueDailyApi.ts rename src/{plugins/api/models/UpdateAllSavedata.ts => @types/PokerogueSavedataApi.ts} (100%) create mode 100644 src/@types/PokerogueSessionSavedataApi.ts create mode 100644 src/@types/PokerogueSystemSavedataApi.ts delete mode 100644 src/@types/pokerogue-api.ts rename src/plugins/api/{api.ts => api-base.ts} (77%) delete mode 100644 src/plugins/api/models/AccountInfo.ts delete mode 100644 src/plugins/api/models/AccountLogin.ts delete mode 100644 src/plugins/api/models/AccountRegister.ts delete mode 100644 src/plugins/api/models/BaseApiResponse.ts delete mode 100644 src/plugins/api/models/ClientSession.ts delete mode 100644 src/plugins/api/models/ErrorResponse.ts delete mode 100644 src/plugins/api/models/UpdateSessionSavedata.ts delete mode 100644 src/plugins/api/models/UpdateSystemSavedata.ts delete mode 100644 src/plugins/api/models/VerifySavedata.ts create mode 100644 src/plugins/api/pokerogue-account-api.ts create mode 100644 src/plugins/api/pokerogue-daily-api.ts create mode 100644 src/plugins/api/pokerogue-savedata-api.ts create mode 100644 src/plugins/api/pokerogue-session-savedata-api.ts create mode 100644 src/plugins/api/pokerogue-system-savedata-api.ts diff --git a/src/@types/PokerogueAccountApi.ts b/src/@types/PokerogueAccountApi.ts new file mode 100644 index 00000000000..765628c2358 --- /dev/null +++ b/src/@types/PokerogueAccountApi.ts @@ -0,0 +1,17 @@ +import type { UserInfo } from "#app/account"; + +export interface AccountInfoResponse extends UserInfo {} + +export interface AccountLoginRequest { + username: string; + password: string; +} + +export interface AccountLoginResponse { + token: string; +} + +export interface AccountRegisterRequest { + username: string; + password: string; +} diff --git a/src/plugins/api/models/LinkAccountToDiscordId.ts b/src/@types/PokerogueAdminApi.ts similarity index 100% rename from src/plugins/api/models/LinkAccountToDiscordId.ts rename to src/@types/PokerogueAdminApi.ts diff --git a/src/plugins/api/models/TitleStats.ts b/src/@types/PokerogueApi.ts similarity index 100% rename from src/plugins/api/models/TitleStats.ts rename to src/@types/PokerogueApi.ts diff --git a/src/@types/PokerogueDailyApi.ts b/src/@types/PokerogueDailyApi.ts new file mode 100644 index 00000000000..3f3d8eb61ca --- /dev/null +++ b/src/@types/PokerogueDailyApi.ts @@ -0,0 +1,10 @@ +import type { ScoreboardCategory } from "#app/ui/daily-run-scoreboard"; + +export interface GetDailyRankingsRequest { + category: ScoreboardCategory; + page?: number; +} + +export interface GetDailyRankingsPageCountRequest { + category: ScoreboardCategory; +} diff --git a/src/plugins/api/models/UpdateAllSavedata.ts b/src/@types/PokerogueSavedataApi.ts similarity index 100% rename from src/plugins/api/models/UpdateAllSavedata.ts rename to src/@types/PokerogueSavedataApi.ts diff --git a/src/@types/PokerogueSessionSavedataApi.ts b/src/@types/PokerogueSessionSavedataApi.ts new file mode 100644 index 00000000000..5fcd8575b15 --- /dev/null +++ b/src/@types/PokerogueSessionSavedataApi.ts @@ -0,0 +1,39 @@ +export class UpdateSessionSavedataRequest { + slot: number; + trainerId: number; + secretId: number; + clientSessionId: string; +} + +/** This is **NOT** similar to {@linkcode ClearSessionSavedataRequest} */ +export interface NewClearSessionSavedataRequest { + slot: number; + clientSessionId: string; +} + +export interface GetSessionSavedataRequest { + slot: number; + clientSessionId: string; +} + +export interface DeleteSessionSavedataRequest { + slot: number; + clientSessionId: string; +} + +/** This is **NOT** similar to {@linkcode NewClearSessionSavedataRequest} */ +export interface ClearSessionSavedataRequest { + slot: number; + trainerId: number; + clientSessionId: string; +} + +/** + * Pokerogue API response for path: `/savedata/session/clear` + */ +export interface ClearSessionSavedataResponse { + /** Contains the error message if any occured */ + error?: string; + /** Is `true` if the request was successfully processed */ + success?: boolean; +} diff --git a/src/@types/PokerogueSystemSavedataApi.ts b/src/@types/PokerogueSystemSavedataApi.ts new file mode 100644 index 00000000000..8ce160a5ec2 --- /dev/null +++ b/src/@types/PokerogueSystemSavedataApi.ts @@ -0,0 +1,20 @@ +import type { SystemSaveData } from "#app/system/game-data"; + +export interface GetSystemSavedataRequest { + clientSessionId: string; +} + +export class UpdateSystemSavedataRequest { + clientSessionId: string; + trainerId?: number; + secretId?: number; +} + +export interface VerifySystemSavedataRequest { + clientSessionId: string; +} + +export interface VerifySystemSavedataResponse { + valid: boolean; + systemData: SystemSaveData; +} diff --git a/src/@types/pokerogue-api.ts b/src/@types/pokerogue-api.ts deleted file mode 100644 index 892869968bb..00000000000 --- a/src/@types/pokerogue-api.ts +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Pokerogue API response for path: `/savedata/session/clear` - */ -export interface PokerogueApiClearSessionData { - /** Contains the error message if any occured */ - error?: string; - /** Is `true` if the request was successfully processed */ - success?: boolean; -} diff --git a/src/account.ts b/src/account.ts index c012e44425e..4c91b61dd67 100644 --- a/src/account.ts +++ b/src/account.ts @@ -44,17 +44,14 @@ export function updateUserInfo(): Promise<[boolean, integer]> { }); return resolve([ true, 200 ]); } - pokerogueApi.getAccountInfo().then((accountInfoOrStatus) => { - if (typeof accountInfoOrStatus === "number") { - resolve([ false, accountInfoOrStatus ]); + pokerogueApi.account.getInfo().then(([accountInfo, status]) => { + if (!accountInfo) { + resolve([ false, status ]); return; } else { - loggedInUser = accountInfoOrStatus; + loggedInUser = accountInfo; resolve([ true, 200 ]); } - }).catch(err => { - console.error(err); - resolve([ false, 500 ]); }); }); } diff --git a/src/data/daily-run.ts b/src/data/daily-run.ts index f6fa3fce72b..506ea0471c6 100644 --- a/src/data/daily-run.ts +++ b/src/data/daily-run.ts @@ -15,9 +15,9 @@ export interface DailyRunConfig { export function fetchDailyRunSeed(): Promise { return new Promise((resolve, reject) => { - pokerogueApi.getDailySeed().then(dailySeed => { + pokerogueApi.daily.getSeed().then(dailySeed => { resolve(dailySeed); - }).catch(err => reject(err)); // TODO: does this ever reject with the api class? + }); }); } diff --git a/src/phases/game-over-phase.ts b/src/phases/game-over-phase.ts index b5cf9b1c4b8..d46389ce4f0 100644 --- a/src/phases/game-over-phase.ts +++ b/src/phases/game-over-phase.ts @@ -178,8 +178,8 @@ export class GameOverPhase extends BattlePhase { If Offline, execute offlineNewClear(), a localStorage implementation of newClear daily run checks */ if (this.victory) { if (!Utils.isLocal || Utils.isLocalServerConnected) { - pokerogueApi.newclearSession(this.scene.sessionSlotId, clientSessionId) - .then((isNewClear) => doGameOver(!!isNewClear)); + pokerogueApi.savedata.session.newclear({ slot: this.scene.sessionSlotId, clientSessionId }) + .then((success) => doGameOver(!!success)); } else { this.scene.gameData.offlineNewClear(this.scene).then(result => { doGameOver(result); diff --git a/src/plugins/api/api.ts b/src/plugins/api/api-base.ts similarity index 77% rename from src/plugins/api/api.ts rename to src/plugins/api/api-base.ts index e31dbc4ad2b..c744ac8df23 100644 --- a/src/plugins/api/api.ts +++ b/src/plugins/api/api-base.ts @@ -3,7 +3,7 @@ import { getCookie } from "#app/utils"; type DataType = "json" | "form-urlencoded"; -export abstract class Api { +export abstract class ApiBase { //#region Fields protected readonly base: string; @@ -71,4 +71,19 @@ export abstract class Api { return await fetch(this.base + path, config); } + + /** + * Helper to transform data to {@linkcode URLSearchParams} + * Any key with a value of `undefined` will be ignored. + * Any key with a value of `null` will be included. + * @param data the data to transform to {@linkcode URLSearchParams} + * @returns a {@linkcode URLSearchParams} representaton of {@linkcode data} + */ + protected toUrlSearchParams>(data: D) { + const arr = Object.entries(data) + .map(([key, value]) => (value !== undefined ? [key, String(value)] : [key, ""])) + .filter(([, value]) => value !== ""); + + return new URLSearchParams(arr); + } } diff --git a/src/plugins/api/models/AccountInfo.ts b/src/plugins/api/models/AccountInfo.ts deleted file mode 100644 index 13e81eb1526..00000000000 --- a/src/plugins/api/models/AccountInfo.ts +++ /dev/null @@ -1,4 +0,0 @@ -import type { UserInfo } from "#app/account"; -import type { BaseApiResponse } from "./BaseApiResponse"; - -export interface AccountInfoResponse extends BaseApiResponse, UserInfo {} diff --git a/src/plugins/api/models/AccountLogin.ts b/src/plugins/api/models/AccountLogin.ts deleted file mode 100644 index a3767898621..00000000000 --- a/src/plugins/api/models/AccountLogin.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { BaseApiResponse } from "./BaseApiResponse"; - -export interface AccountLoginRequest { - username: string; - password: string; -} - -export interface AccountLoginResponse extends BaseApiResponse { - token: string; -} diff --git a/src/plugins/api/models/AccountRegister.ts b/src/plugins/api/models/AccountRegister.ts deleted file mode 100644 index b06d77cc284..00000000000 --- a/src/plugins/api/models/AccountRegister.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface AccountRegisterRequest { - username: string; - password: string; -} diff --git a/src/plugins/api/models/BaseApiResponse.ts b/src/plugins/api/models/BaseApiResponse.ts deleted file mode 100644 index 4e023aea1f1..00000000000 --- a/src/plugins/api/models/BaseApiResponse.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface BaseApiResponse { - error?: { - code: number; - message: string; - }; -} diff --git a/src/plugins/api/models/ClientSession.ts b/src/plugins/api/models/ClientSession.ts deleted file mode 100644 index dccc2bc639c..00000000000 --- a/src/plugins/api/models/ClientSession.ts +++ /dev/null @@ -1,3 +0,0 @@ -import type { GameData } from "#app/system/game-data"; - -export interface ClientSessionResponse extends GameData {} diff --git a/src/plugins/api/models/ErrorResponse.ts b/src/plugins/api/models/ErrorResponse.ts deleted file mode 100644 index c85a9e8716e..00000000000 --- a/src/plugins/api/models/ErrorResponse.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface ErrorResponse { - code: number; - message: string; -} diff --git a/src/plugins/api/models/UpdateSessionSavedata.ts b/src/plugins/api/models/UpdateSessionSavedata.ts deleted file mode 100644 index 8e450e40f6c..00000000000 --- a/src/plugins/api/models/UpdateSessionSavedata.ts +++ /dev/null @@ -1,6 +0,0 @@ -export class UpdateSessionSavedataRequest { - slot: number; - trainerId: number; - secretId: number; - clientSessionId: string; -} diff --git a/src/plugins/api/models/UpdateSystemSavedata.ts b/src/plugins/api/models/UpdateSystemSavedata.ts deleted file mode 100644 index ebf74acfc7e..00000000000 --- a/src/plugins/api/models/UpdateSystemSavedata.ts +++ /dev/null @@ -1,5 +0,0 @@ -export class UpdateSystemSavedataRequest { - clientSessionId: string; - trainerId?: number; - secretId?: number; -} diff --git a/src/plugins/api/models/VerifySavedata.ts b/src/plugins/api/models/VerifySavedata.ts deleted file mode 100644 index afbaad949f2..00000000000 --- a/src/plugins/api/models/VerifySavedata.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type { SystemSaveData } from "#app/system/game-data"; - -export interface VerifySavedataResponse { - valid: boolean; - systemData: SystemSaveData; -} diff --git a/src/plugins/api/pokerogue-account-api.ts b/src/plugins/api/pokerogue-account-api.ts new file mode 100644 index 00000000000..7795ee9fb43 --- /dev/null +++ b/src/plugins/api/pokerogue-account-api.ts @@ -0,0 +1,101 @@ +import type { + AccountInfoResponse, + AccountLoginRequest, + AccountLoginResponse, + AccountRegisterRequest, +} from "#app/@types/PokerogueAccountApi"; +import { SESSION_ID_COOKIE_NAME } from "#app/constants"; +import { ApiBase } from "#app/plugins/api/api-base"; +import { removeCookie, setCookie } from "#app/utils"; + +/** + * A wrapper for PokéRogue account API requests. + */ +export class PokerogueAccountApi extends ApiBase { + //#region Public + + /** + * Request the {@linkcode AccountInfoResponse | UserInfo} of the logged in user. + * The user is identified by the {@linkcode SESSION_ID_COOKIE_NAME | session cookie}. + */ + public async getInfo(): Promise<[data: AccountInfoResponse | null, status: number]> { + try { + const response = await this.doGet("/account/info"); + + if (response.ok) { + const resData = (await response.json()) as AccountInfoResponse; + return [resData, response.status]; + } else { + console.warn("Could not get account info!", response.status, response.statusText); + return [null, response.status]; + } + } catch (err) { + console.warn("Could not get account info!", err); + return [null, 500]; + } + } + + /** + * Register a new account. + * @param registerData The {@linkcode AccountRegisterRequest} to send + * @returns An error message if something went wrong + */ + public async register(registerData: AccountRegisterRequest) { + try { + const response = await this.doPost("/account/register", registerData, "form-urlencoded"); + + if (response.ok) { + return null; + } else { + return response.text(); + } + } catch (err) { + console.warn("Register failed!", err); + } + + return "Unknown error!"; + } + + /** + * Send a login request. + * Sets the session cookie on success. + * @param loginData The {@linkcode AccountLoginRequest} to send + * @returns An error message if something went wrong + */ + public async login(loginData: AccountLoginRequest) { + try { + const response = await this.doPost("/account/login", loginData, "form-urlencoded"); + + if (response.ok) { + const loginResponse = (await response.json()) as AccountLoginResponse; + setCookie(SESSION_ID_COOKIE_NAME, loginResponse.token); + return null; + } else { + console.warn("Login failed!", response.status, response.statusText); + return response.text(); + } + } catch (err) { + console.warn("Login failed!", err); + } + + return "Unknown error!"; + } + + /** + * Send a logout request. + * **Always** (no matter if failed or not) removes the session cookie. + */ + public async logout() { + try { + const response = await this.doGet("/account/logout"); + + if (!response.ok) { + throw new Error(`${response.status}: ${response.statusText}`); + } + } catch (err) { + console.error("Log out failed!", err); + } + + removeCookie(SESSION_ID_COOKIE_NAME); // we are always clearing the cookie. + } +} diff --git a/src/plugins/api/pokerogue-admin-api.ts b/src/plugins/api/pokerogue-admin-api.ts index 3da9055d4f4..44ade99a1ee 100644 --- a/src/plugins/api/pokerogue-admin-api.ts +++ b/src/plugins/api/pokerogue-admin-api.ts @@ -1,17 +1,16 @@ -import { Api } from "#app/plugins/api/api"; -import type { LinkAccountToDiscordIdRequest } from "#app/plugins/api/models/LinkAccountToDiscordId"; +import type { LinkAccountToDiscordIdRequest } from "#app/@types/PokerogueAdminApi"; +import { ApiBase } from "#app/plugins/api/api-base"; -export class PokerogueAdminApi extends Api { +export class PokerogueAdminApi extends ApiBase { /** * Links an account to a discord id. - * @param linkData The {@linkcode LinkAccountToDiscordIdRequest} to send + * @param params The {@linkcode LinkAccountToDiscordIdRequest} to send * @returns `true` if successful, `false` if not */ - public async linkAccountToDiscordId(linkData: LinkAccountToDiscordIdRequest) { + public async linkAccountToDiscord(params: LinkAccountToDiscordIdRequest) { try { - const linkArr = Object.entries(linkData).map(([key, value]) => [key, String(value)]); - const params = new URLSearchParams(linkArr); - const response = await this.doPost("/admin/account/discord-link", params, "form-urlencoded"); + const urlSearchParams = this.toUrlSearchParams(params); + const response = await this.doPost("/admin/account/discord-link", urlSearchParams, "form-urlencoded"); if (response.ok) { return true; diff --git a/src/plugins/api/pokerogue-api.ts b/src/plugins/api/pokerogue-api.ts index b001c9d948e..ed65dab775a 100644 --- a/src/plugins/api/pokerogue-api.ts +++ b/src/plugins/api/pokerogue-api.ts @@ -1,30 +1,29 @@ -import type { PokerogueApiClearSessionData } from "#app/@types/pokerogue-api"; -import { loggedInUser } from "#app/account"; -import { MAX_INT_ATTR_VALUE, SESSION_ID_COOKIE_NAME } from "#app/constants"; -import { Api } from "#app/plugins/api/api"; -import type { AccountInfoResponse } from "#app/plugins/api/models/AccountInfo"; -import type { AccountLoginRequest, AccountLoginResponse } from "#app/plugins/api/models/AccountLogin"; -import type { TitleStatsResponse } from "#app/plugins/api/models/TitleStats"; -import type { UpdateAllSavedataRequest } from "#app/plugins/api/models/UpdateAllSavedata"; -import type { UpdateSessionSavedataRequest } from "#app/plugins/api/models/UpdateSessionSavedata"; -import type { UpdateSystemSavedataRequest } from "#app/plugins/api/models/UpdateSystemSavedata"; -import type { VerifySavedataResponse } from "#app/plugins/api/models/VerifySavedata"; -import type { SessionSaveData } from "#app/system/game-data"; -import type { RankingEntry, ScoreboardCategory } from "#app/ui/daily-run-scoreboard"; -import { removeCookie, setCookie } from "#app/utils"; +import type { TitleStatsResponse } from "#app/@types/PokerogueApi"; +import { ApiBase } from "#app/plugins/api/api-base"; +import { PokerogueAccountApi } from "#app/plugins/api/pokerogue-account-api"; import { PokerogueAdminApi } from "#app/plugins/api/pokerogue-admin-api"; -import type { AccountRegisterRequest } from "./models/AccountRegister"; +import { PokerogueDailyApi } from "#app/plugins/api/pokerogue-daily-api"; +import { PokerogueSavedataApi } from "#app/plugins/api/pokerogue-savedata-api"; -export class PokerogueApi extends Api { - //#region Fields +/** + * A wrapper for PokéRogue API requests. + */ +export class PokerogueApi extends ApiBase { + //#region Fields∏ + public readonly account: PokerogueAccountApi; + public readonly daily: PokerogueDailyApi; public readonly admin: PokerogueAdminApi; + public readonly savedata: PokerogueSavedataApi; //#region Public constructor(base: string) { super(base); + this.account = new PokerogueAccountApi(base); + this.daily = new PokerogueDailyApi(base); this.admin = new PokerogueAdminApi(base); + this.savedata = new PokerogueSavedataApi(base); } /** @@ -40,358 +39,6 @@ export class PokerogueApi extends Api { } } - /** - * Request the {@linkcode AccountInfoResponse | UserInfo} of the logged in user. - * The user is identified by the {@linkcode SESSION_ID_COOKIE_NAME | session cookie}. - */ - public async getAccountInfo() { - try { - const response = await this.doGet("/account/info"); - - if (response.ok) { - return (await response.json()) as AccountInfoResponse; - } else { - console.warn("Could not get account info!", response.status, response.statusText); - return response.status; - } - } catch (err) { - console.warn("Could not get account info!", err); - return 500; - } - } - - /** - * Send a login request. - * Sets the session cookie on success. - * @param loginData The {@linkcode AccountLoginRequest} to send - * @returns An error message if something went wrong - */ - public async login(loginData: AccountLoginRequest) { - try { - const response = await this.doPost("/account/login", loginData, "form-urlencoded"); - - if (response.ok) { - const loginResponse = (await response.json()) as AccountLoginResponse; - setCookie(SESSION_ID_COOKIE_NAME, loginResponse.token); - return null; - } else { - console.warn("Login failed!", response.status, response.statusText); - return response.text(); - } - } catch (err) { - console.warn("Login failed!", err); - } - - return "Unknown error!"; - } - - /** - * Register a new account. - * @param registerData The {@linkcode AccountRegisterRequest} to send - * @returns An error message if something went wrong - */ - public async register(registerData: AccountRegisterRequest) { - try { - const response = await this.doPost("/account/register", registerData, "form-urlencoded"); - - if (response.ok) { - return null; - } else { - return response.text(); - } - } catch (err) { - console.warn("Register failed!", err); - } - - return "Unknown error!"; - } - - /** - * Send a logout request. - * **Always** (no matter if failed or not) removes the session cookie. - */ - public async logout() { - try { - const response = await this.doGet("/account/logout"); - - if (!response.ok) { - throw new Error(`${response.status}: ${response.statusText}`); - } - } catch (err) { - console.error("Log out failed!", err); - } - - removeCookie(SESSION_ID_COOKIE_NAME); // we are always clearing the cookie. - } - - /** - * Request the daily-run seed. - * @returns The active daily-run seed as `string`. - */ - public async getDailySeed() { - try { - const response = await this.doGet("/daily/seed"); - return response.text(); - } catch (err) { - console.warn("Could not get daily-run seed!", err); - return null; - } - } - - /** - * Mark a save-session as cleared. - * @param slot The save-session slot to clear. - * @param sessionId The save-session ID to clear. - * @returns The raw savedata as `string`. - */ - public async newclearSession(slot: number, sessionId: string) { - try { - const params = new URLSearchParams(); - params.append("slot", String(slot)); - params.append("clientSessionId", sessionId); - - const response = await this.doGet(`/savedata/session/newclear?${params}`); - const json = await response.json(); - - return Boolean(json); - } catch (err) { - console.warn("Could not newclear session!", err); - return false; - } - } - - /** - * Get a system savedata. - * @param sessionId The savedata session ID - */ - public async getSystemSavedata(sessionId: string) { - try { - const params = new URLSearchParams(); - params.append("clientSessionId", sessionId); - - const response = await this.doGet(`/savedata/system/get?${params}`); - const rawSavedata = await response.text(); - - return rawSavedata; - } catch (err) { - console.warn("Could not get system savedata!", err); - return null; - } - } - - /** - * Verify if the session is valid. - * If not the {@linkcode SystemSaveData} is returned. - * @param sessionId The savedata session ID - * @returns A {@linkcode SystemSaveData} if **NOT** valid, otherwise `null`. - */ - public async verifySystemSavedata(sessionId: string) { - try { - const params = new URLSearchParams(); - params.append("clientSessionId", sessionId); - const response = await this.doGet(`/savedata/system/verify?${params}`); - - if (response.ok) { - const verifySavedata = (await response.json()) as VerifySavedataResponse; - - if (!verifySavedata.valid) { - return verifySavedata.systemData; - } - } - } catch (err) { - console.warn("Could not verify system savedata!", err); - } - - return null; - } - - /** - * Update a system savedata. - * @param updateData The {@linkcode UpdateSystemSavedataRequest} to send - * @param rawSystemData The raw {@linkcode SystemSaveData} - * @returns An error message if something went wrong - */ - public async updateSystemSavedata(updateData: UpdateSystemSavedataRequest, rawSystemData: string) { - try { - const updateArr = Object.entries(updateData).map(([key, value]) => [key, String(value)]); - const params = new URLSearchParams(updateArr); - const response = await this.doPost(`/savedata/system/update?${params}`, rawSystemData); - - return await response.text(); - } catch (err) { - console.warn("Could not update system savedata!", err); - } - - return null; - } - - /** - * Get a session savedata. - * @param slotId The slot ID to load - * @param sessionId The session ID - * @returns The session as `string` - */ - public async getSessionSavedata(slotId: number, sessionId: string) { - try { - const params = new URLSearchParams(); - params.append("slot", String(slotId)); - params.append("clientSessionId", sessionId); - - const response = await this.doGet(`/savedata/session/get?${params}`); - - return await response.text(); - } catch (err) { - console.warn("Could not get session savedata!", err); - return null; - } - } - - /** - * Update a session savedata. - * @param updateData The {@linkcode UpdateSessionSavedataRequest} to send - * @param rawSavedata The raw savedata (as `string`) - * @returns An error message if something went wrong - */ - public async updateSessionSavedata(updateData: UpdateSessionSavedataRequest, rawSavedata: string) { - try { - const updateArr = Object.entries(updateData).map(([key, value]) => [key, String(value)]); - const params = new URLSearchParams(updateArr); - - const response = await this.doPost(`/savedata/session/update?${params}`, rawSavedata); - - return await response.text(); - } catch (err) { - console.warn("Could not update session savedata!", err); - } - - return null; - } - - /** - * Delete a session savedata slot. - * @param slotId The slot ID to load - * @param sessionId The session ID - * @returns The session as `string` - */ - public async deleteSessionSavedata(slotId: number, sessionId: string) { - try { - const params = new URLSearchParams(); - params.append("slot", String(slotId)); - params.append("clientSessionId", sessionId); - - const response = await this.doGet(`/savedata/session/delete?${params}`); - - if (response.ok) { - if (loggedInUser) { - loggedInUser.lastSessionSlot = -1; - } - - localStorage.removeItem(`sessionData${slotId > 0 ? slotId : ""}_${loggedInUser?.username}`); - } else { - return await response.text(); - } - } catch (err) { - console.warn("Could not get session savedata!", err); - return "Unknown error"; - } - } - - /** - * Clears the session savedata of the given slot. - * @param slotId The slot ID - * @param trainerId The trainer ID - * @param sessionId The session ID - * @param sessionData The {@linkcode SessionSaveData} object - */ - public async clearSessionSavedata( - slotId: number, - trainerId: number, - sessionId: string, - sessionData: SessionSaveData - ) { - try { - const params = new URLSearchParams(); - params.append("slot", String(slotId)); - params.append("trainerId", String(trainerId)); - params.append("clientSessionId", sessionId); - - const response = await this.doPost(`/savedata/session/clear?${params}`, sessionData); - - if (response.ok) { - if (loggedInUser) { - loggedInUser!.lastSessionSlot = -1; - } - localStorage.removeItem(`sessionData${slotId > 0 ? slotId : ""}_${loggedInUser?.username}`); - } - - return (await response.json()) as PokerogueApiClearSessionData; - } catch (err) { - console.warn("Could not clear session savedata!", err); - } - - return null; - } - - /** - * Update all savedata - * @param bodyData The {@linkcode UpdateAllSavedataRequest | request data} to send - * @returns An error message if something went wrong - */ - public async updateAllSavedata(bodyData: UpdateAllSavedataRequest) { - try { - const rawBodyData = JSON.stringify(bodyData, (_k: any, v: any) => - typeof v === "bigint" ? (v <= MAX_INT_ATTR_VALUE ? Number(v) : v.toString()) : v - ); - const response = await this.doPost("/savedata/updateall", rawBodyData); - return await response.text(); - } catch (err) { - console.warn("Could not update all savedata!", err); - return null; - } - } - - /** - * Get the daily rankings for a {@linkcode ScoreboardCategory}. - * @param category The {@linkcode ScoreboardCategory} to fetch. - * @param page The page number to fetch. - */ - public async getDailyRankings(category: ScoreboardCategory, page?: number) { - try { - const params = new URLSearchParams(); - params.append("category", String(category)); - - if (page) { - params.append("page", String(page)); - } - - const response = await this.doGet(`/daily/rankings?${params}`); - - return (await response.json()) as RankingEntry[]; - } catch (err) { - console.warn("Could not get daily rankings!", err); - return null; - } - } - - /** - * Get the page count of the daily rankings for a {@linkcode ScoreboardCategory}. - * @param category The {@linkcode ScoreboardCategory} to fetch. - */ - public async getDailyRankingsPageCount(category: ScoreboardCategory) { - try { - const params = new URLSearchParams(); - params.append("category", String(category)); - - const response = await this.doGet(`/daily/rankingpagecount?${params}`); - const json = await response.json(); - - return Number(json); - } catch (err) { - console.warn("Could not get daily rankings page count!", err); - return 1; - } - } - /** * Unlink the currently logged in user from Discord. * @returns `true` if unlinking was successful, `false` if not @@ -430,17 +77,7 @@ export class PokerogueApi extends Api { return false; } - //#region Private - - private async isLocalMode(): Promise { - return ( - ((window.location.hostname === "localhost" || - /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/.test(window.location.hostname)) && - window.location.port !== "") || - window.location.hostname === "" - ); - } //#endregion } -export const pokerogueApi = new PokerogueApi(import.meta.env.VITE_SERVER_URL ?? "http://localhost:80001"); +export const pokerogueApi = new PokerogueApi(import.meta.env.VITE_SERVER_URL ?? "http://localhost:8001"); diff --git a/src/plugins/api/pokerogue-daily-api.ts b/src/plugins/api/pokerogue-daily-api.ts new file mode 100644 index 00000000000..c9319ae7fdc --- /dev/null +++ b/src/plugins/api/pokerogue-daily-api.ts @@ -0,0 +1,57 @@ +import type { GetDailyRankingsPageCountRequest, GetDailyRankingsRequest } from "#app/@types/PokerogueDailyApi"; +import { ApiBase } from "#app/plugins/api/api-base"; +import type { RankingEntry } from "#app/ui/daily-run-scoreboard"; + +/** + * A wrapper for daily-run PokéRogue API requests. + */ +export class PokerogueDailyApi extends ApiBase { + //#region Public + + /** + * Request the daily-run seed. + * @returns The active daily-run seed as `string`. + */ + public async getSeed() { + try { + const response = await this.doGet("/daily/seed"); + return response.text(); + } catch (err) { + console.warn("Could not get daily-run seed!", err); + return null; + } + } + + /** + * Get the daily rankings for a {@linkcode ScoreboardCategory}. + * @param params The {@linkcode GetDailyRankingsRequest} to send + */ + public async getRankings(params: GetDailyRankingsRequest) { + try { + const urlSearchParams = this.toUrlSearchParams(params); + const response = await this.doGet(`/daily/rankings?${urlSearchParams}`); + + return (await response.json()) as RankingEntry[]; + } catch (err) { + console.warn("Could not get daily rankings!", err); + return null; + } + } + + /** + * Get the page count of the daily rankings for a {@linkcode ScoreboardCategory}. + * @param params The {@linkcode GetDailyRankingsPageCountRequest} to send. + */ + public async getRankingsPageCount(params: GetDailyRankingsPageCountRequest) { + try { + const urlSearchParams = this.toUrlSearchParams(params); + const response = await this.doGet(`/daily/rankingpagecount?${urlSearchParams}`); + const json = await response.json(); + + return Number(json); + } catch (err) { + console.warn("Could not get daily rankings page count!", err); + return 1; + } + } +} diff --git a/src/plugins/api/pokerogue-savedata-api.ts b/src/plugins/api/pokerogue-savedata-api.ts new file mode 100644 index 00000000000..7c5e0ca5b4f --- /dev/null +++ b/src/plugins/api/pokerogue-savedata-api.ts @@ -0,0 +1,41 @@ +import type { UpdateAllSavedataRequest } from "#app/@types/PokerogueSavedataApi"; +import { MAX_INT_ATTR_VALUE } from "#app/constants"; +import { ApiBase } from "#app/plugins/api/api-base"; +import { PokerogueSessionSavedataApi } from "#app/plugins/api/pokerogue-session-savedata-api"; +import { PokerogueSystemSavedataApi } from "#app/plugins/api/pokerogue-system-savedata-api"; + +/** + * A wrapper for PokéRogue savedata API requests. + */ +export class PokerogueSavedataApi extends ApiBase { + //#region Fields + + public readonly system: PokerogueSystemSavedataApi; + public readonly session: PokerogueSessionSavedataApi; + + //#region Public + + constructor(base: string) { + super(base); + this.system = new PokerogueSystemSavedataApi(base); + this.session = new PokerogueSessionSavedataApi(base); + } + + /** + * Update all savedata + * @param bodyData The {@linkcode UpdateAllSavedataRequest | request data} to send + * @returns An error message if something went wrong + */ + public async updateAll(bodyData: UpdateAllSavedataRequest) { + try { + const rawBodyData = JSON.stringify(bodyData, (_k: any, v: any) => + typeof v === "bigint" ? (v <= MAX_INT_ATTR_VALUE ? Number(v) : v.toString()) : v + ); + const response = await this.doPost("/savedata/updateall", rawBodyData); + return await response.text(); + } catch (err) { + console.warn("Could not update all savedata!", err); + return null; + } + } +} diff --git a/src/plugins/api/pokerogue-session-savedata-api.ts b/src/plugins/api/pokerogue-session-savedata-api.ts new file mode 100644 index 00000000000..7ac4b06fef0 --- /dev/null +++ b/src/plugins/api/pokerogue-session-savedata-api.ts @@ -0,0 +1,124 @@ +import type { + ClearSessionSavedataRequest, + ClearSessionSavedataResponse, + DeleteSessionSavedataRequest, + GetSessionSavedataRequest, + NewClearSessionSavedataRequest, + UpdateSessionSavedataRequest, +} from "#app/@types/PokerogueSessionSavedataApi"; +import { loggedInUser } from "#app/account"; +import { ApiBase } from "#app/plugins/api/api-base"; +import type { SessionSaveData } from "#app/system/game-data"; + +/** + * A wrapper for PokéRogue session savedata API requests. + */ +export class PokerogueSessionSavedataApi extends ApiBase { + //#region Public + + /** + * Mark a session as cleared aka "newclear".\ + * *This is **NOT** the same as {@linkcode clear | clear()}.* + * @param params The {@linkcode NewClearSessionSavedataRequest} to send + * @returns The raw savedata as `string`. + */ + public async newclear(params: NewClearSessionSavedataRequest) { + try { + const urlSearchParams = this.toUrlSearchParams(params); + const response = await this.doGet(`/savedata/session/newclear?${urlSearchParams}`); + const json = await response.json(); + + return Boolean(json); + } catch (err) { + console.warn("Could not newclear session!", err); + return false; + } + } + + /** + * Get a session savedata. + * @param params The {@linkcode GetSessionSavedataRequest} to send + * @returns The session as `string` + */ + public async get(params: GetSessionSavedataRequest) { + try { + const urlSearchParams = this.toUrlSearchParams(params); + const response = await this.doGet(`/savedata/session/get?${urlSearchParams}`); + + return await response.text(); + } catch (err) { + console.warn("Could not get session savedata!", err); + return null; + } + } + + /** + * Update a session savedata. + * @param params The {@linkcode UpdateSessionSavedataRequest} to send + * @param rawSavedata The raw savedata (as `string`) + * @returns An error message if something went wrong + */ + public async update(params: UpdateSessionSavedataRequest, rawSavedata: string) { + try { + const urlSearchParams = this.toUrlSearchParams(params); + const response = await this.doPost(`/savedata/session/update?${urlSearchParams}`, rawSavedata); + + return await response.text(); + } catch (err) { + console.warn("Could not update session savedata!", err); + } + + return null; + } + + /** + * Delete a session savedata slot. + * @param params The {@linkcode DeleteSessionSavedataRequest} to send + * @returns The session as `string` + */ + public async delete(params: DeleteSessionSavedataRequest) { + try { + const urlSearchParams = this.toUrlSearchParams(params); + const response = await this.doGet(`/savedata/session/delete?${urlSearchParams}`); + + if (response.ok) { + if (loggedInUser) { + loggedInUser.lastSessionSlot = -1; + } + + localStorage.removeItem(`sessionData${params.slot > 0 ? params.slot : ""}_${loggedInUser?.username}`); + } else { + return await response.text(); + } + } catch (err) { + console.warn("Could not get session savedata!", err); + return "Unknown error"; + } + } + + /** + * Clears the session savedata of the given slot.\ + * *This is **NOT** the same as {@linkcode newclear | newclear()}.* + * @param params The {@linkcode ClearSessionSavedataRequest} to send + * @param sessionData The {@linkcode SessionSaveData} object + */ + public async clear(params: ClearSessionSavedataRequest, sessionData: SessionSaveData) { + try { + const urlSearchParams = this.toUrlSearchParams(params); + const response = await this.doPost(`/savedata/session/clear?${urlSearchParams}`, sessionData); + + if (response.ok) { + if (loggedInUser) { + loggedInUser!.lastSessionSlot = -1; + } + localStorage.removeItem(`sessionData${params.slot > 0 ? params.slot : ""}_${loggedInUser?.username}`); + } + + return (await response.json()) as ClearSessionSavedataResponse; + } catch (err) { + console.warn("Could not clear session savedata!", err); + } + + return null; + } +} diff --git a/src/plugins/api/pokerogue-system-savedata-api.ts b/src/plugins/api/pokerogue-system-savedata-api.ts new file mode 100644 index 00000000000..ef319bfa072 --- /dev/null +++ b/src/plugins/api/pokerogue-system-savedata-api.ts @@ -0,0 +1,78 @@ +import type { + GetSystemSavedataRequest, + UpdateSystemSavedataRequest, + VerifySystemSavedataRequest, + VerifySystemSavedataResponse, +} from "#app/@types/PokerogueSystemSavedataApi"; +import { ApiBase } from "#app/plugins/api/api-base"; + +/** + * A wrapper for PokéRogue system savedata API requests. + */ +export class PokerogueSystemSavedataApi extends ApiBase { + //#region Public + + /** + * Get a system savedata. + * @param params The {@linkcode GetSystemSavedataRequest} to send + * @returns The system savedata as `string` or `null` on error + */ + public async get(params: GetSystemSavedataRequest) { + try { + const urlSearchParams = this.toUrlSearchParams(params); + const response = await this.doGet(`/savedata/system/get?${urlSearchParams}`); + const rawSavedata = await response.text(); + + return rawSavedata; + } catch (err) { + console.warn("Could not get system savedata!", err); + return null; + } + } + + /** + * Verify if the session is valid. + * If not the {@linkcode SystemSaveData} is returned. + * @param params The {@linkcode VerifySystemSavedataRequest} to send + * @returns A {@linkcode SystemSaveData} if **NOT** valid, otherwise `null`. + */ + public async verify(params: VerifySystemSavedataRequest) { + try { + const urlSearchParams = this.toUrlSearchParams(params); + const response = await this.doGet(`/savedata/system/verify?${urlSearchParams}`); + + if (response.ok) { + const verifySavedata = (await response.json()) as VerifySystemSavedataResponse; + + if (!verifySavedata.valid) { + return verifySavedata.systemData; + } else { + console.warn("Invalid system savedata!"); + } + } + } catch (err) { + console.warn("Could not verify system savedata!", err); + } + + return null; + } + + /** + * Update a system savedata. + * @param params The {@linkcode UpdateSystemSavedataRequest} to send + * @param rawSystemData The raw {@linkcode SystemSaveData} + * @returns An error message if something went wrong + */ + public async update(params: UpdateSystemSavedataRequest, rawSystemData: string) { + try { + const urSearchParams = this.toUrlSearchParams(params); + const response = await this.doPost(`/savedata/system/update?${urSearchParams}`, rawSystemData); + + return await response.text(); + } catch (err) { + console.warn("Could not update system savedata!", err); + } + + return null; + } +} diff --git a/src/system/game-data.ts b/src/system/game-data.ts index 5c20eaddd5b..9ccff14fdb0 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -397,7 +397,7 @@ export class GameData { localStorage.setItem(`data_${loggedInUser?.username}`, encrypt(systemData, bypassLogin)); if (!bypassLogin) { - pokerogueApi.updateSystemSavedata({clientSessionId}, systemData) + pokerogueApi.savedata.system.update({clientSessionId}, systemData) .then(error => { this.scene.ui.savingIcon.hide(); if (error) { @@ -430,7 +430,7 @@ export class GameData { } if (!bypassLogin) { - pokerogueApi.getSystemSavedata(clientSessionId) + pokerogueApi.savedata.system.get({ clientSessionId }) .then(saveDataOrErr => { if (!saveDataOrErr || saveDataOrErr.length === 0 || saveDataOrErr[0] !== "{") { if (saveDataOrErr?.startsWith("sql: no rows in result set")) { @@ -581,6 +581,7 @@ export class GameData { if (!Utils.isLocal) { /** * Networking Code DO NOT DELETE! + * Note: Might have to be migrated to `pokerogue-api.ts` * const response = await Utils.apiFetch("savedata/runHistory", true); const data = await response.json(); @@ -661,6 +662,7 @@ export class GameData { return false; } } + NOTE: should be adopted to `pokerogue-api.ts` */ return true; } @@ -705,7 +707,7 @@ export class GameData { return true; } - const systemData = pokerogueApi.verifySystemSavedata(clientSessionId); + const systemData = pokerogueApi.savedata.system.verify({clientSessionId}); if (systemData) { this.scene.clearPhaseQueue(); @@ -984,7 +986,7 @@ export class GameData { }; if (!bypassLogin && !localStorage.getItem(`sessionData${slotId ? slotId : ""}_${loggedInUser?.username}`)) { - pokerogueApi.getSessionSavedata(slotId, clientSessionId) + pokerogueApi.savedata.session.get({slot: slotId, clientSessionId}) .then(async response => { if (!response && response?.length === 0 || response?.[0] !== "{") { console.error(response); @@ -1132,7 +1134,7 @@ export class GameData { if (success !== null && !success) { return resolve(false); } - pokerogueApi.deleteSessionSavedata(slotId, clientSessionId).then(error => { + pokerogueApi.savedata.session.delete({ slot: slotId, clientSessionId }).then(error => { if (error) { if (error.startsWith("session out of date")) { this.scene.clearPhaseQueue(); @@ -1189,7 +1191,8 @@ export class GameData { result = [true, true]; } else { const sessionData = this.getSessionSaveData(scene); - const jsonResponse = await pokerogueApi.clearSessionSavedata(slotId, this.trainerId, clientSessionId, sessionData); + const { trainerId } = this; + const jsonResponse = await pokerogueApi.savedata.session.clear({ slot: slotId, trainerId, clientSessionId}, sessionData); if (!jsonResponse?.error) { result = [true, jsonResponse?.success ?? false]; @@ -1309,7 +1312,7 @@ export class GameData { console.debug("Session data saved"); if (!bypassLogin && sync) { - pokerogueApi.updateAllSavedata(request) + pokerogueApi.savedata.updateAll(request) .then(error => { if (sync) { this.scene.lastSavePlayTime = 0; @@ -1359,9 +1362,9 @@ export class GameData { let promise: Promise = Promise.resolve(null); if (dataType === GameDataType.SYSTEM) { - promise = pokerogueApi.getSystemSavedata(clientSessionId); + promise = pokerogueApi.savedata.system.get({ clientSessionId }); } else if (dataType === GameDataType.SESSION) { - promise = pokerogueApi.getSessionSavedata(slotId, clientSessionId); + promise = pokerogueApi.savedata.session.get({ slot: slotId, clientSessionId }); } promise @@ -1457,9 +1460,9 @@ export class GameData { const { trainerId, secretId } = this; let updatePromise: Promise; if (dataType === GameDataType.SESSION) { - updatePromise = pokerogueApi.updateSessionSavedata({slot: slotId, trainerId, secretId, clientSessionId}, dataStr); + updatePromise = pokerogueApi.savedata.session.update({slot: slotId, trainerId, secretId, clientSessionId}, dataStr); } else { - updatePromise = pokerogueApi.updateSystemSavedata({trainerId, secretId, clientSessionId}, dataStr); + updatePromise = pokerogueApi.savedata.system.update({trainerId, secretId, clientSessionId}, dataStr); } updatePromise .then(error => { diff --git a/src/test/account.test.ts b/src/test/account.test.ts index eb6002f3cf2..c7a6ce81f54 100644 --- a/src/test/account.test.ts +++ b/src/test/account.test.ts @@ -1,7 +1,7 @@ import * as battleScene from "#app/battle-scene"; +import { pokerogueApi } from "#app/plugins/api/pokerogue-api"; import { describe, expect, it, vi } from "vitest"; import { initLoggedInUser, loggedInUser, updateUserInfo } from "../account"; -import * as utils from "../utils"; describe("account", () => { describe("initLoggedInUser", () => { @@ -27,17 +27,16 @@ describe("account", () => { it("should fetch user info from the API if bypassLogin is false", async () => { vi.spyOn(battleScene, "bypassLogin", "get").mockReturnValue(false); - vi.spyOn(utils, "apiFetch").mockResolvedValue( - new Response( - JSON.stringify({ - username: "test", - lastSessionSlot: 99, - }), - { - status: 200, - } - ) - ); + vi.spyOn(pokerogueApi.account, "getInfo").mockResolvedValue([ + { + username: "test", + lastSessionSlot: 99, + discordId: "", + googleId: "", + hasAdminRole: false, + }, + 200, + ]); const [success, status] = await updateUserInfo(); @@ -49,9 +48,7 @@ describe("account", () => { it("should handle resolved API errors", async () => { vi.spyOn(battleScene, "bypassLogin", "get").mockReturnValue(false); - vi.spyOn(utils, "apiFetch").mockResolvedValue( - new Response(null, { status: 401 }) - ); + vi.spyOn(pokerogueApi.account, "getInfo").mockResolvedValue([null, 401]); const [success, status] = await updateUserInfo(); @@ -59,16 +56,14 @@ describe("account", () => { expect(status).toBe(401); }); - it("should handle rejected API errors", async () => { - const consoleErrorSpy = vi.spyOn(console, "error"); + it("should handle 500 API errors", async () => { vi.spyOn(battleScene, "bypassLogin", "get").mockReturnValue(false); - vi.spyOn(utils, "apiFetch").mockRejectedValue(new Error("Api failed!")); + vi.spyOn(pokerogueApi.account, "getInfo").mockResolvedValue([null, 500]); const [success, status] = await updateUserInfo(); expect(success).toBe(false); expect(status).toBe(500); - expect(consoleErrorSpy).toHaveBeenCalled(); }); }); }); diff --git a/src/test/daily_mode.test.ts b/src/test/daily_mode.test.ts index 58692330272..a98bf835733 100644 --- a/src/test/daily_mode.test.ts +++ b/src/test/daily_mode.test.ts @@ -1,10 +1,11 @@ -import { MapModifier } from "#app/modifier/modifier"; -import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; -import GameManager from "./utils/gameManager"; -import { Moves } from "#app/enums/moves"; import { Biome } from "#app/enums/biome"; -import { Mode } from "#app/ui/ui"; +import { Moves } from "#app/enums/moves"; +import { MapModifier } from "#app/modifier/modifier"; +import { pokerogueApi } from "#app/plugins/api/pokerogue-api"; import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler"; +import { Mode } from "#app/ui/ui"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import GameManager from "./utils/gameManager"; //const TIMEOUT = 20 * 1000; @@ -20,6 +21,7 @@ describe("Daily Mode", () => { beforeEach(() => { game = new GameManager(phaserGame); + vi.spyOn(pokerogueApi.daily, "getSeed").mockResolvedValue("test-seed"); }); afterEach(() => { @@ -31,7 +33,7 @@ describe("Daily Mode", () => { const party = game.scene.getParty(); expect(party).toHaveLength(3); - party.forEach(pkm => { + party.forEach((pkm) => { expect(pkm.level).toBe(20); expect(pkm.moveset.length).toBeGreaterThan(0); }); @@ -63,6 +65,7 @@ describe("Shop modifications", async () => { game.modifiers .addCheck("EVIOLITE") .addCheck("MINI_BLACK_HOLE"); + vi.spyOn(pokerogueApi.daily, "getSeed").mockResolvedValue("test-seed"); }); afterEach(() => { diff --git a/src/test/reload.test.ts b/src/test/reload.test.ts index daf8e43a0cd..d4a7166a323 100644 --- a/src/test/reload.test.ts +++ b/src/test/reload.test.ts @@ -1,4 +1,5 @@ import { GameModes } from "#app/game-mode"; +import { pokerogueApi } from "#app/plugins/api/pokerogue-api"; import OptionSelectUiHandler from "#app/ui/settings/option-select-ui-handler"; import { Mode } from "#app/ui/ui"; import { Biome } from "#enums/biome"; @@ -7,7 +8,7 @@ import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import GameManager from "#test/utils/gameManager"; import { MockClock } from "#test/utils/mocks/mockClock"; -import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; describe("Reload", () => { let phaserGame: Phaser.Game; @@ -25,6 +26,8 @@ describe("Reload", () => { beforeEach(() => { game = new GameManager(phaserGame); + vi.spyOn(pokerogueApi, "getGameTitleStats").mockResolvedValue({ battleCount: -1, playerCount: -1 }); + vi.spyOn(pokerogueApi.daily, "getSeed").mockResolvedValue("test-seed"); }); it("should not have RNG inconsistencies in a Classic run", async () => { @@ -114,8 +117,7 @@ describe("Reload", () => { }, 20000); it("should not have RNG inconsistencies at a Daily run double battle", async () => { - game.override - .battleType("double"); + game.override.battleType("double"); await game.dailyMode.startBattle(); const preReloadRngState = Phaser.Math.RND.state(); @@ -128,9 +130,7 @@ describe("Reload", () => { }, 20000); it("should not have RNG inconsistencies at a Daily run Gym Leader fight", async () => { - game.override - .battleType("single") - .startingWave(40); + game.override.battleType("single").startingWave(40); await game.dailyMode.startBattle(); const preReloadRngState = Phaser.Math.RND.state(); @@ -143,9 +143,7 @@ describe("Reload", () => { }, 20000); it("should not have RNG inconsistencies at a Daily run regular trainer fight", async () => { - game.override - .battleType("single") - .startingWave(45); + game.override.battleType("single").startingWave(45); await game.dailyMode.startBattle(); const preReloadRngState = Phaser.Math.RND.state(); @@ -158,9 +156,7 @@ describe("Reload", () => { }, 20000); it("should not have RNG inconsistencies at a Daily run wave 50 Boss fight", async () => { - game.override - .battleType("single") - .startingWave(50); + game.override.battleType("single").startingWave(50); await game.runToFinalBossEncounter([Species.BULBASAUR], GameModes.DAILY); const preReloadRngState = Phaser.Math.RND.state(); diff --git a/src/test/utils/gameWrapper.ts b/src/test/utils/gameWrapper.ts index 0ef5c4d4611..4ee1f29fa4f 100644 --- a/src/test/utils/gameWrapper.ts +++ b/src/test/utils/gameWrapper.ts @@ -77,7 +77,7 @@ export default class GameWrapper { constructor(phaserGame: Phaser.Game, bypassLogin: boolean) { Phaser.Math.RND.sow([ 'test' ]); - vi.spyOn(Utils, "apiFetch", "get").mockReturnValue(fetch); + // vi.spyOn(Utils, "apiFetch", "get").mockReturnValue(fetch); if (bypassLogin) { vi.spyOn(battleScene, "bypassLogin", "get").mockReturnValue(true); } diff --git a/src/ui/admin-ui-handler.ts b/src/ui/admin-ui-handler.ts index 4e69cb6e76b..b25a1d6e33f 100644 --- a/src/ui/admin-ui-handler.ts +++ b/src/ui/admin-ui-handler.ts @@ -62,7 +62,7 @@ export default class AdminUiHandler extends FormModalUiHandler { return onFail("Discord Id is required"); } const [ usernameInput, discordIdInput ] = this.inputs; - pokerogueApi.admin.linkAccountToDiscordId({ username: usernameInput.text, discordId: discordIdInput.text }) + pokerogueApi.admin.linkAccountToDiscord({ username: usernameInput.text, discordId: discordIdInput.text }) .then(isSuccess => { if (isSuccess) { usernameInput.setText(""); diff --git a/src/ui/daily-run-scoreboard.ts b/src/ui/daily-run-scoreboard.ts index 529655de420..35a26110faa 100644 --- a/src/ui/daily-run-scoreboard.ts +++ b/src/ui/daily-run-scoreboard.ts @@ -192,9 +192,9 @@ export class DailyRunScoreboard extends Phaser.GameObjects.Container { } Utils.executeIf(category !== this.category || this.pageCount === undefined, - () => pokerogueApi.getDailyRankingsPageCount(category).then(count => this.pageCount = count) + () => pokerogueApi.daily.getRankingsPageCount(category).then(count => this.pageCount = count) ).then(() => { - pokerogueApi.getDailyRankings(category, page) + pokerogueApi.daily.getRankings(category, page) .then(rankings => { this.page = page; this.category = category; diff --git a/src/ui/login-form-ui-handler.ts b/src/ui/login-form-ui-handler.ts index f63dde2051f..8b00d58c235 100644 --- a/src/ui/login-form-ui-handler.ts +++ b/src/ui/login-form-ui-handler.ts @@ -136,7 +136,7 @@ export default class LoginFormUiHandler extends FormModalUiHandler { const [usernameInput, passwordInput] = this.inputs; - pokerogueApi.login({ username: usernameInput.text, password: passwordInput.text }).then(error => { + pokerogueApi.account.login({ username: usernameInput.text, password: passwordInput.text }).then(error => { if (!error) { originalLoginAction && originalLoginAction(); } else { diff --git a/src/ui/menu-ui-handler.ts b/src/ui/menu-ui-handler.ts index ee0f702b5d7..69a50decee5 100644 --- a/src/ui/menu-ui-handler.ts +++ b/src/ui/menu-ui-handler.ts @@ -581,7 +581,7 @@ export default class MenuUiHandler extends MessageUiHandler { success = true; const doLogout = () => { ui.setMode(Mode.LOADING, { - buttonActions: [], fadeOut: () => pokerogueApi.logout().then(() => { + buttonActions: [], fadeOut: () => pokerogueApi.account.logout().then(() => { updateUserInfo().then(() => this.scene.reset(true, true)); }) }); diff --git a/src/ui/registration-form-ui-handler.ts b/src/ui/registration-form-ui-handler.ts index f45b71b50ba..ecc6ba093f7 100644 --- a/src/ui/registration-form-ui-handler.ts +++ b/src/ui/registration-form-ui-handler.ts @@ -107,10 +107,10 @@ export default class RegistrationFormUiHandler extends FormModalUiHandler { return onFail(i18next.t("menu:passwordNotMatchingConfirmPassword")); } const [usernameInput, passwordInput] = this.inputs; - pokerogueApi.register({ username: usernameInput.text, password: passwordInput.text }) + pokerogueApi.account.register({ username: usernameInput.text, password: passwordInput.text }) .then(registerError => { if (!registerError) { - pokerogueApi.login({ username: usernameInput.text, password: passwordInput.text }) + pokerogueApi.account.login({ username: usernameInput.text, password: passwordInput.text }) .then(loginError => { if (!loginError) { originalRegistrationAction && originalRegistrationAction();