mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-20 22:39:31 +02:00
add tests on import / export settings
This commit is contained in:
parent
6a0605c781
commit
9312545deb
@ -1353,6 +1353,26 @@ export class GameData {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getDataToExport(dataType: GameDataType, slotId: integer = 0): Promise<string | null> {
|
||||||
|
return new Promise<string | null>(resolve => {
|
||||||
|
if (!bypassLogin && dataType < GameDataType.SETTINGS) {
|
||||||
|
Utils.apiFetch(`savedata/${dataType === GameDataType.SYSTEM ? "system" : "session"}/get?clientSessionId=${clientSessionId}${dataType === GameDataType.SESSION ? `&slot=${slotId}` : ""}`, true)
|
||||||
|
.then(response => response.text())
|
||||||
|
.then(response => {
|
||||||
|
if (!response.length || response[0] !== "{") {
|
||||||
|
console.error(response);
|
||||||
|
resolve(null);
|
||||||
|
}
|
||||||
|
resolve(response);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const dataKey: string = getDataTypeKey(dataType, slotId, loggedInUser?.username);
|
||||||
|
const data = localStorage.getItem(dataKey);
|
||||||
|
resolve((!data || dataType === GameDataType.SETTINGS) ? data : decrypt(data, bypassLogin));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public tryExportData(dataType: GameDataType, slotId: integer = 0): Promise<boolean> {
|
public tryExportData(dataType: GameDataType, slotId: integer = 0): Promise<boolean> {
|
||||||
return new Promise<boolean>(resolve => {
|
return new Promise<boolean>(resolve => {
|
||||||
const dataKey: string = getDataTypeKey(dataType, slotId, loggedInUser?.username);
|
const dataKey: string = getDataTypeKey(dataType, slotId, loggedInUser?.username);
|
||||||
@ -1370,33 +1390,56 @@ export class GameData {
|
|||||||
link.click();
|
link.click();
|
||||||
link.remove();
|
link.remove();
|
||||||
};
|
};
|
||||||
if (!bypassLogin && dataType < GameDataType.SETTINGS) {
|
this.getDataToExport(dataType, slotId)
|
||||||
Utils.apiFetch(`savedata/${dataType === GameDataType.SYSTEM ? "system" : "session"}/get?clientSessionId=${clientSessionId}${dataType === GameDataType.SESSION ? `&slot=${slotId}` : ""}`, true)
|
.then(data => {
|
||||||
.then(response => response.text())
|
if (data) {
|
||||||
.then(response => {
|
handleData(data);
|
||||||
if (!response.length || response[0] !== "{") {
|
}
|
||||||
console.error(response);
|
resolve(!!data);
|
||||||
resolve(false);
|
});
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
handleData(response);
|
|
||||||
resolve(true);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
const data = localStorage.getItem(dataKey);
|
|
||||||
if (data) {
|
|
||||||
const decryptedData = (dataType === GameDataType.SETTINGS) ? data : decrypt(data, bypassLogin);
|
|
||||||
handleData(decryptedData);
|
|
||||||
}
|
|
||||||
resolve(!!data);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public importData(dataType: GameDataType, slotId: integer = 0): void {
|
public validateDataToImport(dataStr: string, dataType: GameDataType): boolean {
|
||||||
const dataKey = getDataTypeKey(dataType, slotId, loggedInUser?.username);
|
try {
|
||||||
|
switch (dataType) {
|
||||||
|
case GameDataType.SYSTEM:
|
||||||
|
dataStr = this.convertSystemDataStr(dataStr);
|
||||||
|
const systemData = this.parseSystemData(dataStr);
|
||||||
|
return !!systemData.dexData && !!systemData.timestamp;
|
||||||
|
case GameDataType.SESSION:
|
||||||
|
const sessionData = this.parseSessionData(dataStr);
|
||||||
|
return !!sessionData.party && !!sessionData.enemyParty && !!sessionData.timestamp;
|
||||||
|
case GameDataType.RUN_HISTORY:
|
||||||
|
const data = JSON.parse(dataStr);
|
||||||
|
const keys = Object.keys(data);
|
||||||
|
return keys.every((key) => {
|
||||||
|
const entryKeys = Object.keys(data[key]);
|
||||||
|
return [ "isFavorite", "isVictory", "entry" ].every(v => entryKeys.includes(v)) && entryKeys.length === 3;
|
||||||
|
});
|
||||||
|
case GameDataType.SETTINGS:
|
||||||
|
return Object.entries(JSON.parse(dataStr))
|
||||||
|
.every(([ k, v ]: [string, number]) => {
|
||||||
|
const index: number = settingIndex(k);
|
||||||
|
return index === -1 || Setting[index].options.length > v;
|
||||||
|
});
|
||||||
|
case GameDataType.TUTORIALS:
|
||||||
|
case GameDataType.SEEN_DIALOGUES:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (ex) {
|
||||||
|
console.error(ex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public setImportedData(dataStr: string, dataType: GameDataType, slotId: integer = 0) {
|
||||||
|
const dataKey = getDataTypeKey(dataType, slotId, loggedInUser?.username);
|
||||||
|
const encryptedData = (dataType === GameDataType.SETTINGS) ? dataStr : encrypt(dataStr, bypassLogin);
|
||||||
|
localStorage.setItem(dataKey, encryptedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public importData(dataType: GameDataType, slotId: integer = 0): void {
|
||||||
let saveFile: any = document.getElementById("saveFile");
|
let saveFile: any = document.getElementById("saveFile");
|
||||||
if (saveFile) {
|
if (saveFile) {
|
||||||
saveFile.remove();
|
saveFile.remove();
|
||||||
@ -1413,47 +1456,13 @@ export class GameData {
|
|||||||
|
|
||||||
reader.onload = (_ => {
|
reader.onload = (_ => {
|
||||||
return e => {
|
return e => {
|
||||||
let dataName: string;
|
const dataName = (dataType === GameDataType.RUN_HISTORY)
|
||||||
let dataStr = AES.decrypt(e.target?.result?.toString()!, saveKey).toString(enc.Utf8); // TODO: is this bang correct?
|
? i18next.t("menuUiHandler:RUN_HISTORY").toLowerCase()
|
||||||
let valid = false;
|
: GameDataType[dataType].toLowerCase();
|
||||||
try {
|
const dataStr = AES.decrypt(e.target?.result?.toString()!, saveKey).toString(enc.Utf8); // TODO: is this bang correct?
|
||||||
dataName = GameDataType[dataType].toLowerCase();
|
const valid = this.validateDataToImport(dataStr, dataType);
|
||||||
switch (dataType) {
|
|
||||||
case GameDataType.SYSTEM:
|
|
||||||
dataStr = this.convertSystemDataStr(dataStr);
|
|
||||||
const systemData = this.parseSystemData(dataStr);
|
|
||||||
valid = !!systemData.dexData && !!systemData.timestamp;
|
|
||||||
break;
|
|
||||||
case GameDataType.SESSION:
|
|
||||||
const sessionData = this.parseSessionData(dataStr);
|
|
||||||
valid = !!sessionData.party && !!sessionData.enemyParty && !!sessionData.timestamp;
|
|
||||||
break;
|
|
||||||
case GameDataType.RUN_HISTORY:
|
|
||||||
const data = JSON.parse(dataStr);
|
|
||||||
const keys = Object.keys(data);
|
|
||||||
dataName = i18next.t("menuUiHandler:RUN_HISTORY").toLowerCase();
|
|
||||||
keys.forEach((key) => {
|
|
||||||
const entryKeys = Object.keys(data[key]);
|
|
||||||
valid = [ "isFavorite", "isVictory", "entry" ].every(v => entryKeys.includes(v)) && entryKeys.length === 3;
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case GameDataType.SETTINGS:
|
|
||||||
valid = Object.entries(JSON.parse(dataStr))
|
|
||||||
.every(([ k, v ]: [string, number]) => {
|
|
||||||
const index: number = settingIndex(k);
|
|
||||||
return index === -1 || Setting[index].options.length > v;
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case GameDataType.TUTORIALS:
|
|
||||||
valid = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} catch (ex) {
|
|
||||||
console.error(ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
const displayError = (error: string) => this.scene.ui.showText(error, null, () => this.scene.ui.showText("", 0), Utils.fixedInt(1500));
|
const displayError = (error: string) => this.scene.ui.showText(error, null, () => this.scene.ui.showText("", 0), Utils.fixedInt(1500));
|
||||||
dataName = dataName!; // tell TS compiler that dataName is defined!
|
|
||||||
|
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
return this.scene.ui.showText(`Your ${dataName} data could not be loaded. It may be corrupted.`, null, () => this.scene.ui.showText("", 0), Utils.fixedInt(1500));
|
return this.scene.ui.showText(`Your ${dataName} data could not be loaded. It may be corrupted.`, null, () => this.scene.ui.showText("", 0), Utils.fixedInt(1500));
|
||||||
@ -1461,8 +1470,7 @@ export class GameData {
|
|||||||
|
|
||||||
this.scene.ui.showText(`Your ${dataName} data will be overridden and the page will reload. Proceed?`, null, () => {
|
this.scene.ui.showText(`Your ${dataName} data will be overridden and the page will reload. Proceed?`, null, () => {
|
||||||
this.scene.ui.setOverlayMode(Mode.CONFIRM, () => {
|
this.scene.ui.setOverlayMode(Mode.CONFIRM, () => {
|
||||||
const encryptedData = (dataType === GameDataType.SETTINGS) ? dataStr : encrypt(dataStr, bypassLogin);
|
this.setImportedData(dataStr, dataType, slotId);
|
||||||
localStorage.setItem(dataKey, encryptedData);
|
|
||||||
|
|
||||||
if (!bypassLogin && dataType < GameDataType.SETTINGS) {
|
if (!bypassLogin && dataType < GameDataType.SETTINGS) {
|
||||||
updateUserInfo().then(success => {
|
updateUserInfo().then(success => {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import * as BattleScene from "#app/battle-scene";
|
import * as BattleScene from "#app/battle-scene";
|
||||||
import { SessionSaveData } from "#app/system/game-data";
|
import { SessionSaveData } from "#app/system/game-data";
|
||||||
import { Abilities } from "#enums/abilities";
|
import { Abilities } from "#enums/abilities";
|
||||||
|
import { GameDataType } from "#enums/game-data-type";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import GameManager from "#test/utils/gameManager";
|
import GameManager from "#test/utils/gameManager";
|
||||||
import { http, HttpResponse } from "msw";
|
import { http, HttpResponse } from "msw";
|
||||||
@ -86,4 +87,63 @@ describe("System - Game Data", () => {
|
|||||||
expect(account.updateUserInfo).toHaveBeenCalled();
|
expect(account.updateUserInfo).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("getDataToExport", () => {
|
||||||
|
it("should get default settings", async () => {
|
||||||
|
const defaultSettings = "{\"PLAYER_GENDER\":0,\"gameVersion\":\"1.0.4\"}";
|
||||||
|
localStorage.setItem("settings", defaultSettings);
|
||||||
|
|
||||||
|
const result = await game.scene.gameData.getDataToExport(GameDataType.SETTINGS);
|
||||||
|
|
||||||
|
expect(result).toEqual(defaultSettings);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should get undefined when there is no settings", async () => {
|
||||||
|
const result = await game.scene.gameData.getDataToExport(GameDataType.SETTINGS);
|
||||||
|
|
||||||
|
expect(result).toBeUndefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("setImportedData", () => {
|
||||||
|
it("should set settings in local storage", () => {
|
||||||
|
const settings = "{\"PLAYER_GENDER\":0,\"gameVersion\":\"1.0.4\"}";
|
||||||
|
game.scene.gameData.setImportedData(settings, GameDataType.SETTINGS);
|
||||||
|
|
||||||
|
expect(localStorage.getItem("settings")).toEqual(settings);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should override default settings", () => {
|
||||||
|
const defaultSettings = "{\"PLAYER_GENDER\":0,\"gameVersion\":\"1.0.4\"}";
|
||||||
|
localStorage.setItem("settings", defaultSettings);
|
||||||
|
|
||||||
|
const newSettings = "{\"PLAYER_GENDER\":1,\"gameVersion\":\"1.0.7\",\"GAME_SPEED\":7}";
|
||||||
|
game.scene.gameData.setImportedData(newSettings, GameDataType.SETTINGS);
|
||||||
|
|
||||||
|
expect(localStorage.getItem("settings")).toEqual(newSettings);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("validateDataToImport", () => {
|
||||||
|
it("should be true when the setting data is valid", async () => {
|
||||||
|
const settings = "{\"PLAYER_GENDER\":0,\"gameVersion\":\"1.0.4\"}";
|
||||||
|
const result = await game.scene.gameData.validateDataToImport(settings, GameDataType.SETTINGS);
|
||||||
|
|
||||||
|
expect(result).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should be false when the setting data is an invalid JSON", async () => {
|
||||||
|
const settings = "";
|
||||||
|
const result = await game.scene.gameData.validateDataToImport(settings, GameDataType.SETTINGS);
|
||||||
|
|
||||||
|
expect(result).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should be false when the setting data contains an unknow value", async () => {
|
||||||
|
const settings = "{\"PLAYER_GENDER\":0,\"gameVersion\":\"1.0.4\",\"GAME_SPEED\":999}";
|
||||||
|
const result = await game.scene.gameData.validateDataToImport(settings, GameDataType.SETTINGS);
|
||||||
|
|
||||||
|
expect(result).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user