mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-04-27 07:48:01 -07:00
complete unit testing of redux and api layers
This commit is contained in:
parent
367852866f
commit
3001925430
19 changed files with 2808 additions and 5 deletions
154
webclient/src/store/server/__mocks__/server-fixtures.ts
Normal file
154
webclient/src/store/server/__mocks__/server-fixtures.ts
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
import {
|
||||
BanHistoryItem,
|
||||
DeckList,
|
||||
DeckStorageTreeItem,
|
||||
LogItem,
|
||||
ReplayMatch,
|
||||
SortDirection,
|
||||
StatusEnum,
|
||||
User,
|
||||
UserPrivLevel,
|
||||
UserSortField,
|
||||
WebSocketConnectOptions,
|
||||
WarnHistoryItem,
|
||||
WarnListItem,
|
||||
} from 'types';
|
||||
import { ServerState } from '../server.interfaces';
|
||||
|
||||
export function makeUser(overrides: Partial<User> = {}): User {
|
||||
return {
|
||||
name: 'TestUser',
|
||||
accountageSecs: 0,
|
||||
privlevel: UserPrivLevel.NONE,
|
||||
userLevel: 0,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
export function makeLogItem(overrides: Partial<LogItem> = {}): LogItem {
|
||||
return {
|
||||
message: '',
|
||||
senderId: '',
|
||||
senderIp: '',
|
||||
senderName: '',
|
||||
targetId: '',
|
||||
targetName: '',
|
||||
targetType: '',
|
||||
time: '',
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
export function makeBanHistoryItem(overrides: Partial<BanHistoryItem> = {}): BanHistoryItem {
|
||||
return {
|
||||
adminId: '',
|
||||
adminName: '',
|
||||
banTime: '',
|
||||
banLength: '',
|
||||
banReason: '',
|
||||
visibleReason: '',
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
export function makeWarnHistoryItem(overrides: Partial<WarnHistoryItem> = {}): WarnHistoryItem {
|
||||
return {
|
||||
userName: '',
|
||||
adminName: '',
|
||||
reason: '',
|
||||
timeOf: '',
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
export function makeWarnListItem(overrides: Partial<WarnListItem> = {}): WarnListItem {
|
||||
return {
|
||||
warning: '',
|
||||
userName: '',
|
||||
userClientid: '',
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
export function makeDeckTreeItem(overrides: Partial<DeckStorageTreeItem> = {}): DeckStorageTreeItem {
|
||||
return {
|
||||
id: 1,
|
||||
name: 'item',
|
||||
file: { creationTime: 0 },
|
||||
folder: null,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
export function makeDeckList(overrides: Partial<DeckList> = {}): DeckList {
|
||||
return {
|
||||
root: { items: [] },
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
export function makeReplayMatch(overrides: Partial<ReplayMatch> = {}): ReplayMatch {
|
||||
return {
|
||||
gameId: 1,
|
||||
roomName: 'Test Room',
|
||||
timeStarted: 0,
|
||||
length: 0,
|
||||
gameName: 'Test Game',
|
||||
playerNames: [],
|
||||
doNotHide: false,
|
||||
replayList: [],
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
export function makeConnectOptions(overrides: Partial<WebSocketConnectOptions> = {}): WebSocketConnectOptions {
|
||||
return {
|
||||
host: 'localhost',
|
||||
port: '4747',
|
||||
userName: 'user',
|
||||
password: 'pass',
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
export function makeServerState(overrides: Partial<ServerState> = {}): ServerState {
|
||||
return {
|
||||
initialized: false,
|
||||
buddyList: [],
|
||||
ignoreList: [],
|
||||
status: {
|
||||
state: StatusEnum.DISCONNECTED,
|
||||
description: null,
|
||||
},
|
||||
info: {
|
||||
message: null,
|
||||
name: null,
|
||||
version: null,
|
||||
},
|
||||
logs: {
|
||||
room: [],
|
||||
game: [],
|
||||
chat: [],
|
||||
},
|
||||
user: null,
|
||||
users: [],
|
||||
sortUsersBy: {
|
||||
field: UserSortField.NAME,
|
||||
order: SortDirection.ASC,
|
||||
},
|
||||
connectOptions: {},
|
||||
messages: {},
|
||||
userInfo: {},
|
||||
notifications: [],
|
||||
serverShutdown: null,
|
||||
banUser: '',
|
||||
banHistory: {},
|
||||
warnHistory: {},
|
||||
warnListOptions: [],
|
||||
warnUser: '',
|
||||
adminNotes: {},
|
||||
replays: [],
|
||||
backendDecks: null,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
356
webclient/src/store/server/server.actions.spec.ts
Normal file
356
webclient/src/store/server/server.actions.spec.ts
Normal file
|
|
@ -0,0 +1,356 @@
|
|||
import { Actions } from './server.actions';
|
||||
import { Types } from './server.types';
|
||||
import {
|
||||
makeBanHistoryItem,
|
||||
makeConnectOptions,
|
||||
makeDeckList,
|
||||
makeDeckTreeItem,
|
||||
makeReplayMatch,
|
||||
makeUser,
|
||||
makeWarnHistoryItem,
|
||||
makeWarnListItem,
|
||||
} from './__mocks__/server-fixtures';
|
||||
|
||||
describe('Actions', () => {
|
||||
it('initialized', () => {
|
||||
expect(Actions.initialized()).toEqual({ type: Types.INITIALIZED });
|
||||
});
|
||||
|
||||
it('clearStore', () => {
|
||||
expect(Actions.clearStore()).toEqual({ type: Types.CLEAR_STORE });
|
||||
});
|
||||
|
||||
it('loginSuccessful', () => {
|
||||
const options = makeConnectOptions();
|
||||
expect(Actions.loginSuccessful(options)).toEqual({ type: Types.LOGIN_SUCCESSFUL, options });
|
||||
});
|
||||
|
||||
it('loginFailed', () => {
|
||||
expect(Actions.loginFailed()).toEqual({ type: Types.LOGIN_FAILED });
|
||||
});
|
||||
|
||||
it('connectionClosed', () => {
|
||||
expect(Actions.connectionClosed(3)).toEqual({ type: Types.CONNECTION_CLOSED, reason: 3 });
|
||||
});
|
||||
|
||||
it('connectionFailed', () => {
|
||||
expect(Actions.connectionFailed()).toEqual({ type: Types.CONNECTION_FAILED });
|
||||
});
|
||||
|
||||
it('testConnectionSuccessful', () => {
|
||||
expect(Actions.testConnectionSuccessful()).toEqual({ type: Types.TEST_CONNECTION_SUCCESSFUL });
|
||||
});
|
||||
|
||||
it('testConnectionFailed', () => {
|
||||
expect(Actions.testConnectionFailed()).toEqual({ type: Types.TEST_CONNECTION_FAILED });
|
||||
});
|
||||
|
||||
it('serverMessage', () => {
|
||||
expect(Actions.serverMessage('hello')).toEqual({ type: Types.SERVER_MESSAGE, message: 'hello' });
|
||||
});
|
||||
|
||||
it('updateBuddyList', () => {
|
||||
const list = [makeUser()];
|
||||
expect(Actions.updateBuddyList(list)).toEqual({ type: Types.UPDATE_BUDDY_LIST, buddyList: list });
|
||||
});
|
||||
|
||||
it('addToBuddyList', () => {
|
||||
const user = makeUser();
|
||||
expect(Actions.addToBuddyList(user)).toEqual({ type: Types.ADD_TO_BUDDY_LIST, user });
|
||||
});
|
||||
|
||||
it('removeFromBuddyList', () => {
|
||||
expect(Actions.removeFromBuddyList('Alice')).toEqual({ type: Types.REMOVE_FROM_BUDDY_LIST, userName: 'Alice' });
|
||||
});
|
||||
|
||||
it('updateIgnoreList', () => {
|
||||
const list = [makeUser()];
|
||||
expect(Actions.updateIgnoreList(list)).toEqual({ type: Types.UPDATE_IGNORE_LIST, ignoreList: list });
|
||||
});
|
||||
|
||||
it('addToIgnoreList', () => {
|
||||
const user = makeUser();
|
||||
expect(Actions.addToIgnoreList(user)).toEqual({ type: Types.ADD_TO_IGNORE_LIST, user });
|
||||
});
|
||||
|
||||
it('removeFromIgnoreList', () => {
|
||||
expect(Actions.removeFromIgnoreList('Bob')).toEqual({ type: Types.REMOVE_FROM_IGNORE_LIST, userName: 'Bob' });
|
||||
});
|
||||
|
||||
it('updateInfo', () => {
|
||||
const info = { name: 'Servatrice', version: '2.0' };
|
||||
expect(Actions.updateInfo(info)).toEqual({ type: Types.UPDATE_INFO, info });
|
||||
});
|
||||
|
||||
it('updateStatus', () => {
|
||||
const status = { state: 2, description: 'connected' };
|
||||
expect(Actions.updateStatus(status)).toEqual({ type: Types.UPDATE_STATUS, status });
|
||||
});
|
||||
|
||||
it('updateUser', () => {
|
||||
const user = makeUser();
|
||||
expect(Actions.updateUser(user)).toEqual({ type: Types.UPDATE_USER, user });
|
||||
});
|
||||
|
||||
it('updateUsers', () => {
|
||||
const users = [makeUser()];
|
||||
expect(Actions.updateUsers(users)).toEqual({ type: Types.UPDATE_USERS, users });
|
||||
});
|
||||
|
||||
it('userJoined', () => {
|
||||
const user = makeUser();
|
||||
expect(Actions.userJoined(user)).toEqual({ type: Types.USER_JOINED, user });
|
||||
});
|
||||
|
||||
it('userLeft', () => {
|
||||
expect(Actions.userLeft('Carol')).toEqual({ type: Types.USER_LEFT, name: 'Carol' });
|
||||
});
|
||||
|
||||
it('viewLogs', () => {
|
||||
const logs = { room: [], game: [], chat: [] };
|
||||
expect(Actions.viewLogs(logs)).toEqual({ type: Types.VIEW_LOGS, logs });
|
||||
});
|
||||
|
||||
it('clearLogs', () => {
|
||||
expect(Actions.clearLogs()).toEqual({ type: Types.CLEAR_LOGS });
|
||||
});
|
||||
|
||||
it('registrationRequiresEmail', () => {
|
||||
expect(Actions.registrationRequiresEmail()).toEqual({ type: Types.REGISTRATION_REQUIRES_EMAIL });
|
||||
});
|
||||
|
||||
it('registrationSuccess', () => {
|
||||
expect(Actions.registrationSuccess()).toEqual({ type: Types.REGISTRATION_SUCCES });
|
||||
});
|
||||
|
||||
it('registrationFailed', () => {
|
||||
expect(Actions.registrationFailed('err')).toEqual({ type: Types.REGISTRATION_FAILED, error: 'err' });
|
||||
});
|
||||
|
||||
it('registrationEmailError', () => {
|
||||
expect(Actions.registrationEmailError('bad email')).toEqual({ type: Types.REGISTRATION_EMAIL_ERROR, error: 'bad email' });
|
||||
});
|
||||
|
||||
it('registrationPasswordError', () => {
|
||||
expect(Actions.registrationPasswordError('bad pw')).toEqual({ type: Types.REGISTRATION_PASSWORD_ERROR, error: 'bad pw' });
|
||||
});
|
||||
|
||||
it('registrationUserNameError', () => {
|
||||
expect(Actions.registrationUserNameError('bad name')).toEqual({ type: Types.REGISTRATION_USERNAME_ERROR, error: 'bad name' });
|
||||
});
|
||||
|
||||
it('accountAwaitingActivation', () => {
|
||||
const options = makeConnectOptions();
|
||||
expect(Actions.accountAwaitingActivation(options)).toEqual({ type: Types.ACCOUNT_AWAITING_ACTIVATION, options });
|
||||
});
|
||||
|
||||
it('accountActivationSuccess', () => {
|
||||
expect(Actions.accountActivationSuccess()).toEqual({ type: Types.ACCOUNT_ACTIVATION_SUCCESS });
|
||||
});
|
||||
|
||||
it('accountActivationFailed', () => {
|
||||
expect(Actions.accountActivationFailed()).toEqual({ type: Types.ACCOUNT_ACTIVATION_FAILED });
|
||||
});
|
||||
|
||||
it('resetPassword', () => {
|
||||
expect(Actions.resetPassword()).toEqual({ type: Types.RESET_PASSWORD_REQUESTED });
|
||||
});
|
||||
|
||||
it('resetPasswordFailed', () => {
|
||||
expect(Actions.resetPasswordFailed()).toEqual({ type: Types.RESET_PASSWORD_FAILED });
|
||||
});
|
||||
|
||||
it('resetPasswordChallenge', () => {
|
||||
expect(Actions.resetPasswordChallenge()).toEqual({ type: Types.RESET_PASSWORD_CHALLENGE });
|
||||
});
|
||||
|
||||
it('resetPasswordSuccess', () => {
|
||||
expect(Actions.resetPasswordSuccess()).toEqual({ type: Types.RESET_PASSWORD_SUCCESS });
|
||||
});
|
||||
|
||||
it('adjustMod', () => {
|
||||
expect(Actions.adjustMod('Dan', true, false)).toEqual({
|
||||
type: Types.ADJUST_MOD,
|
||||
userName: 'Dan',
|
||||
shouldBeMod: true,
|
||||
shouldBeJudge: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('reloadConfig', () => {
|
||||
expect(Actions.reloadConfig()).toEqual({ type: Types.RELOAD_CONFIG });
|
||||
});
|
||||
|
||||
it('shutdownServer', () => {
|
||||
expect(Actions.shutdownServer()).toEqual({ type: Types.SHUTDOWN_SERVER });
|
||||
});
|
||||
|
||||
it('updateServerMessage', () => {
|
||||
expect(Actions.updateServerMessage()).toEqual({ type: Types.UPDATE_SERVER_MESSAGE });
|
||||
});
|
||||
|
||||
it('accountPasswordChange', () => {
|
||||
expect(Actions.accountPasswordChange()).toEqual({ type: Types.ACCOUNT_PASSWORD_CHANGE });
|
||||
});
|
||||
|
||||
it('accountEditChanged', () => {
|
||||
const user = makeUser();
|
||||
expect(Actions.accountEditChanged(user)).toEqual({ type: Types.ACCOUNT_EDIT_CHANGED, user });
|
||||
});
|
||||
|
||||
it('accountImageChanged', () => {
|
||||
const user = makeUser();
|
||||
expect(Actions.accountImageChanged(user)).toEqual({ type: Types.ACCOUNT_IMAGE_CHANGED, user });
|
||||
});
|
||||
|
||||
it('directMessageSent', () => {
|
||||
expect(Actions.directMessageSent('Eve', 'hi')).toEqual({
|
||||
type: Types.DIRECT_MESSAGE_SENT,
|
||||
userName: 'Eve',
|
||||
message: 'hi',
|
||||
});
|
||||
});
|
||||
|
||||
it('getUserInfo', () => {
|
||||
const userInfo = makeUser({ name: 'Frank' });
|
||||
expect(Actions.getUserInfo(userInfo)).toEqual({ type: Types.GET_USER_INFO, userInfo });
|
||||
});
|
||||
|
||||
it('notifyUser', () => {
|
||||
const notification = { type: 1, warningReason: '', customTitle: '', customContent: '' };
|
||||
expect(Actions.notifyUser(notification)).toEqual({ type: Types.NOTIFY_USER, notification });
|
||||
});
|
||||
|
||||
it('serverShutdown', () => {
|
||||
const data = { reason: 'maintenance', minutes: 5 };
|
||||
expect(Actions.serverShutdown(data)).toEqual({ type: Types.SERVER_SHUTDOWN, data });
|
||||
});
|
||||
|
||||
it('userMessage', () => {
|
||||
const messageData = { senderName: 'Alice', receiverName: 'Bob', message: 'hey' };
|
||||
expect(Actions.userMessage(messageData)).toEqual({ type: Types.USER_MESSAGE, messageData });
|
||||
});
|
||||
|
||||
it('addToList', () => {
|
||||
expect(Actions.addToList('buddyList', 'Grace')).toEqual({
|
||||
type: Types.ADD_TO_LIST,
|
||||
list: 'buddyList',
|
||||
userName: 'Grace',
|
||||
});
|
||||
});
|
||||
|
||||
it('removeFromList', () => {
|
||||
expect(Actions.removeFromList('buddyList', 'Hank')).toEqual({
|
||||
type: Types.REMOVE_FROM_LIST,
|
||||
list: 'buddyList',
|
||||
userName: 'Hank',
|
||||
});
|
||||
});
|
||||
|
||||
it('banFromServer', () => {
|
||||
expect(Actions.banFromServer('Ira')).toEqual({ type: Types.BAN_FROM_SERVER, userName: 'Ira' });
|
||||
});
|
||||
|
||||
it('banHistory', () => {
|
||||
const history = [makeBanHistoryItem()];
|
||||
expect(Actions.banHistory('Ira', history)).toEqual({ type: Types.BAN_HISTORY, userName: 'Ira', banHistory: history });
|
||||
});
|
||||
|
||||
it('warnHistory', () => {
|
||||
const history = [makeWarnHistoryItem()];
|
||||
expect(Actions.warnHistory('Jack', history)).toEqual({ type: Types.WARN_HISTORY, userName: 'Jack', warnHistory: history });
|
||||
});
|
||||
|
||||
it('warnListOptions', () => {
|
||||
const list = [makeWarnListItem()];
|
||||
expect(Actions.warnListOptions(list)).toEqual({ type: Types.WARN_LIST_OPTIONS, warnList: list });
|
||||
});
|
||||
|
||||
it('warnUser', () => {
|
||||
expect(Actions.warnUser('Kelly')).toEqual({ type: Types.WARN_USER, userName: 'Kelly' });
|
||||
});
|
||||
|
||||
it('grantReplayAccess', () => {
|
||||
expect(Actions.grantReplayAccess(7, 'Moe')).toEqual({
|
||||
type: Types.GRANT_REPLAY_ACCESS,
|
||||
replayId: 7,
|
||||
moderatorName: 'Moe',
|
||||
});
|
||||
});
|
||||
|
||||
it('forceActivateUser', () => {
|
||||
expect(Actions.forceActivateUser('Ned', 'Moe')).toEqual({
|
||||
type: Types.FORCE_ACTIVATE_USER,
|
||||
usernameToActivate: 'Ned',
|
||||
moderatorName: 'Moe',
|
||||
});
|
||||
});
|
||||
|
||||
it('getAdminNotes', () => {
|
||||
expect(Actions.getAdminNotes('Ned', 'some notes')).toEqual({
|
||||
type: Types.GET_ADMIN_NOTES,
|
||||
userName: 'Ned',
|
||||
notes: 'some notes',
|
||||
});
|
||||
});
|
||||
|
||||
it('updateAdminNotes', () => {
|
||||
expect(Actions.updateAdminNotes('Ned', 'updated notes')).toEqual({
|
||||
type: Types.UPDATE_ADMIN_NOTES,
|
||||
userName: 'Ned',
|
||||
notes: 'updated notes',
|
||||
});
|
||||
});
|
||||
|
||||
it('replayList', () => {
|
||||
const list = [makeReplayMatch()];
|
||||
expect(Actions.replayList(list)).toEqual({ type: Types.REPLAY_LIST, matchList: list });
|
||||
});
|
||||
|
||||
it('replayAdded', () => {
|
||||
const match = makeReplayMatch();
|
||||
expect(Actions.replayAdded(match)).toEqual({ type: Types.REPLAY_ADDED, matchInfo: match });
|
||||
});
|
||||
|
||||
it('replayModifyMatch', () => {
|
||||
expect(Actions.replayModifyMatch(5, true)).toEqual({
|
||||
type: Types.REPLAY_MODIFY_MATCH,
|
||||
gameId: 5,
|
||||
doNotHide: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('replayDeleteMatch', () => {
|
||||
expect(Actions.replayDeleteMatch(5)).toEqual({ type: Types.REPLAY_DELETE_MATCH, gameId: 5 });
|
||||
});
|
||||
|
||||
it('backendDecks', () => {
|
||||
const deckList = makeDeckList();
|
||||
expect(Actions.backendDecks(deckList)).toEqual({ type: Types.BACKEND_DECKS, deckList });
|
||||
});
|
||||
|
||||
it('deckNewDir', () => {
|
||||
expect(Actions.deckNewDir('a/b', 'newFolder')).toEqual({
|
||||
type: Types.DECK_NEW_DIR,
|
||||
path: 'a/b',
|
||||
dirName: 'newFolder',
|
||||
});
|
||||
});
|
||||
|
||||
it('deckDelDir', () => {
|
||||
expect(Actions.deckDelDir('a/b')).toEqual({ type: Types.DECK_DEL_DIR, path: 'a/b' });
|
||||
});
|
||||
|
||||
it('deckUpload', () => {
|
||||
const treeItem = makeDeckTreeItem();
|
||||
expect(Actions.deckUpload('a/b', treeItem)).toEqual({
|
||||
type: Types.DECK_UPLOAD,
|
||||
path: 'a/b',
|
||||
treeItem,
|
||||
});
|
||||
});
|
||||
|
||||
it('deckDelete', () => {
|
||||
expect(Actions.deckDelete(42)).toEqual({ type: Types.DECK_DELETE, deckId: 42 });
|
||||
});
|
||||
});
|
||||
388
webclient/src/store/server/server.dispatch.spec.ts
Normal file
388
webclient/src/store/server/server.dispatch.spec.ts
Normal file
|
|
@ -0,0 +1,388 @@
|
|||
jest.mock('store/store', () => ({ store: { dispatch: jest.fn() } }));
|
||||
jest.mock('redux-form', () => ({
|
||||
reset: jest.fn((form) => ({ type: '@@redux-form/RESET', meta: { form } })),
|
||||
}));
|
||||
|
||||
import { store } from 'store/store';
|
||||
import { reset } from 'redux-form';
|
||||
import { Actions } from './server.actions';
|
||||
import { Dispatch } from './server.dispatch';
|
||||
import {
|
||||
makeBanHistoryItem,
|
||||
makeConnectOptions,
|
||||
makeDeckList,
|
||||
makeDeckTreeItem,
|
||||
makeReplayMatch,
|
||||
makeUser,
|
||||
makeWarnHistoryItem,
|
||||
makeWarnListItem,
|
||||
} from './__mocks__/server-fixtures';
|
||||
|
||||
beforeEach(() => jest.clearAllMocks());
|
||||
|
||||
describe('Dispatch', () => {
|
||||
it('initialized dispatches Actions.initialized()', () => {
|
||||
Dispatch.initialized();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.initialized());
|
||||
});
|
||||
|
||||
it('clearStore dispatches Actions.clearStore()', () => {
|
||||
Dispatch.clearStore();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.clearStore());
|
||||
});
|
||||
|
||||
it('loginSuccessful dispatches Actions.loginSuccessful()', () => {
|
||||
const options = makeConnectOptions();
|
||||
Dispatch.loginSuccessful(options);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.loginSuccessful(options));
|
||||
});
|
||||
|
||||
it('loginFailed dispatches Actions.loginFailed()', () => {
|
||||
Dispatch.loginFailed();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.loginFailed());
|
||||
});
|
||||
|
||||
it('connectionClosed dispatches Actions.connectionClosed()', () => {
|
||||
Dispatch.connectionClosed(3);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.connectionClosed(3));
|
||||
});
|
||||
|
||||
it('connectionFailed dispatches Actions.connectionFailed()', () => {
|
||||
Dispatch.connectionFailed();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.connectionFailed());
|
||||
});
|
||||
|
||||
it('testConnectionSuccessful dispatches Actions.testConnectionSuccessful()', () => {
|
||||
Dispatch.testConnectionSuccessful();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.testConnectionSuccessful());
|
||||
});
|
||||
|
||||
it('testConnectionFailed dispatches Actions.testConnectionFailed()', () => {
|
||||
Dispatch.testConnectionFailed();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.testConnectionFailed());
|
||||
});
|
||||
|
||||
it('updateBuddyList dispatches Actions.updateBuddyList()', () => {
|
||||
const list = [makeUser()];
|
||||
Dispatch.updateBuddyList(list);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.updateBuddyList(list));
|
||||
});
|
||||
|
||||
it('addToBuddyList dispatches reset("addToBuddies") then Actions.addToBuddyList()', () => {
|
||||
const user = makeUser();
|
||||
Dispatch.addToBuddyList(user);
|
||||
expect(store.dispatch).toHaveBeenNthCalledWith(1, (reset as jest.Mock)('addToBuddies'));
|
||||
expect(store.dispatch).toHaveBeenNthCalledWith(2, Actions.addToBuddyList(user));
|
||||
});
|
||||
|
||||
it('removeFromBuddyList dispatches Actions.removeFromBuddyList()', () => {
|
||||
Dispatch.removeFromBuddyList('Alice');
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.removeFromBuddyList('Alice'));
|
||||
});
|
||||
|
||||
it('updateIgnoreList dispatches Actions.updateIgnoreList()', () => {
|
||||
const list = [makeUser()];
|
||||
Dispatch.updateIgnoreList(list);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.updateIgnoreList(list));
|
||||
});
|
||||
|
||||
it('addToIgnoreList dispatches reset("addToIgnore") then Actions.addToIgnoreList()', () => {
|
||||
const user = makeUser();
|
||||
Dispatch.addToIgnoreList(user);
|
||||
expect(store.dispatch).toHaveBeenNthCalledWith(1, (reset as jest.Mock)('addToIgnore'));
|
||||
expect(store.dispatch).toHaveBeenNthCalledWith(2, Actions.addToIgnoreList(user));
|
||||
});
|
||||
|
||||
it('removeFromIgnoreList dispatches Actions.removeFromIgnoreList()', () => {
|
||||
Dispatch.removeFromIgnoreList('Bob');
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.removeFromIgnoreList('Bob'));
|
||||
});
|
||||
|
||||
it('updateInfo dispatches Actions.updateInfo({ name, version })', () => {
|
||||
Dispatch.updateInfo('Servatrice', '2.9');
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.updateInfo({ name: 'Servatrice', version: '2.9' }));
|
||||
});
|
||||
|
||||
it('updateStatus dispatches Actions.updateStatus({ state, description })', () => {
|
||||
Dispatch.updateStatus(2, 'ok');
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.updateStatus({ state: 2, description: 'ok' }));
|
||||
});
|
||||
|
||||
it('updateUser dispatches Actions.updateUser()', () => {
|
||||
const user = makeUser();
|
||||
Dispatch.updateUser(user);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.updateUser(user));
|
||||
});
|
||||
|
||||
it('updateUsers dispatches Actions.updateUsers()', () => {
|
||||
const users = [makeUser()];
|
||||
Dispatch.updateUsers(users);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.updateUsers(users));
|
||||
});
|
||||
|
||||
it('userJoined dispatches Actions.userJoined()', () => {
|
||||
const user = makeUser();
|
||||
Dispatch.userJoined(user);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.userJoined(user));
|
||||
});
|
||||
|
||||
it('userLeft dispatches Actions.userLeft()', () => {
|
||||
Dispatch.userLeft('Carol');
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.userLeft('Carol'));
|
||||
});
|
||||
|
||||
it('viewLogs dispatches Actions.viewLogs()', () => {
|
||||
const logs = { room: [], game: [], chat: [] };
|
||||
Dispatch.viewLogs(logs);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.viewLogs(logs));
|
||||
});
|
||||
|
||||
it('clearLogs dispatches Actions.clearLogs()', () => {
|
||||
Dispatch.clearLogs();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.clearLogs());
|
||||
});
|
||||
|
||||
it('serverMessage dispatches Actions.serverMessage()', () => {
|
||||
Dispatch.serverMessage('Welcome!');
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.serverMessage('Welcome!'));
|
||||
});
|
||||
|
||||
it('registrationRequiresEmail dispatches correctly', () => {
|
||||
Dispatch.registrationRequiresEmail();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.registrationRequiresEmail());
|
||||
});
|
||||
|
||||
it('registrationSuccess dispatches correctly', () => {
|
||||
Dispatch.registrationSuccess();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.registrationSuccess());
|
||||
});
|
||||
|
||||
it('registrationFailed dispatches correctly', () => {
|
||||
Dispatch.registrationFailed('err');
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.registrationFailed('err'));
|
||||
});
|
||||
|
||||
it('registrationEmailError dispatches correctly', () => {
|
||||
Dispatch.registrationEmailError('bad');
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.registrationEmailError('bad'));
|
||||
});
|
||||
|
||||
it('registrationPasswordError dispatches correctly', () => {
|
||||
Dispatch.registrationPasswordError('weak');
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.registrationPasswordError('weak'));
|
||||
});
|
||||
|
||||
it('registrationUserNameError dispatches correctly', () => {
|
||||
Dispatch.registrationUserNameError('taken');
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.registrationUserNameError('taken'));
|
||||
});
|
||||
|
||||
it('accountAwaitingActivation dispatches correctly', () => {
|
||||
const options = makeConnectOptions();
|
||||
Dispatch.accountAwaitingActivation(options);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.accountAwaitingActivation(options));
|
||||
});
|
||||
|
||||
it('accountActivationSuccess dispatches correctly', () => {
|
||||
Dispatch.accountActivationSuccess();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.accountActivationSuccess());
|
||||
});
|
||||
|
||||
it('accountActivationFailed dispatches correctly', () => {
|
||||
Dispatch.accountActivationFailed();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.accountActivationFailed());
|
||||
});
|
||||
|
||||
it('resetPassword dispatches correctly', () => {
|
||||
Dispatch.resetPassword();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.resetPassword());
|
||||
});
|
||||
|
||||
it('resetPasswordFailed dispatches correctly', () => {
|
||||
Dispatch.resetPasswordFailed();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.resetPasswordFailed());
|
||||
});
|
||||
|
||||
it('resetPasswordChallenge dispatches correctly', () => {
|
||||
Dispatch.resetPasswordChallenge();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.resetPasswordChallenge());
|
||||
});
|
||||
|
||||
it('resetPasswordSuccess dispatches correctly', () => {
|
||||
Dispatch.resetPasswordSuccess();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.resetPasswordSuccess());
|
||||
});
|
||||
|
||||
it('adjustMod dispatches Actions.adjustMod()', () => {
|
||||
Dispatch.adjustMod('Dan', true, false);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.adjustMod('Dan', true, false));
|
||||
});
|
||||
|
||||
it('reloadConfig dispatches correctly', () => {
|
||||
Dispatch.reloadConfig();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.reloadConfig());
|
||||
});
|
||||
|
||||
it('shutdownServer dispatches correctly', () => {
|
||||
Dispatch.shutdownServer();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.shutdownServer());
|
||||
});
|
||||
|
||||
it('updateServerMessage dispatches correctly', () => {
|
||||
Dispatch.updateServerMessage();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.updateServerMessage());
|
||||
});
|
||||
|
||||
it('accountPasswordChange dispatches correctly', () => {
|
||||
Dispatch.accountPasswordChange();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.accountPasswordChange());
|
||||
});
|
||||
|
||||
it('accountEditChanged dispatches correctly', () => {
|
||||
const user = makeUser();
|
||||
Dispatch.accountEditChanged(user);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.accountEditChanged(user));
|
||||
});
|
||||
|
||||
it('accountImageChanged dispatches correctly', () => {
|
||||
const user = makeUser();
|
||||
Dispatch.accountImageChanged(user);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.accountImageChanged(user));
|
||||
});
|
||||
|
||||
it('directMessageSent dispatches correctly', () => {
|
||||
Dispatch.directMessageSent('Eve', 'hi');
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.directMessageSent('Eve', 'hi'));
|
||||
});
|
||||
|
||||
it('getUserInfo dispatches correctly', () => {
|
||||
const userInfo = makeUser({ name: 'Frank' });
|
||||
Dispatch.getUserInfo(userInfo);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.getUserInfo(userInfo));
|
||||
});
|
||||
|
||||
it('notifyUser dispatches correctly', () => {
|
||||
const notification = { type: 1, warningReason: '', customTitle: '', customContent: '' };
|
||||
Dispatch.notifyUser(notification);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.notifyUser(notification));
|
||||
});
|
||||
|
||||
it('serverShutdown dispatches correctly', () => {
|
||||
const data = { reason: 'maintenance', minutes: 5 };
|
||||
Dispatch.serverShutdown(data);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.serverShutdown(data));
|
||||
});
|
||||
|
||||
it('userMessage dispatches correctly', () => {
|
||||
const messageData = { senderName: 'Alice', receiverName: 'Bob', message: 'hey' };
|
||||
Dispatch.userMessage(messageData);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.userMessage(messageData));
|
||||
});
|
||||
|
||||
it('addToList dispatches correctly', () => {
|
||||
Dispatch.addToList('buddyList', 'Grace');
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.addToList('buddyList', 'Grace'));
|
||||
});
|
||||
|
||||
it('removeFromList dispatches correctly', () => {
|
||||
Dispatch.removeFromList('buddyList', 'Hank');
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.removeFromList('buddyList', 'Hank'));
|
||||
});
|
||||
|
||||
it('banFromServer dispatches correctly', () => {
|
||||
Dispatch.banFromServer('Ira');
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.banFromServer('Ira'));
|
||||
});
|
||||
|
||||
it('banHistory dispatches correctly', () => {
|
||||
const history = [makeBanHistoryItem()];
|
||||
Dispatch.banHistory('Ira', history);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.banHistory('Ira', history));
|
||||
});
|
||||
|
||||
it('warnHistory dispatches correctly', () => {
|
||||
const history = [makeWarnHistoryItem()];
|
||||
Dispatch.warnHistory('Jack', history);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.warnHistory('Jack', history));
|
||||
});
|
||||
|
||||
it('warnListOptions dispatches correctly', () => {
|
||||
const list = [makeWarnListItem()];
|
||||
Dispatch.warnListOptions(list);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.warnListOptions(list));
|
||||
});
|
||||
|
||||
it('warnUser dispatches correctly', () => {
|
||||
Dispatch.warnUser('Kelly');
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.warnUser('Kelly'));
|
||||
});
|
||||
|
||||
it('grantReplayAccess dispatches correctly', () => {
|
||||
Dispatch.grantReplayAccess(7, 'Moe');
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.grantReplayAccess(7, 'Moe'));
|
||||
});
|
||||
|
||||
it('forceActivateUser dispatches correctly', () => {
|
||||
Dispatch.forceActivateUser('Ned', 'Moe');
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.forceActivateUser('Ned', 'Moe'));
|
||||
});
|
||||
|
||||
it('getAdminNotes dispatches correctly', () => {
|
||||
Dispatch.getAdminNotes('Ned', 'notes');
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.getAdminNotes('Ned', 'notes'));
|
||||
});
|
||||
|
||||
it('updateAdminNotes dispatches correctly', () => {
|
||||
Dispatch.updateAdminNotes('Ned', 'updated');
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.updateAdminNotes('Ned', 'updated'));
|
||||
});
|
||||
|
||||
it('replayList dispatches correctly', () => {
|
||||
const list = [makeReplayMatch()];
|
||||
Dispatch.replayList(list);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.replayList(list));
|
||||
});
|
||||
|
||||
it('replayAdded dispatches correctly', () => {
|
||||
const match = makeReplayMatch();
|
||||
Dispatch.replayAdded(match);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.replayAdded(match));
|
||||
});
|
||||
|
||||
it('replayModifyMatch dispatches correctly', () => {
|
||||
Dispatch.replayModifyMatch(5, true);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.replayModifyMatch(5, true));
|
||||
});
|
||||
|
||||
it('replayDeleteMatch dispatches correctly', () => {
|
||||
Dispatch.replayDeleteMatch(5);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.replayDeleteMatch(5));
|
||||
});
|
||||
|
||||
it('backendDecks dispatches correctly', () => {
|
||||
const deckList = makeDeckList();
|
||||
Dispatch.backendDecks(deckList);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.backendDecks(deckList));
|
||||
});
|
||||
|
||||
it('deckNewDir dispatches correctly', () => {
|
||||
Dispatch.deckNewDir('a/b', 'newFolder');
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.deckNewDir('a/b', 'newFolder'));
|
||||
});
|
||||
|
||||
it('deckDelDir dispatches correctly', () => {
|
||||
Dispatch.deckDelDir('a/b');
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.deckDelDir('a/b'));
|
||||
});
|
||||
|
||||
it('deckUpload dispatches correctly', () => {
|
||||
const treeItem = makeDeckTreeItem();
|
||||
Dispatch.deckUpload('a/b', treeItem);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.deckUpload('a/b', treeItem));
|
||||
});
|
||||
|
||||
it('deckDelete dispatches correctly', () => {
|
||||
Dispatch.deckDelete(42);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.deckDelete(42));
|
||||
});
|
||||
});
|
||||
526
webclient/src/store/server/server.reducer.spec.ts
Normal file
526
webclient/src/store/server/server.reducer.spec.ts
Normal file
|
|
@ -0,0 +1,526 @@
|
|||
import { StatusEnum, UserLevelFlag } from 'types';
|
||||
import { serverReducer } from './server.reducer';
|
||||
import { Types } from './server.types';
|
||||
import {
|
||||
makeBanHistoryItem,
|
||||
makeConnectOptions,
|
||||
makeDeckList,
|
||||
makeDeckTreeItem,
|
||||
makeLogItem,
|
||||
makeReplayMatch,
|
||||
makeServerState,
|
||||
makeUser,
|
||||
makeWarnHistoryItem,
|
||||
makeWarnListItem,
|
||||
} from './__mocks__/server-fixtures';
|
||||
|
||||
// ── Initialisation ───────────────────────────────────────────────────────────
|
||||
|
||||
describe('Initialisation', () => {
|
||||
it('returns initialState when called with undefined state', () => {
|
||||
const result = serverReducer(undefined, { type: '@@INIT' });
|
||||
expect(result.initialized).toBe(false);
|
||||
expect(result.buddyList).toEqual([]);
|
||||
expect(result.status.state).toBe(StatusEnum.DISCONNECTED);
|
||||
});
|
||||
|
||||
it('INITIALIZED → resets to initialState with initialized: true', () => {
|
||||
const state = makeServerState({ banUser: 'someone', initialized: false });
|
||||
const result = serverReducer(state, { type: Types.INITIALIZED });
|
||||
expect(result.initialized).toBe(true);
|
||||
expect(result.banUser).toBe('');
|
||||
expect(result.buddyList).toEqual([]);
|
||||
});
|
||||
|
||||
it('CLEAR_STORE → resets to initialState but preserves status', () => {
|
||||
const status = { state: StatusEnum.LOGGED_IN, description: 'logged in' };
|
||||
const state = makeServerState({ status, banUser: 'someone' });
|
||||
const result = serverReducer(state, { type: Types.CLEAR_STORE });
|
||||
expect(result.banUser).toBe('');
|
||||
expect(result.status).toEqual(status);
|
||||
expect(result.initialized).toBe(false);
|
||||
});
|
||||
|
||||
it('default → returns state unchanged for unknown action', () => {
|
||||
const state = makeServerState();
|
||||
const result = serverReducer(state, { type: '@@UNKNOWN' });
|
||||
expect(result).toBe(state);
|
||||
});
|
||||
});
|
||||
|
||||
// ── Account & Connection ─────────────────────────────────────────────────────
|
||||
|
||||
describe('Account & Connection', () => {
|
||||
it('ACCOUNT_AWAITING_ACTIVATION → sets connectOptions from action.options', () => {
|
||||
const options = makeConnectOptions();
|
||||
const state = makeServerState();
|
||||
const result = serverReducer(state, { type: Types.ACCOUNT_AWAITING_ACTIVATION, options });
|
||||
expect(result.connectOptions).toEqual(options);
|
||||
});
|
||||
|
||||
it('ACCOUNT_ACTIVATION_SUCCESS → clears connectOptions to {}', () => {
|
||||
const state = makeServerState({ connectOptions: makeConnectOptions() });
|
||||
const result = serverReducer(state, { type: Types.ACCOUNT_ACTIVATION_SUCCESS });
|
||||
expect(result.connectOptions).toEqual({});
|
||||
});
|
||||
|
||||
it('ACCOUNT_ACTIVATION_FAILED → clears connectOptions to {}', () => {
|
||||
const state = makeServerState({ connectOptions: makeConnectOptions() });
|
||||
const result = serverReducer(state, { type: Types.ACCOUNT_ACTIVATION_FAILED });
|
||||
expect(result.connectOptions).toEqual({});
|
||||
});
|
||||
});
|
||||
|
||||
// ── Server Info & Status ──────────────────────────────────────────────────────
|
||||
|
||||
describe('Server Info & Status', () => {
|
||||
it('SERVER_MESSAGE → merges message into state.info', () => {
|
||||
const state = makeServerState({ info: { message: null, name: 'Old', version: '1.0' } });
|
||||
const result = serverReducer(state, { type: Types.SERVER_MESSAGE, message: 'Welcome!' });
|
||||
expect(result.info.message).toBe('Welcome!');
|
||||
expect(result.info.name).toBe('Old');
|
||||
expect(result.info.version).toBe('1.0');
|
||||
});
|
||||
|
||||
it('UPDATE_INFO → merges name and version into state.info (not message)', () => {
|
||||
const state = makeServerState({ info: { message: 'hi', name: null, version: null } });
|
||||
const result = serverReducer(state, {
|
||||
type: Types.UPDATE_INFO,
|
||||
info: { name: 'Servatrice', version: '2.9.0' },
|
||||
});
|
||||
expect(result.info.name).toBe('Servatrice');
|
||||
expect(result.info.version).toBe('2.9.0');
|
||||
expect(result.info.message).toBe('hi');
|
||||
});
|
||||
|
||||
it('UPDATE_STATUS → replaces state.status entirely', () => {
|
||||
const state = makeServerState();
|
||||
const status = { state: StatusEnum.LOGGED_IN, description: 'ok' };
|
||||
const result = serverReducer(state, { type: Types.UPDATE_STATUS, status });
|
||||
expect(result.status).toEqual(status);
|
||||
});
|
||||
});
|
||||
|
||||
// ── User ──────────────────────────────────────────────────────────────────────
|
||||
|
||||
describe('User', () => {
|
||||
it('UPDATE_USER → merges action.user into state.user', () => {
|
||||
const state = makeServerState({ user: makeUser({ name: 'Alice', userLevel: 1 }) });
|
||||
const result = serverReducer(state, {
|
||||
type: Types.UPDATE_USER,
|
||||
user: { userLevel: 8 },
|
||||
});
|
||||
expect(result.user.name).toBe('Alice');
|
||||
expect(result.user.userLevel).toBe(8);
|
||||
});
|
||||
|
||||
it('ACCOUNT_EDIT_CHANGED → merges action.user into state.user', () => {
|
||||
const state = makeServerState({ user: makeUser({ name: 'Alice' }) });
|
||||
const result = serverReducer(state, { type: Types.ACCOUNT_EDIT_CHANGED, user: { realName: 'Alice Smith' } });
|
||||
expect(result.user.realName).toBe('Alice Smith');
|
||||
expect(result.user.name).toBe('Alice');
|
||||
});
|
||||
|
||||
it('ACCOUNT_IMAGE_CHANGED → merges action.user into state.user', () => {
|
||||
const state = makeServerState({ user: makeUser({ name: 'Alice' }) });
|
||||
const result = serverReducer(state, { type: Types.ACCOUNT_IMAGE_CHANGED, user: { country: 'US' } });
|
||||
expect(result.user.country).toBe('US');
|
||||
});
|
||||
});
|
||||
|
||||
// ── Users List ────────────────────────────────────────────────────────────────
|
||||
|
||||
describe('Users List', () => {
|
||||
it('UPDATE_USERS → replaces users list and sorts by name ASC', () => {
|
||||
const state = makeServerState();
|
||||
const users = [makeUser({ name: 'Zane' }), makeUser({ name: 'Alice' })];
|
||||
const result = serverReducer(state, { type: Types.UPDATE_USERS, users });
|
||||
expect(result.users[0].name).toBe('Alice');
|
||||
expect(result.users[1].name).toBe('Zane');
|
||||
});
|
||||
|
||||
it('USER_JOINED → appends user and sorts', () => {
|
||||
const state = makeServerState({ users: [makeUser({ name: 'Zane' })] });
|
||||
const result = serverReducer(state, { type: Types.USER_JOINED, user: makeUser({ name: 'Alice' }) });
|
||||
expect(result.users[0].name).toBe('Alice');
|
||||
expect(result.users[1].name).toBe('Zane');
|
||||
});
|
||||
|
||||
it('USER_LEFT → removes user by name', () => {
|
||||
const state = makeServerState({ users: [makeUser({ name: 'Alice' }), makeUser({ name: 'Bob' })] });
|
||||
const result = serverReducer(state, { type: Types.USER_LEFT, name: 'Alice' });
|
||||
expect(result.users).toHaveLength(1);
|
||||
expect(result.users[0].name).toBe('Bob');
|
||||
});
|
||||
});
|
||||
|
||||
// ── Buddy & Ignore Lists ──────────────────────────────────────────────────────
|
||||
|
||||
describe('Buddy List', () => {
|
||||
it('UPDATE_BUDDY_LIST → replaces and sorts buddy list', () => {
|
||||
const state = makeServerState();
|
||||
const buddyList = [makeUser({ name: 'Zane' }), makeUser({ name: 'Alice' })];
|
||||
const result = serverReducer(state, { type: Types.UPDATE_BUDDY_LIST, buddyList });
|
||||
expect(result.buddyList[0].name).toBe('Alice');
|
||||
});
|
||||
|
||||
it('ADD_TO_BUDDY_LIST → appends user and sorts', () => {
|
||||
const state = makeServerState({ buddyList: [makeUser({ name: 'Zane' })] });
|
||||
const result = serverReducer(state, { type: Types.ADD_TO_BUDDY_LIST, user: makeUser({ name: 'Alice' }) });
|
||||
expect(result.buddyList[0].name).toBe('Alice');
|
||||
expect(result.buddyList).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('REMOVE_FROM_BUDDY_LIST → removes user by name', () => {
|
||||
const state = makeServerState({ buddyList: [makeUser({ name: 'Alice' }), makeUser({ name: 'Bob' })] });
|
||||
const result = serverReducer(state, { type: Types.REMOVE_FROM_BUDDY_LIST, userName: 'Alice' });
|
||||
expect(result.buddyList).toHaveLength(1);
|
||||
expect(result.buddyList[0].name).toBe('Bob');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Ignore List', () => {
|
||||
it('UPDATE_IGNORE_LIST → replaces and sorts ignore list', () => {
|
||||
const state = makeServerState();
|
||||
const ignoreList = [makeUser({ name: 'Zane' }), makeUser({ name: 'Alice' })];
|
||||
const result = serverReducer(state, { type: Types.UPDATE_IGNORE_LIST, ignoreList });
|
||||
expect(result.ignoreList[0].name).toBe('Alice');
|
||||
});
|
||||
|
||||
it('ADD_TO_IGNORE_LIST → appends user and sorts', () => {
|
||||
const state = makeServerState({ ignoreList: [makeUser({ name: 'Zane' })] });
|
||||
const result = serverReducer(state, { type: Types.ADD_TO_IGNORE_LIST, user: makeUser({ name: 'Alice' }) });
|
||||
expect(result.ignoreList[0].name).toBe('Alice');
|
||||
expect(result.ignoreList).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('REMOVE_FROM_IGNORE_LIST → removes user by name', () => {
|
||||
const state = makeServerState({ ignoreList: [makeUser({ name: 'Alice' }), makeUser({ name: 'Bob' })] });
|
||||
const result = serverReducer(state, { type: Types.REMOVE_FROM_IGNORE_LIST, userName: 'Alice' });
|
||||
expect(result.ignoreList).toHaveLength(1);
|
||||
expect(result.ignoreList[0].name).toBe('Bob');
|
||||
});
|
||||
});
|
||||
|
||||
// ── Logs ─────────────────────────────────────────────────────────────────────
|
||||
|
||||
describe('Logs', () => {
|
||||
it('VIEW_LOGS → replaces logs entirely', () => {
|
||||
const logs = { room: [makeLogItem()], game: [], chat: [] };
|
||||
const state = makeServerState();
|
||||
const result = serverReducer(state, { type: Types.VIEW_LOGS, logs });
|
||||
expect(result.logs).toEqual(logs);
|
||||
});
|
||||
|
||||
it('CLEAR_LOGS → resets logs to empty arrays', () => {
|
||||
const state = makeServerState({ logs: { room: [makeLogItem()], game: [], chat: [] } });
|
||||
const result = serverReducer(state, { type: Types.CLEAR_LOGS });
|
||||
expect(result.logs.room).toEqual([]);
|
||||
expect(result.logs.game).toEqual([]);
|
||||
expect(result.logs.chat).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
// ── Messaging ─────────────────────────────────────────────────────────────────
|
||||
|
||||
describe('Messaging', () => {
|
||||
it('USER_MESSAGE → uses receiverName as key when current user is sender', () => {
|
||||
const state = makeServerState({ user: makeUser({ name: 'Alice' }), messages: {} });
|
||||
const messageData = { senderName: 'Alice', receiverName: 'Bob', message: 'hi' };
|
||||
const result = serverReducer(state, { type: Types.USER_MESSAGE, messageData });
|
||||
expect(result.messages['Bob']).toHaveLength(1);
|
||||
expect(result.messages['Bob'][0]).toBe(messageData);
|
||||
});
|
||||
|
||||
it('USER_MESSAGE → uses senderName as key when current user is receiver', () => {
|
||||
const state = makeServerState({ user: makeUser({ name: 'Bob' }), messages: {} });
|
||||
const messageData = { senderName: 'Alice', receiverName: 'Bob', message: 'yo' };
|
||||
const result = serverReducer(state, { type: Types.USER_MESSAGE, messageData });
|
||||
expect(result.messages['Alice']).toHaveLength(1);
|
||||
expect(result.messages['Alice'][0]).toBe(messageData);
|
||||
});
|
||||
|
||||
it('USER_MESSAGE → appends to existing messages for that user', () => {
|
||||
const existingMsg = { senderName: 'Alice', receiverName: 'Bob', message: 'first' };
|
||||
const state = makeServerState({
|
||||
user: makeUser({ name: 'Bob' }),
|
||||
messages: { Alice: [existingMsg] },
|
||||
});
|
||||
const newMsg = { senderName: 'Alice', receiverName: 'Bob', message: 'second' };
|
||||
const result = serverReducer(state, { type: Types.USER_MESSAGE, messageData: newMsg });
|
||||
expect(result.messages['Alice']).toHaveLength(2);
|
||||
});
|
||||
});
|
||||
|
||||
// ── User Info & Notifications ─────────────────────────────────────────────────
|
||||
|
||||
describe('User Info & Notifications', () => {
|
||||
it('GET_USER_INFO → adds userInfo keyed by name', () => {
|
||||
const userInfo = makeUser({ name: 'Eve' });
|
||||
const state = makeServerState();
|
||||
const result = serverReducer(state, { type: Types.GET_USER_INFO, userInfo });
|
||||
expect(result.userInfo['Eve']).toBe(userInfo);
|
||||
});
|
||||
|
||||
it('NOTIFY_USER → appends notification to list', () => {
|
||||
const state = makeServerState({ notifications: [] });
|
||||
const notification = { type: 1, warningReason: '', customTitle: '', customContent: '' };
|
||||
const result = serverReducer(state, { type: Types.NOTIFY_USER, notification });
|
||||
expect(result.notifications).toHaveLength(1);
|
||||
expect(result.notifications[0]).toBe(notification);
|
||||
});
|
||||
|
||||
it('SERVER_SHUTDOWN → sets serverShutdown to action.data', () => {
|
||||
const data = { reason: 'maintenance', minutes: 10 };
|
||||
const state = makeServerState();
|
||||
const result = serverReducer(state, { type: Types.SERVER_SHUTDOWN, data });
|
||||
expect(result.serverShutdown).toBe(data);
|
||||
});
|
||||
});
|
||||
|
||||
// ── Moderation ────────────────────────────────────────────────────────────────
|
||||
|
||||
describe('Moderation', () => {
|
||||
it('BAN_FROM_SERVER → sets banUser', () => {
|
||||
const state = makeServerState();
|
||||
const result = serverReducer(state, { type: Types.BAN_FROM_SERVER, userName: 'Frank' });
|
||||
expect(result.banUser).toBe('Frank');
|
||||
});
|
||||
|
||||
it('BAN_HISTORY → adds banHistory keyed by userName', () => {
|
||||
const history = [makeBanHistoryItem()];
|
||||
const state = makeServerState();
|
||||
const result = serverReducer(state, { type: Types.BAN_HISTORY, userName: 'Frank', banHistory: history });
|
||||
expect(result.banHistory['Frank']).toBe(history);
|
||||
});
|
||||
|
||||
it('WARN_HISTORY → adds warnHistory keyed by userName', () => {
|
||||
const history = [makeWarnHistoryItem()];
|
||||
const state = makeServerState();
|
||||
const result = serverReducer(state, { type: Types.WARN_HISTORY, userName: 'Grace', warnHistory: history });
|
||||
expect(result.warnHistory['Grace']).toBe(history);
|
||||
});
|
||||
|
||||
it('WARN_LIST_OPTIONS → replaces warnListOptions', () => {
|
||||
const list = [makeWarnListItem()];
|
||||
const state = makeServerState();
|
||||
const result = serverReducer(state, { type: Types.WARN_LIST_OPTIONS, warnList: list });
|
||||
expect(result.warnListOptions).toBe(list);
|
||||
});
|
||||
|
||||
it('WARN_USER → sets warnUser', () => {
|
||||
const state = makeServerState();
|
||||
const result = serverReducer(state, { type: Types.WARN_USER, userName: 'Hank' });
|
||||
expect(result.warnUser).toBe('Hank');
|
||||
});
|
||||
|
||||
it('GET_ADMIN_NOTES → adds adminNotes keyed by userName', () => {
|
||||
const state = makeServerState();
|
||||
const result = serverReducer(state, { type: Types.GET_ADMIN_NOTES, userName: 'Ira', notes: 'note1' });
|
||||
expect(result.adminNotes['Ira']).toBe('note1');
|
||||
});
|
||||
|
||||
it('UPDATE_ADMIN_NOTES → updates adminNotes keyed by userName', () => {
|
||||
const state = makeServerState({ adminNotes: { Ira: 'old' } });
|
||||
const result = serverReducer(state, { type: Types.UPDATE_ADMIN_NOTES, userName: 'Ira', notes: 'new' });
|
||||
expect(result.adminNotes['Ira']).toBe('new');
|
||||
});
|
||||
});
|
||||
|
||||
// ── ADJUST_MOD ────────────────────────────────────────────────────────────────
|
||||
|
||||
describe('ADJUST_MOD', () => {
|
||||
const baseUserLevel = UserLevelFlag.IsUser | UserLevelFlag.IsRegistered | UserLevelFlag.IsModerator | UserLevelFlag.IsJudge;
|
||||
|
||||
it('shouldBeMod=true, shouldBeJudge=true → keeps IsModerator and IsJudge bits', () => {
|
||||
const state = makeServerState({ users: [makeUser({ name: 'Dan', userLevel: baseUserLevel })] });
|
||||
const result = serverReducer(state, { type: Types.ADJUST_MOD, userName: 'Dan', shouldBeMod: true, shouldBeJudge: true });
|
||||
// IsModerator(4) | IsJudge(16)
|
||||
expect(result.users[0].userLevel).toBe(20);
|
||||
});
|
||||
|
||||
it('shouldBeMod=true, shouldBeJudge=false → keeps only IsModerator bit', () => {
|
||||
const state = makeServerState({ users: [makeUser({ name: 'Dan', userLevel: baseUserLevel })] });
|
||||
const result = serverReducer(state, { type: Types.ADJUST_MOD, userName: 'Dan', shouldBeMod: true, shouldBeJudge: false });
|
||||
// IsModerator(4)
|
||||
expect(result.users[0].userLevel).toBe(4);
|
||||
});
|
||||
|
||||
it('shouldBeMod=false, shouldBeJudge=true → keeps only IsJudge bit', () => {
|
||||
const state = makeServerState({ users: [makeUser({ name: 'Dan', userLevel: baseUserLevel })] });
|
||||
const result = serverReducer(state, { type: Types.ADJUST_MOD, userName: 'Dan', shouldBeMod: false, shouldBeJudge: true });
|
||||
// IsJudge(16)
|
||||
expect(result.users[0].userLevel).toBe(16);
|
||||
});
|
||||
|
||||
it('shouldBeMod=false, shouldBeJudge=false → clears both bits', () => {
|
||||
const state = makeServerState({ users: [makeUser({ name: 'Dan', userLevel: baseUserLevel })] });
|
||||
const result = serverReducer(state, { type: Types.ADJUST_MOD, userName: 'Dan', shouldBeMod: false, shouldBeJudge: false });
|
||||
expect(result.users[0].userLevel).toBe(0);
|
||||
});
|
||||
|
||||
it('non-matching users are left unchanged', () => {
|
||||
const alice = makeUser({ name: 'Alice', userLevel: 7 });
|
||||
const state = makeServerState({ users: [alice, makeUser({ name: 'Dan', userLevel: baseUserLevel })] });
|
||||
const result = serverReducer(state, { type: Types.ADJUST_MOD, userName: 'Dan', shouldBeMod: false, shouldBeJudge: false });
|
||||
expect(result.users.find(u => u.name === 'Alice').userLevel).toBe(7);
|
||||
});
|
||||
});
|
||||
|
||||
// ── Replays ───────────────────────────────────────────────────────────────────
|
||||
|
||||
describe('Replays', () => {
|
||||
it('REPLAY_LIST → replaces replays list', () => {
|
||||
const matchList = [makeReplayMatch({ gameId: 10 })];
|
||||
const state = makeServerState({ replays: [makeReplayMatch({ gameId: 99 })] });
|
||||
const result = serverReducer(state, { type: Types.REPLAY_LIST, matchList });
|
||||
expect(result.replays).toHaveLength(1);
|
||||
expect(result.replays[0].gameId).toBe(10);
|
||||
});
|
||||
|
||||
it('REPLAY_ADDED → appends matchInfo to replays', () => {
|
||||
const existing = makeReplayMatch({ gameId: 1 });
|
||||
const added = makeReplayMatch({ gameId: 2 });
|
||||
const state = makeServerState({ replays: [existing] });
|
||||
const result = serverReducer(state, { type: Types.REPLAY_ADDED, matchInfo: added });
|
||||
expect(result.replays).toHaveLength(2);
|
||||
expect(result.replays[1]).toBe(added);
|
||||
});
|
||||
|
||||
it('REPLAY_MODIFY_MATCH → updates doNotHide for matching gameId', () => {
|
||||
const state = makeServerState({ replays: [makeReplayMatch({ gameId: 5, doNotHide: false })] });
|
||||
const result = serverReducer(state, { type: Types.REPLAY_MODIFY_MATCH, gameId: 5, doNotHide: true });
|
||||
expect(result.replays[0].doNotHide).toBe(true);
|
||||
});
|
||||
|
||||
it('REPLAY_MODIFY_MATCH → leaves non-matching replays unchanged', () => {
|
||||
const r1 = makeReplayMatch({ gameId: 1, doNotHide: false });
|
||||
const r2 = makeReplayMatch({ gameId: 2, doNotHide: false });
|
||||
const state = makeServerState({ replays: [r1, r2] });
|
||||
const result = serverReducer(state, { type: Types.REPLAY_MODIFY_MATCH, gameId: 1, doNotHide: true });
|
||||
expect(result.replays[1].doNotHide).toBe(false);
|
||||
});
|
||||
|
||||
it('REPLAY_DELETE_MATCH → removes replay by gameId', () => {
|
||||
const state = makeServerState({ replays: [makeReplayMatch({ gameId: 5 }), makeReplayMatch({ gameId: 6 })] });
|
||||
const result = serverReducer(state, { type: Types.REPLAY_DELETE_MATCH, gameId: 5 });
|
||||
expect(result.replays).toHaveLength(1);
|
||||
expect(result.replays[0].gameId).toBe(6);
|
||||
});
|
||||
});
|
||||
|
||||
// ── Deck Storage ──────────────────────────────────────────────────────────────
|
||||
|
||||
describe('Deck Storage', () => {
|
||||
it('BACKEND_DECKS → sets backendDecks', () => {
|
||||
const deckList = makeDeckList();
|
||||
const state = makeServerState();
|
||||
const result = serverReducer(state, { type: Types.BACKEND_DECKS, deckList });
|
||||
expect(result.backendDecks).toBe(deckList);
|
||||
});
|
||||
|
||||
it('DECK_UPLOAD with null backendDecks → returns state unchanged', () => {
|
||||
const state = makeServerState({ backendDecks: null });
|
||||
const result = serverReducer(state, { type: Types.DECK_UPLOAD, path: '', treeItem: makeDeckTreeItem() });
|
||||
expect(result).toBe(state);
|
||||
});
|
||||
|
||||
it('DECK_UPLOAD with flat path → appends item to root', () => {
|
||||
const state = makeServerState({ backendDecks: makeDeckList() });
|
||||
const item = makeDeckTreeItem({ name: 'deck.cod' });
|
||||
const result = serverReducer(state, { type: Types.DECK_UPLOAD, path: '', treeItem: item });
|
||||
expect(result.backendDecks.root.items).toHaveLength(1);
|
||||
expect(result.backendDecks.root.items[0]).toBe(item);
|
||||
});
|
||||
|
||||
it('DECK_UPLOAD with nested path → inserts into matching subfolder', () => {
|
||||
const subfolder = { id: 0, name: 'myDecks', file: null, folder: { items: [] } };
|
||||
const state = makeServerState({ backendDecks: { root: { items: [subfolder] } } });
|
||||
const item = makeDeckTreeItem({ name: 'new.cod' });
|
||||
const result = serverReducer(state, { type: Types.DECK_UPLOAD, path: 'myDecks', treeItem: item });
|
||||
const folder = result.backendDecks.root.items.find(i => i.name === 'myDecks');
|
||||
expect(folder.folder.items).toHaveLength(1);
|
||||
expect(folder.folder.items[0]).toBe(item);
|
||||
});
|
||||
|
||||
it('DECK_UPLOAD with non-existent intermediate folder → creates folder and inserts', () => {
|
||||
const state = makeServerState({ backendDecks: makeDeckList() });
|
||||
const item = makeDeckTreeItem({ name: 'deck.cod' });
|
||||
const result = serverReducer(state, { type: Types.DECK_UPLOAD, path: 'newFolder', treeItem: item });
|
||||
expect(result.backendDecks.root.items).toHaveLength(1);
|
||||
expect(result.backendDecks.root.items[0].name).toBe('newFolder');
|
||||
expect(result.backendDecks.root.items[0].folder.items[0]).toBe(item);
|
||||
});
|
||||
|
||||
it('DECK_DELETE with null backendDecks → returns state unchanged', () => {
|
||||
const state = makeServerState({ backendDecks: null });
|
||||
const result = serverReducer(state, { type: Types.DECK_DELETE, deckId: 1 });
|
||||
expect(result).toBe(state);
|
||||
});
|
||||
|
||||
it('DECK_DELETE → removes item by id from tree', () => {
|
||||
const item = makeDeckTreeItem({ id: 7 });
|
||||
const state = makeServerState({ backendDecks: { root: { items: [item] } } });
|
||||
const result = serverReducer(state, { type: Types.DECK_DELETE, deckId: 7 });
|
||||
expect(result.backendDecks.root.items).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('DECK_DELETE → recursively removes item nested inside a subfolder', () => {
|
||||
const nested = makeDeckTreeItem({ id: 9, name: 'nested.cod' });
|
||||
const subfolder = { id: 0, name: 'sub', file: null, folder: { items: [nested] } };
|
||||
const state = makeServerState({ backendDecks: { root: { items: [subfolder] } } });
|
||||
const result = serverReducer(state, { type: Types.DECK_DELETE, deckId: 9 });
|
||||
expect(result.backendDecks.root.items[0].folder.items).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('DECK_NEW_DIR with null backendDecks → returns state unchanged', () => {
|
||||
const state = makeServerState({ backendDecks: null });
|
||||
const result = serverReducer(state, { type: Types.DECK_NEW_DIR, path: '', dirName: 'newDir' });
|
||||
expect(result).toBe(state);
|
||||
});
|
||||
|
||||
it('DECK_NEW_DIR at root → appends folder to root items', () => {
|
||||
const state = makeServerState({ backendDecks: makeDeckList() });
|
||||
const result = serverReducer(state, { type: Types.DECK_NEW_DIR, path: '', dirName: 'myDir' });
|
||||
expect(result.backendDecks.root.items).toHaveLength(1);
|
||||
expect(result.backendDecks.root.items[0].name).toBe('myDir');
|
||||
expect(result.backendDecks.root.items[0].folder).toEqual({ items: [] });
|
||||
});
|
||||
|
||||
it('DECK_NEW_DIR nested → inserts folder inside matching subfolder', () => {
|
||||
const subfolder = { id: 0, name: 'parent', file: null, folder: { items: [] } };
|
||||
const state = makeServerState({ backendDecks: { root: { items: [subfolder] } } });
|
||||
const result = serverReducer(state, { type: Types.DECK_NEW_DIR, path: 'parent', dirName: 'child' });
|
||||
const parent = result.backendDecks.root.items.find(i => i.name === 'parent');
|
||||
expect(parent.folder.items).toHaveLength(1);
|
||||
expect(parent.folder.items[0].name).toBe('child');
|
||||
});
|
||||
|
||||
it('DECK_DEL_DIR with null backendDecks → returns state unchanged', () => {
|
||||
const state = makeServerState({ backendDecks: null });
|
||||
const result = serverReducer(state, { type: Types.DECK_DEL_DIR, path: 'myDir' });
|
||||
expect(result).toBe(state);
|
||||
});
|
||||
|
||||
it('DECK_DEL_DIR → removes folder from root by name', () => {
|
||||
const subfolder = { id: 0, name: 'myDir', file: null, folder: { items: [] } };
|
||||
const state = makeServerState({ backendDecks: { root: { items: [subfolder] } } });
|
||||
const result = serverReducer(state, { type: Types.DECK_DEL_DIR, path: 'myDir' });
|
||||
expect(result.backendDecks.root.items).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('DECK_DEL_DIR → returns deck tree unchanged when path is empty', () => {
|
||||
const subfolder = { id: 0, name: 'keep', file: null, folder: { items: [] } };
|
||||
const state = makeServerState({ backendDecks: { root: { items: [subfolder] } } });
|
||||
const result = serverReducer(state, { type: Types.DECK_DEL_DIR, path: '' });
|
||||
expect(result.backendDecks.root.items).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('DECK_DEL_DIR → recursively removes nested subfolder via multi-segment path', () => {
|
||||
const child = { id: 0, name: 'child', file: null, folder: { items: [] } };
|
||||
const parent = { id: 0, name: 'parent', file: null, folder: { items: [child] } };
|
||||
const state = makeServerState({ backendDecks: { root: { items: [parent] } } });
|
||||
const result = serverReducer(state, { type: Types.DECK_DEL_DIR, path: 'parent/child' });
|
||||
expect(result.backendDecks.root.items[0].folder.items).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
98
webclient/src/store/server/server.selectors.spec.ts
Normal file
98
webclient/src/store/server/server.selectors.spec.ts
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
import { Selectors } from './server.selectors';
|
||||
import { ServerState } from './server.interfaces';
|
||||
import {
|
||||
makeDeckList,
|
||||
makeReplayMatch,
|
||||
makeServerState,
|
||||
makeUser,
|
||||
} from './__mocks__/server-fixtures';
|
||||
import { StatusEnum } from 'types';
|
||||
|
||||
function rootState(server: ServerState) {
|
||||
return { server };
|
||||
}
|
||||
|
||||
describe('Selectors', () => {
|
||||
it('getInitialized → returns initialized flag', () => {
|
||||
const state = makeServerState({ initialized: true });
|
||||
expect(Selectors.getInitialized(rootState(state))).toBe(true);
|
||||
});
|
||||
|
||||
it('getConnectOptions → returns connectOptions', () => {
|
||||
const connectOptions = { host: 'localhost', port: '4747' };
|
||||
const state = makeServerState({ connectOptions });
|
||||
expect(Selectors.getConnectOptions(rootState(state))).toBe(connectOptions);
|
||||
});
|
||||
|
||||
it('getMessage → returns info.message', () => {
|
||||
const state = makeServerState({ info: { message: 'Welcome!', name: null, version: null } });
|
||||
expect(Selectors.getMessage(rootState(state))).toBe('Welcome!');
|
||||
});
|
||||
|
||||
it('getName → returns info.name', () => {
|
||||
const state = makeServerState({ info: { message: null, name: 'Servatrice', version: null } });
|
||||
expect(Selectors.getName(rootState(state))).toBe('Servatrice');
|
||||
});
|
||||
|
||||
it('getVersion → returns info.version', () => {
|
||||
const state = makeServerState({ info: { message: null, name: null, version: '2.9.0' } });
|
||||
expect(Selectors.getVersion(rootState(state))).toBe('2.9.0');
|
||||
});
|
||||
|
||||
it('getDescription → returns status.description', () => {
|
||||
const state = makeServerState({ status: { state: StatusEnum.CONNECTED, description: 'ok' } });
|
||||
expect(Selectors.getDescription(rootState(state))).toBe('ok');
|
||||
});
|
||||
|
||||
it('getState → returns status.state', () => {
|
||||
const state = makeServerState({ status: { state: StatusEnum.LOGGED_IN, description: null } });
|
||||
expect(Selectors.getState(rootState(state))).toBe(StatusEnum.LOGGED_IN);
|
||||
});
|
||||
|
||||
it('getUser → returns user', () => {
|
||||
const user = makeUser({ name: 'Alice' });
|
||||
const state = makeServerState({ user });
|
||||
expect(Selectors.getUser(rootState(state))).toBe(user);
|
||||
});
|
||||
|
||||
it('getUsers → returns users array', () => {
|
||||
const users = [makeUser(), makeUser({ name: 'Bob' })];
|
||||
const state = makeServerState({ users });
|
||||
expect(Selectors.getUsers(rootState(state))).toBe(users);
|
||||
});
|
||||
|
||||
it('getLogs → returns logs object', () => {
|
||||
const logs = { room: [], game: [], chat: [] };
|
||||
const state = makeServerState({ logs });
|
||||
expect(Selectors.getLogs(rootState(state))).toBe(logs);
|
||||
});
|
||||
|
||||
it('getBuddyList → returns buddyList', () => {
|
||||
const buddyList = [makeUser({ name: 'Carol' })];
|
||||
const state = makeServerState({ buddyList });
|
||||
expect(Selectors.getBuddyList(rootState(state))).toBe(buddyList);
|
||||
});
|
||||
|
||||
it('getIgnoreList → returns ignoreList', () => {
|
||||
const ignoreList = [makeUser({ name: 'Dave' })];
|
||||
const state = makeServerState({ ignoreList });
|
||||
expect(Selectors.getIgnoreList(rootState(state))).toBe(ignoreList);
|
||||
});
|
||||
|
||||
it('getReplays → returns replays', () => {
|
||||
const replays = [makeReplayMatch()];
|
||||
const state = makeServerState({ replays });
|
||||
expect(Selectors.getReplays(rootState(state))).toBe(replays);
|
||||
});
|
||||
|
||||
it('getBackendDecks → returns backendDecks', () => {
|
||||
const backendDecks = makeDeckList();
|
||||
const state = makeServerState({ backendDecks });
|
||||
expect(Selectors.getBackendDecks(rootState(state))).toBe(backendDecks);
|
||||
});
|
||||
|
||||
it('getBackendDecks → returns null when not set', () => {
|
||||
const state = makeServerState({ backendDecks: null });
|
||||
expect(Selectors.getBackendDecks(rootState(state))).toBeNull();
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue