mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-07-01 11:03:54 -07:00
migrate from CRA to vite
This commit is contained in:
parent
98ce317ee1
commit
68e22d22bf
56 changed files with 5699 additions and 28288 deletions
2
.github/workflows/web-build.yml
vendored
2
.github/workflows/web-build.yml
vendored
|
|
@ -30,7 +30,7 @@ jobs:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
node_version:
|
node_version:
|
||||||
- 16
|
- 20
|
||||||
- lts/*
|
- lts/*
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
ESLINT_NO_DEV_ERRORS=true
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
DISABLE_ESLINT_PLUGIN=true
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
CI=true
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
"root": true,
|
"root": true,
|
||||||
"parser": "@typescript-eslint/parser",
|
"parser": "@typescript-eslint/parser",
|
||||||
"parserOptions": {"project": ["./tsconfig.json"]},
|
"parserOptions": {"ecmaVersion": 2020, "sourceType": "module", "ecmaFeatures": {"jsx": true}},
|
||||||
"plugins": [
|
"plugins": [
|
||||||
"@typescript-eslint"
|
"@typescript-eslint"
|
||||||
],
|
],
|
||||||
|
|
|
||||||
22
webclient/index.html
Normal file
22
webclient/index.html
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<link rel="icon" href="/favicon.ico" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="/reset.css">
|
||||||
|
<meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no" />
|
||||||
|
<meta name="theme-color" content="#000000" />
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
content="Webatrice: A Cockatrice Web Client"
|
||||||
|
/>
|
||||||
|
<link rel="apple-touch-icon" href="logo192.png" />
|
||||||
|
<link rel="manifest" href="/manifest.json" />
|
||||||
|
<title>Webatrice</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/src/index.tsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
31974
webclient/package-lock.json
generated
31974
webclient/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -5,13 +5,13 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prebuild": "node prebuild.js",
|
"prebuild": "node prebuild.js",
|
||||||
"prestart": "node prebuild.js",
|
"prestart": "node prebuild.js",
|
||||||
"build": "react-scripts build",
|
"build": "vite build",
|
||||||
"start": "react-scripts start",
|
"start": "vite",
|
||||||
"test": "react-scripts test",
|
"preview": "vite preview",
|
||||||
"test:watch": "react-scripts test",
|
"test": "vitest run",
|
||||||
"eject": "react-scripts eject",
|
"test:watch": "vitest",
|
||||||
"lint": "eslint \"./**/*.{ts,tsx}\"",
|
"lint": "eslint src/**/*.{ts,tsx}",
|
||||||
"lint:fix": "eslint \"./**/*.{ts,tsx}\" --fix",
|
"lint:fix": "eslint src/**/*.{ts,tsx} --fix",
|
||||||
"golden": "npm run lint && npm run test",
|
"golden": "npm run lint && npm run test",
|
||||||
"prepare": "cd .. && husky install",
|
"prepare": "cd .. && husky install",
|
||||||
"translate": "node prebuild.js -i18nOnly"
|
"translate": "node prebuild.js -i18nOnly"
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
"@mui/material": "^5.5.1",
|
"@mui/material": "^5.5.1",
|
||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
"dexie": "^3.2.2",
|
"dexie": "^3.2.2",
|
||||||
|
"dompurify": "^3.3.3",
|
||||||
"final-form": "^4.20.6",
|
"final-form": "^4.20.6",
|
||||||
"final-form-set-field-touched": "^1.0.1",
|
"final-form-set-field-touched": "^1.0.1",
|
||||||
"i18next": "^22.0.4",
|
"i18next": "^22.0.4",
|
||||||
|
|
@ -39,21 +40,18 @@
|
||||||
"react-i18next": "^12.0.0",
|
"react-i18next": "^12.0.0",
|
||||||
"react-redux": "^8.0.4",
|
"react-redux": "^8.0.4",
|
||||||
"react-router-dom": "^6.2.2",
|
"react-router-dom": "^6.2.2",
|
||||||
"react-scripts": "5.0.1",
|
|
||||||
"react-virtualized-auto-sizer": "^1.0.6",
|
"react-virtualized-auto-sizer": "^1.0.6",
|
||||||
"react-window": "^1.8.6",
|
"react-window": "^1.8.6",
|
||||||
"redux": "^4.1.2",
|
"redux": "^4.1.2",
|
||||||
"redux-form": "^8.3.8",
|
"redux-form": "^8.3.8",
|
||||||
"redux-thunk": "^2.4.1",
|
"redux-thunk": "^2.4.1",
|
||||||
"rxjs": "^7.5.4",
|
"rxjs": "^7.5.4"
|
||||||
"sanitize-html": "^2.7.3"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.17.5",
|
|
||||||
"@mui/types": "^7.1.3",
|
"@mui/types": "^7.1.3",
|
||||||
"@testing-library/jest-dom": "^5.16.2",
|
"@testing-library/jest-dom": "^6.4.0",
|
||||||
"@testing-library/react": "^13.4.0",
|
"@testing-library/react": "^13.4.0",
|
||||||
"@types/jest": "29.2.0",
|
"@types/dompurify": "^3.0.5",
|
||||||
"@types/jquery": "^3.5.14",
|
"@types/jquery": "^3.5.14",
|
||||||
"@types/lodash": "^4.14.179",
|
"@types/lodash": "^4.14.179",
|
||||||
"@types/node": "18.11.7",
|
"@types/node": "18.11.7",
|
||||||
|
|
@ -67,12 +65,16 @@
|
||||||
"@types/redux-form": "^8.3.3",
|
"@types/redux-form": "^8.3.3",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.14.0",
|
"@typescript-eslint/eslint-plugin": "^5.14.0",
|
||||||
"@typescript-eslint/parser": "^5.14.0",
|
"@typescript-eslint/parser": "^5.14.0",
|
||||||
|
"@vitejs/plugin-react": "^4.2.0",
|
||||||
|
"@vitest/coverage-v8": "^1.3.0",
|
||||||
|
"eslint": "^8.0.0",
|
||||||
"fs-extra": "^10.0.1",
|
"fs-extra": "^10.0.1",
|
||||||
"husky": "^8.0.1",
|
"husky": "^8.0.1",
|
||||||
"typescript": "^4.6.2"
|
"jsdom": "^24.0.0",
|
||||||
},
|
"typescript": "^4.6.2",
|
||||||
"eslintConfig": {
|
"vite": "^5.1.0",
|
||||||
"extends": "react-app"
|
"vite-tsconfig-paths": "^4.3.1",
|
||||||
|
"vitest": "^1.3.0"
|
||||||
},
|
},
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
"production": [
|
"production": [
|
||||||
|
|
@ -85,10 +87,5 @@
|
||||||
"last 1 firefox version",
|
"last 1 firefox version",
|
||||||
"last 1 safari version"
|
"last 1 safari version"
|
||||||
]
|
]
|
||||||
},
|
|
||||||
"jest": {
|
|
||||||
"moduleNameMapper": {
|
|
||||||
"\\.(css|less)$": "identity-obj-proxy"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
|
||||||
<link rel="stylesheet" type="text/css" href="%PUBLIC_URL%/reset.css">
|
|
||||||
<meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no" />
|
|
||||||
<meta name="theme-color" content="#000000" />
|
|
||||||
<meta
|
|
||||||
name="description"
|
|
||||||
content="Webatrice: A Cockatrice Web Client"
|
|
||||||
/>
|
|
||||||
<link rel="apple-touch-icon" href="logo192.png" />
|
|
||||||
<!--
|
|
||||||
manifest.json provides metadata used when your web app is installed on a
|
|
||||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
|
||||||
-->
|
|
||||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
|
||||||
<!--
|
|
||||||
Notice the use of %PUBLIC_URL% in the tags above.
|
|
||||||
It will be replaced with the URL of the `public` folder during the build.
|
|
||||||
Only files inside the `public` folder can be referenced from the HTML.
|
|
||||||
|
|
||||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
|
||||||
work correctly both with client-side routing and a non-root public URL.
|
|
||||||
Learn how to configure a non-root public URL by running `npm run build`.
|
|
||||||
-->
|
|
||||||
<title>Webatrice</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
||||||
<div id="root"></div>
|
|
||||||
<!--
|
|
||||||
This HTML file is a template.
|
|
||||||
If you open it directly in the browser, you will see an empty page.
|
|
||||||
|
|
||||||
You can add webfonts, meta tags, or analytics to this file.
|
|
||||||
The build step will place the bundled scripts into the <body> tag.
|
|
||||||
|
|
||||||
To begin the development, run `npm start` or `yarn start`.
|
|
||||||
To create a production bundle, use `npm run build` or `yarn build`.
|
|
||||||
-->
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"short_name": "React App",
|
"short_name": "Webatrice",
|
||||||
"name": "Create React App Sample",
|
"name": "Webatrice",
|
||||||
"icons": [
|
"icons": [
|
||||||
{
|
{
|
||||||
"src": "favicon.ico",
|
"src": "favicon.ico",
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
jest.mock('websocket', () => ({
|
vi.mock('websocket', () => ({
|
||||||
AdminCommands: {
|
AdminCommands: {
|
||||||
adjustMod: jest.fn(),
|
adjustMod: vi.fn(),
|
||||||
reloadConfig: jest.fn(),
|
reloadConfig: vi.fn(),
|
||||||
shutdownServer: jest.fn(),
|
shutdownServer: vi.fn(),
|
||||||
updateServerMessage: jest.fn(),
|
updateServerMessage: vi.fn(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import { AdminService } from './AdminService';
|
import { AdminService } from './AdminService';
|
||||||
import { AdminCommands } from 'websocket';
|
import { AdminCommands } from 'websocket';
|
||||||
|
|
||||||
beforeEach(() => jest.clearAllMocks());
|
beforeEach(() => vi.clearAllMocks());
|
||||||
|
|
||||||
describe('AdminService', () => {
|
describe('AdminService', () => {
|
||||||
describe('adjustMod', () => {
|
describe('adjustMod', () => {
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
jest.mock('websocket', () => ({
|
vi.mock('websocket', () => ({
|
||||||
SessionCommands: {
|
SessionCommands: {
|
||||||
connect: jest.fn(),
|
connect: vi.fn(),
|
||||||
disconnect: jest.fn(),
|
disconnect: vi.fn(),
|
||||||
},
|
},
|
||||||
webClient: {
|
webClient: {
|
||||||
connectionAttemptMade: false,
|
connectionAttemptMade: false,
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('websocket/services/ProtoController', () => ({
|
vi.mock('websocket/services/ProtoController', () => ({
|
||||||
ProtoController: {
|
ProtoController: {
|
||||||
root: {
|
root: {
|
||||||
ServerInfo_User: {
|
ServerInfo_User: {
|
||||||
|
|
@ -26,7 +26,7 @@ import { StatusEnum, WebSocketConnectOptions, WebSocketConnectReason } from 'typ
|
||||||
|
|
||||||
const testOptions: WebSocketConnectOptions = { host: 'localhost', port: '4748', userName: 'user', password: 'pw' };
|
const testOptions: WebSocketConnectOptions = { host: 'localhost', port: '4748', userName: 'user', password: 'pw' };
|
||||||
|
|
||||||
beforeEach(() => jest.clearAllMocks());
|
beforeEach(() => vi.clearAllMocks());
|
||||||
|
|
||||||
describe('AuthenticationService', () => {
|
describe('AuthenticationService', () => {
|
||||||
describe('login', () => {
|
describe('login', () => {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
jest.mock('websocket', () => ({
|
vi.mock('websocket', () => ({
|
||||||
ModeratorCommands: {
|
ModeratorCommands: {
|
||||||
banFromServer: jest.fn(),
|
banFromServer: vi.fn(),
|
||||||
getBanHistory: jest.fn(),
|
getBanHistory: vi.fn(),
|
||||||
getWarnHistory: jest.fn(),
|
getWarnHistory: vi.fn(),
|
||||||
getWarnList: jest.fn(),
|
getWarnList: vi.fn(),
|
||||||
viewLogHistory: jest.fn(),
|
viewLogHistory: vi.fn(),
|
||||||
warnUser: jest.fn(),
|
warnUser: vi.fn(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
@ -13,7 +13,7 @@ import { ModeratorService } from './ModeratorService';
|
||||||
import { ModeratorCommands } from 'websocket';
|
import { ModeratorCommands } from 'websocket';
|
||||||
import { LogFilters } from 'types';
|
import { LogFilters } from 'types';
|
||||||
|
|
||||||
beforeEach(() => jest.clearAllMocks());
|
beforeEach(() => vi.clearAllMocks());
|
||||||
|
|
||||||
describe('ModeratorService', () => {
|
describe('ModeratorService', () => {
|
||||||
describe('banFromServer', () => {
|
describe('banFromServer', () => {
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,17 @@
|
||||||
jest.mock('websocket', () => ({
|
vi.mock('websocket', () => ({
|
||||||
SessionCommands: {
|
SessionCommands: {
|
||||||
joinRoom: jest.fn(),
|
joinRoom: vi.fn(),
|
||||||
},
|
},
|
||||||
RoomCommands: {
|
RoomCommands: {
|
||||||
leaveRoom: jest.fn(),
|
leaveRoom: vi.fn(),
|
||||||
roomSay: jest.fn(),
|
roomSay: vi.fn(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import { RoomsService } from './RoomsService';
|
import { RoomsService } from './RoomsService';
|
||||||
import { RoomCommands, SessionCommands } from 'websocket';
|
import { RoomCommands, SessionCommands } from 'websocket';
|
||||||
|
|
||||||
beforeEach(() => jest.clearAllMocks());
|
beforeEach(() => vi.clearAllMocks());
|
||||||
|
|
||||||
describe('RoomsService', () => {
|
describe('RoomsService', () => {
|
||||||
describe('joinRoom', () => {
|
describe('joinRoom', () => {
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,22 @@
|
||||||
jest.mock('websocket', () => ({
|
vi.mock('websocket', () => ({
|
||||||
SessionCommands: {
|
SessionCommands: {
|
||||||
addToBuddyList: jest.fn(),
|
addToBuddyList: vi.fn(),
|
||||||
removeFromBuddyList: jest.fn(),
|
removeFromBuddyList: vi.fn(),
|
||||||
addToIgnoreList: jest.fn(),
|
addToIgnoreList: vi.fn(),
|
||||||
removeFromIgnoreList: jest.fn(),
|
removeFromIgnoreList: vi.fn(),
|
||||||
accountPassword: jest.fn(),
|
accountPassword: vi.fn(),
|
||||||
accountEdit: jest.fn(),
|
accountEdit: vi.fn(),
|
||||||
accountImage: jest.fn(),
|
accountImage: vi.fn(),
|
||||||
message: jest.fn(),
|
message: vi.fn(),
|
||||||
getUserInfo: jest.fn(),
|
getUserInfo: vi.fn(),
|
||||||
getGamesOfUser: jest.fn(),
|
getGamesOfUser: vi.fn(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import { SessionService } from './SessionService';
|
import { SessionService } from './SessionService';
|
||||||
import { SessionCommands } from 'websocket';
|
import { SessionCommands } from 'websocket';
|
||||||
|
|
||||||
beforeEach(() => jest.clearAllMocks());
|
beforeEach(() => vi.clearAllMocks());
|
||||||
|
|
||||||
describe('SessionService', () => {
|
describe('SessionService', () => {
|
||||||
describe('addToBuddyList', () => {
|
describe('addToBuddyList', () => {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import { useFireOnce } from './useFireOnce';
|
||||||
describe('useFireOnce hook', () => {
|
describe('useFireOnce hook', () => {
|
||||||
test('it only fires once when button is clicked twice', async () => {
|
test('it only fires once when button is clicked twice', async () => {
|
||||||
// Mock a promise with a delay
|
// Mock a promise with a delay
|
||||||
const onClickWithPromise = jest.fn((e) => {
|
const onClickWithPromise = vi.fn((e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|
@ -54,7 +54,7 @@ describe('useFireOnce hook', () => {
|
||||||
|
|
||||||
test('it only fires once when form is submitted twice', async () => {
|
test('it only fires once when form is submitted twice', async () => {
|
||||||
// Mock a promise with a delay
|
// Mock a promise with a delay
|
||||||
const onClickWithPromise = jest.fn((e) => {
|
const onClickWithPromise = vi.fn((e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { Language } from 'types';
|
||||||
|
|
||||||
class I18nBackend {
|
class I18nBackend {
|
||||||
static type: ModuleType = 'backend';
|
static type: ModuleType = 'backend';
|
||||||
static BASE_URL = `${process.env.PUBLIC_URL}/locales`;
|
static BASE_URL = `${import.meta.env.BASE_URL}locales`;
|
||||||
|
|
||||||
read(language, namespace, callback) {
|
read(language, namespace, callback) {
|
||||||
if (!Language[language]) {
|
if (!Language[language]) {
|
||||||
|
|
|
||||||
|
|
@ -1,256 +1,254 @@
|
||||||
// Remove !file-loader! once the following is no longer an issue
|
import ad from './ad.svg';
|
||||||
// https://github.com/facebook/create-react-app/issues/11770
|
import ae from './ae.svg';
|
||||||
import ad from '!file-loader!./ad.svg';
|
import af from './af.svg';
|
||||||
import ae from '!file-loader!./ae.svg';
|
import ag from './ag.svg';
|
||||||
import af from '!file-loader!./af.svg';
|
import ai from './ai.svg';
|
||||||
import ag from '!file-loader!./ag.svg';
|
import al from './al.svg';
|
||||||
import ai from '!file-loader!./ai.svg';
|
import am from './am.svg';
|
||||||
import al from '!file-loader!./al.svg';
|
import ao from './ao.svg';
|
||||||
import am from '!file-loader!./am.svg';
|
import aq from './aq.svg';
|
||||||
import ao from '!file-loader!./ao.svg';
|
import ar from './ar.svg';
|
||||||
import aq from '!file-loader!./aq.svg';
|
import as from './as.svg';
|
||||||
import ar from '!file-loader!./ar.svg';
|
import at from './at.svg';
|
||||||
import as from '!file-loader!./as.svg';
|
import au from './au.svg';
|
||||||
import at from '!file-loader!./at.svg';
|
import aw from './aw.svg';
|
||||||
import au from '!file-loader!./au.svg';
|
import ax from './ax.svg';
|
||||||
import aw from '!file-loader!./aw.svg';
|
import az from './az.svg';
|
||||||
import ax from '!file-loader!./ax.svg';
|
import ba from './ba.svg';
|
||||||
import az from '!file-loader!./az.svg';
|
import bb from './bb.svg';
|
||||||
import ba from '!file-loader!./ba.svg';
|
import bd from './bd.svg';
|
||||||
import bb from '!file-loader!./bb.svg';
|
import be from './be.svg';
|
||||||
import bd from '!file-loader!./bd.svg';
|
import bf from './bf.svg';
|
||||||
import be from '!file-loader!./be.svg';
|
import bg from './bg.svg';
|
||||||
import bf from '!file-loader!./bf.svg';
|
import bh from './bh.svg';
|
||||||
import bg from '!file-loader!./bg.svg';
|
import bi from './bi.svg';
|
||||||
import bh from '!file-loader!./bh.svg';
|
import bj from './bj.svg';
|
||||||
import bi from '!file-loader!./bi.svg';
|
import bl from './bl.svg';
|
||||||
import bj from '!file-loader!./bj.svg';
|
import bm from './bm.svg';
|
||||||
import bl from '!file-loader!./bl.svg';
|
import bn from './bn.svg';
|
||||||
import bm from '!file-loader!./bm.svg';
|
import bo from './bo.svg';
|
||||||
import bn from '!file-loader!./bn.svg';
|
import bq from './bq.svg';
|
||||||
import bo from '!file-loader!./bo.svg';
|
import br from './br.svg';
|
||||||
import bq from '!file-loader!./bq.svg';
|
import bs from './bs.svg';
|
||||||
import br from '!file-loader!./br.svg';
|
import bt from './bt.svg';
|
||||||
import bs from '!file-loader!./bs.svg';
|
import bv from './bv.svg';
|
||||||
import bt from '!file-loader!./bt.svg';
|
import bw from './bw.svg';
|
||||||
import bv from '!file-loader!./bv.svg';
|
import by from './by.svg';
|
||||||
import bw from '!file-loader!./bw.svg';
|
import bz from './bz.svg';
|
||||||
import by from '!file-loader!./by.svg';
|
import ca from './ca.svg';
|
||||||
import bz from '!file-loader!./bz.svg';
|
import cc from './cc.svg';
|
||||||
import ca from '!file-loader!./ca.svg';
|
import cd from './cd.svg';
|
||||||
import cc from '!file-loader!./cc.svg';
|
import cf from './cf.svg';
|
||||||
import cd from '!file-loader!./cd.svg';
|
import cg from './cg.svg';
|
||||||
import cf from '!file-loader!./cf.svg';
|
import ch from './ch.svg';
|
||||||
import cg from '!file-loader!./cg.svg';
|
import ci from './ci.svg';
|
||||||
import ch from '!file-loader!./ch.svg';
|
import ck from './ck.svg';
|
||||||
import ci from '!file-loader!./ci.svg';
|
import cl from './cl.svg';
|
||||||
import ck from '!file-loader!./ck.svg';
|
import cm from './cm.svg';
|
||||||
import cl from '!file-loader!./cl.svg';
|
import cn from './cn.svg';
|
||||||
import cm from '!file-loader!./cm.svg';
|
import co from './co.svg';
|
||||||
import cn from '!file-loader!./cn.svg';
|
import cr from './cr.svg';
|
||||||
import co from '!file-loader!./co.svg';
|
import cu from './cu.svg';
|
||||||
import cr from '!file-loader!./cr.svg';
|
import cv from './cv.svg';
|
||||||
import cu from '!file-loader!./cu.svg';
|
import cw from './cw.svg';
|
||||||
import cv from '!file-loader!./cv.svg';
|
import cx from './cx.svg';
|
||||||
import cw from '!file-loader!./cw.svg';
|
import cy from './cy.svg';
|
||||||
import cx from '!file-loader!./cx.svg';
|
import cz from './cz.svg';
|
||||||
import cy from '!file-loader!./cy.svg';
|
import de from './de.svg';
|
||||||
import cz from '!file-loader!./cz.svg';
|
import dj from './dj.svg';
|
||||||
import de from '!file-loader!./de.svg';
|
import dk from './dk.svg';
|
||||||
import dj from '!file-loader!./dj.svg';
|
import dm from './dm.svg';
|
||||||
import dk from '!file-loader!./dk.svg';
|
import _do from './do.svg';
|
||||||
import dm from '!file-loader!./dm.svg';
|
import dz from './dz.svg';
|
||||||
import _do from '!file-loader!./do.svg';
|
import ec from './ec.svg';
|
||||||
import dz from '!file-loader!./dz.svg';
|
import ee from './ee.svg';
|
||||||
import ec from '!file-loader!./ec.svg';
|
import eg from './eg.svg';
|
||||||
import ee from '!file-loader!./ee.svg';
|
import eh from './eh.svg';
|
||||||
import eg from '!file-loader!./eg.svg';
|
import er from './er.svg';
|
||||||
import eh from '!file-loader!./eh.svg';
|
import es from './es.svg';
|
||||||
import er from '!file-loader!./er.svg';
|
import et from './et.svg';
|
||||||
import es from '!file-loader!./es.svg';
|
import eu from './eu.svg';
|
||||||
import et from '!file-loader!./et.svg';
|
import fi from './fi.svg';
|
||||||
import eu from '!file-loader!./eu.svg';
|
import fj from './fj.svg';
|
||||||
import fi from '!file-loader!./fi.svg';
|
import fk from './fk.svg';
|
||||||
import fj from '!file-loader!./fj.svg';
|
import fm from './fm.svg';
|
||||||
import fk from '!file-loader!./fk.svg';
|
import fo from './fo.svg';
|
||||||
import fm from '!file-loader!./fm.svg';
|
import fr from './fr.svg';
|
||||||
import fo from '!file-loader!./fo.svg';
|
import ga from './ga.svg';
|
||||||
import fr from '!file-loader!./fr.svg';
|
import gb from './gb.svg';
|
||||||
import ga from '!file-loader!./ga.svg';
|
import gd from './gd.svg';
|
||||||
import gb from '!file-loader!./gb.svg';
|
import ge from './ge.svg';
|
||||||
import gd from '!file-loader!./gd.svg';
|
import gf from './gf.svg';
|
||||||
import ge from '!file-loader!./ge.svg';
|
import gg from './gg.svg';
|
||||||
import gf from '!file-loader!./gf.svg';
|
import gh from './gh.svg';
|
||||||
import gg from '!file-loader!./gg.svg';
|
import gi from './gi.svg';
|
||||||
import gh from '!file-loader!./gh.svg';
|
import gl from './gl.svg';
|
||||||
import gi from '!file-loader!./gi.svg';
|
import gm from './gm.svg';
|
||||||
import gl from '!file-loader!./gl.svg';
|
import gn from './gn.svg';
|
||||||
import gm from '!file-loader!./gm.svg';
|
import gp from './gp.svg';
|
||||||
import gn from '!file-loader!./gn.svg';
|
import gq from './gq.svg';
|
||||||
import gp from '!file-loader!./gp.svg';
|
import gr from './gr.svg';
|
||||||
import gq from '!file-loader!./gq.svg';
|
import gs from './gs.svg';
|
||||||
import gr from '!file-loader!./gr.svg';
|
import gt from './gt.svg';
|
||||||
import gs from '!file-loader!./gs.svg';
|
import gu from './gu.svg';
|
||||||
import gt from '!file-loader!./gt.svg';
|
import gw from './gw.svg';
|
||||||
import gu from '!file-loader!./gu.svg';
|
import gy from './gy.svg';
|
||||||
import gw from '!file-loader!./gw.svg';
|
import hk from './hk.svg';
|
||||||
import gy from '!file-loader!./gy.svg';
|
import hm from './hm.svg';
|
||||||
import hk from '!file-loader!./hk.svg';
|
import hn from './hn.svg';
|
||||||
import hm from '!file-loader!./hm.svg';
|
import hr from './hr.svg';
|
||||||
import hn from '!file-loader!./hn.svg';
|
import ht from './ht.svg';
|
||||||
import hr from '!file-loader!./hr.svg';
|
import hu from './hu.svg';
|
||||||
import ht from '!file-loader!./ht.svg';
|
import id from './id.svg';
|
||||||
import hu from '!file-loader!./hu.svg';
|
import ie from './ie.svg';
|
||||||
import id from '!file-loader!./id.svg';
|
import il from './il.svg';
|
||||||
import ie from '!file-loader!./ie.svg';
|
import im from './im.svg';
|
||||||
import il from '!file-loader!./il.svg';
|
import _in from './in.svg';
|
||||||
import im from '!file-loader!./im.svg';
|
import io from './io.svg';
|
||||||
import _in from '!file-loader!./in.svg';
|
import iq from './iq.svg';
|
||||||
import io from '!file-loader!./io.svg';
|
import ir from './ir.svg';
|
||||||
import iq from '!file-loader!./iq.svg';
|
import is from './is.svg';
|
||||||
import ir from '!file-loader!./ir.svg';
|
import it from './it.svg';
|
||||||
import is from '!file-loader!./is.svg';
|
import je from './je.svg';
|
||||||
import it from '!file-loader!./it.svg';
|
import jm from './jm.svg';
|
||||||
import je from '!file-loader!./je.svg';
|
import jo from './jo.svg';
|
||||||
import jm from '!file-loader!./jm.svg';
|
import jp from './jp.svg';
|
||||||
import jo from '!file-loader!./jo.svg';
|
import ke from './ke.svg';
|
||||||
import jp from '!file-loader!./jp.svg';
|
import kg from './kg.svg';
|
||||||
import ke from '!file-loader!./ke.svg';
|
import kh from './kh.svg';
|
||||||
import kg from '!file-loader!./kg.svg';
|
import ki from './ki.svg';
|
||||||
import kh from '!file-loader!./kh.svg';
|
import km from './km.svg';
|
||||||
import ki from '!file-loader!./ki.svg';
|
import kn from './kn.svg';
|
||||||
import km from '!file-loader!./km.svg';
|
import kp from './kp.svg';
|
||||||
import kn from '!file-loader!./kn.svg';
|
import kr from './kr.svg';
|
||||||
import kp from '!file-loader!./kp.svg';
|
import kw from './kw.svg';
|
||||||
import kr from '!file-loader!./kr.svg';
|
import ky from './ky.svg';
|
||||||
import kw from '!file-loader!./kw.svg';
|
import kz from './kz.svg';
|
||||||
import ky from '!file-loader!./ky.svg';
|
import la from './la.svg';
|
||||||
import kz from '!file-loader!./kz.svg';
|
import lb from './lb.svg';
|
||||||
import la from '!file-loader!./la.svg';
|
import lc from './lc.svg';
|
||||||
import lb from '!file-loader!./lb.svg';
|
import li from './li.svg';
|
||||||
import lc from '!file-loader!./lc.svg';
|
import lk from './lk.svg';
|
||||||
import li from '!file-loader!./li.svg';
|
import lr from './lr.svg';
|
||||||
import lk from '!file-loader!./lk.svg';
|
import ls from './ls.svg';
|
||||||
import lr from '!file-loader!./lr.svg';
|
import lt from './lt.svg';
|
||||||
import ls from '!file-loader!./ls.svg';
|
import lu from './lu.svg';
|
||||||
import lt from '!file-loader!./lt.svg';
|
import lv from './lv.svg';
|
||||||
import lu from '!file-loader!./lu.svg';
|
import ly from './ly.svg';
|
||||||
import lv from '!file-loader!./lv.svg';
|
import ma from './ma.svg';
|
||||||
import ly from '!file-loader!./ly.svg';
|
import mc from './mc.svg';
|
||||||
import ma from '!file-loader!./ma.svg';
|
import md from './md.svg';
|
||||||
import mc from '!file-loader!./mc.svg';
|
import me from './me.svg';
|
||||||
import md from '!file-loader!./md.svg';
|
import mf from './mf.svg';
|
||||||
import me from '!file-loader!./me.svg';
|
import mg from './mg.svg';
|
||||||
import mf from '!file-loader!./mf.svg';
|
import mh from './mh.svg';
|
||||||
import mg from '!file-loader!./mg.svg';
|
import mk from './mk.svg';
|
||||||
import mh from '!file-loader!./mh.svg';
|
import ml from './ml.svg';
|
||||||
import mk from '!file-loader!./mk.svg';
|
import mm from './mm.svg';
|
||||||
import ml from '!file-loader!./ml.svg';
|
import mn from './mn.svg';
|
||||||
import mm from '!file-loader!./mm.svg';
|
import mo from './mo.svg';
|
||||||
import mn from '!file-loader!./mn.svg';
|
import mp from './mp.svg';
|
||||||
import mo from '!file-loader!./mo.svg';
|
import mq from './mq.svg';
|
||||||
import mp from '!file-loader!./mp.svg';
|
import mr from './mr.svg';
|
||||||
import mq from '!file-loader!./mq.svg';
|
import ms from './ms.svg';
|
||||||
import mr from '!file-loader!./mr.svg';
|
import mt from './mt.svg';
|
||||||
import ms from '!file-loader!./ms.svg';
|
import mu from './mu.svg';
|
||||||
import mt from '!file-loader!./mt.svg';
|
import mv from './mv.svg';
|
||||||
import mu from '!file-loader!./mu.svg';
|
import mw from './mw.svg';
|
||||||
import mv from '!file-loader!./mv.svg';
|
import mx from './mx.svg';
|
||||||
import mw from '!file-loader!./mw.svg';
|
import my from './my.svg';
|
||||||
import mx from '!file-loader!./mx.svg';
|
import mz from './mz.svg';
|
||||||
import my from '!file-loader!./my.svg';
|
import na from './na.svg';
|
||||||
import mz from '!file-loader!./mz.svg';
|
import nc from './nc.svg';
|
||||||
import na from '!file-loader!./na.svg';
|
import ne from './ne.svg';
|
||||||
import nc from '!file-loader!./nc.svg';
|
import nf from './nf.svg';
|
||||||
import ne from '!file-loader!./ne.svg';
|
import ng from './ng.svg';
|
||||||
import nf from '!file-loader!./nf.svg';
|
import ni from './ni.svg';
|
||||||
import ng from '!file-loader!./ng.svg';
|
import nl from './nl.svg';
|
||||||
import ni from '!file-loader!./ni.svg';
|
import no from './no.svg';
|
||||||
import nl from '!file-loader!./nl.svg';
|
import np from './np.svg';
|
||||||
import no from '!file-loader!./no.svg';
|
import nr from './nr.svg';
|
||||||
import np from '!file-loader!./np.svg';
|
import nu from './nu.svg';
|
||||||
import nr from '!file-loader!./nr.svg';
|
import nz from './nz.svg';
|
||||||
import nu from '!file-loader!./nu.svg';
|
import om from './om.svg';
|
||||||
import nz from '!file-loader!./nz.svg';
|
import pa from './pa.svg';
|
||||||
import om from '!file-loader!./om.svg';
|
import pe from './pe.svg';
|
||||||
import pa from '!file-loader!./pa.svg';
|
import pf from './pf.svg';
|
||||||
import pe from '!file-loader!./pe.svg';
|
import pg from './pg.svg';
|
||||||
import pf from '!file-loader!./pf.svg';
|
import ph from './ph.svg';
|
||||||
import pg from '!file-loader!./pg.svg';
|
import pk from './pk.svg';
|
||||||
import ph from '!file-loader!./ph.svg';
|
import pl from './pl.svg';
|
||||||
import pk from '!file-loader!./pk.svg';
|
import pm from './pm.svg';
|
||||||
import pl from '!file-loader!./pl.svg';
|
import pn from './pn.svg';
|
||||||
import pm from '!file-loader!./pm.svg';
|
import pr from './pr.svg';
|
||||||
import pn from '!file-loader!./pn.svg';
|
import ps from './ps.svg';
|
||||||
import pr from '!file-loader!./pr.svg';
|
import pt from './pt.svg';
|
||||||
import ps from '!file-loader!./ps.svg';
|
import pw from './pw.svg';
|
||||||
import pt from '!file-loader!./pt.svg';
|
import py from './py.svg';
|
||||||
import pw from '!file-loader!./pw.svg';
|
import qa from './qa.svg';
|
||||||
import py from '!file-loader!./py.svg';
|
import re from './re.svg';
|
||||||
import qa from '!file-loader!./qa.svg';
|
import ro from './ro.svg';
|
||||||
import re from '!file-loader!./re.svg';
|
import rs from './rs.svg';
|
||||||
import ro from '!file-loader!./ro.svg';
|
import ru from './ru.svg';
|
||||||
import rs from '!file-loader!./rs.svg';
|
import rw from './rw.svg';
|
||||||
import ru from '!file-loader!./ru.svg';
|
import sa from './sa.svg';
|
||||||
import rw from '!file-loader!./rw.svg';
|
import sb from './sb.svg';
|
||||||
import sa from '!file-loader!./sa.svg';
|
import sc from './sc.svg';
|
||||||
import sb from '!file-loader!./sb.svg';
|
import sd from './sd.svg';
|
||||||
import sc from '!file-loader!./sc.svg';
|
import se from './se.svg';
|
||||||
import sd from '!file-loader!./sd.svg';
|
import sg from './sg.svg';
|
||||||
import se from '!file-loader!./se.svg';
|
import sh from './sh.svg';
|
||||||
import sg from '!file-loader!./sg.svg';
|
import si from './si.svg';
|
||||||
import sh from '!file-loader!./sh.svg';
|
import sj from './sj.svg';
|
||||||
import si from '!file-loader!./si.svg';
|
import sk from './sk.svg';
|
||||||
import sj from '!file-loader!./sj.svg';
|
import sl from './sl.svg';
|
||||||
import sk from '!file-loader!./sk.svg';
|
import sm from './sm.svg';
|
||||||
import sl from '!file-loader!./sl.svg';
|
import sn from './sn.svg';
|
||||||
import sm from '!file-loader!./sm.svg';
|
import so from './so.svg';
|
||||||
import sn from '!file-loader!./sn.svg';
|
import sr from './sr.svg';
|
||||||
import so from '!file-loader!./so.svg';
|
import ss from './ss.svg';
|
||||||
import sr from '!file-loader!./sr.svg';
|
import st from './st.svg';
|
||||||
import ss from '!file-loader!./ss.svg';
|
import sv from './sv.svg';
|
||||||
import st from '!file-loader!./st.svg';
|
import sx from './sx.svg';
|
||||||
import sv from '!file-loader!./sv.svg';
|
import sy from './sy.svg';
|
||||||
import sx from '!file-loader!./sx.svg';
|
import sz from './sz.svg';
|
||||||
import sy from '!file-loader!./sy.svg';
|
import tc from './tc.svg';
|
||||||
import sz from '!file-loader!./sz.svg';
|
import td from './td.svg';
|
||||||
import tc from '!file-loader!./tc.svg';
|
import tf from './tf.svg';
|
||||||
import td from '!file-loader!./td.svg';
|
import tg from './tg.svg';
|
||||||
import tf from '!file-loader!./tf.svg';
|
import th from './th.svg';
|
||||||
import tg from '!file-loader!./tg.svg';
|
import tj from './tj.svg';
|
||||||
import th from '!file-loader!./th.svg';
|
import tk from './tk.svg';
|
||||||
import tj from '!file-loader!./tj.svg';
|
import tl from './tl.svg';
|
||||||
import tk from '!file-loader!./tk.svg';
|
import tm from './tm.svg';
|
||||||
import tl from '!file-loader!./tl.svg';
|
import tn from './tn.svg';
|
||||||
import tm from '!file-loader!./tm.svg';
|
import to from './to.svg';
|
||||||
import tn from '!file-loader!./tn.svg';
|
import tr from './tr.svg';
|
||||||
import to from '!file-loader!./to.svg';
|
import tt from './tt.svg';
|
||||||
import tr from '!file-loader!./tr.svg';
|
import tv from './tv.svg';
|
||||||
import tt from '!file-loader!./tt.svg';
|
import tw from './tw.svg';
|
||||||
import tv from '!file-loader!./tv.svg';
|
import tz from './tz.svg';
|
||||||
import tw from '!file-loader!./tw.svg';
|
import ua from './ua.svg';
|
||||||
import tz from '!file-loader!./tz.svg';
|
import ug from './ug.svg';
|
||||||
import ua from '!file-loader!./ua.svg';
|
import um from './um.svg';
|
||||||
import ug from '!file-loader!./ug.svg';
|
import us from './us.svg';
|
||||||
import um from '!file-loader!./um.svg';
|
import uy from './uy.svg';
|
||||||
import us from '!file-loader!./us.svg';
|
import uz from './uz.svg';
|
||||||
import uy from '!file-loader!./uy.svg';
|
import va from './va.svg';
|
||||||
import uz from '!file-loader!./uz.svg';
|
import vc from './vc.svg';
|
||||||
import va from '!file-loader!./va.svg';
|
import ve from './ve.svg';
|
||||||
import vc from '!file-loader!./vc.svg';
|
import vg from './vg.svg';
|
||||||
import ve from '!file-loader!./ve.svg';
|
import vi from './vi.svg';
|
||||||
import vg from '!file-loader!./vg.svg';
|
import vn from './vn.svg';
|
||||||
import vi from '!file-loader!./vi.svg';
|
import vu from './vu.svg';
|
||||||
import vn from '!file-loader!./vn.svg';
|
import wf from './wf.svg';
|
||||||
import vu from '!file-loader!./vu.svg';
|
import ws from './ws.svg';
|
||||||
import wf from '!file-loader!./wf.svg';
|
import xk from './xk.svg';
|
||||||
import ws from '!file-loader!./ws.svg';
|
import ye from './ye.svg';
|
||||||
import xk from '!file-loader!./xk.svg';
|
import yt from './yt.svg';
|
||||||
import ye from '!file-loader!./ye.svg';
|
import za from './za.svg';
|
||||||
import yt from '!file-loader!./yt.svg';
|
import zm from './zm.svg';
|
||||||
import za from '!file-loader!./za.svg';
|
import zw from './zw.svg';
|
||||||
import zm from '!file-loader!./zm.svg';
|
|
||||||
import zw from '!file-loader!./zw.svg';
|
|
||||||
|
|
||||||
export const Countries = {
|
export const Countries = {
|
||||||
ad,
|
ad,
|
||||||
|
|
|
||||||
1
webclient/src/react-app-env.d.ts
vendored
1
webclient/src/react-app-env.d.ts
vendored
|
|
@ -1 +0,0 @@
|
||||||
/// <reference types="react-scripts" />
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import protobuf from 'protobufjs';
|
import protobuf from 'protobufjs';
|
||||||
|
|
||||||
// ensure jest-dom is always available during testing to cut down on boilerplate
|
// ensure jest-dom is always available during testing to cut down on boilerplate
|
||||||
import '@testing-library/jest-dom';
|
import '@testing-library/jest-dom/vitest';
|
||||||
|
|
||||||
class MockProtobufRoot {
|
class MockProtobufRoot {
|
||||||
load() {}
|
load() {}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
jest.mock('store/store', () => ({ store: { dispatch: jest.fn() } }));
|
vi.mock('store/store', () => ({ store: { dispatch: vi.fn() } }));
|
||||||
|
|
||||||
import { store } from 'store/store';
|
import { store } from 'store/store';
|
||||||
import { Actions } from './game.actions';
|
import { Actions } from './game.actions';
|
||||||
|
|
@ -11,7 +11,7 @@ import {
|
||||||
makePlayerProperties,
|
makePlayerProperties,
|
||||||
} from './__mocks__/fixtures';
|
} from './__mocks__/fixtures';
|
||||||
|
|
||||||
beforeEach(() => jest.clearAllMocks());
|
beforeEach(() => vi.clearAllMocks());
|
||||||
|
|
||||||
describe('Dispatch', () => {
|
describe('Dispatch', () => {
|
||||||
it('clearStore dispatches Actions.clearStore()', () => {
|
it('clearStore dispatches Actions.clearStore()', () => {
|
||||||
|
|
|
||||||
|
|
@ -890,14 +890,14 @@ describe('2J: Turn, phase, and chat', () => {
|
||||||
|
|
||||||
it('GAME_SAY → appends message with mocked Date.now() as timeReceived', () => {
|
it('GAME_SAY → appends message with mocked Date.now() as timeReceived', () => {
|
||||||
const state = makeState();
|
const state = makeState();
|
||||||
jest.spyOn(Date, 'now').mockReturnValue(123456789);
|
vi.spyOn(Date, 'now').mockReturnValue(123456789);
|
||||||
const result = gamesReducer(state, {
|
const result = gamesReducer(state, {
|
||||||
type: Types.GAME_SAY,
|
type: Types.GAME_SAY,
|
||||||
gameId: 1,
|
gameId: 1,
|
||||||
playerId: 2,
|
playerId: 2,
|
||||||
message: 'gg',
|
message: 'gg',
|
||||||
});
|
});
|
||||||
jest.restoreAllMocks();
|
vi.restoreAllMocks();
|
||||||
|
|
||||||
expect(result.games[1].messages).toHaveLength(1);
|
expect(result.games[1].messages).toHaveLength(1);
|
||||||
expect(result.games[1].messages[0]).toEqual({ playerId: 2, message: 'gg', timeReceived: 123456789 });
|
expect(result.games[1].messages[0]).toEqual({ playerId: 2, message: 'gg', timeReceived: 123456789 });
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
jest.mock('store/store', () => ({ store: { dispatch: jest.fn() } }));
|
vi.mock('store/store', () => ({ store: { dispatch: vi.fn() } }));
|
||||||
jest.mock('redux-form', () => ({
|
vi.mock('redux-form', () => ({
|
||||||
reset: jest.fn((form) => ({ type: '@@redux-form/RESET', meta: { form } })),
|
reset: vi.fn((form) => ({ type: '@@redux-form/RESET', meta: { form } })),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import { store } from 'store/store';
|
import { store } from 'store/store';
|
||||||
|
|
@ -10,7 +10,7 @@ import { Dispatch } from './rooms.dispatch';
|
||||||
import { makeGame, makeMessage, makeRoom, makeUser } from './__mocks__/rooms-fixtures';
|
import { makeGame, makeMessage, makeRoom, makeUser } from './__mocks__/rooms-fixtures';
|
||||||
import { GameSortField, SortDirection } from 'types';
|
import { GameSortField, SortDirection } from 'types';
|
||||||
|
|
||||||
beforeEach(() => jest.clearAllMocks());
|
beforeEach(() => vi.clearAllMocks());
|
||||||
|
|
||||||
describe('Dispatch', () => {
|
describe('Dispatch', () => {
|
||||||
it('clearStore dispatches Actions.clearStore()', () => {
|
it('clearStore dispatches Actions.clearStore()', () => {
|
||||||
|
|
@ -45,7 +45,7 @@ describe('Dispatch', () => {
|
||||||
it('addMessage with message.name truthy → dispatches reset("sayMessage") then Actions.addMessage()', () => {
|
it('addMessage with message.name truthy → dispatches reset("sayMessage") then Actions.addMessage()', () => {
|
||||||
const message = { ...makeMessage(), name: 'Alice' };
|
const message = { ...makeMessage(), name: 'Alice' };
|
||||||
Dispatch.addMessage(1, message);
|
Dispatch.addMessage(1, message);
|
||||||
expect(store.dispatch).toHaveBeenNthCalledWith(1, (reset as jest.Mock)('sayMessage'));
|
expect(store.dispatch).toHaveBeenNthCalledWith(1, (reset as vi.Mock)('sayMessage'));
|
||||||
expect(store.dispatch).toHaveBeenNthCalledWith(2, Actions.addMessage(1, message));
|
expect(store.dispatch).toHaveBeenNthCalledWith(2, Actions.addMessage(1, message));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
jest.mock('store/store', () => ({ store: { dispatch: jest.fn() } }));
|
vi.mock('store/store', () => ({ store: { dispatch: vi.fn() } }));
|
||||||
jest.mock('redux-form', () => ({
|
vi.mock('redux-form', () => ({
|
||||||
reset: jest.fn((form) => ({ type: '@@redux-form/RESET', meta: { form } })),
|
reset: vi.fn((form) => ({ type: '@@redux-form/RESET', meta: { form } })),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import { store } from 'store/store';
|
import { store } from 'store/store';
|
||||||
|
|
@ -18,7 +18,7 @@ import {
|
||||||
makeWarnListItem,
|
makeWarnListItem,
|
||||||
} from './__mocks__/server-fixtures';
|
} from './__mocks__/server-fixtures';
|
||||||
|
|
||||||
beforeEach(() => jest.clearAllMocks());
|
beforeEach(() => vi.clearAllMocks());
|
||||||
|
|
||||||
describe('Dispatch', () => {
|
describe('Dispatch', () => {
|
||||||
it('initialized dispatches Actions.initialized()', () => {
|
it('initialized dispatches Actions.initialized()', () => {
|
||||||
|
|
@ -71,7 +71,7 @@ describe('Dispatch', () => {
|
||||||
it('addToBuddyList dispatches reset("addToBuddies") then Actions.addToBuddyList()', () => {
|
it('addToBuddyList dispatches reset("addToBuddies") then Actions.addToBuddyList()', () => {
|
||||||
const user = makeUser();
|
const user = makeUser();
|
||||||
Dispatch.addToBuddyList(user);
|
Dispatch.addToBuddyList(user);
|
||||||
expect(store.dispatch).toHaveBeenNthCalledWith(1, (reset as jest.Mock)('addToBuddies'));
|
expect(store.dispatch).toHaveBeenNthCalledWith(1, (reset as vi.Mock)('addToBuddies'));
|
||||||
expect(store.dispatch).toHaveBeenNthCalledWith(2, Actions.addToBuddyList(user));
|
expect(store.dispatch).toHaveBeenNthCalledWith(2, Actions.addToBuddyList(user));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -89,7 +89,7 @@ describe('Dispatch', () => {
|
||||||
it('addToIgnoreList dispatches reset("addToIgnore") then Actions.addToIgnoreList()', () => {
|
it('addToIgnoreList dispatches reset("addToIgnore") then Actions.addToIgnoreList()', () => {
|
||||||
const user = makeUser();
|
const user = makeUser();
|
||||||
Dispatch.addToIgnoreList(user);
|
Dispatch.addToIgnoreList(user);
|
||||||
expect(store.dispatch).toHaveBeenNthCalledWith(1, (reset as jest.Mock)('addToIgnore'));
|
expect(store.dispatch).toHaveBeenNthCalledWith(1, (reset as vi.Mock)('addToIgnore'));
|
||||||
expect(store.dispatch).toHaveBeenNthCalledWith(2, Actions.addToIgnoreList(user));
|
expect(store.dispatch).toHaveBeenNthCalledWith(2, Actions.addToIgnoreList(user));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
2
webclient/src/vite-env.d.ts
vendored
Normal file
2
webclient/src/vite-env.d.ts
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
/// <reference types="vite/client" />
|
||||||
|
/// <reference types="vitest/globals" />
|
||||||
|
|
@ -1,26 +1,28 @@
|
||||||
jest.mock('./services/WebSocketService', () => ({
|
vi.mock('./services/WebSocketService', () => ({
|
||||||
WebSocketService: jest.fn().mockImplementation(() => ({
|
WebSocketService: vi.fn().mockImplementation(() => ({
|
||||||
message$: { subscribe: jest.fn() },
|
message$: { subscribe: vi.fn() },
|
||||||
connect: jest.fn(),
|
connect: vi.fn(),
|
||||||
testConnect: jest.fn(),
|
testConnect: vi.fn(),
|
||||||
disconnect: jest.fn(),
|
disconnect: vi.fn(),
|
||||||
})),
|
})),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('./services/ProtobufService', () => ({
|
vi.mock('./services/ProtobufService', () => ({
|
||||||
ProtobufService: jest.fn().mockImplementation(() => ({
|
ProtobufService: vi.fn().mockImplementation(() => ({
|
||||||
handleMessageEvent: jest.fn(),
|
handleMessageEvent: vi.fn(),
|
||||||
sendKeepAliveCommand: jest.fn(),
|
sendKeepAliveCommand: vi.fn(),
|
||||||
resetCommands: jest.fn(),
|
resetCommands: vi.fn(),
|
||||||
})),
|
})),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('./persistence', () => ({
|
vi.mock('./persistence', () => ({
|
||||||
RoomPersistence: { clearStore: jest.fn() },
|
RoomPersistence: { clearStore: vi.fn() },
|
||||||
SessionPersistence: { clearStore: jest.fn() },
|
SessionPersistence: { clearStore: vi.fn() },
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import { WebClient } from './WebClient';
|
import { WebClient } from './WebClient';
|
||||||
|
import { WebSocketService } from './services/WebSocketService';
|
||||||
|
import { ProtobufService } from './services/ProtobufService';
|
||||||
import { RoomPersistence, SessionPersistence } from './persistence';
|
import { RoomPersistence, SessionPersistence } from './persistence';
|
||||||
import { StatusEnum } from 'types';
|
import { StatusEnum } from 'types';
|
||||||
import { Subject } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
|
|
@ -30,28 +32,26 @@ describe('WebClient', () => {
|
||||||
let messageSubject: Subject<MessageEvent>;
|
let messageSubject: Subject<MessageEvent>;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
const { ProtobufService } = require('./services/ProtobufService');
|
(ProtobufService as vi.Mock).mockImplementation(() => ({
|
||||||
ProtobufService.mockImplementation(() => ({
|
handleMessageEvent: vi.fn(),
|
||||||
handleMessageEvent: jest.fn(),
|
sendKeepAliveCommand: vi.fn(),
|
||||||
sendKeepAliveCommand: jest.fn(),
|
resetCommands: vi.fn(),
|
||||||
resetCommands: jest.fn(),
|
|
||||||
}));
|
}));
|
||||||
messageSubject = new Subject<MessageEvent>();
|
messageSubject = new Subject<MessageEvent>();
|
||||||
const { WebSocketService } = require('./services/WebSocketService');
|
(WebSocketService as vi.Mock).mockImplementation(() => ({
|
||||||
WebSocketService.mockImplementation(() => ({
|
|
||||||
message$: messageSubject,
|
message$: messageSubject,
|
||||||
connect: jest.fn(),
|
connect: vi.fn(),
|
||||||
testConnect: jest.fn(),
|
testConnect: vi.fn(),
|
||||||
disconnect: jest.fn(),
|
disconnect: vi.fn(),
|
||||||
}));
|
}));
|
||||||
// suppress console.log from constructor in non-test-env check
|
// suppress console.log from constructor in non-test-env check
|
||||||
jest.spyOn(console, 'log').mockImplementation(() => {});
|
vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||||
client = new WebClient();
|
client = new WebClient();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.restoreAllMocks();
|
vi.restoreAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('constructor', () => {
|
describe('constructor', () => {
|
||||||
|
|
@ -94,7 +94,7 @@ describe('WebClient', () => {
|
||||||
|
|
||||||
describe('keepAlive', () => {
|
describe('keepAlive', () => {
|
||||||
it('delegates to protobuf.sendKeepAliveCommand', () => {
|
it('delegates to protobuf.sendKeepAliveCommand', () => {
|
||||||
const pingCb = jest.fn();
|
const pingCb = vi.fn();
|
||||||
client.keepAlive(pingCb);
|
client.keepAlive(pingCb);
|
||||||
expect(client.protobuf.sendKeepAliveCommand).toHaveBeenCalledWith(pingCb);
|
expect(client.protobuf.sendKeepAliveCommand).toHaveBeenCalledWith(pingCb);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ export class WebClient {
|
||||||
this.protobuf.handleMessageEvent(message);
|
this.protobuf.handleMessageEvent(message);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== 'test') {
|
if (import.meta.env.MODE !== 'test') {
|
||||||
console.log(this);
|
console.log(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
/**
|
/**
|
||||||
* Factory for invoking BackendService command callbacks in unit tests.
|
* Factory for invoking BackendService command callbacks in unit tests.
|
||||||
*
|
*
|
||||||
* @param mockFn - The jest.Mock for the BackendService send method
|
* @param mockFn - The vi.Mock for the BackendService send method
|
||||||
* (e.g. BackendService.sendSessionCommand as jest.Mock).
|
* (e.g. BackendService.sendSessionCommand as vi.Mock).
|
||||||
* @param optsArgIndex - Index of the options argument in the mock call.
|
* @param optsArgIndex - Index of the options argument in the mock call.
|
||||||
* Defaults to 2 (commandName, params, options).
|
* Defaults to 2 (commandName, params, options).
|
||||||
* Use 3 for sendRoomCommand (roomId, commandName, params, options).
|
* Use 3 for sendRoomCommand (roomId, commandName, params, options).
|
||||||
*/
|
*/
|
||||||
export function makeCallbackHelpers(mockFn: jest.Mock, optsArgIndex = 2) {
|
export function makeCallbackHelpers(mockFn: vi.Mock, optsArgIndex = 2) {
|
||||||
function getLastSendOpts() {
|
function getLastSendOpts() {
|
||||||
const calls = mockFn.mock.calls;
|
const calls = mockFn.mock.calls;
|
||||||
return calls[calls.length - 1]?.[optsArgIndex];
|
return calls[calls.length - 1]?.[optsArgIndex];
|
||||||
|
|
|
||||||
|
|
@ -6,18 +6,18 @@
|
||||||
|
|
||||||
/** Builds a minimal mock of ProtoController.root */
|
/** Builds a minimal mock of ProtoController.root */
|
||||||
export function makeMockProtoRoot() {
|
export function makeMockProtoRoot() {
|
||||||
const encode = { finish: jest.fn().mockReturnValue(new Uint8Array()) };
|
const encode = { finish: vi.fn().mockReturnValue(new Uint8Array()) };
|
||||||
return {
|
return {
|
||||||
CommandContainer: {
|
CommandContainer: {
|
||||||
create: jest.fn(args => ({ ...args })),
|
create: vi.fn(args => ({ ...args })),
|
||||||
encode: jest.fn().mockReturnValue(encode),
|
encode: vi.fn().mockReturnValue(encode),
|
||||||
},
|
},
|
||||||
SessionCommand: { create: jest.fn(args => ({ ...args })) },
|
SessionCommand: { create: vi.fn(args => ({ ...args })) },
|
||||||
RoomCommand: { create: jest.fn(args => ({ ...args })) },
|
RoomCommand: { create: vi.fn(args => ({ ...args })) },
|
||||||
ModeratorCommand: { create: jest.fn(args => ({ ...args })) },
|
ModeratorCommand: { create: vi.fn(args => ({ ...args })) },
|
||||||
AdminCommand: { create: jest.fn(args => ({ ...args })) },
|
AdminCommand: { create: vi.fn(args => ({ ...args })) },
|
||||||
ServerMessage: {
|
ServerMessage: {
|
||||||
decode: jest.fn(),
|
decode: vi.fn(),
|
||||||
MessageType: {
|
MessageType: {
|
||||||
RESPONSE: 'RESPONSE',
|
RESPONSE: 'RESPONSE',
|
||||||
ROOM_EVENT: 'ROOM_EVENT',
|
ROOM_EVENT: 'ROOM_EVENT',
|
||||||
|
|
@ -52,8 +52,8 @@ export function makeMockProtoRoot() {
|
||||||
/** Builds a mock WebSocket instance */
|
/** Builds a mock WebSocket instance */
|
||||||
export function makeMockWebSocketInstance() {
|
export function makeMockWebSocketInstance() {
|
||||||
return {
|
return {
|
||||||
send: jest.fn(),
|
send: vi.fn(),
|
||||||
close: jest.fn(),
|
close: vi.fn(),
|
||||||
readyState: WebSocket.OPEN,
|
readyState: WebSocket.OPEN,
|
||||||
binaryType: '' as BinaryType,
|
binaryType: '' as BinaryType,
|
||||||
onopen: null as any,
|
onopen: null as any,
|
||||||
|
|
@ -66,7 +66,7 @@ export function makeMockWebSocketInstance() {
|
||||||
/** Installs a mock WebSocket constructor on global. Returns the mock instance. */
|
/** Installs a mock WebSocket constructor on global. Returns the mock instance. */
|
||||||
export function installMockWebSocket() {
|
export function installMockWebSocket() {
|
||||||
const mockInstance = makeMockWebSocketInstance();
|
const mockInstance = makeMockWebSocketInstance();
|
||||||
const MockWS = jest.fn(() => mockInstance) as any;
|
const MockWS = vi.fn(() => mockInstance) as any;
|
||||||
MockWS.OPEN = 1;
|
MockWS.OPEN = 1;
|
||||||
MockWS.CLOSED = 3;
|
MockWS.CLOSED = 3;
|
||||||
(global as any).WebSocket = MockWS;
|
(global as any).WebSocket = MockWS;
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
/**
|
/**
|
||||||
* Shared mock shape factories for session command specs.
|
* Shared mock shape factories for session command specs.
|
||||||
*
|
*
|
||||||
* Usage inside jest.mock() factory callbacks (require is used because
|
* Usage inside vi.mock() factory callbacks (require is used because
|
||||||
* jest.mock() is hoisted above imports):
|
* vi.mock() is hoisted above imports):
|
||||||
*
|
*
|
||||||
* jest.mock('../../WebClient', () => {
|
* vi.mock('../../WebClient', () => {
|
||||||
* const { makeWebClientMock } = require('../../__mocks__/sessionCommandMocks');
|
* const { makeWebClientMock } = require('../../__mocks__/sessionCommandMocks');
|
||||||
* return { __esModule: true, default: makeWebClientMock() };
|
* return { __esModule: true, default: makeWebClientMock() };
|
||||||
* });
|
* });
|
||||||
|
|
@ -13,10 +13,10 @@
|
||||||
/** Superset WebClient mock — covers all properties used across both session spec files. */
|
/** Superset WebClient mock — covers all properties used across both session spec files. */
|
||||||
export function makeWebClientMock() {
|
export function makeWebClientMock() {
|
||||||
return {
|
return {
|
||||||
connect: jest.fn(),
|
connect: vi.fn(),
|
||||||
testConnect: jest.fn(),
|
testConnect: vi.fn(),
|
||||||
disconnect: jest.fn(),
|
disconnect: vi.fn(),
|
||||||
updateStatus: jest.fn(),
|
updateStatus: vi.fn(),
|
||||||
clientConfig: { clientid: 'webatrice', clientver: '1.0', clientfeatures: [] },
|
clientConfig: { clientid: 'webatrice', clientver: '1.0', clientfeatures: [] },
|
||||||
options: {},
|
options: {},
|
||||||
protocolVersion: 14,
|
protocolVersion: 14,
|
||||||
|
|
@ -60,72 +60,72 @@ export function makeProtoControllerRootMock() {
|
||||||
/** Utils mock with unified return values. */
|
/** Utils mock with unified return values. */
|
||||||
export function makeUtilsMock() {
|
export function makeUtilsMock() {
|
||||||
return {
|
return {
|
||||||
hashPassword: jest.fn().mockReturnValue('hashed_pw'),
|
hashPassword: vi.fn().mockReturnValue('hashed_pw'),
|
||||||
generateSalt: jest.fn().mockReturnValue('randSalt'),
|
generateSalt: vi.fn().mockReturnValue('randSalt'),
|
||||||
passwordSaltSupported: jest.fn().mockReturnValue(0),
|
passwordSaltSupported: vi.fn().mockReturnValue(0),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Superset SessionPersistence mock — covers all methods used across both session spec files. */
|
/** Superset SessionPersistence mock — covers all methods used across both session spec files. */
|
||||||
export function makeSessionPersistenceMock() {
|
export function makeSessionPersistenceMock() {
|
||||||
return {
|
return {
|
||||||
loginSuccessful: jest.fn(),
|
loginSuccessful: vi.fn(),
|
||||||
loginFailed: jest.fn(),
|
loginFailed: vi.fn(),
|
||||||
updateBuddyList: jest.fn(),
|
updateBuddyList: vi.fn(),
|
||||||
updateIgnoreList: jest.fn(),
|
updateIgnoreList: vi.fn(),
|
||||||
updateUser: jest.fn(),
|
updateUser: vi.fn(),
|
||||||
updateUsers: jest.fn(),
|
updateUsers: vi.fn(),
|
||||||
accountAwaitingActivation: jest.fn(),
|
accountAwaitingActivation: vi.fn(),
|
||||||
accountActivationSuccess: jest.fn(),
|
accountActivationSuccess: vi.fn(),
|
||||||
accountActivationFailed: jest.fn(),
|
accountActivationFailed: vi.fn(),
|
||||||
updateStatus: jest.fn(),
|
updateStatus: vi.fn(),
|
||||||
addToList: jest.fn(),
|
addToList: vi.fn(),
|
||||||
removeFromList: jest.fn(),
|
removeFromList: vi.fn(),
|
||||||
deleteServerDeck: jest.fn(),
|
deleteServerDeck: vi.fn(),
|
||||||
deleteServerDeckDir: jest.fn(),
|
deleteServerDeckDir: vi.fn(),
|
||||||
updateServerDecks: jest.fn(),
|
updateServerDecks: vi.fn(),
|
||||||
uploadServerDeck: jest.fn(),
|
uploadServerDeck: vi.fn(),
|
||||||
createServerDeckDir: jest.fn(),
|
createServerDeckDir: vi.fn(),
|
||||||
getGamesOfUser: jest.fn(),
|
getGamesOfUser: vi.fn(),
|
||||||
getUserInfo: jest.fn(),
|
getUserInfo: vi.fn(),
|
||||||
accountPasswordChange: jest.fn(),
|
accountPasswordChange: vi.fn(),
|
||||||
accountEditChanged: jest.fn(),
|
accountEditChanged: vi.fn(),
|
||||||
accountImageChanged: jest.fn(),
|
accountImageChanged: vi.fn(),
|
||||||
replayList: jest.fn(),
|
replayList: vi.fn(),
|
||||||
replayAdded: jest.fn(),
|
replayAdded: vi.fn(),
|
||||||
replayModifyMatch: jest.fn(),
|
replayModifyMatch: vi.fn(),
|
||||||
replayDeleteMatch: jest.fn(),
|
replayDeleteMatch: vi.fn(),
|
||||||
resetPasswordChallenge: jest.fn(),
|
resetPasswordChallenge: vi.fn(),
|
||||||
resetPassword: jest.fn(),
|
resetPassword: vi.fn(),
|
||||||
resetPasswordFailed: jest.fn(),
|
resetPasswordFailed: vi.fn(),
|
||||||
resetPasswordSuccess: jest.fn(),
|
resetPasswordSuccess: vi.fn(),
|
||||||
registrationFailed: jest.fn(),
|
registrationFailed: vi.fn(),
|
||||||
registrationSuccess: jest.fn(),
|
registrationSuccess: vi.fn(),
|
||||||
registrationUserNameError: jest.fn(),
|
registrationUserNameError: vi.fn(),
|
||||||
registrationPasswordError: jest.fn(),
|
registrationPasswordError: vi.fn(),
|
||||||
registrationEmailError: jest.fn(),
|
registrationEmailError: vi.fn(),
|
||||||
registrationRequiresEmail: jest.fn(),
|
registrationRequiresEmail: vi.fn(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Session barrel mock — pure jest.fn() map for all cross-command calls.
|
* Session barrel mock — pure vi.fn() map for all cross-command calls.
|
||||||
* Used as-is by sessionCommands-complex.spec.ts, or spread over jest.requireActual
|
* Used as-is by sessionCommands-complex.spec.ts, or spread over jest.requireActual
|
||||||
* by sessionCommands-simple.spec.ts to preserve real implementations for
|
* by sessionCommands-simple.spec.ts to preserve real implementations for
|
||||||
* the commands under test.
|
* the commands under test.
|
||||||
*/
|
*/
|
||||||
export function makeSessionBarrelMock() {
|
export function makeSessionBarrelMock() {
|
||||||
return {
|
return {
|
||||||
login: jest.fn(),
|
login: vi.fn(),
|
||||||
register: jest.fn(),
|
register: vi.fn(),
|
||||||
activate: jest.fn(),
|
activate: vi.fn(),
|
||||||
forgotPasswordReset: jest.fn(),
|
forgotPasswordReset: vi.fn(),
|
||||||
forgotPasswordRequest: jest.fn(),
|
forgotPasswordRequest: vi.fn(),
|
||||||
forgotPasswordChallenge: jest.fn(),
|
forgotPasswordChallenge: vi.fn(),
|
||||||
requestPasswordSalt: jest.fn(),
|
requestPasswordSalt: vi.fn(),
|
||||||
listUsers: jest.fn(),
|
listUsers: vi.fn(),
|
||||||
listRooms: jest.fn(),
|
listRooms: vi.fn(),
|
||||||
updateStatus: jest.fn(),
|
updateStatus: vi.fn(),
|
||||||
disconnect: jest.fn(),
|
disconnect: vi.fn(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,36 @@
|
||||||
jest.mock('../../services/BackendService', () => ({
|
vi.mock('../../services/BackendService', () => ({
|
||||||
BackendService: {
|
BackendService: {
|
||||||
sendAdminCommand: jest.fn(),
|
sendAdminCommand: vi.fn(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../../persistence', () => ({
|
vi.mock('../../persistence', () => ({
|
||||||
AdminPersistence: {
|
AdminPersistence: {
|
||||||
adjustMod: jest.fn(),
|
adjustMod: vi.fn(),
|
||||||
reloadConfig: jest.fn(),
|
reloadConfig: vi.fn(),
|
||||||
shutdownServer: jest.fn(),
|
shutdownServer: vi.fn(),
|
||||||
updateServerMessage: jest.fn(),
|
updateServerMessage: vi.fn(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import { makeCallbackHelpers } from '../../__mocks__/callbackHelpers';
|
import { makeCallbackHelpers } from '../../__mocks__/callbackHelpers';
|
||||||
import { BackendService } from '../../services/BackendService';
|
import { BackendService } from '../../services/BackendService';
|
||||||
import { AdminPersistence } from '../../persistence';
|
import { AdminPersistence } from '../../persistence';
|
||||||
|
import { adjustMod } from './adjustMod';
|
||||||
|
import { reloadConfig } from './reloadConfig';
|
||||||
|
import { shutdownServer } from './shutdownServer';
|
||||||
|
import { updateServerMessage } from './updateServerMessage';
|
||||||
|
|
||||||
const { getLastSendOpts, invokeOnSuccess } = makeCallbackHelpers(
|
const { getLastSendOpts, invokeOnSuccess } = makeCallbackHelpers(
|
||||||
BackendService.sendAdminCommand as jest.Mock
|
BackendService.sendAdminCommand as vi.Mock
|
||||||
);
|
);
|
||||||
|
|
||||||
beforeEach(() => jest.clearAllMocks());
|
beforeEach(() => vi.clearAllMocks());
|
||||||
|
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
// adjustMod
|
// adjustMod
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('adjustMod', () => {
|
describe('adjustMod', () => {
|
||||||
const { adjustMod } = jest.requireActual('./adjustMod');
|
|
||||||
|
|
||||||
it('calls sendAdminCommand with Command_AdjustMod', () => {
|
it('calls sendAdminCommand with Command_AdjustMod', () => {
|
||||||
adjustMod('alice', true, false);
|
adjustMod('alice', true, false);
|
||||||
|
|
@ -49,7 +52,6 @@ describe('adjustMod', () => {
|
||||||
// reloadConfig
|
// reloadConfig
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('reloadConfig', () => {
|
describe('reloadConfig', () => {
|
||||||
const { reloadConfig } = jest.requireActual('./reloadConfig');
|
|
||||||
|
|
||||||
it('calls sendAdminCommand with Command_ReloadConfig', () => {
|
it('calls sendAdminCommand with Command_ReloadConfig', () => {
|
||||||
reloadConfig();
|
reloadConfig();
|
||||||
|
|
@ -67,7 +69,6 @@ describe('reloadConfig', () => {
|
||||||
// shutdownServer
|
// shutdownServer
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('shutdownServer', () => {
|
describe('shutdownServer', () => {
|
||||||
const { shutdownServer } = jest.requireActual('./shutdownServer');
|
|
||||||
|
|
||||||
it('calls sendAdminCommand with Command_ShutdownServer', () => {
|
it('calls sendAdminCommand with Command_ShutdownServer', () => {
|
||||||
shutdownServer('maintenance', 10);
|
shutdownServer('maintenance', 10);
|
||||||
|
|
@ -89,7 +90,6 @@ describe('shutdownServer', () => {
|
||||||
// updateServerMessage
|
// updateServerMessage
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('updateServerMessage', () => {
|
describe('updateServerMessage', () => {
|
||||||
const { updateServerMessage } = jest.requireActual('./updateServerMessage');
|
|
||||||
|
|
||||||
it('calls sendAdminCommand with Command_UpdateServerMessage', () => {
|
it('calls sendAdminCommand with Command_UpdateServerMessage', () => {
|
||||||
updateServerMessage();
|
updateServerMessage();
|
||||||
|
|
|
||||||
|
|
@ -33,15 +33,15 @@ import { undoDraw } from './undoDraw';
|
||||||
import { unconcede } from './unconcede';
|
import { unconcede } from './unconcede';
|
||||||
import { judge } from './judge';
|
import { judge } from './judge';
|
||||||
|
|
||||||
jest.mock('../../services/BackendService', () => ({
|
vi.mock('../../services/BackendService', () => ({
|
||||||
BackendService: { sendGameCommand: jest.fn() },
|
BackendService: { sendGameCommand: vi.fn() },
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const gameId = 1;
|
const gameId = 1;
|
||||||
const params = {} as any;
|
const params = {} as any;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
(BackendService.sendGameCommand as jest.Mock).mockClear();
|
(BackendService.sendGameCommand as vi.Mock).mockClear();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Game commands — delegate to BackendService.sendGameCommand', () => {
|
describe('Game commands — delegate to BackendService.sendGameCommand', () => {
|
||||||
|
|
|
||||||
|
|
@ -1,39 +1,48 @@
|
||||||
jest.mock('../../services/BackendService', () => ({
|
vi.mock('../../services/BackendService', () => ({
|
||||||
BackendService: {
|
BackendService: {
|
||||||
sendModeratorCommand: jest.fn(),
|
sendModeratorCommand: vi.fn(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../../persistence', () => ({
|
vi.mock('../../persistence', () => ({
|
||||||
ModeratorPersistence: {
|
ModeratorPersistence: {
|
||||||
banFromServer: jest.fn(),
|
banFromServer: vi.fn(),
|
||||||
forceActivateUser: jest.fn(),
|
forceActivateUser: vi.fn(),
|
||||||
getAdminNotes: jest.fn(),
|
getAdminNotes: vi.fn(),
|
||||||
banHistory: jest.fn(),
|
banHistory: vi.fn(),
|
||||||
warnHistory: jest.fn(),
|
warnHistory: vi.fn(),
|
||||||
warnListOptions: jest.fn(),
|
warnListOptions: vi.fn(),
|
||||||
grantReplayAccess: jest.fn(),
|
grantReplayAccess: vi.fn(),
|
||||||
updateAdminNotes: jest.fn(),
|
updateAdminNotes: vi.fn(),
|
||||||
viewLogs: jest.fn(),
|
viewLogs: vi.fn(),
|
||||||
warnUser: jest.fn(),
|
warnUser: vi.fn(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import { makeCallbackHelpers } from '../../__mocks__/callbackHelpers';
|
import { makeCallbackHelpers } from '../../__mocks__/callbackHelpers';
|
||||||
import { BackendService } from '../../services/BackendService';
|
import { BackendService } from '../../services/BackendService';
|
||||||
import { ModeratorPersistence } from '../../persistence';
|
import { ModeratorPersistence } from '../../persistence';
|
||||||
|
import { banFromServer } from './banFromServer';
|
||||||
|
import { forceActivateUser } from './forceActivateUser';
|
||||||
|
import { getAdminNotes } from './getAdminNotes';
|
||||||
|
import { getBanHistory } from './getBanHistory';
|
||||||
|
import { getWarnHistory } from './getWarnHistory';
|
||||||
|
import { getWarnList } from './getWarnList';
|
||||||
|
import { grantReplayAccess } from './grantReplayAccess';
|
||||||
|
import { updateAdminNotes } from './updateAdminNotes';
|
||||||
|
import { viewLogHistory } from './viewLogHistory';
|
||||||
|
import { warnUser } from './warnUser';
|
||||||
|
|
||||||
const { getLastSendOpts, invokeOnSuccess } = makeCallbackHelpers(
|
const { getLastSendOpts, invokeOnSuccess } = makeCallbackHelpers(
|
||||||
BackendService.sendModeratorCommand as jest.Mock
|
BackendService.sendModeratorCommand as vi.Mock
|
||||||
);
|
);
|
||||||
|
|
||||||
beforeEach(() => jest.clearAllMocks());
|
beforeEach(() => vi.clearAllMocks());
|
||||||
|
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
// banFromServer
|
// banFromServer
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('banFromServer', () => {
|
describe('banFromServer', () => {
|
||||||
const { banFromServer } = jest.requireActual('./banFromServer');
|
|
||||||
|
|
||||||
it('calls sendModeratorCommand with Command_BanFromServer', () => {
|
it('calls sendModeratorCommand with Command_BanFromServer', () => {
|
||||||
banFromServer(30, 'alice', '1.2.3.4', 'reason', 'visible', 'cid', 1);
|
banFromServer(30, 'alice', '1.2.3.4', 'reason', 'visible', 'cid', 1);
|
||||||
|
|
@ -55,7 +64,6 @@ describe('banFromServer', () => {
|
||||||
// forceActivateUser
|
// forceActivateUser
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('forceActivateUser', () => {
|
describe('forceActivateUser', () => {
|
||||||
const { forceActivateUser } = jest.requireActual('./forceActivateUser');
|
|
||||||
|
|
||||||
it('calls sendModeratorCommand with Command_ForceActivateUser', () => {
|
it('calls sendModeratorCommand with Command_ForceActivateUser', () => {
|
||||||
forceActivateUser('alice', 'mod1');
|
forceActivateUser('alice', 'mod1');
|
||||||
|
|
@ -73,7 +81,6 @@ describe('forceActivateUser', () => {
|
||||||
// getAdminNotes
|
// getAdminNotes
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('getAdminNotes', () => {
|
describe('getAdminNotes', () => {
|
||||||
const { getAdminNotes } = jest.requireActual('./getAdminNotes');
|
|
||||||
|
|
||||||
it('calls sendModeratorCommand with Command_GetAdminNotes', () => {
|
it('calls sendModeratorCommand with Command_GetAdminNotes', () => {
|
||||||
getAdminNotes('alice');
|
getAdminNotes('alice');
|
||||||
|
|
@ -96,7 +103,6 @@ describe('getAdminNotes', () => {
|
||||||
// getBanHistory
|
// getBanHistory
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('getBanHistory', () => {
|
describe('getBanHistory', () => {
|
||||||
const { getBanHistory } = jest.requireActual('./getBanHistory');
|
|
||||||
|
|
||||||
it('calls sendModeratorCommand with Command_GetBanHistory', () => {
|
it('calls sendModeratorCommand with Command_GetBanHistory', () => {
|
||||||
getBanHistory('alice');
|
getBanHistory('alice');
|
||||||
|
|
@ -119,7 +125,6 @@ describe('getBanHistory', () => {
|
||||||
// getWarnHistory
|
// getWarnHistory
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('getWarnHistory', () => {
|
describe('getWarnHistory', () => {
|
||||||
const { getWarnHistory } = jest.requireActual('./getWarnHistory');
|
|
||||||
|
|
||||||
it('calls sendModeratorCommand with Command_GetWarnHistory', () => {
|
it('calls sendModeratorCommand with Command_GetWarnHistory', () => {
|
||||||
getWarnHistory('alice');
|
getWarnHistory('alice');
|
||||||
|
|
@ -142,7 +147,6 @@ describe('getWarnHistory', () => {
|
||||||
// getWarnList
|
// getWarnList
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('getWarnList', () => {
|
describe('getWarnList', () => {
|
||||||
const { getWarnList } = jest.requireActual('./getWarnList');
|
|
||||||
|
|
||||||
it('calls sendModeratorCommand with Command_GetWarnList', () => {
|
it('calls sendModeratorCommand with Command_GetWarnList', () => {
|
||||||
getWarnList('mod1', 'alice', 'US');
|
getWarnList('mod1', 'alice', 'US');
|
||||||
|
|
@ -165,7 +169,6 @@ describe('getWarnList', () => {
|
||||||
// grantReplayAccess
|
// grantReplayAccess
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('grantReplayAccess', () => {
|
describe('grantReplayAccess', () => {
|
||||||
const { grantReplayAccess } = jest.requireActual('./grantReplayAccess');
|
|
||||||
|
|
||||||
it('calls sendModeratorCommand with Command_GrantReplayAccess', () => {
|
it('calls sendModeratorCommand with Command_GrantReplayAccess', () => {
|
||||||
grantReplayAccess(10, 'mod1');
|
grantReplayAccess(10, 'mod1');
|
||||||
|
|
@ -183,7 +186,6 @@ describe('grantReplayAccess', () => {
|
||||||
// updateAdminNotes
|
// updateAdminNotes
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('updateAdminNotes', () => {
|
describe('updateAdminNotes', () => {
|
||||||
const { updateAdminNotes } = jest.requireActual('./updateAdminNotes');
|
|
||||||
|
|
||||||
it('calls sendModeratorCommand with Command_UpdateAdminNotes', () => {
|
it('calls sendModeratorCommand with Command_UpdateAdminNotes', () => {
|
||||||
updateAdminNotes('alice', 'new notes');
|
updateAdminNotes('alice', 'new notes');
|
||||||
|
|
@ -201,7 +203,6 @@ describe('updateAdminNotes', () => {
|
||||||
// viewLogHistory
|
// viewLogHistory
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('viewLogHistory', () => {
|
describe('viewLogHistory', () => {
|
||||||
const { viewLogHistory } = jest.requireActual('./viewLogHistory');
|
|
||||||
|
|
||||||
it('calls sendModeratorCommand with Command_ViewLogHistory', () => {
|
it('calls sendModeratorCommand with Command_ViewLogHistory', () => {
|
||||||
viewLogHistory({ filters: 'all' } as any);
|
viewLogHistory({ filters: 'all' } as any);
|
||||||
|
|
@ -224,7 +225,6 @@ describe('viewLogHistory', () => {
|
||||||
// warnUser
|
// warnUser
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('warnUser', () => {
|
describe('warnUser', () => {
|
||||||
const { warnUser } = jest.requireActual('./warnUser');
|
|
||||||
|
|
||||||
it('calls sendModeratorCommand with Command_WarnUser', () => {
|
it('calls sendModeratorCommand with Command_WarnUser', () => {
|
||||||
warnUser('alice', 'bad behavior', 'cid');
|
warnUser('alice', 'bad behavior', 'cid');
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,37 @@
|
||||||
jest.mock('../../services/BackendService', () => ({
|
vi.mock('../../services/BackendService', () => ({
|
||||||
BackendService: {
|
BackendService: {
|
||||||
sendRoomCommand: jest.fn(),
|
sendRoomCommand: vi.fn(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../../persistence', () => ({
|
vi.mock('../../persistence', () => ({
|
||||||
RoomPersistence: {
|
RoomPersistence: {
|
||||||
gameCreated: jest.fn(),
|
gameCreated: vi.fn(),
|
||||||
joinedGame: jest.fn(),
|
joinedGame: vi.fn(),
|
||||||
leaveRoom: jest.fn(),
|
leaveRoom: vi.fn(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import { makeCallbackHelpers } from '../../__mocks__/callbackHelpers';
|
import { makeCallbackHelpers } from '../../__mocks__/callbackHelpers';
|
||||||
import { BackendService } from '../../services/BackendService';
|
import { BackendService } from '../../services/BackendService';
|
||||||
import { RoomPersistence } from '../../persistence';
|
import { RoomPersistence } from '../../persistence';
|
||||||
|
import { createGame } from './createGame';
|
||||||
|
import { joinGame } from './joinGame';
|
||||||
|
import { leaveRoom } from './leaveRoom';
|
||||||
|
import { roomSay } from './roomSay';
|
||||||
|
|
||||||
const { getLastSendOpts, invokeOnSuccess } = makeCallbackHelpers(
|
const { getLastSendOpts, invokeOnSuccess } = makeCallbackHelpers(
|
||||||
BackendService.sendRoomCommand as jest.Mock,
|
BackendService.sendRoomCommand as vi.Mock,
|
||||||
// sendRoomCommand(roomId, commandName, params, options) — options at index 3
|
// sendRoomCommand(roomId, commandName, params, options) — options at index 3
|
||||||
3
|
3
|
||||||
);
|
);
|
||||||
|
|
||||||
beforeEach(() => jest.clearAllMocks());
|
beforeEach(() => vi.clearAllMocks());
|
||||||
|
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
// createGame
|
// createGame
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('createGame', () => {
|
describe('createGame', () => {
|
||||||
const { createGame } = jest.requireActual('./createGame');
|
|
||||||
|
|
||||||
it('calls sendRoomCommand with Command_CreateGame', () => {
|
it('calls sendRoomCommand with Command_CreateGame', () => {
|
||||||
createGame(5, { maxPlayers: 4 } as any);
|
createGame(5, { maxPlayers: 4 } as any);
|
||||||
|
|
@ -46,7 +49,6 @@ describe('createGame', () => {
|
||||||
// joinGame
|
// joinGame
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('joinGame', () => {
|
describe('joinGame', () => {
|
||||||
const { joinGame } = jest.requireActual('./joinGame');
|
|
||||||
|
|
||||||
it('calls sendRoomCommand with Command_JoinGame', () => {
|
it('calls sendRoomCommand with Command_JoinGame', () => {
|
||||||
joinGame(7, { gameId: 42, password: '' } as any);
|
joinGame(7, { gameId: 42, password: '' } as any);
|
||||||
|
|
@ -64,7 +66,6 @@ describe('joinGame', () => {
|
||||||
// leaveRoom
|
// leaveRoom
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('leaveRoom', () => {
|
describe('leaveRoom', () => {
|
||||||
const { leaveRoom } = jest.requireActual('./leaveRoom');
|
|
||||||
|
|
||||||
it('calls sendRoomCommand with Command_LeaveRoom', () => {
|
it('calls sendRoomCommand with Command_LeaveRoom', () => {
|
||||||
leaveRoom(3);
|
leaveRoom(3);
|
||||||
|
|
@ -82,7 +83,6 @@ describe('leaveRoom', () => {
|
||||||
// roomSay
|
// roomSay
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('roomSay', () => {
|
describe('roomSay', () => {
|
||||||
const { roomSay } = jest.requireActual('./roomSay');
|
|
||||||
|
|
||||||
it('calls sendRoomCommand with trimmed message', () => {
|
it('calls sendRoomCommand with trimmed message', () => {
|
||||||
roomSay(2, ' hello ');
|
roomSay(2, ' hello ');
|
||||||
|
|
|
||||||
|
|
@ -1,38 +1,38 @@
|
||||||
// Tests for complex session commands that call webClient directly
|
// Tests for complex session commands that call webClient directly
|
||||||
// or have multiple branching callbacks.
|
// or have multiple branching callbacks.
|
||||||
|
|
||||||
jest.mock('../../services/BackendService', () => ({
|
vi.mock('../../services/BackendService', () => ({
|
||||||
BackendService: {
|
BackendService: {
|
||||||
sendSessionCommand: jest.fn(),
|
sendSessionCommand: vi.fn(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../../persistence', () => {
|
vi.mock('../../persistence', async () => {
|
||||||
const { makeSessionPersistenceMock } = require('../../__mocks__/sessionCommandMocks');
|
const { makeSessionPersistenceMock } = await import('../../__mocks__/sessionCommandMocks');
|
||||||
return {
|
return {
|
||||||
SessionPersistence: makeSessionPersistenceMock(),
|
SessionPersistence: makeSessionPersistenceMock(),
|
||||||
RoomPersistence: {},
|
RoomPersistence: {},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
jest.mock('../../WebClient', () => {
|
vi.mock('../../WebClient', async () => {
|
||||||
const { makeWebClientMock } = require('../../__mocks__/sessionCommandMocks');
|
const { makeWebClientMock } = await import('../../__mocks__/sessionCommandMocks');
|
||||||
return { __esModule: true, default: makeWebClientMock() };
|
return { __esModule: true, default: makeWebClientMock() };
|
||||||
});
|
});
|
||||||
|
|
||||||
jest.mock('../../services/ProtoController', () => {
|
vi.mock('../../services/ProtoController', async () => {
|
||||||
const { makeProtoControllerRootMock } = require('../../__mocks__/sessionCommandMocks');
|
const { makeProtoControllerRootMock } = await import('../../__mocks__/sessionCommandMocks');
|
||||||
return { ProtoController: { root: makeProtoControllerRootMock() } };
|
return { ProtoController: { root: makeProtoControllerRootMock() } };
|
||||||
});
|
});
|
||||||
|
|
||||||
jest.mock('../../utils', () => {
|
vi.mock('../../utils', async () => {
|
||||||
const { makeUtilsMock } = require('../../__mocks__/sessionCommandMocks');
|
const { makeUtilsMock } = await import('../../__mocks__/sessionCommandMocks');
|
||||||
return makeUtilsMock();
|
return makeUtilsMock();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Intercept all re-exported commands to avoid recursive real invocations
|
// Intercept all re-exported commands to avoid recursive real invocations
|
||||||
jest.mock('./', () => {
|
vi.mock('./', async () => {
|
||||||
const { makeSessionBarrelMock } = require('../../__mocks__/sessionCommandMocks');
|
const { makeSessionBarrelMock } = await import('../../__mocks__/sessionCommandMocks');
|
||||||
return makeSessionBarrelMock();
|
return makeSessionBarrelMock();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -43,23 +43,31 @@ import webClient from '../../WebClient';
|
||||||
import * as SessionIndexMocks from './';
|
import * as SessionIndexMocks from './';
|
||||||
import { StatusEnum, WebSocketConnectReason } from 'types';
|
import { StatusEnum, WebSocketConnectReason } from 'types';
|
||||||
import { hashPassword, generateSalt, passwordSaltSupported } from '../../utils';
|
import { hashPassword, generateSalt, passwordSaltSupported } from '../../utils';
|
||||||
|
import { connect } from './connect';
|
||||||
|
import { updateStatus } from './updateStatus';
|
||||||
|
import { login } from './login';
|
||||||
|
import { register } from './register';
|
||||||
|
import { activate } from './activate';
|
||||||
|
import { forgotPasswordChallenge } from './forgotPasswordChallenge';
|
||||||
|
import { forgotPasswordRequest } from './forgotPasswordRequest';
|
||||||
|
import { forgotPasswordReset } from './forgotPasswordReset';
|
||||||
|
import { requestPasswordSalt } from './requestPasswordSalt';
|
||||||
|
|
||||||
const { getLastSendOpts, invokeOnSuccess, invokeResponseCode, invokeOnError } = makeCallbackHelpers(
|
const { getLastSendOpts, invokeOnSuccess, invokeResponseCode, invokeOnError } = makeCallbackHelpers(
|
||||||
BackendService.sendSessionCommand as jest.Mock
|
BackendService.sendSessionCommand as vi.Mock
|
||||||
);
|
);
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
(hashPassword as jest.Mock).mockReturnValue('hashed_pw');
|
(hashPassword as vi.Mock).mockReturnValue('hashed_pw');
|
||||||
(generateSalt as jest.Mock).mockReturnValue('randSalt');
|
(generateSalt as vi.Mock).mockReturnValue('randSalt');
|
||||||
(passwordSaltSupported as jest.Mock).mockReturnValue(0);
|
(passwordSaltSupported as vi.Mock).mockReturnValue(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
// connect.ts
|
// connect.ts
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('connect', () => {
|
describe('connect', () => {
|
||||||
const { connect } = jest.requireActual('./connect');
|
|
||||||
|
|
||||||
it('calls updateStatus CONNECTING for LOGIN reason', () => {
|
it('calls updateStatus CONNECTING for LOGIN reason', () => {
|
||||||
connect({ host: 'h', port: 1 } as any, WebSocketConnectReason.LOGIN);
|
connect({ host: 'h', port: 1 } as any, WebSocketConnectReason.LOGIN);
|
||||||
|
|
@ -108,7 +116,6 @@ describe('connect', () => {
|
||||||
// updateStatus.ts
|
// updateStatus.ts
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('updateStatus', () => {
|
describe('updateStatus', () => {
|
||||||
const { updateStatus } = jest.requireActual('./updateStatus');
|
|
||||||
|
|
||||||
it('calls SessionPersistence.updateStatus and webClient.updateStatus', () => {
|
it('calls SessionPersistence.updateStatus and webClient.updateStatus', () => {
|
||||||
updateStatus(StatusEnum.CONNECTED, 'OK');
|
updateStatus(StatusEnum.CONNECTED, 'OK');
|
||||||
|
|
@ -121,7 +128,6 @@ describe('updateStatus', () => {
|
||||||
// login.ts
|
// login.ts
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('login', () => {
|
describe('login', () => {
|
||||||
const { login } = jest.requireActual('./login');
|
|
||||||
|
|
||||||
it('sends Command_Login with plain password when no salt', () => {
|
it('sends Command_Login with plain password when no salt', () => {
|
||||||
login({ userName: 'alice' } as any, 'pw');
|
login({ userName: 'alice' } as any, 'pw');
|
||||||
|
|
@ -167,7 +173,7 @@ describe('login', () => {
|
||||||
login({ userName: 'alice' } as any, 'secret');
|
login({ userName: 'alice' } as any, 'secret');
|
||||||
const loginResp = { buddyList: [], ignoreList: [], userInfo: { name: 'alice' } };
|
const loginResp = { buddyList: [], ignoreList: [], userInfo: { name: 'alice' } };
|
||||||
invokeOnSuccess(loginResp, { responseCode: 0, '.Response_Login.ext': loginResp });
|
invokeOnSuccess(loginResp, { responseCode: 0, '.Response_Login.ext': loginResp });
|
||||||
const calledWith = (SessionPersistence.loginSuccessful as jest.Mock).mock.calls[0][0];
|
const calledWith = (SessionPersistence.loginSuccessful as vi.Mock).mock.calls[0][0];
|
||||||
expect(calledWith).not.toHaveProperty('password');
|
expect(calledWith).not.toHaveProperty('password');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -175,7 +181,7 @@ describe('login', () => {
|
||||||
login({ userName: 'alice' } as any, 'pw', 'salt');
|
login({ userName: 'alice' } as any, 'pw', 'salt');
|
||||||
const loginResp = { buddyList: [], ignoreList: [], userInfo: { name: 'alice' } };
|
const loginResp = { buddyList: [], ignoreList: [], userInfo: { name: 'alice' } };
|
||||||
invokeOnSuccess(loginResp, { responseCode: 0, '.Response_Login.ext': loginResp });
|
invokeOnSuccess(loginResp, { responseCode: 0, '.Response_Login.ext': loginResp });
|
||||||
const calledWith = (SessionPersistence.loginSuccessful as jest.Mock).mock.calls[0][0];
|
const calledWith = (SessionPersistence.loginSuccessful as vi.Mock).mock.calls[0][0];
|
||||||
expect(calledWith).toHaveProperty('hashedPassword', 'hashed_pw');
|
expect(calledWith).toHaveProperty('hashedPassword', 'hashed_pw');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -248,7 +254,6 @@ describe('login', () => {
|
||||||
// register.ts
|
// register.ts
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('register', () => {
|
describe('register', () => {
|
||||||
const { register } = jest.requireActual('./register');
|
|
||||||
|
|
||||||
it('sends Command_Register with plain password when no salt', () => {
|
it('sends Command_Register with plain password when no salt', () => {
|
||||||
register({ userName: 'alice', email: 'a@b.com', country: 'US', realName: 'Al' } as any, 'pw');
|
register({ userName: 'alice', email: 'a@b.com', country: 'US', realName: 'Al' } as any, 'pw');
|
||||||
|
|
@ -350,7 +355,6 @@ describe('register', () => {
|
||||||
// activate.ts
|
// activate.ts
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('activate', () => {
|
describe('activate', () => {
|
||||||
const { activate } = jest.requireActual('./activate');
|
|
||||||
|
|
||||||
it('sends Command_Activate with userName and token, not password', () => {
|
it('sends Command_Activate with userName and token, not password', () => {
|
||||||
activate({ userName: 'alice', token: 'tok' } as any, 'pw');
|
activate({ userName: 'alice', token: 'tok' } as any, 'pw');
|
||||||
|
|
@ -385,7 +389,6 @@ describe('activate', () => {
|
||||||
// forgotPasswordChallenge.ts
|
// forgotPasswordChallenge.ts
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('forgotPasswordChallenge', () => {
|
describe('forgotPasswordChallenge', () => {
|
||||||
const { forgotPasswordChallenge } = jest.requireActual('./forgotPasswordChallenge');
|
|
||||||
|
|
||||||
it('sends Command_ForgotPasswordChallenge', () => {
|
it('sends Command_ForgotPasswordChallenge', () => {
|
||||||
forgotPasswordChallenge({ userName: 'alice', email: 'a@b.com' } as any);
|
forgotPasswordChallenge({ userName: 'alice', email: 'a@b.com' } as any);
|
||||||
|
|
@ -413,7 +416,6 @@ describe('forgotPasswordChallenge', () => {
|
||||||
// forgotPasswordRequest.ts
|
// forgotPasswordRequest.ts
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('forgotPasswordRequest', () => {
|
describe('forgotPasswordRequest', () => {
|
||||||
const { forgotPasswordRequest } = jest.requireActual('./forgotPasswordRequest');
|
|
||||||
|
|
||||||
it('sends Command_ForgotPasswordRequest', () => {
|
it('sends Command_ForgotPasswordRequest', () => {
|
||||||
forgotPasswordRequest({ userName: 'alice' } as any);
|
forgotPasswordRequest({ userName: 'alice' } as any);
|
||||||
|
|
@ -448,7 +450,6 @@ describe('forgotPasswordRequest', () => {
|
||||||
// forgotPasswordReset.ts
|
// forgotPasswordReset.ts
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('forgotPasswordReset', () => {
|
describe('forgotPasswordReset', () => {
|
||||||
const { forgotPasswordReset } = jest.requireActual('./forgotPasswordReset');
|
|
||||||
|
|
||||||
it('sends Command_ForgotPasswordReset with plain newPassword when no salt', () => {
|
it('sends Command_ForgotPasswordReset with plain newPassword when no salt', () => {
|
||||||
forgotPasswordReset({ userName: 'alice', token: 'tok' } as any, 'newpw');
|
forgotPasswordReset({ userName: 'alice', token: 'tok' } as any, 'newpw');
|
||||||
|
|
@ -487,7 +488,6 @@ describe('forgotPasswordReset', () => {
|
||||||
// requestPasswordSalt.ts
|
// requestPasswordSalt.ts
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('requestPasswordSalt', () => {
|
describe('requestPasswordSalt', () => {
|
||||||
const { requestPasswordSalt } = jest.requireActual('./requestPasswordSalt');
|
|
||||||
|
|
||||||
it('sends Command_RequestPasswordSalt', () => {
|
it('sends Command_RequestPasswordSalt', () => {
|
||||||
requestPasswordSalt({ userName: 'alice', reason: WebSocketConnectReason.LOGIN } as any, 'pw');
|
requestPasswordSalt({ userName: 'alice', reason: WebSocketConnectReason.LOGIN } as any, 'pw');
|
||||||
|
|
|
||||||
|
|
@ -1,39 +1,39 @@
|
||||||
// Shared mock setup for session command tests
|
// Shared mock setup for session command tests
|
||||||
|
|
||||||
jest.mock('../../services/BackendService', () => ({
|
vi.mock('../../services/BackendService', () => ({
|
||||||
BackendService: {
|
BackendService: {
|
||||||
sendSessionCommand: jest.fn(),
|
sendSessionCommand: vi.fn(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../../persistence', () => {
|
vi.mock('../../persistence', async () => {
|
||||||
const { makeSessionPersistenceMock } = require('../../__mocks__/sessionCommandMocks');
|
const { makeSessionPersistenceMock } = await import('../../__mocks__/sessionCommandMocks');
|
||||||
return {
|
return {
|
||||||
SessionPersistence: makeSessionPersistenceMock(),
|
SessionPersistence: makeSessionPersistenceMock(),
|
||||||
RoomPersistence: { joinRoom: jest.fn() },
|
RoomPersistence: { joinRoom: vi.fn() },
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
jest.mock('../../WebClient', () => {
|
vi.mock('../../WebClient', async () => {
|
||||||
const { makeWebClientMock } = require('../../__mocks__/sessionCommandMocks');
|
const { makeWebClientMock } = await import('../../__mocks__/sessionCommandMocks');
|
||||||
return { __esModule: true, default: makeWebClientMock() };
|
return { __esModule: true, default: makeWebClientMock() };
|
||||||
});
|
});
|
||||||
|
|
||||||
jest.mock('../../services/ProtoController', () => {
|
vi.mock('../../services/ProtoController', async () => {
|
||||||
const { makeProtoControllerRootMock } = require('../../__mocks__/sessionCommandMocks');
|
const { makeProtoControllerRootMock } = await import('../../__mocks__/sessionCommandMocks');
|
||||||
return { ProtoController: { root: makeProtoControllerRootMock() } };
|
return { ProtoController: { root: makeProtoControllerRootMock() } };
|
||||||
});
|
});
|
||||||
|
|
||||||
jest.mock('../../utils', () => {
|
vi.mock('../../utils', async () => {
|
||||||
const { makeUtilsMock } = require('../../__mocks__/sessionCommandMocks');
|
const { makeUtilsMock } = await import('../../__mocks__/sessionCommandMocks');
|
||||||
return makeUtilsMock();
|
return makeUtilsMock();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Mock session commands barrel to allow cross-command calls while keeping real implementations
|
// Mock session commands barrel to allow cross-command calls while keeping real implementations
|
||||||
jest.mock('./', () => {
|
vi.mock('./', async () => {
|
||||||
const actual = jest.requireActual('./');
|
const actual = await vi.importActual('./');
|
||||||
const { makeSessionBarrelMock } = require('../../__mocks__/sessionCommandMocks');
|
const { makeSessionBarrelMock } = await import('../../__mocks__/sessionCommandMocks');
|
||||||
return { ...actual, ...makeSessionBarrelMock() };
|
return { ...(actual as any), ...makeSessionBarrelMock() };
|
||||||
});
|
});
|
||||||
|
|
||||||
import { makeCallbackHelpers } from '../../__mocks__/callbackHelpers';
|
import { makeCallbackHelpers } from '../../__mocks__/callbackHelpers';
|
||||||
|
|
@ -43,23 +43,45 @@ import { RoomPersistence } from '../../persistence';
|
||||||
import webClient from '../../WebClient';
|
import webClient from '../../WebClient';
|
||||||
import * as SessionCommands from './';
|
import * as SessionCommands from './';
|
||||||
import { hashPassword, generateSalt, passwordSaltSupported } from '../../utils';
|
import { hashPassword, generateSalt, passwordSaltSupported } from '../../utils';
|
||||||
|
import { accountEdit } from './accountEdit';
|
||||||
|
import { accountImage } from './accountImage';
|
||||||
|
import { accountPassword } from './accountPassword';
|
||||||
|
import { deckDel } from './deckDel';
|
||||||
|
import { deckDelDir } from './deckDelDir';
|
||||||
|
import { deckList } from './deckList';
|
||||||
|
import { deckNewDir } from './deckNewDir';
|
||||||
|
import { deckUpload } from './deckUpload';
|
||||||
|
import { disconnect } from './disconnect';
|
||||||
|
import { getGamesOfUser } from './getGamesOfUser';
|
||||||
|
import { getUserInfo } from './getUserInfo';
|
||||||
|
import { joinRoom } from './joinRoom';
|
||||||
|
import { listRooms } from './listRooms';
|
||||||
|
import { listUsers } from './listUsers';
|
||||||
|
import { message } from './message';
|
||||||
|
import { ping } from './ping';
|
||||||
|
import { replayDeleteMatch } from './replayDeleteMatch';
|
||||||
|
import { replayList } from './replayList';
|
||||||
|
import { replayModifyMatch } from './replayModifyMatch';
|
||||||
|
import { addToList, addToBuddyList, addToIgnoreList } from './addToList';
|
||||||
|
import { removeFromList, removeFromBuddyList, removeFromIgnoreList } from './removeFromList';
|
||||||
|
import { replayGetCode } from './replayGetCode';
|
||||||
|
import { replaySubmitCode } from './replaySubmitCode';
|
||||||
|
|
||||||
const { invokeOnSuccess, invokeCallback } = makeCallbackHelpers(
|
const { invokeOnSuccess, invokeCallback } = makeCallbackHelpers(
|
||||||
BackendService.sendSessionCommand as jest.Mock
|
BackendService.sendSessionCommand as vi.Mock
|
||||||
);
|
);
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
(hashPassword as jest.Mock).mockReturnValue('hashed_pw');
|
(hashPassword as vi.Mock).mockReturnValue('hashed_pw');
|
||||||
(generateSalt as jest.Mock).mockReturnValue('randSalt');
|
(generateSalt as vi.Mock).mockReturnValue('randSalt');
|
||||||
(passwordSaltSupported as jest.Mock).mockReturnValue(0);
|
(passwordSaltSupported as vi.Mock).mockReturnValue(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
|
|
||||||
describe('accountEdit', () => {
|
describe('accountEdit', () => {
|
||||||
const { accountEdit } = jest.requireActual('./accountEdit');
|
beforeEach(() => vi.clearAllMocks());
|
||||||
beforeEach(() => jest.clearAllMocks());
|
|
||||||
|
|
||||||
it('sends Command_AccountEdit with correct params', () => {
|
it('sends Command_AccountEdit with correct params', () => {
|
||||||
accountEdit('pw', 'Alice', 'a@b.com', 'US');
|
accountEdit('pw', 'Alice', 'a@b.com', 'US');
|
||||||
|
|
@ -78,8 +100,7 @@ describe('accountEdit', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('accountImage', () => {
|
describe('accountImage', () => {
|
||||||
const { accountImage } = jest.requireActual('./accountImage');
|
beforeEach(() => vi.clearAllMocks());
|
||||||
beforeEach(() => jest.clearAllMocks());
|
|
||||||
|
|
||||||
it('sends Command_AccountImage', () => {
|
it('sends Command_AccountImage', () => {
|
||||||
const img = new Uint8Array([1, 2]);
|
const img = new Uint8Array([1, 2]);
|
||||||
|
|
@ -96,8 +117,7 @@ describe('accountImage', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('accountPassword', () => {
|
describe('accountPassword', () => {
|
||||||
const { accountPassword } = jest.requireActual('./accountPassword');
|
beforeEach(() => vi.clearAllMocks());
|
||||||
beforeEach(() => jest.clearAllMocks());
|
|
||||||
|
|
||||||
it('sends Command_AccountPassword', () => {
|
it('sends Command_AccountPassword', () => {
|
||||||
accountPassword('old', 'new', 'hashed');
|
accountPassword('old', 'new', 'hashed');
|
||||||
|
|
@ -116,8 +136,7 @@ describe('accountPassword', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('deckDel', () => {
|
describe('deckDel', () => {
|
||||||
const { deckDel } = jest.requireActual('./deckDel');
|
beforeEach(() => vi.clearAllMocks());
|
||||||
beforeEach(() => jest.clearAllMocks());
|
|
||||||
|
|
||||||
it('sends Command_DeckDel', () => {
|
it('sends Command_DeckDel', () => {
|
||||||
deckDel(42);
|
deckDel(42);
|
||||||
|
|
@ -132,8 +151,7 @@ describe('deckDel', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('deckDelDir', () => {
|
describe('deckDelDir', () => {
|
||||||
const { deckDelDir } = jest.requireActual('./deckDelDir');
|
beforeEach(() => vi.clearAllMocks());
|
||||||
beforeEach(() => jest.clearAllMocks());
|
|
||||||
|
|
||||||
it('sends Command_DeckDelDir', () => {
|
it('sends Command_DeckDelDir', () => {
|
||||||
deckDelDir('/path');
|
deckDelDir('/path');
|
||||||
|
|
@ -148,8 +166,7 @@ describe('deckDelDir', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('deckList', () => {
|
describe('deckList', () => {
|
||||||
const { deckList } = jest.requireActual('./deckList');
|
beforeEach(() => vi.clearAllMocks());
|
||||||
beforeEach(() => jest.clearAllMocks());
|
|
||||||
|
|
||||||
it('sends Command_DeckList', () => {
|
it('sends Command_DeckList', () => {
|
||||||
deckList();
|
deckList();
|
||||||
|
|
@ -165,8 +182,7 @@ describe('deckList', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('deckNewDir', () => {
|
describe('deckNewDir', () => {
|
||||||
const { deckNewDir } = jest.requireActual('./deckNewDir');
|
beforeEach(() => vi.clearAllMocks());
|
||||||
beforeEach(() => jest.clearAllMocks());
|
|
||||||
|
|
||||||
it('sends Command_DeckNewDir', () => {
|
it('sends Command_DeckNewDir', () => {
|
||||||
deckNewDir('/path', 'dir');
|
deckNewDir('/path', 'dir');
|
||||||
|
|
@ -183,8 +199,7 @@ describe('deckNewDir', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('deckUpload', () => {
|
describe('deckUpload', () => {
|
||||||
const { deckUpload } = jest.requireActual('./deckUpload');
|
beforeEach(() => vi.clearAllMocks());
|
||||||
beforeEach(() => jest.clearAllMocks());
|
|
||||||
|
|
||||||
it('sends Command_DeckUpload', () => {
|
it('sends Command_DeckUpload', () => {
|
||||||
deckUpload('/path', 1, 'content');
|
deckUpload('/path', 1, 'content');
|
||||||
|
|
@ -204,8 +219,7 @@ describe('deckUpload', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('disconnect', () => {
|
describe('disconnect', () => {
|
||||||
const { disconnect } = jest.requireActual('./disconnect');
|
beforeEach(() => vi.clearAllMocks());
|
||||||
beforeEach(() => jest.clearAllMocks());
|
|
||||||
|
|
||||||
it('calls webClient.disconnect', () => {
|
it('calls webClient.disconnect', () => {
|
||||||
disconnect();
|
disconnect();
|
||||||
|
|
@ -214,8 +228,7 @@ describe('disconnect', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getGamesOfUser', () => {
|
describe('getGamesOfUser', () => {
|
||||||
const { getGamesOfUser } = jest.requireActual('./getGamesOfUser');
|
beforeEach(() => vi.clearAllMocks());
|
||||||
beforeEach(() => jest.clearAllMocks());
|
|
||||||
|
|
||||||
it('sends Command_GetGamesOfUser', () => {
|
it('sends Command_GetGamesOfUser', () => {
|
||||||
getGamesOfUser('alice');
|
getGamesOfUser('alice');
|
||||||
|
|
@ -231,8 +244,7 @@ describe('getGamesOfUser', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getUserInfo', () => {
|
describe('getUserInfo', () => {
|
||||||
const { getUserInfo } = jest.requireActual('./getUserInfo');
|
beforeEach(() => vi.clearAllMocks());
|
||||||
beforeEach(() => jest.clearAllMocks());
|
|
||||||
|
|
||||||
it('sends Command_GetUserInfo', () => {
|
it('sends Command_GetUserInfo', () => {
|
||||||
getUserInfo('alice');
|
getUserInfo('alice');
|
||||||
|
|
@ -248,8 +260,7 @@ describe('getUserInfo', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('joinRoom', () => {
|
describe('joinRoom', () => {
|
||||||
const { joinRoom } = jest.requireActual('./joinRoom');
|
beforeEach(() => vi.clearAllMocks());
|
||||||
beforeEach(() => jest.clearAllMocks());
|
|
||||||
|
|
||||||
it('sends Command_JoinRoom', () => {
|
it('sends Command_JoinRoom', () => {
|
||||||
joinRoom(5);
|
joinRoom(5);
|
||||||
|
|
@ -265,8 +276,7 @@ describe('joinRoom', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('listRooms (command)', () => {
|
describe('listRooms (command)', () => {
|
||||||
const { listRooms } = jest.requireActual('./listRooms');
|
beforeEach(() => vi.clearAllMocks());
|
||||||
beforeEach(() => jest.clearAllMocks());
|
|
||||||
|
|
||||||
it('sends Command_ListRooms', () => {
|
it('sends Command_ListRooms', () => {
|
||||||
listRooms();
|
listRooms();
|
||||||
|
|
@ -275,8 +285,7 @@ describe('listRooms (command)', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('listUsers', () => {
|
describe('listUsers', () => {
|
||||||
const { listUsers } = jest.requireActual('./listUsers');
|
beforeEach(() => vi.clearAllMocks());
|
||||||
beforeEach(() => jest.clearAllMocks());
|
|
||||||
|
|
||||||
it('sends Command_ListUsers', () => {
|
it('sends Command_ListUsers', () => {
|
||||||
listUsers();
|
listUsers();
|
||||||
|
|
@ -292,8 +301,7 @@ describe('listUsers', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('message', () => {
|
describe('message', () => {
|
||||||
const { message } = jest.requireActual('./message');
|
beforeEach(() => vi.clearAllMocks());
|
||||||
beforeEach(() => jest.clearAllMocks());
|
|
||||||
|
|
||||||
it('sends Command_Message', () => {
|
it('sends Command_Message', () => {
|
||||||
message('bob', 'hi');
|
message('bob', 'hi');
|
||||||
|
|
@ -305,17 +313,16 @@ describe('message', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('ping', () => {
|
describe('ping', () => {
|
||||||
const { ping } = jest.requireActual('./ping');
|
beforeEach(() => vi.clearAllMocks());
|
||||||
beforeEach(() => jest.clearAllMocks());
|
|
||||||
|
|
||||||
it('sends Command_Ping', () => {
|
it('sends Command_Ping', () => {
|
||||||
const pingReceived = jest.fn();
|
const pingReceived = vi.fn();
|
||||||
ping(pingReceived);
|
ping(pingReceived);
|
||||||
expect(BackendService.sendSessionCommand).toHaveBeenCalledWith('Command_Ping', {}, expect.any(Object));
|
expect(BackendService.sendSessionCommand).toHaveBeenCalledWith('Command_Ping', {}, expect.any(Object));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('calls pingReceived via onResponse', () => {
|
it('calls pingReceived via onResponse', () => {
|
||||||
const pingReceived = jest.fn();
|
const pingReceived = vi.fn();
|
||||||
ping(pingReceived);
|
ping(pingReceived);
|
||||||
const raw = {};
|
const raw = {};
|
||||||
invokeCallback('onResponse', raw);
|
invokeCallback('onResponse', raw);
|
||||||
|
|
@ -324,8 +331,7 @@ describe('ping', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('replayDeleteMatch', () => {
|
describe('replayDeleteMatch', () => {
|
||||||
const { replayDeleteMatch } = jest.requireActual('./replayDeleteMatch');
|
beforeEach(() => vi.clearAllMocks());
|
||||||
beforeEach(() => jest.clearAllMocks());
|
|
||||||
|
|
||||||
it('sends Command_ReplayDeleteMatch', () => {
|
it('sends Command_ReplayDeleteMatch', () => {
|
||||||
replayDeleteMatch(7);
|
replayDeleteMatch(7);
|
||||||
|
|
@ -340,8 +346,7 @@ describe('replayDeleteMatch', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('replayList', () => {
|
describe('replayList', () => {
|
||||||
const { replayList } = jest.requireActual('./replayList');
|
beforeEach(() => vi.clearAllMocks());
|
||||||
beforeEach(() => jest.clearAllMocks());
|
|
||||||
|
|
||||||
it('sends Command_ReplayList', () => {
|
it('sends Command_ReplayList', () => {
|
||||||
replayList();
|
replayList();
|
||||||
|
|
@ -357,8 +362,7 @@ describe('replayList', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('replayModifyMatch', () => {
|
describe('replayModifyMatch', () => {
|
||||||
const { replayModifyMatch } = jest.requireActual('./replayModifyMatch');
|
beforeEach(() => vi.clearAllMocks());
|
||||||
beforeEach(() => jest.clearAllMocks());
|
|
||||||
|
|
||||||
it('sends Command_ReplayModifyMatch', () => {
|
it('sends Command_ReplayModifyMatch', () => {
|
||||||
replayModifyMatch(7, true);
|
replayModifyMatch(7, true);
|
||||||
|
|
@ -375,8 +379,7 @@ describe('replayModifyMatch', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('addToList / addToBuddyList / addToIgnoreList', () => {
|
describe('addToList / addToBuddyList / addToIgnoreList', () => {
|
||||||
const { addToList, addToBuddyList, addToIgnoreList } = jest.requireActual('./addToList');
|
beforeEach(() => vi.clearAllMocks());
|
||||||
beforeEach(() => jest.clearAllMocks());
|
|
||||||
|
|
||||||
it('addToBuddyList sends Command_AddToList with list=buddy', () => {
|
it('addToBuddyList sends Command_AddToList with list=buddy', () => {
|
||||||
addToBuddyList('alice');
|
addToBuddyList('alice');
|
||||||
|
|
@ -400,8 +403,7 @@ describe('addToList / addToBuddyList / addToIgnoreList', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('removeFromList / removeFromBuddyList / removeFromIgnoreList', () => {
|
describe('removeFromList / removeFromBuddyList / removeFromIgnoreList', () => {
|
||||||
const { removeFromList, removeFromBuddyList, removeFromIgnoreList } = jest.requireActual('./removeFromList');
|
beforeEach(() => vi.clearAllMocks());
|
||||||
beforeEach(() => jest.clearAllMocks());
|
|
||||||
|
|
||||||
it('removeFromBuddyList sends Command_RemoveFromList with list=buddy', () => {
|
it('removeFromBuddyList sends Command_RemoveFromList with list=buddy', () => {
|
||||||
removeFromBuddyList('alice');
|
removeFromBuddyList('alice');
|
||||||
|
|
@ -425,11 +427,10 @@ describe('removeFromList / removeFromBuddyList / removeFromIgnoreList', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('replayGetCode', () => {
|
describe('replayGetCode', () => {
|
||||||
const { replayGetCode } = jest.requireActual('./replayGetCode');
|
beforeEach(() => vi.clearAllMocks());
|
||||||
beforeEach(() => jest.clearAllMocks());
|
|
||||||
|
|
||||||
it('sends Command_ReplayGetCode with gameId and responseName', () => {
|
it('sends Command_ReplayGetCode with gameId and responseName', () => {
|
||||||
replayGetCode(42, jest.fn());
|
replayGetCode(42, vi.fn());
|
||||||
expect(BackendService.sendSessionCommand).toHaveBeenCalledWith(
|
expect(BackendService.sendSessionCommand).toHaveBeenCalledWith(
|
||||||
'Command_ReplayGetCode',
|
'Command_ReplayGetCode',
|
||||||
{ gameId: 42 },
|
{ gameId: 42 },
|
||||||
|
|
@ -438,7 +439,7 @@ describe('replayGetCode', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('calls onCodeReceived with replayCode on success', () => {
|
it('calls onCodeReceived with replayCode on success', () => {
|
||||||
const onCodeReceived = jest.fn();
|
const onCodeReceived = vi.fn();
|
||||||
replayGetCode(42, onCodeReceived);
|
replayGetCode(42, onCodeReceived);
|
||||||
invokeOnSuccess({ replayCode: 'abc123-xyz' });
|
invokeOnSuccess({ replayCode: 'abc123-xyz' });
|
||||||
expect(onCodeReceived).toHaveBeenCalledWith('abc123-xyz');
|
expect(onCodeReceived).toHaveBeenCalledWith('abc123-xyz');
|
||||||
|
|
@ -446,8 +447,7 @@ describe('replayGetCode', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('replaySubmitCode', () => {
|
describe('replaySubmitCode', () => {
|
||||||
const { replaySubmitCode } = jest.requireActual('./replaySubmitCode');
|
beforeEach(() => vi.clearAllMocks());
|
||||||
beforeEach(() => jest.clearAllMocks());
|
|
||||||
|
|
||||||
it('sends Command_ReplaySubmitCode with replayCode', () => {
|
it('sends Command_ReplaySubmitCode with replayCode', () => {
|
||||||
replaySubmitCode('42-abc123');
|
replaySubmitCode('42-abc123');
|
||||||
|
|
@ -459,14 +459,14 @@ describe('replaySubmitCode', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('forwards onSuccess callback', () => {
|
it('forwards onSuccess callback', () => {
|
||||||
const onSuccess = jest.fn();
|
const onSuccess = vi.fn();
|
||||||
replaySubmitCode('42-abc123', onSuccess);
|
replaySubmitCode('42-abc123', onSuccess);
|
||||||
invokeOnSuccess();
|
invokeOnSuccess();
|
||||||
expect(onSuccess).toHaveBeenCalled();
|
expect(onSuccess).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('forwards onError callback', () => {
|
it('forwards onError callback', () => {
|
||||||
const onError = jest.fn();
|
const onError = vi.fn();
|
||||||
replaySubmitCode('42-abc123', undefined, onError);
|
replaySubmitCode('42-abc123', undefined, onError);
|
||||||
invokeCallback('onError', 404);
|
invokeCallback('onError', 404);
|
||||||
expect(onError).toHaveBeenCalledWith(404);
|
expect(onError).toHaveBeenCalledWith(404);
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,34 @@
|
||||||
jest.mock('../../persistence', () => ({
|
vi.mock('../../persistence', () => ({
|
||||||
GamePersistence: {
|
GamePersistence: {
|
||||||
gameStateChanged: jest.fn(),
|
gameStateChanged: vi.fn(),
|
||||||
playerJoined: jest.fn(),
|
playerJoined: vi.fn(),
|
||||||
playerLeft: jest.fn(),
|
playerLeft: vi.fn(),
|
||||||
playerPropertiesChanged: jest.fn(),
|
playerPropertiesChanged: vi.fn(),
|
||||||
gameClosed: jest.fn(),
|
gameClosed: vi.fn(),
|
||||||
gameHostChanged: jest.fn(),
|
gameHostChanged: vi.fn(),
|
||||||
kicked: jest.fn(),
|
kicked: vi.fn(),
|
||||||
gameSay: jest.fn(),
|
gameSay: vi.fn(),
|
||||||
cardMoved: jest.fn(),
|
cardMoved: vi.fn(),
|
||||||
cardFlipped: jest.fn(),
|
cardFlipped: vi.fn(),
|
||||||
cardDestroyed: jest.fn(),
|
cardDestroyed: vi.fn(),
|
||||||
cardAttached: jest.fn(),
|
cardAttached: vi.fn(),
|
||||||
tokenCreated: jest.fn(),
|
tokenCreated: vi.fn(),
|
||||||
cardAttrChanged: jest.fn(),
|
cardAttrChanged: vi.fn(),
|
||||||
cardCounterChanged: jest.fn(),
|
cardCounterChanged: vi.fn(),
|
||||||
arrowCreated: jest.fn(),
|
arrowCreated: vi.fn(),
|
||||||
arrowDeleted: jest.fn(),
|
arrowDeleted: vi.fn(),
|
||||||
counterCreated: jest.fn(),
|
counterCreated: vi.fn(),
|
||||||
counterSet: jest.fn(),
|
counterSet: vi.fn(),
|
||||||
counterDeleted: jest.fn(),
|
counterDeleted: vi.fn(),
|
||||||
cardsDrawn: jest.fn(),
|
cardsDrawn: vi.fn(),
|
||||||
cardsRevealed: jest.fn(),
|
cardsRevealed: vi.fn(),
|
||||||
zoneShuffled: jest.fn(),
|
zoneShuffled: vi.fn(),
|
||||||
dieRolled: jest.fn(),
|
dieRolled: vi.fn(),
|
||||||
activePlayerSet: jest.fn(),
|
activePlayerSet: vi.fn(),
|
||||||
activePhaseSet: jest.fn(),
|
activePhaseSet: vi.fn(),
|
||||||
turnReversed: jest.fn(),
|
turnReversed: vi.fn(),
|
||||||
zoneDumped: jest.fn(),
|
zoneDumped: vi.fn(),
|
||||||
zonePropertiesChanged: jest.fn(),
|
zonePropertiesChanged: vi.fn(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
@ -63,7 +63,7 @@ import { setCardCounter } from './setCardCounter';
|
||||||
import { setCounter } from './setCounter';
|
import { setCounter } from './setCounter';
|
||||||
import { shuffle } from './shuffle';
|
import { shuffle } from './shuffle';
|
||||||
|
|
||||||
beforeEach(() => jest.clearAllMocks());
|
beforeEach(() => vi.clearAllMocks());
|
||||||
|
|
||||||
const meta = { gameId: 5, playerId: 2, context: null, secondsElapsed: 0, forcedByJudge: 0 };
|
const meta = { gameId: 5, playerId: 2, context: null, secondsElapsed: 0, forcedByJudge: 0 };
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,25 @@
|
||||||
jest.mock('../../persistence', () => ({
|
vi.mock('../../persistence', () => ({
|
||||||
RoomPersistence: {
|
RoomPersistence: {
|
||||||
userJoined: jest.fn(),
|
userJoined: vi.fn(),
|
||||||
userLeft: jest.fn(),
|
userLeft: vi.fn(),
|
||||||
updateGames: jest.fn(),
|
updateGames: vi.fn(),
|
||||||
removeMessages: jest.fn(),
|
removeMessages: vi.fn(),
|
||||||
addMessage: jest.fn(),
|
addMessage: vi.fn(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import { RoomPersistence } from '../../persistence';
|
import { RoomPersistence } from '../../persistence';
|
||||||
|
import { joinRoom } from './joinRoom';
|
||||||
|
import { leaveRoom } from './leaveRoom';
|
||||||
|
import { listGames } from './listGames';
|
||||||
|
import { removeMessages } from './removeMessages';
|
||||||
|
import { roomSay } from './roomSay';
|
||||||
|
|
||||||
const makeRoomEvent = (roomId: number) => ({ roomEvent: { roomId } });
|
const makeRoomEvent = (roomId: number) => ({ roomEvent: { roomId } });
|
||||||
|
|
||||||
beforeEach(() => jest.clearAllMocks());
|
beforeEach(() => vi.clearAllMocks());
|
||||||
|
|
||||||
describe('joinRoom room event', () => {
|
describe('joinRoom room event', () => {
|
||||||
const { joinRoom } = jest.requireActual('./joinRoom');
|
|
||||||
|
|
||||||
it('calls RoomPersistence.userJoined with roomId and userInfo', () => {
|
it('calls RoomPersistence.userJoined with roomId and userInfo', () => {
|
||||||
const userInfo = { name: 'alice' } as any;
|
const userInfo = { name: 'alice' } as any;
|
||||||
|
|
@ -25,7 +29,6 @@ describe('joinRoom room event', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('leaveRoom room event', () => {
|
describe('leaveRoom room event', () => {
|
||||||
const { leaveRoom } = jest.requireActual('./leaveRoom');
|
|
||||||
|
|
||||||
it('calls RoomPersistence.userLeft with roomId and name', () => {
|
it('calls RoomPersistence.userLeft with roomId and name', () => {
|
||||||
leaveRoom({ name: 'alice' }, makeRoomEvent(4));
|
leaveRoom({ name: 'alice' }, makeRoomEvent(4));
|
||||||
|
|
@ -34,7 +37,6 @@ describe('leaveRoom room event', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('listGames room event', () => {
|
describe('listGames room event', () => {
|
||||||
const { listGames } = jest.requireActual('./listGames');
|
|
||||||
|
|
||||||
it('calls RoomPersistence.updateGames with roomId and gameList', () => {
|
it('calls RoomPersistence.updateGames with roomId and gameList', () => {
|
||||||
const gameList = [{ gameId: 1 }] as any;
|
const gameList = [{ gameId: 1 }] as any;
|
||||||
|
|
@ -44,7 +46,6 @@ describe('listGames room event', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('removeMessages room event', () => {
|
describe('removeMessages room event', () => {
|
||||||
const { removeMessages } = jest.requireActual('./removeMessages');
|
|
||||||
|
|
||||||
it('calls RoomPersistence.removeMessages with roomId, name, amount', () => {
|
it('calls RoomPersistence.removeMessages with roomId, name, amount', () => {
|
||||||
removeMessages({ name: 'bob', amount: 10 }, makeRoomEvent(6));
|
removeMessages({ name: 'bob', amount: 10 }, makeRoomEvent(6));
|
||||||
|
|
@ -53,7 +54,6 @@ describe('removeMessages room event', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('roomSay room event', () => {
|
describe('roomSay room event', () => {
|
||||||
const { roomSay } = jest.requireActual('./roomSay');
|
|
||||||
|
|
||||||
it('calls RoomPersistence.addMessage with roomId and message', () => {
|
it('calls RoomPersistence.addMessage with roomId and message', () => {
|
||||||
const msg = { text: 'hello' } as any;
|
const msg = { text: 'hello' } as any;
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,30 @@
|
||||||
// Tests for simple session events that delegate 1:1 to SessionPersistence
|
// Tests for simple session events that delegate 1:1 to SessionPersistence
|
||||||
// or RoomPersistence with minimal logic.
|
// or RoomPersistence with minimal logic.
|
||||||
|
|
||||||
jest.mock('../../persistence', () => ({
|
vi.mock('../../persistence', () => ({
|
||||||
SessionPersistence: {
|
SessionPersistence: {
|
||||||
gameJoined: jest.fn(),
|
gameJoined: vi.fn(),
|
||||||
notifyUser: jest.fn(),
|
notifyUser: vi.fn(),
|
||||||
replayAdded: jest.fn(),
|
replayAdded: vi.fn(),
|
||||||
serverMessage: jest.fn(),
|
serverMessage: vi.fn(),
|
||||||
serverShutdown: jest.fn(),
|
serverShutdown: vi.fn(),
|
||||||
updateUsers: jest.fn(),
|
updateUsers: vi.fn(),
|
||||||
updateInfo: jest.fn(),
|
updateInfo: vi.fn(),
|
||||||
userJoined: jest.fn(),
|
userJoined: vi.fn(),
|
||||||
userLeft: jest.fn(),
|
userLeft: vi.fn(),
|
||||||
userMessage: jest.fn(),
|
userMessage: vi.fn(),
|
||||||
addToBuddyList: jest.fn(),
|
addToBuddyList: vi.fn(),
|
||||||
addToIgnoreList: jest.fn(),
|
addToIgnoreList: vi.fn(),
|
||||||
removeFromBuddyList: jest.fn(),
|
removeFromBuddyList: vi.fn(),
|
||||||
removeFromIgnoreList: jest.fn(),
|
removeFromIgnoreList: vi.fn(),
|
||||||
playerPropertiesChanged: jest.fn(),
|
playerPropertiesChanged: vi.fn(),
|
||||||
},
|
},
|
||||||
RoomPersistence: {
|
RoomPersistence: {
|
||||||
updateRooms: jest.fn(),
|
updateRooms: vi.fn(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../../WebClient', () => ({
|
vi.mock('../../WebClient', () => ({
|
||||||
__esModule: true,
|
__esModule: true,
|
||||||
default: {
|
default: {
|
||||||
clientOptions: { autojoinrooms: false },
|
clientOptions: { autojoinrooms: false },
|
||||||
|
|
@ -33,25 +33,25 @@ jest.mock('../../WebClient', () => ({
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../../commands/session', () => ({
|
vi.mock('../../commands/session', () => ({
|
||||||
joinRoom: jest.fn(),
|
joinRoom: vi.fn(),
|
||||||
updateStatus: jest.fn(),
|
updateStatus: vi.fn(),
|
||||||
disconnect: jest.fn(),
|
disconnect: vi.fn(),
|
||||||
login: jest.fn(),
|
login: vi.fn(),
|
||||||
register: jest.fn(),
|
register: vi.fn(),
|
||||||
activate: jest.fn(),
|
activate: vi.fn(),
|
||||||
requestPasswordSalt: jest.fn(),
|
requestPasswordSalt: vi.fn(),
|
||||||
forgotPasswordRequest: jest.fn(),
|
forgotPasswordRequest: vi.fn(),
|
||||||
forgotPasswordChallenge: jest.fn(),
|
forgotPasswordChallenge: vi.fn(),
|
||||||
forgotPasswordReset: jest.fn(),
|
forgotPasswordReset: vi.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../../utils', () => ({
|
vi.mock('../../utils', () => ({
|
||||||
generateSalt: jest.fn().mockReturnValue('newSalt'),
|
generateSalt: vi.fn().mockReturnValue('newSalt'),
|
||||||
passwordSaltSupported: jest.fn().mockReturnValue(0),
|
passwordSaltSupported: vi.fn().mockReturnValue(0),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../../services/ProtoController', () => ({
|
vi.mock('../../services/ProtoController', () => ({
|
||||||
ProtoController: {
|
ProtoController: {
|
||||||
root: {
|
root: {
|
||||||
Event_ConnectionClosed: {
|
Event_ConnectionClosed: {
|
||||||
|
|
@ -76,18 +76,31 @@ import { SessionPersistence, RoomPersistence } from '../../persistence';
|
||||||
import webClient from '../../WebClient';
|
import webClient from '../../WebClient';
|
||||||
import * as SessionCmds from '../../commands/session';
|
import * as SessionCmds from '../../commands/session';
|
||||||
import * as Utils from '../../utils';
|
import * as Utils from '../../utils';
|
||||||
|
import { gameJoined } from './gameJoined';
|
||||||
|
import { notifyUser } from './notifyUser';
|
||||||
|
import { replayAdded } from './replayAdded';
|
||||||
|
import { serverCompleteList } from './serverCompleteList';
|
||||||
|
import { serverMessage } from './serverMessage';
|
||||||
|
import { serverShutdown } from './serverShutdown';
|
||||||
|
import { userJoined } from './userJoined';
|
||||||
|
import { userLeft } from './userLeft';
|
||||||
|
import { userMessage } from './userMessage';
|
||||||
|
import { addToList } from './addToList';
|
||||||
|
import { removeFromList } from './removeFromList';
|
||||||
|
import { listRooms } from './listRooms';
|
||||||
|
import { connectionClosed } from './connectionClosed';
|
||||||
|
import { serverIdentification } from './serverIdentification';
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
(Utils.generateSalt as jest.Mock).mockReturnValue('newSalt');
|
(Utils.generateSalt as vi.Mock).mockReturnValue('newSalt');
|
||||||
(Utils.passwordSaltSupported as jest.Mock).mockReturnValue(0);
|
(Utils.passwordSaltSupported as vi.Mock).mockReturnValue(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
// gameJoined
|
// gameJoined
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('gameJoined', () => {
|
describe('gameJoined', () => {
|
||||||
const { gameJoined } = jest.requireActual('./gameJoined');
|
|
||||||
|
|
||||||
it('calls SessionPersistence.gameJoined', () => {
|
it('calls SessionPersistence.gameJoined', () => {
|
||||||
const data = { gameId: 1 } as any;
|
const data = { gameId: 1 } as any;
|
||||||
|
|
@ -100,7 +113,6 @@ describe('gameJoined', () => {
|
||||||
// notifyUser
|
// notifyUser
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('notifyUser', () => {
|
describe('notifyUser', () => {
|
||||||
const { notifyUser } = jest.requireActual('./notifyUser');
|
|
||||||
|
|
||||||
it('calls SessionPersistence.notifyUser', () => {
|
it('calls SessionPersistence.notifyUser', () => {
|
||||||
const data = { message: 'yo' } as any;
|
const data = { message: 'yo' } as any;
|
||||||
|
|
@ -113,7 +125,6 @@ describe('notifyUser', () => {
|
||||||
// replayAdded
|
// replayAdded
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('replayAdded', () => {
|
describe('replayAdded', () => {
|
||||||
const { replayAdded } = jest.requireActual('./replayAdded');
|
|
||||||
|
|
||||||
it('calls SessionPersistence.replayAdded with matchInfo', () => {
|
it('calls SessionPersistence.replayAdded with matchInfo', () => {
|
||||||
replayAdded({ matchInfo: { id: 42 } } as any);
|
replayAdded({ matchInfo: { id: 42 } } as any);
|
||||||
|
|
@ -125,7 +136,6 @@ describe('replayAdded', () => {
|
||||||
// serverCompleteList
|
// serverCompleteList
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('serverCompleteList', () => {
|
describe('serverCompleteList', () => {
|
||||||
const { serverCompleteList } = jest.requireActual('./serverCompleteList');
|
|
||||||
|
|
||||||
it('calls SessionPersistence.updateUsers and RoomPersistence.updateRooms', () => {
|
it('calls SessionPersistence.updateUsers and RoomPersistence.updateRooms', () => {
|
||||||
serverCompleteList({ userList: ['u'], roomList: ['r'] } as any);
|
serverCompleteList({ userList: ['u'], roomList: ['r'] } as any);
|
||||||
|
|
@ -138,7 +148,6 @@ describe('serverCompleteList', () => {
|
||||||
// serverMessage
|
// serverMessage
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('serverMessage', () => {
|
describe('serverMessage', () => {
|
||||||
const { serverMessage } = jest.requireActual('./serverMessage');
|
|
||||||
|
|
||||||
it('calls SessionPersistence.serverMessage with message', () => {
|
it('calls SessionPersistence.serverMessage with message', () => {
|
||||||
serverMessage({ message: 'hello server' });
|
serverMessage({ message: 'hello server' });
|
||||||
|
|
@ -150,7 +159,6 @@ describe('serverMessage', () => {
|
||||||
// serverShutdown
|
// serverShutdown
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('serverShutdown', () => {
|
describe('serverShutdown', () => {
|
||||||
const { serverShutdown } = jest.requireActual('./serverShutdown');
|
|
||||||
|
|
||||||
it('calls SessionPersistence.serverShutdown', () => {
|
it('calls SessionPersistence.serverShutdown', () => {
|
||||||
const payload = { reason: 'maintenance' } as any;
|
const payload = { reason: 'maintenance' } as any;
|
||||||
|
|
@ -163,7 +171,6 @@ describe('serverShutdown', () => {
|
||||||
// userJoined
|
// userJoined
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('userJoined', () => {
|
describe('userJoined', () => {
|
||||||
const { userJoined } = jest.requireActual('./userJoined');
|
|
||||||
|
|
||||||
it('calls SessionPersistence.userJoined with userInfo', () => {
|
it('calls SessionPersistence.userJoined with userInfo', () => {
|
||||||
userJoined({ userInfo: { name: 'alice' } } as any);
|
userJoined({ userInfo: { name: 'alice' } } as any);
|
||||||
|
|
@ -175,7 +182,6 @@ describe('userJoined', () => {
|
||||||
// userLeft
|
// userLeft
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('userLeft', () => {
|
describe('userLeft', () => {
|
||||||
const { userLeft } = jest.requireActual('./userLeft');
|
|
||||||
|
|
||||||
it('calls SessionPersistence.userLeft with name', () => {
|
it('calls SessionPersistence.userLeft with name', () => {
|
||||||
userLeft({ name: 'bob' });
|
userLeft({ name: 'bob' });
|
||||||
|
|
@ -187,7 +193,6 @@ describe('userLeft', () => {
|
||||||
// userMessage
|
// userMessage
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('userMessage', () => {
|
describe('userMessage', () => {
|
||||||
const { userMessage } = jest.requireActual('./userMessage');
|
|
||||||
|
|
||||||
it('calls SessionPersistence.userMessage', () => {
|
it('calls SessionPersistence.userMessage', () => {
|
||||||
const payload = { userName: 'alice', message: 'hi' } as any;
|
const payload = { userName: 'alice', message: 'hi' } as any;
|
||||||
|
|
@ -200,8 +205,7 @@ describe('userMessage', () => {
|
||||||
// addToList
|
// addToList
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('addToList', () => {
|
describe('addToList', () => {
|
||||||
const { addToList } = jest.requireActual('./addToList');
|
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||||
const logSpy = jest.spyOn(console, 'log').mockImplementation(() => {});
|
|
||||||
afterAll(() => logSpy.mockRestore());
|
afterAll(() => logSpy.mockRestore());
|
||||||
|
|
||||||
it('buddy list → addToBuddyList', () => {
|
it('buddy list → addToBuddyList', () => {
|
||||||
|
|
@ -224,7 +228,6 @@ describe('addToList', () => {
|
||||||
// removeFromList
|
// removeFromList
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('removeFromList', () => {
|
describe('removeFromList', () => {
|
||||||
const { removeFromList } = jest.requireActual('./removeFromList');
|
|
||||||
|
|
||||||
it('buddy list → removeFromBuddyList', () => {
|
it('buddy list → removeFromBuddyList', () => {
|
||||||
removeFromList({ listName: 'buddy', userName: 'alice' } as any);
|
removeFromList({ listName: 'buddy', userName: 'alice' } as any);
|
||||||
|
|
@ -237,7 +240,7 @@ describe('removeFromList', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('unknown list → console.log', () => {
|
it('unknown list → console.log', () => {
|
||||||
const logSpy = jest.spyOn(console, 'log').mockImplementation(() => {});
|
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||||
removeFromList({ listName: 'other', userName: 'x' } as any);
|
removeFromList({ listName: 'other', userName: 'x' } as any);
|
||||||
expect(logSpy).toHaveBeenCalled();
|
expect(logSpy).toHaveBeenCalled();
|
||||||
logSpy.mockRestore();
|
logSpy.mockRestore();
|
||||||
|
|
@ -248,7 +251,6 @@ describe('removeFromList', () => {
|
||||||
// listRooms
|
// listRooms
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('listRooms', () => {
|
describe('listRooms', () => {
|
||||||
const { listRooms } = jest.requireActual('./listRooms');
|
|
||||||
|
|
||||||
it('calls RoomPersistence.updateRooms', () => {
|
it('calls RoomPersistence.updateRooms', () => {
|
||||||
listRooms({ roomList: [] });
|
listRooms({ roomList: [] });
|
||||||
|
|
@ -273,7 +275,6 @@ describe('listRooms', () => {
|
||||||
// connectionClosed
|
// connectionClosed
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('connectionClosed', () => {
|
describe('connectionClosed', () => {
|
||||||
const { connectionClosed } = jest.requireActual('./connectionClosed');
|
|
||||||
|
|
||||||
it('uses reasonStr when provided', () => {
|
it('uses reasonStr when provided', () => {
|
||||||
connectionClosed({ reason: 0, reasonStr: 'custom' } as any);
|
connectionClosed({ reason: 0, reasonStr: 'custom' } as any);
|
||||||
|
|
@ -361,7 +362,6 @@ describe('connectionClosed', () => {
|
||||||
// serverIdentification
|
// serverIdentification
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
describe('serverIdentification', () => {
|
describe('serverIdentification', () => {
|
||||||
const { serverIdentification } = jest.requireActual('./serverIdentification');
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
(webClient as any).protocolVersion = 14;
|
(webClient as any).protocolVersion = 14;
|
||||||
|
|
@ -376,7 +376,7 @@ describe('serverIdentification', () => {
|
||||||
|
|
||||||
it('LOGIN reason without salt → calls login with password as separate param', () => {
|
it('LOGIN reason without salt → calls login with password as separate param', () => {
|
||||||
(webClient as any).options = { reason: WebSocketConnectReason.LOGIN, password: 'secret' };
|
(webClient as any).options = { reason: WebSocketConnectReason.LOGIN, password: 'secret' };
|
||||||
(Utils.passwordSaltSupported as jest.Mock).mockReturnValue(0);
|
(Utils.passwordSaltSupported as vi.Mock).mockReturnValue(0);
|
||||||
serverIdentification({ serverName: 's', serverVersion: '1', protocolVersion: 14, serverOptions: 0 } as any);
|
serverIdentification({ serverName: 's', serverVersion: '1', protocolVersion: 14, serverOptions: 0 } as any);
|
||||||
expect(SessionCmds.login).toHaveBeenCalledWith(
|
expect(SessionCmds.login).toHaveBeenCalledWith(
|
||||||
expect.not.objectContaining({ password: expect.anything() }),
|
expect.not.objectContaining({ password: expect.anything() }),
|
||||||
|
|
@ -386,7 +386,7 @@ describe('serverIdentification', () => {
|
||||||
|
|
||||||
it('LOGIN reason with salt → calls requestPasswordSalt with password as separate param', () => {
|
it('LOGIN reason with salt → calls requestPasswordSalt with password as separate param', () => {
|
||||||
(webClient as any).options = { reason: WebSocketConnectReason.LOGIN, password: 'secret' };
|
(webClient as any).options = { reason: WebSocketConnectReason.LOGIN, password: 'secret' };
|
||||||
(Utils.passwordSaltSupported as jest.Mock).mockReturnValue(1);
|
(Utils.passwordSaltSupported as vi.Mock).mockReturnValue(1);
|
||||||
serverIdentification({ serverName: 's', serverVersion: '1', protocolVersion: 14, serverOptions: 1 } as any);
|
serverIdentification({ serverName: 's', serverVersion: '1', protocolVersion: 14, serverOptions: 1 } as any);
|
||||||
expect(SessionCmds.requestPasswordSalt).toHaveBeenCalledWith(
|
expect(SessionCmds.requestPasswordSalt).toHaveBeenCalledWith(
|
||||||
expect.not.objectContaining({ password: expect.anything() }),
|
expect.not.objectContaining({ password: expect.anything() }),
|
||||||
|
|
@ -396,7 +396,7 @@ describe('serverIdentification', () => {
|
||||||
|
|
||||||
it('REGISTER reason without salt → calls register with password and null salt', () => {
|
it('REGISTER reason without salt → calls register with password and null salt', () => {
|
||||||
(webClient as any).options = { reason: WebSocketConnectReason.REGISTER, password: 'secret' };
|
(webClient as any).options = { reason: WebSocketConnectReason.REGISTER, password: 'secret' };
|
||||||
(Utils.passwordSaltSupported as jest.Mock).mockReturnValue(0);
|
(Utils.passwordSaltSupported as vi.Mock).mockReturnValue(0);
|
||||||
serverIdentification({ serverName: 's', serverVersion: '1', protocolVersion: 14, serverOptions: 0 } as any);
|
serverIdentification({ serverName: 's', serverVersion: '1', protocolVersion: 14, serverOptions: 0 } as any);
|
||||||
expect(SessionCmds.register).toHaveBeenCalledWith(
|
expect(SessionCmds.register).toHaveBeenCalledWith(
|
||||||
expect.not.objectContaining({ password: expect.anything() }),
|
expect.not.objectContaining({ password: expect.anything() }),
|
||||||
|
|
@ -407,7 +407,7 @@ describe('serverIdentification', () => {
|
||||||
|
|
||||||
it('REGISTER reason with salt → calls register with password and generated salt', () => {
|
it('REGISTER reason with salt → calls register with password and generated salt', () => {
|
||||||
(webClient as any).options = { reason: WebSocketConnectReason.REGISTER, password: 'secret' };
|
(webClient as any).options = { reason: WebSocketConnectReason.REGISTER, password: 'secret' };
|
||||||
(Utils.passwordSaltSupported as jest.Mock).mockReturnValue(1);
|
(Utils.passwordSaltSupported as vi.Mock).mockReturnValue(1);
|
||||||
serverIdentification({ serverName: 's', serverVersion: '1', protocolVersion: 14, serverOptions: 1 } as any);
|
serverIdentification({ serverName: 's', serverVersion: '1', protocolVersion: 14, serverOptions: 1 } as any);
|
||||||
expect(SessionCmds.register).toHaveBeenCalledWith(
|
expect(SessionCmds.register).toHaveBeenCalledWith(
|
||||||
expect.not.objectContaining({ password: expect.anything() }),
|
expect.not.objectContaining({ password: expect.anything() }),
|
||||||
|
|
@ -418,7 +418,7 @@ describe('serverIdentification', () => {
|
||||||
|
|
||||||
it('ACTIVATE_ACCOUNT reason without salt → calls activate with password as separate param', () => {
|
it('ACTIVATE_ACCOUNT reason without salt → calls activate with password as separate param', () => {
|
||||||
(webClient as any).options = { reason: WebSocketConnectReason.ACTIVATE_ACCOUNT, password: 'secret' };
|
(webClient as any).options = { reason: WebSocketConnectReason.ACTIVATE_ACCOUNT, password: 'secret' };
|
||||||
(Utils.passwordSaltSupported as jest.Mock).mockReturnValue(0);
|
(Utils.passwordSaltSupported as vi.Mock).mockReturnValue(0);
|
||||||
serverIdentification({ serverName: 's', serverVersion: '1', protocolVersion: 14, serverOptions: 0 } as any);
|
serverIdentification({ serverName: 's', serverVersion: '1', protocolVersion: 14, serverOptions: 0 } as any);
|
||||||
expect(SessionCmds.activate).toHaveBeenCalledWith(
|
expect(SessionCmds.activate).toHaveBeenCalledWith(
|
||||||
expect.not.objectContaining({ password: expect.anything() }),
|
expect.not.objectContaining({ password: expect.anything() }),
|
||||||
|
|
@ -428,7 +428,7 @@ describe('serverIdentification', () => {
|
||||||
|
|
||||||
it('ACTIVATE_ACCOUNT reason with salt → calls requestPasswordSalt with password as separate param', () => {
|
it('ACTIVATE_ACCOUNT reason with salt → calls requestPasswordSalt with password as separate param', () => {
|
||||||
(webClient as any).options = { reason: WebSocketConnectReason.ACTIVATE_ACCOUNT, password: 'secret' };
|
(webClient as any).options = { reason: WebSocketConnectReason.ACTIVATE_ACCOUNT, password: 'secret' };
|
||||||
(Utils.passwordSaltSupported as jest.Mock).mockReturnValue(1);
|
(Utils.passwordSaltSupported as vi.Mock).mockReturnValue(1);
|
||||||
serverIdentification({ serverName: 's', serverVersion: '1', protocolVersion: 14, serverOptions: 1 } as any);
|
serverIdentification({ serverName: 's', serverVersion: '1', protocolVersion: 14, serverOptions: 1 } as any);
|
||||||
expect(SessionCmds.requestPasswordSalt).toHaveBeenCalledWith(
|
expect(SessionCmds.requestPasswordSalt).toHaveBeenCalledWith(
|
||||||
expect.not.objectContaining({ password: expect.anything() }),
|
expect.not.objectContaining({ password: expect.anything() }),
|
||||||
|
|
@ -450,7 +450,7 @@ describe('serverIdentification', () => {
|
||||||
|
|
||||||
it('PASSWORD_RESET reason without salt → calls forgotPasswordReset with newPassword as separate param', () => {
|
it('PASSWORD_RESET reason without salt → calls forgotPasswordReset with newPassword as separate param', () => {
|
||||||
(webClient as any).options = { reason: WebSocketConnectReason.PASSWORD_RESET, newPassword: 'newpw' };
|
(webClient as any).options = { reason: WebSocketConnectReason.PASSWORD_RESET, newPassword: 'newpw' };
|
||||||
(Utils.passwordSaltSupported as jest.Mock).mockReturnValue(0);
|
(Utils.passwordSaltSupported as vi.Mock).mockReturnValue(0);
|
||||||
serverIdentification({ serverName: 's', serverVersion: '1', protocolVersion: 14, serverOptions: 0 } as any);
|
serverIdentification({ serverName: 's', serverVersion: '1', protocolVersion: 14, serverOptions: 0 } as any);
|
||||||
expect(SessionCmds.forgotPasswordReset).toHaveBeenCalledWith(
|
expect(SessionCmds.forgotPasswordReset).toHaveBeenCalledWith(
|
||||||
expect.not.objectContaining({ newPassword: expect.anything() }),
|
expect.not.objectContaining({ newPassword: expect.anything() }),
|
||||||
|
|
@ -460,7 +460,7 @@ describe('serverIdentification', () => {
|
||||||
|
|
||||||
it('PASSWORD_RESET reason with salt → calls requestPasswordSalt with newPassword as separate param', () => {
|
it('PASSWORD_RESET reason with salt → calls requestPasswordSalt with newPassword as separate param', () => {
|
||||||
(webClient as any).options = { reason: WebSocketConnectReason.PASSWORD_RESET, newPassword: 'newpw' };
|
(webClient as any).options = { reason: WebSocketConnectReason.PASSWORD_RESET, newPassword: 'newpw' };
|
||||||
(Utils.passwordSaltSupported as jest.Mock).mockReturnValue(1);
|
(Utils.passwordSaltSupported as vi.Mock).mockReturnValue(1);
|
||||||
serverIdentification({ serverName: 's', serverVersion: '1', protocolVersion: 14, serverOptions: 1 } as any);
|
serverIdentification({ serverName: 's', serverVersion: '1', protocolVersion: 14, serverOptions: 1 } as any);
|
||||||
expect(SessionCmds.requestPasswordSalt).toHaveBeenCalledWith(
|
expect(SessionCmds.requestPasswordSalt).toHaveBeenCalledWith(
|
||||||
expect.not.objectContaining({ newPassword: expect.anything() }),
|
expect.not.objectContaining({ newPassword: expect.anything() }),
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
jest.mock('store', () => ({
|
vi.mock('store', () => ({
|
||||||
ServerDispatch: {
|
ServerDispatch: {
|
||||||
adjustMod: jest.fn(),
|
adjustMod: vi.fn(),
|
||||||
reloadConfig: jest.fn(),
|
reloadConfig: vi.fn(),
|
||||||
shutdownServer: jest.fn(),
|
shutdownServer: vi.fn(),
|
||||||
updateServerMessage: jest.fn(),
|
updateServerMessage: vi.fn(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
@ -11,7 +11,7 @@ import { AdminPersistence } from './AdminPersistence';
|
||||||
import { ServerDispatch } from 'store';
|
import { ServerDispatch } from 'store';
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('AdminPersistence', () => {
|
describe('AdminPersistence', () => {
|
||||||
|
|
|
||||||
|
|
@ -1,42 +1,42 @@
|
||||||
import { GamePersistence } from './GamePersistence';
|
import { GamePersistence } from './GamePersistence';
|
||||||
|
|
||||||
jest.mock('store', () => ({
|
vi.mock('store', () => ({
|
||||||
GameDispatch: {
|
GameDispatch: {
|
||||||
gameStateChanged: jest.fn(),
|
gameStateChanged: vi.fn(),
|
||||||
playerJoined: jest.fn(),
|
playerJoined: vi.fn(),
|
||||||
playerLeft: jest.fn(),
|
playerLeft: vi.fn(),
|
||||||
playerPropertiesChanged: jest.fn(),
|
playerPropertiesChanged: vi.fn(),
|
||||||
gameClosed: jest.fn(),
|
gameClosed: vi.fn(),
|
||||||
gameHostChanged: jest.fn(),
|
gameHostChanged: vi.fn(),
|
||||||
kicked: jest.fn(),
|
kicked: vi.fn(),
|
||||||
gameSay: jest.fn(),
|
gameSay: vi.fn(),
|
||||||
cardMoved: jest.fn(),
|
cardMoved: vi.fn(),
|
||||||
cardFlipped: jest.fn(),
|
cardFlipped: vi.fn(),
|
||||||
cardDestroyed: jest.fn(),
|
cardDestroyed: vi.fn(),
|
||||||
cardAttached: jest.fn(),
|
cardAttached: vi.fn(),
|
||||||
tokenCreated: jest.fn(),
|
tokenCreated: vi.fn(),
|
||||||
cardAttrChanged: jest.fn(),
|
cardAttrChanged: vi.fn(),
|
||||||
cardCounterChanged: jest.fn(),
|
cardCounterChanged: vi.fn(),
|
||||||
arrowCreated: jest.fn(),
|
arrowCreated: vi.fn(),
|
||||||
arrowDeleted: jest.fn(),
|
arrowDeleted: vi.fn(),
|
||||||
counterCreated: jest.fn(),
|
counterCreated: vi.fn(),
|
||||||
counterSet: jest.fn(),
|
counterSet: vi.fn(),
|
||||||
counterDeleted: jest.fn(),
|
counterDeleted: vi.fn(),
|
||||||
cardsDrawn: jest.fn(),
|
cardsDrawn: vi.fn(),
|
||||||
cardsRevealed: jest.fn(),
|
cardsRevealed: vi.fn(),
|
||||||
zoneShuffled: jest.fn(),
|
zoneShuffled: vi.fn(),
|
||||||
dieRolled: jest.fn(),
|
dieRolled: vi.fn(),
|
||||||
activePlayerSet: jest.fn(),
|
activePlayerSet: vi.fn(),
|
||||||
activePhaseSet: jest.fn(),
|
activePhaseSet: vi.fn(),
|
||||||
turnReversed: jest.fn(),
|
turnReversed: vi.fn(),
|
||||||
zoneDumped: jest.fn(),
|
zoneDumped: vi.fn(),
|
||||||
zonePropertiesChanged: jest.fn(),
|
zonePropertiesChanged: vi.fn(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import { GameDispatch } from 'store';
|
import { GameDispatch } from 'store';
|
||||||
|
|
||||||
beforeEach(() => jest.clearAllMocks());
|
beforeEach(() => vi.clearAllMocks());
|
||||||
|
|
||||||
describe('GamePersistence', () => {
|
describe('GamePersistence', () => {
|
||||||
it('gameStateChanged dispatches via GameDispatch', () => {
|
it('gameStateChanged dispatches via GameDispatch', () => {
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,22 @@
|
||||||
jest.mock('store', () => ({
|
vi.mock('store', () => ({
|
||||||
ServerDispatch: {
|
ServerDispatch: {
|
||||||
banFromServer: jest.fn(),
|
banFromServer: vi.fn(),
|
||||||
banHistory: jest.fn(),
|
banHistory: vi.fn(),
|
||||||
viewLogs: jest.fn(),
|
viewLogs: vi.fn(),
|
||||||
warnHistory: jest.fn(),
|
warnHistory: vi.fn(),
|
||||||
warnListOptions: jest.fn(),
|
warnListOptions: vi.fn(),
|
||||||
warnUser: jest.fn(),
|
warnUser: vi.fn(),
|
||||||
grantReplayAccess: jest.fn(),
|
grantReplayAccess: vi.fn(),
|
||||||
forceActivateUser: jest.fn(),
|
forceActivateUser: vi.fn(),
|
||||||
getAdminNotes: jest.fn(),
|
getAdminNotes: vi.fn(),
|
||||||
updateAdminNotes: jest.fn(),
|
updateAdminNotes: vi.fn(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../utils/NormalizeService', () => ({
|
vi.mock('../utils/NormalizeService', () => ({
|
||||||
__esModule: true,
|
__esModule: true,
|
||||||
default: {
|
default: {
|
||||||
normalizeLogs: jest.fn((logs: any) => ({ normalized: logs })),
|
normalizeLogs: vi.fn((logs: any) => ({ normalized: logs })),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
@ -25,8 +25,8 @@ import { ServerDispatch } from 'store';
|
||||||
import NormalizeService from '../utils/NormalizeService';
|
import NormalizeService from '../utils/NormalizeService';
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
(NormalizeService.normalizeLogs as jest.Mock).mockImplementation((logs: any) => ({ normalized: logs }));
|
(NormalizeService.normalizeLogs as vi.Mock).mockImplementation((logs: any) => ({ normalized: logs }));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('ModeratorPersistence', () => {
|
describe('ModeratorPersistence', () => {
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,29 @@
|
||||||
jest.mock('store', () => ({
|
vi.mock('store', () => ({
|
||||||
store: { getState: jest.fn().mockReturnValue({}) },
|
store: { getState: vi.fn().mockReturnValue({}) },
|
||||||
RoomsDispatch: {
|
RoomsDispatch: {
|
||||||
clearStore: jest.fn(),
|
clearStore: vi.fn(),
|
||||||
joinRoom: jest.fn(),
|
joinRoom: vi.fn(),
|
||||||
leaveRoom: jest.fn(),
|
leaveRoom: vi.fn(),
|
||||||
updateRooms: jest.fn(),
|
updateRooms: vi.fn(),
|
||||||
updateGames: jest.fn(),
|
updateGames: vi.fn(),
|
||||||
addMessage: jest.fn(),
|
addMessage: vi.fn(),
|
||||||
userJoined: jest.fn(),
|
userJoined: vi.fn(),
|
||||||
userLeft: jest.fn(),
|
userLeft: vi.fn(),
|
||||||
removeMessages: jest.fn(),
|
removeMessages: vi.fn(),
|
||||||
gameCreated: jest.fn(),
|
gameCreated: vi.fn(),
|
||||||
joinedGame: jest.fn(),
|
joinedGame: vi.fn(),
|
||||||
},
|
},
|
||||||
RoomsSelectors: {
|
RoomsSelectors: {
|
||||||
getRoom: jest.fn(),
|
getRoom: vi.fn(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../utils/NormalizeService', () => ({
|
vi.mock('../utils/NormalizeService', () => ({
|
||||||
__esModule: true,
|
__esModule: true,
|
||||||
default: {
|
default: {
|
||||||
normalizeRoomInfo: jest.fn(),
|
normalizeRoomInfo: vi.fn(),
|
||||||
normalizeGameObject: jest.fn(),
|
normalizeGameObject: vi.fn(),
|
||||||
normalizeUserMessage: jest.fn(),
|
normalizeUserMessage: vi.fn(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
@ -32,7 +32,7 @@ import { store, RoomsDispatch, RoomsSelectors } from 'store';
|
||||||
import NormalizeService from '../utils/NormalizeService';
|
import NormalizeService from '../utils/NormalizeService';
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('RoomPersistence', () => {
|
describe('RoomPersistence', () => {
|
||||||
|
|
@ -62,7 +62,7 @@ describe('RoomPersistence', () => {
|
||||||
it('normalizes game when gameType is missing and room exists', () => {
|
it('normalizes game when gameType is missing and room exists', () => {
|
||||||
const game = { gameType: null, gameTypes: [1] } as any;
|
const game = { gameType: null, gameTypes: [1] } as any;
|
||||||
const room = { gametypeMap: { 1: 'Standard' } } as any;
|
const room = { gametypeMap: { 1: 'Standard' } } as any;
|
||||||
(RoomsSelectors.getRoom as jest.Mock).mockReturnValue(room);
|
(RoomsSelectors.getRoom as vi.Mock).mockReturnValue(room);
|
||||||
RoomPersistence.updateGames(1, [game]);
|
RoomPersistence.updateGames(1, [game]);
|
||||||
expect(NormalizeService.normalizeGameObject).toHaveBeenCalledWith(game, room.gametypeMap);
|
expect(NormalizeService.normalizeGameObject).toHaveBeenCalledWith(game, room.gametypeMap);
|
||||||
expect(RoomsDispatch.updateGames).toHaveBeenCalledWith(1, [game]);
|
expect(RoomsDispatch.updateGames).toHaveBeenCalledWith(1, [game]);
|
||||||
|
|
@ -76,7 +76,7 @@ describe('RoomPersistence', () => {
|
||||||
|
|
||||||
it('does not normalize when room is not found', () => {
|
it('does not normalize when room is not found', () => {
|
||||||
const game = { gameType: null } as any;
|
const game = { gameType: null } as any;
|
||||||
(RoomsSelectors.getRoom as jest.Mock).mockReturnValue(null);
|
(RoomsSelectors.getRoom as vi.Mock).mockReturnValue(null);
|
||||||
RoomPersistence.updateGames(1, [game]);
|
RoomPersistence.updateGames(1, [game]);
|
||||||
expect(NormalizeService.normalizeGameObject).not.toHaveBeenCalled();
|
expect(NormalizeService.normalizeGameObject).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,74 +1,74 @@
|
||||||
jest.mock('store', () => ({
|
vi.mock('store', () => ({
|
||||||
ServerDispatch: {
|
ServerDispatch: {
|
||||||
initialized: jest.fn(),
|
initialized: vi.fn(),
|
||||||
clearStore: jest.fn(),
|
clearStore: vi.fn(),
|
||||||
loginSuccessful: jest.fn(),
|
loginSuccessful: vi.fn(),
|
||||||
loginFailed: jest.fn(),
|
loginFailed: vi.fn(),
|
||||||
connectionClosed: jest.fn(),
|
connectionClosed: vi.fn(),
|
||||||
connectionFailed: jest.fn(),
|
connectionFailed: vi.fn(),
|
||||||
testConnectionSuccessful: jest.fn(),
|
testConnectionSuccessful: vi.fn(),
|
||||||
testConnectionFailed: jest.fn(),
|
testConnectionFailed: vi.fn(),
|
||||||
updateBuddyList: jest.fn(),
|
updateBuddyList: vi.fn(),
|
||||||
addToBuddyList: jest.fn(),
|
addToBuddyList: vi.fn(),
|
||||||
removeFromBuddyList: jest.fn(),
|
removeFromBuddyList: vi.fn(),
|
||||||
updateIgnoreList: jest.fn(),
|
updateIgnoreList: vi.fn(),
|
||||||
addToIgnoreList: jest.fn(),
|
addToIgnoreList: vi.fn(),
|
||||||
removeFromIgnoreList: jest.fn(),
|
removeFromIgnoreList: vi.fn(),
|
||||||
updateInfo: jest.fn(),
|
updateInfo: vi.fn(),
|
||||||
updateStatus: jest.fn(),
|
updateStatus: vi.fn(),
|
||||||
updateUser: jest.fn(),
|
updateUser: vi.fn(),
|
||||||
updateUsers: jest.fn(),
|
updateUsers: vi.fn(),
|
||||||
userJoined: jest.fn(),
|
userJoined: vi.fn(),
|
||||||
userLeft: jest.fn(),
|
userLeft: vi.fn(),
|
||||||
serverMessage: jest.fn(),
|
serverMessage: vi.fn(),
|
||||||
accountAwaitingActivation: jest.fn(),
|
accountAwaitingActivation: vi.fn(),
|
||||||
accountActivationSuccess: jest.fn(),
|
accountActivationSuccess: vi.fn(),
|
||||||
accountActivationFailed: jest.fn(),
|
accountActivationFailed: vi.fn(),
|
||||||
registrationRequiresEmail: jest.fn(),
|
registrationRequiresEmail: vi.fn(),
|
||||||
registrationSuccess: jest.fn(),
|
registrationSuccess: vi.fn(),
|
||||||
registrationFailed: jest.fn(),
|
registrationFailed: vi.fn(),
|
||||||
registrationEmailError: jest.fn(),
|
registrationEmailError: vi.fn(),
|
||||||
registrationPasswordError: jest.fn(),
|
registrationPasswordError: vi.fn(),
|
||||||
registrationUserNameError: jest.fn(),
|
registrationUserNameError: vi.fn(),
|
||||||
resetPasswordChallenge: jest.fn(),
|
resetPasswordChallenge: vi.fn(),
|
||||||
resetPassword: jest.fn(),
|
resetPassword: vi.fn(),
|
||||||
resetPasswordSuccess: jest.fn(),
|
resetPasswordSuccess: vi.fn(),
|
||||||
resetPasswordFailed: jest.fn(),
|
resetPasswordFailed: vi.fn(),
|
||||||
accountPasswordChange: jest.fn(),
|
accountPasswordChange: vi.fn(),
|
||||||
accountEditChanged: jest.fn(),
|
accountEditChanged: vi.fn(),
|
||||||
accountImageChanged: jest.fn(),
|
accountImageChanged: vi.fn(),
|
||||||
getUserInfo: jest.fn(),
|
getUserInfo: vi.fn(),
|
||||||
notifyUser: jest.fn(),
|
notifyUser: vi.fn(),
|
||||||
serverShutdown: jest.fn(),
|
serverShutdown: vi.fn(),
|
||||||
userMessage: jest.fn(),
|
userMessage: vi.fn(),
|
||||||
addToList: jest.fn(),
|
addToList: vi.fn(),
|
||||||
removeFromList: jest.fn(),
|
removeFromList: vi.fn(),
|
||||||
deckDelete: jest.fn(),
|
deckDelete: vi.fn(),
|
||||||
backendDecks: jest.fn(),
|
backendDecks: vi.fn(),
|
||||||
deckUpload: jest.fn(),
|
deckUpload: vi.fn(),
|
||||||
deckNewDir: jest.fn(),
|
deckNewDir: vi.fn(),
|
||||||
deckDelDir: jest.fn(),
|
deckDelDir: vi.fn(),
|
||||||
replayList: jest.fn(),
|
replayList: vi.fn(),
|
||||||
replayAdded: jest.fn(),
|
replayAdded: vi.fn(),
|
||||||
replayModifyMatch: jest.fn(),
|
replayModifyMatch: vi.fn(),
|
||||||
replayDeleteMatch: jest.fn(),
|
replayDeleteMatch: vi.fn(),
|
||||||
gamesOfUser: jest.fn(),
|
gamesOfUser: vi.fn(),
|
||||||
},
|
},
|
||||||
GameDispatch: {
|
GameDispatch: {
|
||||||
gameJoined: jest.fn(),
|
gameJoined: vi.fn(),
|
||||||
playerPropertiesChanged: jest.fn(),
|
playerPropertiesChanged: vi.fn(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('websocket/utils', () => ({
|
vi.mock('websocket/utils', () => ({
|
||||||
sanitizeHtml: jest.fn((msg: string) => `sanitized:${msg}`),
|
sanitizeHtml: vi.fn((msg: string) => `sanitized:${msg}`),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../utils/NormalizeService', () => ({
|
vi.mock('../utils/NormalizeService', () => ({
|
||||||
__esModule: true,
|
__esModule: true,
|
||||||
default: {
|
default: {
|
||||||
normalizeBannedUserError: jest.fn((r: string, t: number) => `banned:${r}:${t}`),
|
normalizeBannedUserError: vi.fn((r: string, t: number) => `banned:${r}:${t}`),
|
||||||
normalizeGameObject: jest.fn(),
|
normalizeGameObject: vi.fn(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
@ -79,9 +79,9 @@ import NormalizeService from '../utils/NormalizeService';
|
||||||
import { StatusEnum } from 'types';
|
import { StatusEnum } from 'types';
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
(sanitizeHtml as jest.Mock).mockImplementation((msg: string) => `sanitized:${msg}`);
|
(sanitizeHtml as vi.Mock).mockImplementation((msg: string) => `sanitized:${msg}`);
|
||||||
(NormalizeService.normalizeBannedUserError as jest.Mock).mockImplementation(
|
(NormalizeService.normalizeBannedUserError as vi.Mock).mockImplementation(
|
||||||
(r: string, t: number) => `banned:${r}:${t}`
|
(r: string, t: number) => `banned:${r}:${t}`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
import { makeMockProtoRoot } from '../__mocks__/helpers';
|
import { makeMockProtoRoot } from '../__mocks__/helpers';
|
||||||
|
|
||||||
jest.mock('./ProtoController', () => ({
|
vi.mock('./ProtoController', () => ({
|
||||||
ProtoController: { root: null },
|
ProtoController: { root: null },
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../WebClient', () => {
|
vi.mock('../WebClient', () => {
|
||||||
const mockProtobuf = {
|
const mockProtobuf = {
|
||||||
sendGameCommand: jest.fn(),
|
sendGameCommand: vi.fn(),
|
||||||
sendSessionCommand: jest.fn(),
|
sendSessionCommand: vi.fn(),
|
||||||
sendRoomCommand: jest.fn(),
|
sendRoomCommand: vi.fn(),
|
||||||
sendModeratorCommand: jest.fn(),
|
sendModeratorCommand: vi.fn(),
|
||||||
sendAdminCommand: jest.fn(),
|
sendAdminCommand: vi.fn(),
|
||||||
};
|
};
|
||||||
return { __esModule: true, default: { protobuf: mockProtobuf } };
|
return { __esModule: true, default: { protobuf: mockProtobuf } };
|
||||||
});
|
});
|
||||||
|
|
@ -20,18 +20,18 @@ import { ProtoController } from './ProtoController';
|
||||||
import webClient from '../WebClient';
|
import webClient from '../WebClient';
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
ProtoController.root = makeMockProtoRoot();
|
ProtoController.root = makeMockProtoRoot();
|
||||||
ProtoController.root.GameCommand = { create: jest.fn(args => ({ ...args })) };
|
ProtoController.root.GameCommand = { create: vi.fn(args => ({ ...args })) };
|
||||||
ProtoController.root['Command_Game'] = { create: jest.fn(p => ({ ...p })) };
|
ProtoController.root['Command_Game'] = { create: vi.fn(p => ({ ...p })) };
|
||||||
ProtoController.root['Command_Test'] = { create: jest.fn(p => ({ ...p })) };
|
ProtoController.root['Command_Test'] = { create: vi.fn(p => ({ ...p })) };
|
||||||
ProtoController.root['Command_Room'] = { create: jest.fn(p => ({ ...p })) };
|
ProtoController.root['Command_Room'] = { create: vi.fn(p => ({ ...p })) };
|
||||||
ProtoController.root['Command_Mod'] = { create: jest.fn(p => ({ ...p })) };
|
ProtoController.root['Command_Mod'] = { create: vi.fn(p => ({ ...p })) };
|
||||||
ProtoController.root['Command_Admin'] = { create: jest.fn(p => ({ ...p })) };
|
ProtoController.root['Command_Admin'] = { create: vi.fn(p => ({ ...p })) };
|
||||||
ProtoController.root['Response_Test'] = {};
|
ProtoController.root['Response_Test'] = {};
|
||||||
});
|
});
|
||||||
|
|
||||||
function captureCallback(sendFn: jest.Mock) {
|
function captureCallback(sendFn: vi.Mock) {
|
||||||
return sendFn.mock.calls[0][sendFn === (webClient.protobuf as any).sendRoomCommand ? 2 : 1];
|
return sendFn.mock.calls[0][sendFn === (webClient.protobuf as any).sendRoomCommand ? 2 : 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -51,7 +51,7 @@ describe('BackendService', () => {
|
||||||
|
|
||||||
describe('handleResponse via non-session command callbacks', () => {
|
describe('handleResponse via non-session command callbacks', () => {
|
||||||
it('sendGameCommand callback invokes handleResponse', () => {
|
it('sendGameCommand callback invokes handleResponse', () => {
|
||||||
const onSuccess = jest.fn();
|
const onSuccess = vi.fn();
|
||||||
BackendService.sendGameCommand(7, 'Command_Game', {}, { onSuccess });
|
BackendService.sendGameCommand(7, 'Command_Game', {}, { onSuccess });
|
||||||
const cb = (webClient.protobuf as any).sendGameCommand.mock.calls[0][2];
|
const cb = (webClient.protobuf as any).sendGameCommand.mock.calls[0][2];
|
||||||
cb({ responseCode: 0 });
|
cb({ responseCode: 0 });
|
||||||
|
|
@ -59,21 +59,21 @@ describe('BackendService', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sendRoomCommand callback invokes handleResponse', () => {
|
it('sendRoomCommand callback invokes handleResponse', () => {
|
||||||
const onSuccess = jest.fn();
|
const onSuccess = vi.fn();
|
||||||
BackendService.sendRoomCommand(5, 'Command_Room', {}, { onSuccess });
|
BackendService.sendRoomCommand(5, 'Command_Room', {}, { onSuccess });
|
||||||
captureCallback((webClient.protobuf as any).sendRoomCommand)({ responseCode: 0 });
|
captureCallback((webClient.protobuf as any).sendRoomCommand)({ responseCode: 0 });
|
||||||
expect(onSuccess).toHaveBeenCalled();
|
expect(onSuccess).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sendModeratorCommand callback invokes handleResponse', () => {
|
it('sendModeratorCommand callback invokes handleResponse', () => {
|
||||||
const onSuccess = jest.fn();
|
const onSuccess = vi.fn();
|
||||||
BackendService.sendModeratorCommand('Command_Mod', {}, { onSuccess });
|
BackendService.sendModeratorCommand('Command_Mod', {}, { onSuccess });
|
||||||
captureCallback((webClient.protobuf as any).sendModeratorCommand)({ responseCode: 0 });
|
captureCallback((webClient.protobuf as any).sendModeratorCommand)({ responseCode: 0 });
|
||||||
expect(onSuccess).toHaveBeenCalled();
|
expect(onSuccess).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sendAdminCommand callback invokes handleResponse', () => {
|
it('sendAdminCommand callback invokes handleResponse', () => {
|
||||||
const onSuccess = jest.fn();
|
const onSuccess = vi.fn();
|
||||||
BackendService.sendAdminCommand('Command_Admin', {}, { onSuccess });
|
BackendService.sendAdminCommand('Command_Admin', {}, { onSuccess });
|
||||||
captureCallback((webClient.protobuf as any).sendAdminCommand)({ responseCode: 0 });
|
captureCallback((webClient.protobuf as any).sendAdminCommand)({ responseCode: 0 });
|
||||||
expect(onSuccess).toHaveBeenCalled();
|
expect(onSuccess).toHaveBeenCalled();
|
||||||
|
|
@ -88,41 +88,41 @@ describe('BackendService', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
it('calls onResponse and returns early when provided', () => {
|
it('calls onResponse and returns early when provided', () => {
|
||||||
const onResponse = jest.fn();
|
const onResponse = vi.fn();
|
||||||
const onSuccess = jest.fn();
|
const onSuccess = vi.fn();
|
||||||
invokeCallback({ onResponse, onSuccess }, { responseCode: 99 });
|
invokeCallback({ onResponse, onSuccess }, { responseCode: 99 });
|
||||||
expect(onResponse).toHaveBeenCalled();
|
expect(onResponse).toHaveBeenCalled();
|
||||||
expect(onSuccess).not.toHaveBeenCalled();
|
expect(onSuccess).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('calls onSuccess with raw when responseCode is RespOk and no responseName', () => {
|
it('calls onSuccess with raw when responseCode is RespOk and no responseName', () => {
|
||||||
const onSuccess = jest.fn();
|
const onSuccess = vi.fn();
|
||||||
const raw = { responseCode: 0 };
|
const raw = { responseCode: 0 };
|
||||||
invokeCallback({ onSuccess }, raw);
|
invokeCallback({ onSuccess }, raw);
|
||||||
expect(onSuccess).toHaveBeenCalledWith(raw, raw);
|
expect(onSuccess).toHaveBeenCalledWith(raw, raw);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('calls onSuccess with nested response when responseName is set', () => {
|
it('calls onSuccess with nested response when responseName is set', () => {
|
||||||
const onSuccess = jest.fn();
|
const onSuccess = vi.fn();
|
||||||
const raw = { responseCode: 0, '.Response_Test.ext': { nested: true } };
|
const raw = { responseCode: 0, '.Response_Test.ext': { nested: true } };
|
||||||
invokeCallback({ onSuccess, responseName: 'Response_Test' }, raw);
|
invokeCallback({ onSuccess, responseName: 'Response_Test' }, raw);
|
||||||
expect(onSuccess).toHaveBeenCalledWith({ nested: true }, raw);
|
expect(onSuccess).toHaveBeenCalledWith({ nested: true }, raw);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('calls onResponseCode handler when code matches', () => {
|
it('calls onResponseCode handler when code matches', () => {
|
||||||
const specificHandler = jest.fn();
|
const specificHandler = vi.fn();
|
||||||
invokeCallback({ onResponseCode: { 5: specificHandler } }, { responseCode: 5 });
|
invokeCallback({ onResponseCode: { 5: specificHandler } }, { responseCode: 5 });
|
||||||
expect(specificHandler).toHaveBeenCalled();
|
expect(specificHandler).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('calls onError when responseCode is not RespOk and no specific handler', () => {
|
it('calls onError when responseCode is not RespOk and no specific handler', () => {
|
||||||
const onError = jest.fn();
|
const onError = vi.fn();
|
||||||
invokeCallback({ onError }, { responseCode: 99 });
|
invokeCallback({ onError }, { responseCode: 99 });
|
||||||
expect(onError).toHaveBeenCalledWith(99, { responseCode: 99 });
|
expect(onError).toHaveBeenCalledWith(99, { responseCode: 99 });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('logs error to console when no callbacks for non-RespOk response', () => {
|
it('logs error to console when no callbacks for non-RespOk response', () => {
|
||||||
const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
invokeCallback({}, { responseCode: 42 });
|
invokeCallback({}, { responseCode: 42 });
|
||||||
expect(consoleSpy).toHaveBeenCalled();
|
expect(consoleSpy).toHaveBeenCalled();
|
||||||
consoleSpy.mockRestore();
|
consoleSpy.mockRestore();
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ describe('KeepAliveService', () => {
|
||||||
let service: KeepAliveService;
|
let service: KeepAliveService;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.useFakeTimers();
|
vi.useFakeTimers();
|
||||||
|
|
||||||
service = new KeepAliveService(webClient.socket);
|
service = new KeepAliveService(webClient.socket);
|
||||||
});
|
});
|
||||||
|
|
@ -27,11 +27,11 @@ describe('KeepAliveService', () => {
|
||||||
promise = new Promise(resolve => resolvePing = resolve);
|
promise = new Promise(resolve => resolvePing = resolve);
|
||||||
ping = (done) => promise.then(done);
|
ping = (done) => promise.then(done);
|
||||||
|
|
||||||
checkReadyStateSpy = jest.spyOn(webClient.socket, 'checkReadyState');
|
checkReadyStateSpy = vi.spyOn(webClient.socket, 'checkReadyState');
|
||||||
checkReadyStateSpy.mockImplementation(() => true);
|
checkReadyStateSpy.mockImplementation(() => true);
|
||||||
|
|
||||||
service.startPingLoop(interval, ping);
|
service.startPingLoop(interval, ping);
|
||||||
jest.advanceTimersByTime(interval);
|
vi.advanceTimersByTime(interval);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should start ping loop', () => {
|
it('should start ping loop', () => {
|
||||||
|
|
@ -39,28 +39,27 @@ describe('KeepAliveService', () => {
|
||||||
expect((service as any).lastPingPending).toBeTruthy();
|
expect((service as any).lastPingPending).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call ping callback when done', (done: jest.DoneCallback) => {
|
it('should call ping callback when done', () => {
|
||||||
resolvePing();
|
resolvePing();
|
||||||
|
|
||||||
promise.then(() => {
|
return promise.then(() => {
|
||||||
expect((service as any).lastPingPending).toBeFalsy();
|
expect((service as any).lastPingPending).toBeFalsy();
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fire disconnected$ if lastPingPending is still true', () => {
|
it('should fire disconnected$ if lastPingPending is still true', () => {
|
||||||
jest.spyOn(service.disconnected$, 'next').mockImplementation(() => {});
|
vi.spyOn(service.disconnected$, 'next').mockImplementation(() => {});
|
||||||
jest.advanceTimersByTime(interval);
|
vi.advanceTimersByTime(interval);
|
||||||
|
|
||||||
expect(service.disconnected$.next).toHaveBeenCalled();
|
expect(service.disconnected$.next).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should endPingLoop if socket is not open', () => {
|
it('should endPingLoop if socket is not open', () => {
|
||||||
jest.spyOn(service, 'endPingLoop').mockImplementation(() => {});
|
vi.spyOn(service, 'endPingLoop').mockImplementation(() => {});
|
||||||
checkReadyStateSpy.mockImplementation(() => false);
|
checkReadyStateSpy.mockImplementation(() => false);
|
||||||
|
|
||||||
resolvePing();
|
resolvePing();
|
||||||
jest.advanceTimersByTime(interval);
|
vi.advanceTimersByTime(interval);
|
||||||
|
|
||||||
expect(service.endPingLoop).toHaveBeenCalled();
|
expect(service.endPingLoop).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,16 @@
|
||||||
jest.mock('../persistence', () => ({
|
vi.mock('../persistence', () => ({
|
||||||
SessionPersistence: { initialized: jest.fn() },
|
SessionPersistence: { initialized: vi.fn() },
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../../proto-files.json', () => ['test.proto'], { virtual: true });
|
vi.mock('../../proto-files.json', () => ({ default: ['test.proto'] }));
|
||||||
|
|
||||||
import { ProtoController } from './ProtoController';
|
import { ProtoController } from './ProtoController';
|
||||||
import { SessionPersistence } from '../persistence';
|
import { SessionPersistence } from '../persistence';
|
||||||
import protobuf from 'protobufjs';
|
import protobuf from 'protobufjs';
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
ProtoController.root = null;
|
ProtoController.root = null;
|
||||||
(process.env as any).PUBLIC_URL = '';
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('ProtoController', () => {
|
describe('ProtoController', () => {
|
||||||
|
|
@ -22,7 +21,7 @@ describe('ProtoController', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('calls initialized when callback succeeds', () => {
|
it('calls initialized when callback succeeds', () => {
|
||||||
const loadSpy = jest.spyOn(protobuf.Root.prototype, 'load').mockImplementation(
|
const loadSpy = vi.spyOn(protobuf.Root.prototype, 'load').mockImplementation(
|
||||||
((_files: any, _opts: any, cb: any) => cb(null)) as any
|
((_files: any, _opts: any, cb: any) => cb(null)) as any
|
||||||
);
|
);
|
||||||
ProtoController.load();
|
ProtoController.load();
|
||||||
|
|
@ -31,7 +30,7 @@ describe('ProtoController', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throws when callback receives an error', () => {
|
it('throws when callback receives an error', () => {
|
||||||
const loadSpy = jest.spyOn(protobuf.Root.prototype, 'load').mockImplementation(
|
const loadSpy = vi.spyOn(protobuf.Root.prototype, 'load').mockImplementation(
|
||||||
((_files: any, _opts: any, cb: any) => cb(new Error('load failed'))) as any
|
((_files: any, _opts: any, cb: any) => cb(new Error('load failed'))) as any
|
||||||
);
|
);
|
||||||
expect(() => ProtoController.load()).toThrow('load failed');
|
expect(() => ProtoController.load()).toThrow('load failed');
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import protobuf from 'protobufjs';
|
||||||
import { SessionPersistence } from '../persistence';
|
import { SessionPersistence } from '../persistence';
|
||||||
import ProtoFiles from '../../proto-files.json';
|
import ProtoFiles from '../../proto-files.json';
|
||||||
|
|
||||||
const PB_FILE_DIR = `${process.env.PUBLIC_URL}/pb`;
|
const PB_FILE_DIR = `${import.meta.env.BASE_URL}pb`;
|
||||||
|
|
||||||
// Leaf module — no imports from the websocket layer other than persistence.
|
// Leaf module — no imports from the websocket layer other than persistence.
|
||||||
// Both BackendService and ProtobufService import this; neither should import
|
// Both BackendService and ProtobufService import this; neither should import
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,24 @@
|
||||||
import { makeMockProtoRoot } from '../__mocks__/helpers';
|
import { makeMockProtoRoot } from '../__mocks__/helpers';
|
||||||
|
|
||||||
jest.mock('./ProtoController', () => ({
|
vi.mock('./ProtoController', () => ({
|
||||||
ProtoController: { root: null, load: jest.fn() },
|
ProtoController: { root: null, load: vi.fn() },
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../commands/session', () => ({
|
vi.mock('../commands/session', () => ({
|
||||||
SessionCommands: { ping: jest.fn() },
|
SessionCommands: { ping: vi.fn() },
|
||||||
ping: jest.fn(),
|
ping: vi.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../events', () => ({
|
vi.mock('../events', () => ({
|
||||||
GameEvents: { '.Event_Game.ext': jest.fn() },
|
GameEvents: { '.Event_Game.ext': vi.fn() },
|
||||||
RoomEvents: { '.Event_Room.ext': jest.fn() },
|
RoomEvents: { '.Event_Room.ext': vi.fn() },
|
||||||
SessionEvents: { '.Event_Session.ext': jest.fn() },
|
SessionEvents: { '.Event_Session.ext': vi.fn() },
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../WebClient');
|
vi.mock('../WebClient', () => ({
|
||||||
|
__esModule: true,
|
||||||
|
default: {},
|
||||||
|
}));
|
||||||
|
|
||||||
import { ProtobufService } from './ProtobufService';
|
import { ProtobufService } from './ProtobufService';
|
||||||
import { ProtoController } from './ProtoController';
|
import { ProtoController } from './ProtoController';
|
||||||
|
|
@ -26,15 +29,15 @@ let mockSocket: any;
|
||||||
let mockWebClient: any;
|
let mockWebClient: any;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
|
|
||||||
ProtoController.root = makeMockProtoRoot();
|
ProtoController.root = makeMockProtoRoot();
|
||||||
const encodeResult = { finish: jest.fn().mockReturnValue(new Uint8Array([1, 2])) };
|
const encodeResult = { finish: vi.fn().mockReturnValue(new Uint8Array([1, 2])) };
|
||||||
ProtoController.root.CommandContainer.encode = jest.fn().mockReturnValue(encodeResult);
|
ProtoController.root.CommandContainer.encode = vi.fn().mockReturnValue(encodeResult);
|
||||||
|
|
||||||
mockSocket = {
|
mockSocket = {
|
||||||
checkReadyState: jest.fn().mockReturnValue(true),
|
checkReadyState: vi.fn().mockReturnValue(true),
|
||||||
send: jest.fn(),
|
send: vi.fn(),
|
||||||
};
|
};
|
||||||
|
|
||||||
mockWebClient = {
|
mockWebClient = {
|
||||||
|
|
@ -52,7 +55,7 @@ describe('ProtobufService', () => {
|
||||||
it('resets cmdId and pendingCommands', () => {
|
it('resets cmdId and pendingCommands', () => {
|
||||||
const service = new ProtobufService(mockWebClient);
|
const service = new ProtobufService(mockWebClient);
|
||||||
// add a pending command
|
// add a pending command
|
||||||
service.sendSessionCommand({}, jest.fn());
|
service.sendSessionCommand({}, vi.fn());
|
||||||
expect((service as any).cmdId).toBe(1);
|
expect((service as any).cmdId).toBe(1);
|
||||||
service.resetCommands();
|
service.resetCommands();
|
||||||
expect((service as any).cmdId).toBe(0);
|
expect((service as any).cmdId).toBe(0);
|
||||||
|
|
@ -63,7 +66,7 @@ describe('ProtobufService', () => {
|
||||||
describe('sendCommand', () => {
|
describe('sendCommand', () => {
|
||||||
it('increments cmdId and stores callback', () => {
|
it('increments cmdId and stores callback', () => {
|
||||||
const service = new ProtobufService(mockWebClient);
|
const service = new ProtobufService(mockWebClient);
|
||||||
const cb = jest.fn();
|
const cb = vi.fn();
|
||||||
service.sendCommand({}, cb);
|
service.sendCommand({}, cb);
|
||||||
expect((service as any).cmdId).toBe(1);
|
expect((service as any).cmdId).toBe(1);
|
||||||
expect((service as any).pendingCommands[1]).toBe(cb);
|
expect((service as any).pendingCommands[1]).toBe(cb);
|
||||||
|
|
@ -72,14 +75,14 @@ describe('ProtobufService', () => {
|
||||||
it('sends encoded data when socket is OPEN', () => {
|
it('sends encoded data when socket is OPEN', () => {
|
||||||
const service = new ProtobufService(mockWebClient);
|
const service = new ProtobufService(mockWebClient);
|
||||||
mockSocket.checkReadyState.mockReturnValue(true);
|
mockSocket.checkReadyState.mockReturnValue(true);
|
||||||
service.sendCommand({}, jest.fn());
|
service.sendCommand({}, vi.fn());
|
||||||
expect(mockSocket.send).toHaveBeenCalled();
|
expect(mockSocket.send).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not send when socket is not OPEN', () => {
|
it('does not send when socket is not OPEN', () => {
|
||||||
const service = new ProtobufService(mockWebClient);
|
const service = new ProtobufService(mockWebClient);
|
||||||
mockSocket.checkReadyState.mockReturnValue(false);
|
mockSocket.checkReadyState.mockReturnValue(false);
|
||||||
service.sendCommand({}, jest.fn());
|
service.sendCommand({}, vi.fn());
|
||||||
expect(mockSocket.send).not.toHaveBeenCalled();
|
expect(mockSocket.send).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -87,7 +90,7 @@ describe('ProtobufService', () => {
|
||||||
describe('sendSessionCommand', () => {
|
describe('sendSessionCommand', () => {
|
||||||
it('creates a CommandContainer and calls sendCommand', () => {
|
it('creates a CommandContainer and calls sendCommand', () => {
|
||||||
const service = new ProtobufService(mockWebClient);
|
const service = new ProtobufService(mockWebClient);
|
||||||
const cb = jest.fn();
|
const cb = vi.fn();
|
||||||
service.sendSessionCommand({ cmdType: 'test' }, cb);
|
service.sendSessionCommand({ cmdType: 'test' }, cb);
|
||||||
expect(ProtoController.root.CommandContainer.create).toHaveBeenCalledWith(
|
expect(ProtoController.root.CommandContainer.create).toHaveBeenCalledWith(
|
||||||
expect.objectContaining({ sessionCommand: expect.anything() })
|
expect.objectContaining({ sessionCommand: expect.anything() })
|
||||||
|
|
@ -96,7 +99,7 @@ describe('ProtobufService', () => {
|
||||||
|
|
||||||
it('invokes callback with raw response when the pending command is triggered', () => {
|
it('invokes callback with raw response when the pending command is triggered', () => {
|
||||||
const service = new ProtobufService(mockWebClient);
|
const service = new ProtobufService(mockWebClient);
|
||||||
const cb = jest.fn();
|
const cb = vi.fn();
|
||||||
service.sendSessionCommand({ cmdType: 'test' }, cb);
|
service.sendSessionCommand({ cmdType: 'test' }, cb);
|
||||||
|
|
||||||
const storedCb = (service as any).pendingCommands[1];
|
const storedCb = (service as any).pendingCommands[1];
|
||||||
|
|
@ -117,7 +120,7 @@ describe('ProtobufService', () => {
|
||||||
describe('sendRoomCommand', () => {
|
describe('sendRoomCommand', () => {
|
||||||
it('creates a CommandContainer with roomId and calls sendCommand', () => {
|
it('creates a CommandContainer with roomId and calls sendCommand', () => {
|
||||||
const service = new ProtobufService(mockWebClient);
|
const service = new ProtobufService(mockWebClient);
|
||||||
service.sendRoomCommand(42, { roomCmdType: 'test' }, jest.fn());
|
service.sendRoomCommand(42, { roomCmdType: 'test' }, vi.fn());
|
||||||
expect(ProtoController.root.CommandContainer.create).toHaveBeenCalledWith(
|
expect(ProtoController.root.CommandContainer.create).toHaveBeenCalledWith(
|
||||||
expect.objectContaining({ roomId: 42 })
|
expect.objectContaining({ roomId: 42 })
|
||||||
);
|
);
|
||||||
|
|
@ -125,7 +128,7 @@ describe('ProtobufService', () => {
|
||||||
|
|
||||||
it('invokes callback with raw response when the pending command is triggered', () => {
|
it('invokes callback with raw response when the pending command is triggered', () => {
|
||||||
const service = new ProtobufService(mockWebClient);
|
const service = new ProtobufService(mockWebClient);
|
||||||
const cb = jest.fn();
|
const cb = vi.fn();
|
||||||
service.sendRoomCommand(42, { roomCmdType: 'test' }, cb);
|
service.sendRoomCommand(42, { roomCmdType: 'test' }, cb);
|
||||||
|
|
||||||
const storedCb = (service as any).pendingCommands[1];
|
const storedCb = (service as any).pendingCommands[1];
|
||||||
|
|
@ -146,7 +149,7 @@ describe('ProtobufService', () => {
|
||||||
describe('sendGameCommand', () => {
|
describe('sendGameCommand', () => {
|
||||||
it('creates a CommandContainer with gameId and gameCommand', () => {
|
it('creates a CommandContainer with gameId and gameCommand', () => {
|
||||||
const service = new ProtobufService(mockWebClient);
|
const service = new ProtobufService(mockWebClient);
|
||||||
service.sendGameCommand(7, { gameCmdType: 'test' }, jest.fn());
|
service.sendGameCommand(7, { gameCmdType: 'test' }, vi.fn());
|
||||||
expect(ProtoController.root.CommandContainer.create).toHaveBeenCalledWith(
|
expect(ProtoController.root.CommandContainer.create).toHaveBeenCalledWith(
|
||||||
expect.objectContaining({ gameId: 7, gameCommand: expect.anything() })
|
expect.objectContaining({ gameId: 7, gameCommand: expect.anything() })
|
||||||
);
|
);
|
||||||
|
|
@ -154,7 +157,7 @@ describe('ProtobufService', () => {
|
||||||
|
|
||||||
it('invokes callback with raw response when the pending command is triggered', () => {
|
it('invokes callback with raw response when the pending command is triggered', () => {
|
||||||
const service = new ProtobufService(mockWebClient);
|
const service = new ProtobufService(mockWebClient);
|
||||||
const cb = jest.fn();
|
const cb = vi.fn();
|
||||||
service.sendGameCommand(7, { gameCmdType: 'test' }, cb);
|
service.sendGameCommand(7, { gameCmdType: 'test' }, cb);
|
||||||
|
|
||||||
const storedCb = (service as any).pendingCommands[1];
|
const storedCb = (service as any).pendingCommands[1];
|
||||||
|
|
@ -175,7 +178,7 @@ describe('ProtobufService', () => {
|
||||||
describe('sendModeratorCommand', () => {
|
describe('sendModeratorCommand', () => {
|
||||||
it('creates a CommandContainer with moderatorCommand', () => {
|
it('creates a CommandContainer with moderatorCommand', () => {
|
||||||
const service = new ProtobufService(mockWebClient);
|
const service = new ProtobufService(mockWebClient);
|
||||||
service.sendModeratorCommand({ modCmdType: 'test' }, jest.fn());
|
service.sendModeratorCommand({ modCmdType: 'test' }, vi.fn());
|
||||||
expect(ProtoController.root.CommandContainer.create).toHaveBeenCalledWith(
|
expect(ProtoController.root.CommandContainer.create).toHaveBeenCalledWith(
|
||||||
expect.objectContaining({ moderatorCommand: expect.anything() })
|
expect.objectContaining({ moderatorCommand: expect.anything() })
|
||||||
);
|
);
|
||||||
|
|
@ -183,7 +186,7 @@ describe('ProtobufService', () => {
|
||||||
|
|
||||||
it('invokes callback with raw response when the pending command is triggered', () => {
|
it('invokes callback with raw response when the pending command is triggered', () => {
|
||||||
const service = new ProtobufService(mockWebClient);
|
const service = new ProtobufService(mockWebClient);
|
||||||
const cb = jest.fn();
|
const cb = vi.fn();
|
||||||
service.sendModeratorCommand({ modCmdType: 'test' }, cb);
|
service.sendModeratorCommand({ modCmdType: 'test' }, cb);
|
||||||
|
|
||||||
const storedCb = (service as any).pendingCommands[1];
|
const storedCb = (service as any).pendingCommands[1];
|
||||||
|
|
@ -204,7 +207,7 @@ describe('ProtobufService', () => {
|
||||||
describe('sendAdminCommand', () => {
|
describe('sendAdminCommand', () => {
|
||||||
it('creates a CommandContainer with adminCommand', () => {
|
it('creates a CommandContainer with adminCommand', () => {
|
||||||
const service = new ProtobufService(mockWebClient);
|
const service = new ProtobufService(mockWebClient);
|
||||||
service.sendAdminCommand({ adminCmdType: 'test' }, jest.fn());
|
service.sendAdminCommand({ adminCmdType: 'test' }, vi.fn());
|
||||||
expect(ProtoController.root.CommandContainer.create).toHaveBeenCalledWith(
|
expect(ProtoController.root.CommandContainer.create).toHaveBeenCalledWith(
|
||||||
expect.objectContaining({ adminCommand: expect.anything() })
|
expect.objectContaining({ adminCommand: expect.anything() })
|
||||||
);
|
);
|
||||||
|
|
@ -212,7 +215,7 @@ describe('ProtobufService', () => {
|
||||||
|
|
||||||
it('invokes callback with raw response when the pending command is triggered', () => {
|
it('invokes callback with raw response when the pending command is triggered', () => {
|
||||||
const service = new ProtobufService(mockWebClient);
|
const service = new ProtobufService(mockWebClient);
|
||||||
const cb = jest.fn();
|
const cb = vi.fn();
|
||||||
service.sendAdminCommand({ adminCmdType: 'test' }, cb);
|
service.sendAdminCommand({ adminCmdType: 'test' }, cb);
|
||||||
|
|
||||||
const storedCb = (service as any).pendingCommands[1];
|
const storedCb = (service as any).pendingCommands[1];
|
||||||
|
|
@ -233,7 +236,7 @@ describe('ProtobufService', () => {
|
||||||
describe('sendKeepAliveCommand', () => {
|
describe('sendKeepAliveCommand', () => {
|
||||||
it('delegates to SessionCommands.ping', () => {
|
it('delegates to SessionCommands.ping', () => {
|
||||||
const service = new ProtobufService(mockWebClient);
|
const service = new ProtobufService(mockWebClient);
|
||||||
const pingReceived = jest.fn();
|
const pingReceived = vi.fn();
|
||||||
service.sendKeepAliveCommand(pingReceived);
|
service.sendKeepAliveCommand(pingReceived);
|
||||||
expect(sessionPing).toHaveBeenCalledWith(pingReceived);
|
expect(sessionPing).toHaveBeenCalledWith(pingReceived);
|
||||||
});
|
});
|
||||||
|
|
@ -242,13 +245,13 @@ describe('ProtobufService', () => {
|
||||||
describe('handleMessageEvent', () => {
|
describe('handleMessageEvent', () => {
|
||||||
it('routes RESPONSE message to processServerResponse', () => {
|
it('routes RESPONSE message to processServerResponse', () => {
|
||||||
const service = new ProtobufService(mockWebClient);
|
const service = new ProtobufService(mockWebClient);
|
||||||
const cb = jest.fn();
|
const cb = vi.fn();
|
||||||
// store a callback for cmdId 1
|
// store a callback for cmdId 1
|
||||||
(service as any).cmdId = 1;
|
(service as any).cmdId = 1;
|
||||||
(service as any).pendingCommands[1] = cb;
|
(service as any).pendingCommands[1] = cb;
|
||||||
|
|
||||||
const response = { cmdId: 1 };
|
const response = { cmdId: 1 };
|
||||||
ProtoController.root.ServerMessage.decode = jest.fn().mockReturnValue({
|
ProtoController.root.ServerMessage.decode = vi.fn().mockReturnValue({
|
||||||
messageType: ProtoController.root.ServerMessage.MessageType.RESPONSE,
|
messageType: ProtoController.root.ServerMessage.MessageType.RESPONSE,
|
||||||
response,
|
response,
|
||||||
});
|
});
|
||||||
|
|
@ -260,14 +263,14 @@ describe('ProtobufService', () => {
|
||||||
|
|
||||||
it('resolves pending command when response cmdId is a protobufjs Long object', () => {
|
it('resolves pending command when response cmdId is a protobufjs Long object', () => {
|
||||||
const service = new ProtobufService(mockWebClient);
|
const service = new ProtobufService(mockWebClient);
|
||||||
const cb = jest.fn();
|
const cb = vi.fn();
|
||||||
(service as any).cmdId = 1;
|
(service as any).cmdId = 1;
|
||||||
(service as any).pendingCommands[1] = cb;
|
(service as any).pendingCommands[1] = cb;
|
||||||
|
|
||||||
// Simulate protobufjs decoding cmdId as a Long object (low=1, high=0)
|
// Simulate protobufjs decoding cmdId as a Long object (low=1, high=0)
|
||||||
const longCmdId = { low: 1, high: 0, unsigned: false, toString: () => '1' };
|
const longCmdId = { low: 1, high: 0, unsigned: false, toString: () => '1' };
|
||||||
const response = { cmdId: longCmdId };
|
const response = { cmdId: longCmdId };
|
||||||
ProtoController.root.ServerMessage.decode = jest.fn().mockReturnValue({
|
ProtoController.root.ServerMessage.decode = vi.fn().mockReturnValue({
|
||||||
messageType: ProtoController.root.ServerMessage.MessageType.RESPONSE,
|
messageType: ProtoController.root.ServerMessage.MessageType.RESPONSE,
|
||||||
response,
|
response,
|
||||||
});
|
});
|
||||||
|
|
@ -279,8 +282,8 @@ describe('ProtobufService', () => {
|
||||||
|
|
||||||
it('routes ROOM_EVENT message', () => {
|
it('routes ROOM_EVENT message', () => {
|
||||||
const service = new ProtobufService(mockWebClient);
|
const service = new ProtobufService(mockWebClient);
|
||||||
const processRoomEvent = jest.spyOn(service as any, 'processRoomEvent');
|
const processRoomEvent = vi.spyOn(service as any, 'processRoomEvent');
|
||||||
ProtoController.root.ServerMessage.decode = jest.fn().mockReturnValue({
|
ProtoController.root.ServerMessage.decode = vi.fn().mockReturnValue({
|
||||||
messageType: ProtoController.root.ServerMessage.MessageType.ROOM_EVENT,
|
messageType: ProtoController.root.ServerMessage.MessageType.ROOM_EVENT,
|
||||||
roomEvent: { '.Event_Room.ext': {} },
|
roomEvent: { '.Event_Room.ext': {} },
|
||||||
});
|
});
|
||||||
|
|
@ -290,8 +293,8 @@ describe('ProtobufService', () => {
|
||||||
|
|
||||||
it('routes SESSION_EVENT message', () => {
|
it('routes SESSION_EVENT message', () => {
|
||||||
const service = new ProtobufService(mockWebClient);
|
const service = new ProtobufService(mockWebClient);
|
||||||
const processSessionEvent = jest.spyOn(service as any, 'processSessionEvent');
|
const processSessionEvent = vi.spyOn(service as any, 'processSessionEvent');
|
||||||
ProtoController.root.ServerMessage.decode = jest.fn().mockReturnValue({
|
ProtoController.root.ServerMessage.decode = vi.fn().mockReturnValue({
|
||||||
messageType: ProtoController.root.ServerMessage.MessageType.SESSION_EVENT,
|
messageType: ProtoController.root.ServerMessage.MessageType.SESSION_EVENT,
|
||||||
sessionEvent: { '.Event_Session.ext': {} },
|
sessionEvent: { '.Event_Session.ext': {} },
|
||||||
});
|
});
|
||||||
|
|
@ -301,8 +304,8 @@ describe('ProtobufService', () => {
|
||||||
|
|
||||||
it('routes GAME_EVENT_CONTAINER message', () => {
|
it('routes GAME_EVENT_CONTAINER message', () => {
|
||||||
const service = new ProtobufService(mockWebClient);
|
const service = new ProtobufService(mockWebClient);
|
||||||
const processGameEvent = jest.spyOn(service as any, 'processGameEvent');
|
const processGameEvent = vi.spyOn(service as any, 'processGameEvent');
|
||||||
ProtoController.root.ServerMessage.decode = jest.fn().mockReturnValue({
|
ProtoController.root.ServerMessage.decode = vi.fn().mockReturnValue({
|
||||||
messageType: ProtoController.root.ServerMessage.MessageType.GAME_EVENT_CONTAINER,
|
messageType: ProtoController.root.ServerMessage.MessageType.GAME_EVENT_CONTAINER,
|
||||||
gameEvent: { '.Event_Game.ext': {} },
|
gameEvent: { '.Event_Game.ext': {} },
|
||||||
});
|
});
|
||||||
|
|
@ -312,8 +315,8 @@ describe('ProtobufService', () => {
|
||||||
|
|
||||||
it('logs unknown message types (default case)', () => {
|
it('logs unknown message types (default case)', () => {
|
||||||
const service = new ProtobufService(mockWebClient);
|
const service = new ProtobufService(mockWebClient);
|
||||||
const consoleSpy = jest.spyOn(console, 'log').mockImplementation(() => {});
|
const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||||
ProtoController.root.ServerMessage.decode = jest.fn().mockReturnValue({
|
ProtoController.root.ServerMessage.decode = vi.fn().mockReturnValue({
|
||||||
messageType: 'UNKNOWN_TYPE',
|
messageType: 'UNKNOWN_TYPE',
|
||||||
});
|
});
|
||||||
service.handleMessageEvent({ data: new ArrayBuffer(0) } as MessageEvent);
|
service.handleMessageEvent({ data: new ArrayBuffer(0) } as MessageEvent);
|
||||||
|
|
@ -323,14 +326,14 @@ describe('ProtobufService', () => {
|
||||||
|
|
||||||
it('does nothing when decoded message is null', () => {
|
it('does nothing when decoded message is null', () => {
|
||||||
const service = new ProtobufService(mockWebClient);
|
const service = new ProtobufService(mockWebClient);
|
||||||
ProtoController.root.ServerMessage.decode = jest.fn().mockReturnValue(null);
|
ProtoController.root.ServerMessage.decode = vi.fn().mockReturnValue(null);
|
||||||
expect(() => service.handleMessageEvent({ data: new ArrayBuffer(0) } as MessageEvent)).not.toThrow();
|
expect(() => service.handleMessageEvent({ data: new ArrayBuffer(0) } as MessageEvent)).not.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('catches and logs decode errors', () => {
|
it('catches and logs decode errors', () => {
|
||||||
const service = new ProtobufService(mockWebClient);
|
const service = new ProtobufService(mockWebClient);
|
||||||
const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
ProtoController.root.ServerMessage.decode = jest.fn().mockImplementation(() => {
|
ProtoController.root.ServerMessage.decode = vi.fn().mockImplementation(() => {
|
||||||
throw new Error('decode error');
|
throw new Error('decode error');
|
||||||
});
|
});
|
||||||
expect(() => service.handleMessageEvent({ data: new ArrayBuffer(0) } as MessageEvent)).not.toThrow();
|
expect(() => service.handleMessageEvent({ data: new ArrayBuffer(0) } as MessageEvent)).not.toThrow();
|
||||||
|
|
@ -342,14 +345,14 @@ describe('ProtobufService', () => {
|
||||||
describe('processGameEvent', () => {
|
describe('processGameEvent', () => {
|
||||||
it('returns early when container has no eventList', () => {
|
it('returns early when container has no eventList', () => {
|
||||||
const service = new ProtobufService(mockWebClient);
|
const service = new ProtobufService(mockWebClient);
|
||||||
const gameEventHandler = (GameEvents as any)['.Event_Game.ext'] as jest.Mock;
|
const gameEventHandler = (GameEvents as any)['.Event_Game.ext'] as vi.Mock;
|
||||||
(service as any).processGameEvent(null, {});
|
(service as any).processGameEvent(null, {});
|
||||||
expect(gameEventHandler).not.toHaveBeenCalled();
|
expect(gameEventHandler).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches to a GameEvents handler when event key matches', () => {
|
it('dispatches to a GameEvents handler when event key matches', () => {
|
||||||
const service = new ProtobufService(mockWebClient);
|
const service = new ProtobufService(mockWebClient);
|
||||||
const gameEventHandler = (GameEvents as any)['.Event_Game.ext'] as jest.Mock;
|
const gameEventHandler = (GameEvents as any)['.Event_Game.ext'] as vi.Mock;
|
||||||
const payload = { someData: 1 };
|
const payload = { someData: 1 };
|
||||||
(service as any).processGameEvent({
|
(service as any).processGameEvent({
|
||||||
gameId: 42,
|
gameId: 42,
|
||||||
|
|
@ -366,7 +369,7 @@ describe('ProtobufService', () => {
|
||||||
describe('processEvent', () => {
|
describe('processEvent', () => {
|
||||||
it('calls matching event handler with payload and raw', () => {
|
it('calls matching event handler with payload and raw', () => {
|
||||||
const service = new ProtobufService(mockWebClient);
|
const service = new ProtobufService(mockWebClient);
|
||||||
const handler = jest.fn();
|
const handler = vi.fn();
|
||||||
const events = { '.Event_Test.ext': handler };
|
const events = { '.Event_Test.ext': handler };
|
||||||
const payload = { someData: 1 };
|
const payload = { someData: 1 };
|
||||||
const response = { '.Event_Test.ext': payload };
|
const response = { '.Event_Test.ext': payload };
|
||||||
|
|
@ -379,8 +382,8 @@ describe('ProtobufService', () => {
|
||||||
|
|
||||||
it('stops after first matching event', () => {
|
it('stops after first matching event', () => {
|
||||||
const service = new ProtobufService(mockWebClient);
|
const service = new ProtobufService(mockWebClient);
|
||||||
const handler1 = jest.fn();
|
const handler1 = vi.fn();
|
||||||
const handler2 = jest.fn();
|
const handler2 = vi.fn();
|
||||||
const events = { '.Event_A.ext': handler1, '.Event_B.ext': handler2 };
|
const events = { '.Event_A.ext': handler1, '.Event_B.ext': handler2 };
|
||||||
const response = { '.Event_A.ext': { x: 1 } };
|
const response = { '.Event_A.ext': { x: 1 } };
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
import { installMockWebSocket } from '../__mocks__/helpers';
|
import { installMockWebSocket } from '../__mocks__/helpers';
|
||||||
|
|
||||||
jest.mock('../commands/session', () => ({
|
vi.mock('../commands/session', () => ({
|
||||||
updateStatus: jest.fn(),
|
updateStatus: vi.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../persistence', () => ({
|
vi.mock('../persistence', () => ({
|
||||||
SessionPersistence: {
|
SessionPersistence: {
|
||||||
connectionFailed: jest.fn(),
|
connectionFailed: vi.fn(),
|
||||||
testConnectionSuccessful: jest.fn(),
|
testConnectionSuccessful: vi.fn(),
|
||||||
testConnectionFailed: jest.fn(),
|
testConnectionFailed: vi.fn(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
@ -17,13 +17,13 @@ import { SessionPersistence } from '../persistence';
|
||||||
import { updateStatus } from '../commands/session';
|
import { updateStatus } from '../commands/session';
|
||||||
import { StatusEnum } from 'types';
|
import { StatusEnum } from 'types';
|
||||||
|
|
||||||
let MockWS: jest.Mock;
|
let MockWS: vi.Mock;
|
||||||
let mockInstance: ReturnType<typeof installMockWebSocket>['mockInstance'];
|
let mockInstance: ReturnType<typeof installMockWebSocket>['mockInstance'];
|
||||||
let mockWebClient: any;
|
let mockWebClient: any;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.useFakeTimers();
|
vi.useFakeTimers();
|
||||||
jest.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
|
|
||||||
const installed = installMockWebSocket();
|
const installed = installMockWebSocket();
|
||||||
MockWS = installed.MockWS;
|
MockWS = installed.MockWS;
|
||||||
|
|
@ -32,12 +32,12 @@ beforeEach(() => {
|
||||||
mockWebClient = {
|
mockWebClient = {
|
||||||
status: StatusEnum.CONNECTED,
|
status: StatusEnum.CONNECTED,
|
||||||
clientOptions: { keepalive: 1000 },
|
clientOptions: { keepalive: 1000 },
|
||||||
keepAlive: jest.fn(),
|
keepAlive: vi.fn(),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.useRealTimers();
|
vi.useRealTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('WebSocketService', () => {
|
describe('WebSocketService', () => {
|
||||||
|
|
@ -99,14 +99,14 @@ describe('WebSocketService', () => {
|
||||||
|
|
||||||
it('fires socket.close after keepalive timeout', () => {
|
it('fires socket.close after keepalive timeout', () => {
|
||||||
createConnectedService();
|
createConnectedService();
|
||||||
jest.advanceTimersByTime(1000);
|
vi.advanceTimersByTime(1000);
|
||||||
expect(mockInstance.close).toHaveBeenCalled();
|
expect(mockInstance.close).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('socket event handlers (onopen)', () => {
|
describe('socket event handlers (onopen)', () => {
|
||||||
it('clears the connection timeout when socket opens', () => {
|
it('clears the connection timeout when socket opens', () => {
|
||||||
const clearSpy = jest.spyOn(global, 'clearTimeout');
|
const clearSpy = vi.spyOn(global, 'clearTimeout');
|
||||||
createConnectedService();
|
createConnectedService();
|
||||||
mockInstance.onopen();
|
mockInstance.onopen();
|
||||||
expect(clearSpy).toHaveBeenCalled();
|
expect(clearSpy).toHaveBeenCalled();
|
||||||
|
|
@ -120,7 +120,7 @@ describe('WebSocketService', () => {
|
||||||
|
|
||||||
it('starts the ping loop with the keepalive interval', () => {
|
it('starts the ping loop with the keepalive interval', () => {
|
||||||
const service = new WebSocketService(mockWebClient);
|
const service = new WebSocketService(mockWebClient);
|
||||||
const startSpy = jest.spyOn((service as any).keepAliveService, 'startPingLoop');
|
const startSpy = vi.spyOn((service as any).keepAliveService, 'startPingLoop');
|
||||||
service.connect({ host: 'h', port: 1 } as any, 'ws');
|
service.connect({ host: 'h', port: 1 } as any, 'ws');
|
||||||
mockInstance.onopen();
|
mockInstance.onopen();
|
||||||
expect(startSpy).toHaveBeenCalledWith(1000, expect.any(Function));
|
expect(startSpy).toHaveBeenCalledWith(1000, expect.any(Function));
|
||||||
|
|
@ -128,11 +128,11 @@ describe('WebSocketService', () => {
|
||||||
|
|
||||||
it('ping loop callback calls webClient.keepAlive', () => {
|
it('ping loop callback calls webClient.keepAlive', () => {
|
||||||
const service = new WebSocketService(mockWebClient);
|
const service = new WebSocketService(mockWebClient);
|
||||||
const startSpy = jest.spyOn((service as any).keepAliveService, 'startPingLoop');
|
const startSpy = vi.spyOn((service as any).keepAliveService, 'startPingLoop');
|
||||||
service.connect({ host: 'h', port: 1 } as any, 'ws');
|
service.connect({ host: 'h', port: 1 } as any, 'ws');
|
||||||
mockInstance.onopen();
|
mockInstance.onopen();
|
||||||
const pingCb = startSpy.mock.calls[0][1] as (done: Function) => void;
|
const pingCb = startSpy.mock.calls[0][1] as (done: Function) => void;
|
||||||
const done = jest.fn();
|
const done = vi.fn();
|
||||||
pingCb(done);
|
pingCb(done);
|
||||||
expect(mockWebClient.keepAlive).toHaveBeenCalledWith(done);
|
expect(mockWebClient.keepAlive).toHaveBeenCalledWith(done);
|
||||||
});
|
});
|
||||||
|
|
@ -154,7 +154,7 @@ describe('WebSocketService', () => {
|
||||||
|
|
||||||
it('ends the ping loop on close', () => {
|
it('ends the ping loop on close', () => {
|
||||||
const service = new WebSocketService(mockWebClient);
|
const service = new WebSocketService(mockWebClient);
|
||||||
const endSpy = jest.spyOn((service as any).keepAliveService, 'endPingLoop');
|
const endSpy = vi.spyOn((service as any).keepAliveService, 'endPingLoop');
|
||||||
service.connect({ host: 'h', port: 1 } as any, 'ws');
|
service.connect({ host: 'h', port: 1 } as any, 'ws');
|
||||||
mockInstance.onclose();
|
mockInstance.onclose();
|
||||||
expect(endSpy).toHaveBeenCalled();
|
expect(endSpy).toHaveBeenCalled();
|
||||||
|
|
@ -178,7 +178,7 @@ describe('WebSocketService', () => {
|
||||||
describe('socket event handlers (onmessage)', () => {
|
describe('socket event handlers (onmessage)', () => {
|
||||||
it('emits on message$ subject', () => {
|
it('emits on message$ subject', () => {
|
||||||
const service = createConnectedService();
|
const service = createConnectedService();
|
||||||
const handler = jest.fn();
|
const handler = vi.fn();
|
||||||
service.message$.subscribe(handler);
|
service.message$.subscribe(handler);
|
||||||
const event = { data: new ArrayBuffer(4) } as MessageEvent;
|
const event = { data: new ArrayBuffer(4) } as MessageEvent;
|
||||||
mockInstance.onmessage(event);
|
mockInstance.onmessage(event);
|
||||||
|
|
@ -262,7 +262,7 @@ describe('WebSocketService', () => {
|
||||||
|
|
||||||
it('calls SessionPersistence.testConnectionSuccessful on open', () => {
|
it('calls SessionPersistence.testConnectionSuccessful on open', () => {
|
||||||
createTestConnectedService();
|
createTestConnectedService();
|
||||||
const timer = jest.spyOn(global, 'clearTimeout');
|
const timer = vi.spyOn(global, 'clearTimeout');
|
||||||
mockInstance.onopen();
|
mockInstance.onopen();
|
||||||
expect(SessionPersistence.testConnectionSuccessful).toHaveBeenCalled();
|
expect(SessionPersistence.testConnectionSuccessful).toHaveBeenCalled();
|
||||||
expect(mockInstance.close).toHaveBeenCalled();
|
expect(mockInstance.close).toHaveBeenCalled();
|
||||||
|
|
@ -270,7 +270,7 @@ describe('WebSocketService', () => {
|
||||||
|
|
||||||
it('fires socket.close after keepalive timeout for testConnect', () => {
|
it('fires socket.close after keepalive timeout for testConnect', () => {
|
||||||
createTestConnectedService();
|
createTestConnectedService();
|
||||||
jest.advanceTimersByTime(1000);
|
vi.advanceTimersByTime(1000);
|
||||||
expect(mockInstance.close).toHaveBeenCalled();
|
expect(mockInstance.close).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ describe('guid', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns deterministic value when Math.random is mocked', () => {
|
it('returns deterministic value when Math.random is mocked', () => {
|
||||||
const spy = jest.spyOn(Math, 'random').mockReturnValue(0.5);
|
const spy = vi.spyOn(Math, 'random').mockReturnValue(0.5);
|
||||||
const result = guid();
|
const result = guid();
|
||||||
expect(result).toBe(guid());
|
expect(result).toBe(guid());
|
||||||
spy.mockRestore();
|
spy.mockRestore();
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { makeMockProtoRoot } from '../__mocks__/helpers';
|
import { makeMockProtoRoot } from '../__mocks__/helpers';
|
||||||
|
|
||||||
jest.mock('../services/ProtoController', () => ({
|
vi.mock('../services/ProtoController', () => ({
|
||||||
ProtoController: { root: null },
|
ProtoController: { root: null },
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ describe('sanitizeHtml', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows <br> tag', () => {
|
it('allows <br> tag', () => {
|
||||||
expect(sanitizeHtml('line1<br>line2')).toBe('line1<br />line2');
|
expect(sanitizeHtml('line1<br>line2')).toBe('line1<br>line2');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows <b> tag', () => {
|
it('allows <b> tag', () => {
|
||||||
|
|
@ -14,7 +14,7 @@ describe('sanitizeHtml', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows <img> tag', () => {
|
it('allows <img> tag', () => {
|
||||||
expect(sanitizeHtml('<img>')).toBe('<img />');
|
expect(sanitizeHtml('<img>')).toBe('<img>');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows <center> tag', () => {
|
it('allows <center> tag', () => {
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,17 @@
|
||||||
import sanitize from 'sanitize-html';
|
import DOMPurify from 'dompurify';
|
||||||
|
|
||||||
|
DOMPurify.addHook('afterSanitizeAttributes', (node) => {
|
||||||
|
if (node.tagName === 'A') {
|
||||||
|
node.setAttribute('target', '_blank');
|
||||||
|
node.setAttribute('rel', 'noopener noreferrer');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
export function sanitizeHtml(msg: string): string {
|
export function sanitizeHtml(msg: string): string {
|
||||||
return sanitize(msg, {
|
return DOMPurify.sanitize(msg, {
|
||||||
allowedTags: ['br', 'a', 'img', 'center', 'b', 'font'],
|
ALLOWED_TAGS: ['br', 'a', 'img', 'center', 'b', 'font'],
|
||||||
allowedAttributes: {
|
ALLOWED_ATTR: ['href', 'color', 'rel', 'target', 'src', 'alt'],
|
||||||
'*': ['href', 'color', 'rel', 'target'],
|
ADD_URI_SAFE_ATTR: ['color'],
|
||||||
'img': ['src', 'alt'],
|
ALLOWED_URI_REGEXP: /^(?:(?:https?|ftp):)/i,
|
||||||
},
|
|
||||||
allowedSchemes: ['http', 'https', 'ftp'],
|
|
||||||
transformTags: {
|
|
||||||
'a': sanitize.simpleTransform('a', {
|
|
||||||
target: '_blank',
|
|
||||||
rel: 'noopener noreferrer',
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
"strict": false,
|
"strict": false,
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"module": "esnext",
|
"module": "esnext",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "bundler",
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
|
|
|
||||||
21
webclient/vite.config.ts
Normal file
21
webclient/vite.config.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
import react from '@vitejs/plugin-react';
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
import tsconfigPaths from 'vite-tsconfig-paths';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [react(), tsconfigPaths()],
|
||||||
|
publicDir: 'public',
|
||||||
|
build: {
|
||||||
|
outDir: 'build',
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
open: true,
|
||||||
|
},
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
environment: 'jsdom',
|
||||||
|
setupFiles: ['./src/setupTests.ts'],
|
||||||
|
include: ['src/**/*.spec.{ts,tsx}'],
|
||||||
|
css: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
Loading…
Add table
Add a link
Reference in a new issue