Some more tests
This commit is contained in:
parent
fb53bc2c2a
commit
e143471fa8
@ -17,21 +17,21 @@
|
||||
<template>
|
||||
<section class="sidebar" role="none" ref="sidebar">
|
||||
<header class="sidebar__buttons">
|
||||
<button v-if="mapCount > 1 || serverCount > 1" class="button--maps" data-section="maps"
|
||||
<button ref="maps-button" v-if="mapCount > 1 || serverCount > 1" class="button--maps" data-section="maps"
|
||||
:title="mapCount > 1 ? messageWorlds : messageServers"
|
||||
:aria-label="mapCount > 1 ? messageWorlds : messageServers"
|
||||
:aria-expanded="mapsVisible"
|
||||
@click="handleSectionClick" @keydown="handleSectionKeydown">
|
||||
<SvgIcon :name="mapCount > 1 ? 'maps' : 'servers'"></SvgIcon>
|
||||
<SvgIcon ref="maps-icon" :name="mapCount > 1 ? 'maps' : 'servers'"></SvgIcon>
|
||||
</button>
|
||||
<button v-if="markerUIEnabled" class="button--markers" data-section="markers"
|
||||
<button ref="markers-button" v-if="markerUIEnabled" class="button--markers" data-section="markers"
|
||||
:title="messageMarkers"
|
||||
:aria-label="messageMarkers"
|
||||
:aria-expanded="markersVisible"
|
||||
@click="handleSectionClick" @keydown="handleSectionKeydown">
|
||||
<SvgIcon name="marker_point"></SvgIcon>
|
||||
</button>
|
||||
<button v-if="playerMakersEnabled" class="button--players" data-section="players"
|
||||
<button ref="players-button" v-if="playerMakersEnabled" class="button--players" data-section="players"
|
||||
:title="messagePlayers" :aria-label="messagePlayers" :aria-expanded="playersVisible"
|
||||
@click="handleSectionClick" @keydown="handleSectionKeydown">
|
||||
<SvgIcon name="players"></SvgIcon>
|
||||
|
47
test/components/PlayerImage.test.ts
Normal file
47
test/components/PlayerImage.test.ts
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2022 James Lyne
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { mount } from '@vue/test-utils';
|
||||
import PlayerImage from '@/Components/PlayerImage.vue';
|
||||
import {getDefaultPlayerImage, getPlayerImage} from "@/util/images";
|
||||
import {useTestImageProvider} from "../helpers";
|
||||
|
||||
describe('PlayerImage', async () => {
|
||||
it('exists', () => {
|
||||
expect(PlayerImage).toBeTruthy()
|
||||
});
|
||||
|
||||
const player = {
|
||||
name: 'gamer',
|
||||
displayName: 'Gamer',
|
||||
armor: 10,
|
||||
health: 10,
|
||||
sort: 1,
|
||||
hidden: false,
|
||||
location: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0,
|
||||
}
|
||||
},
|
||||
wrapper = mount(PlayerImage, {
|
||||
props: { player },
|
||||
});
|
||||
|
||||
it('displays the default image', () => {
|
||||
expect(wrapper.element.getAttribute('src')).toEqual(getDefaultPlayerImage())
|
||||
});
|
||||
});
|
105
test/components/Sidebar.test.ts
Normal file
105
test/components/Sidebar.test.ts
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2022 James Lyne
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import {mount, VueWrapper} from '@vue/test-utils';
|
||||
import Sidebar from '@/Components/Sidebar.vue';
|
||||
import {addDynmapServer, addWorld, clearServers, clearWorlds, enablePlayerMarkers} from "../helpers";
|
||||
import {nextTick} from "vue";
|
||||
import {useStore} from "@/store";
|
||||
import {MutationTypes} from "@/store/mutation-types";
|
||||
|
||||
describe('Sidebar', () => {
|
||||
it('exists', () => {
|
||||
expect(Sidebar).toBeTruthy()
|
||||
});
|
||||
|
||||
let component: VueWrapper;
|
||||
|
||||
beforeEach(async () => {
|
||||
clearServers();
|
||||
clearWorlds();
|
||||
|
||||
//Add single dynmap server with single world
|
||||
addDynmapServer(true);
|
||||
addWorld('overworld', 1);
|
||||
|
||||
const host = document.createElement('div');
|
||||
document.body.appendChild(host);
|
||||
|
||||
component = mount(Sidebar, {
|
||||
attachTo: host,
|
||||
});
|
||||
|
||||
useStore().commit(MutationTypes.SET_LOADED, undefined);
|
||||
|
||||
await nextTick();
|
||||
});
|
||||
|
||||
describe('Maps button', () => {
|
||||
it('not shown when single map and server exist', () =>
|
||||
expect(component.find({ref: 'maps-button'}).exists()).toBeFalsy());
|
||||
|
||||
it('shown with server icon when multiple servers exist with single map', async () => {
|
||||
addDynmapServer(false); //Extra server
|
||||
|
||||
await nextTick();
|
||||
|
||||
expect(component.find({ref: 'maps-button'}).exists()).toBeTruthy();
|
||||
expect(component.getComponent({ref: 'maps-icon'}).props('name')).toBe("servers");
|
||||
});
|
||||
|
||||
it('shown with map icon when multiple worlds defined', async () => {
|
||||
addWorld('overworld', 1); //Extra world
|
||||
|
||||
await nextTick();
|
||||
|
||||
expect(component.find({ref: 'maps-button'}).exists()).toBeTruthy();
|
||||
expect(component.getComponent({ref: 'maps-icon'}).props('name')).toBe("maps");
|
||||
});
|
||||
|
||||
it('shown with map icon when single world with multiple maps defined', async () => {
|
||||
clearWorlds();
|
||||
addWorld('overworld', 2); //World with 2 maps
|
||||
|
||||
await nextTick();
|
||||
|
||||
expect(component.find({ref: 'maps-button'}).exists()).toBeTruthy();
|
||||
expect(component.getComponent({ref: 'maps-icon'}).props('name')).toBe("maps");
|
||||
});
|
||||
});
|
||||
|
||||
describe('Players button', () => {
|
||||
it('not shown when player markers are disabled', () => {
|
||||
expect(component.find({ref: 'players-button'}).exists()).toBeFalsy();
|
||||
});
|
||||
|
||||
it('shown when player markers are enabled', async () => {
|
||||
enablePlayerMarkers();
|
||||
await nextTick();
|
||||
|
||||
expect(component.find({ref: 'players-button'}).exists()).toBeTruthy();
|
||||
});
|
||||
|
||||
it('moves focus to players section on down arrow press', async () => {
|
||||
const button = component.find({ref: 'players-button'});
|
||||
(button.element as HTMLElement).focus();
|
||||
await button.trigger('keydown', {key: 'ArrowDown'})
|
||||
|
||||
expect(document.activeElement!.id).toEqual('players-heading');
|
||||
});
|
||||
});
|
||||
});
|
60
test/components/SvgIcon.test.ts
Normal file
60
test/components/SvgIcon.test.ts
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2022 James Lyne
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { mount } from '@vue/test-utils';
|
||||
import SVGIcon from '@/Components/SVGIcon.vue';
|
||||
|
||||
describe('SVGIcon', async () => {
|
||||
it('exists', () => {
|
||||
expect(SVGIcon).toBeTruthy()
|
||||
});
|
||||
|
||||
const wrapper = mount(SVGIcon, {
|
||||
props: {
|
||||
name: 'maps',
|
||||
},
|
||||
});
|
||||
|
||||
it('displays the correct icon', () => {
|
||||
expect(wrapper.find('use').attributes().href).toEqual('#icon--maps');
|
||||
});
|
||||
|
||||
it('has the correct classname', () => {
|
||||
expect(wrapper.element.classList.contains('svg-icon--maps')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('displays the correct icon when updated', async () => {
|
||||
await wrapper.setProps({
|
||||
name: 'servers',
|
||||
});
|
||||
expect(wrapper.find('use').attributes().href).toEqual('#icon--servers');
|
||||
});
|
||||
|
||||
it('has the correct classname when updated', () => {
|
||||
expect(wrapper.element.classList.contains('svg-icon--servers')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('doesn\'t render <title> when not provided', () => {
|
||||
expect(wrapper.find('title').exists()).toBeFalsy();
|
||||
});
|
||||
|
||||
it('renders <title> when provided', async () => {
|
||||
await wrapper.setProps({
|
||||
title: 'test icon title',
|
||||
});
|
||||
expect(wrapper.text()).toContain('test icon title');
|
||||
});
|
||||
});
|
182
test/helpers.ts
Normal file
182
test/helpers.ts
Normal file
@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright 2022 James Lyne
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {useStore} from "@/store";
|
||||
import {MutationTypes} from "@/store/mutation-types";
|
||||
import {getDefaultPlayerImage} from "@/util/images";
|
||||
import {LiveAtlasDimension, LiveAtlasWorldDefinition, PlayerImageQueueEntry} from "../src";
|
||||
import LiveAtlasMapDefinition from "../src/model/LiveAtlasMapDefinition";
|
||||
|
||||
export const enablePlayerMarkers = () => {
|
||||
useStore().commit(MutationTypes.SET_COMPONENTS, {
|
||||
players: {
|
||||
markers: {
|
||||
hideByDefault: false,
|
||||
layerName: 'Players',
|
||||
imageSize: 'large',
|
||||
layerPriority: 0,
|
||||
showHealth: true,
|
||||
showArmor: true,
|
||||
showYaw: false,
|
||||
},
|
||||
showImages: true,
|
||||
grayHiddenPlayers: true,
|
||||
imageUrl: getDefaultPlayerImage,
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Clears any test servers added to the store
|
||||
*/
|
||||
export const clearServers = () => {
|
||||
useStore().commit(MutationTypes.SET_SERVERS, new Map());
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a test Dynmap server definition to the store, optionally setting it as the current server
|
||||
* @param setAsCurrent
|
||||
*/
|
||||
export const addDynmapServer = (setAsCurrent: boolean) => {
|
||||
const store = useStore(),
|
||||
servers = new Map(store.state.servers),
|
||||
id = `dynmap_${servers.size}`;
|
||||
|
||||
servers.set(id, {
|
||||
id,
|
||||
label: `Dynmap ${servers.size}`,
|
||||
dynmap: {
|
||||
configuration: 'configuration',
|
||||
update: 'update',
|
||||
sendmessage: 'sendMessage',
|
||||
login: 'login',
|
||||
register: 'register',
|
||||
tiles: 'tiles',
|
||||
markers: 'markers',
|
||||
}
|
||||
})
|
||||
|
||||
useStore().commit(MutationTypes.SET_SERVERS, servers);
|
||||
|
||||
if(setAsCurrent) {
|
||||
useStore().commit(MutationTypes.SET_CURRENT_SERVER, id);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a test Pl3xmap server definition to the store, optionally setting it as the current server
|
||||
* @param setAsCurrent
|
||||
*/
|
||||
export const addPl3xmapServer = (setAsCurrent: boolean) => {
|
||||
const store = useStore(),
|
||||
servers = new Map(store.state.servers),
|
||||
id = `pl3xmap_${servers.size}`;
|
||||
|
||||
servers.set(id, {
|
||||
id,
|
||||
label: `Pl3xmap ${servers.size}`,
|
||||
pl3xmap: 'pl3xmap',
|
||||
});
|
||||
|
||||
useStore().commit(MutationTypes.SET_SERVERS, servers);
|
||||
|
||||
if(setAsCurrent) {
|
||||
useStore().commit(MutationTypes.SET_CURRENT_SERVER, id);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a test Overviewer server definition to the store, optionally setting it as the current server
|
||||
* @param setAsCurrent
|
||||
*/
|
||||
export const addOverviewerServer = (setAsCurrent: boolean) => {
|
||||
const store = useStore(),
|
||||
servers = new Map(store.state.servers),
|
||||
id = `overviewer_${servers.size}`;
|
||||
|
||||
servers.set(id, {
|
||||
id,
|
||||
label: `Overviewer ${servers.size}`,
|
||||
overviewer: 'overviewer',
|
||||
});
|
||||
|
||||
useStore().commit(MutationTypes.SET_SERVERS, servers);
|
||||
|
||||
if(setAsCurrent) {
|
||||
useStore().commit(MutationTypes.SET_CURRENT_SERVER, id);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Clears any test worlds added to the store
|
||||
*/
|
||||
export const clearWorlds = () => {
|
||||
useStore().commit(MutationTypes.SET_WORLDS, [])
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a test world to the store with the given dimension and number of test maps
|
||||
* @param dimension
|
||||
* @param mapCount
|
||||
*/
|
||||
export const addWorld = (dimension: LiveAtlasDimension, mapCount: number) => {
|
||||
const store = useStore(),
|
||||
worlds = [...store.state.worlds.values()],
|
||||
world: LiveAtlasWorldDefinition = {
|
||||
name: `${dimension}_${worlds.length}`,
|
||||
displayName: `${dimension} ${worlds.length}`,
|
||||
dimension,
|
||||
seaLevel: 64,
|
||||
maps: new Set()
|
||||
};
|
||||
|
||||
for(let i = 0; i < mapCount; i++) {
|
||||
world.maps.add(new LiveAtlasMapDefinition({
|
||||
name: `map_${i}`,
|
||||
world,
|
||||
baseUrl: 'test/',
|
||||
tileSize: 128,
|
||||
imageFormat: 'png',
|
||||
nativeZoomLevels: 1
|
||||
}));
|
||||
}
|
||||
|
||||
worlds.push(world);
|
||||
store.commit(MutationTypes.SET_WORLDS, worlds);
|
||||
};
|
||||
|
||||
export const useDefaultImageProvider = () => {
|
||||
const store = useStore();
|
||||
|
||||
store.commit(MutationTypes.SET_COMPONENTS, {
|
||||
players: Object.assign({
|
||||
imageUrl: getDefaultPlayerImage
|
||||
}, store.state.components.players)
|
||||
});
|
||||
}
|
||||
|
||||
export const useTestImageProvider = (): (entry: PlayerImageQueueEntry) => string => {
|
||||
const provider = (entry: PlayerImageQueueEntry) => `/test/${entry.name}`,
|
||||
store = useStore();
|
||||
|
||||
store.commit(MutationTypes.SET_COMPONENTS, {
|
||||
players: Object.assign({
|
||||
imageUrl: provider
|
||||
}, store.state.components.players)
|
||||
});
|
||||
|
||||
return provider;
|
||||
}
|
@ -14,8 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {parseUrl} from "@/util";
|
||||
import {LiveAtlasParsedUrl} from "@/index";
|
||||
import {getGlobalMessages, getMessages, getUrlForLocation, guessWorldDimension, parseUrl} from "@/util";
|
||||
import {LiveAtlasDimension, LiveAtlasGlobalMessageConfig, LiveAtlasMessageConfig, LiveAtlasParsedUrl} from "@/index";
|
||||
import LiveAtlasMapDefinition from "@/model/LiveAtlasMapDefinition";
|
||||
import {globalMessages, serverMessages} from "../messages";
|
||||
|
||||
const validURLs: [string, URL, LiveAtlasParsedUrl][] = [
|
||||
[
|
||||
@ -392,3 +394,72 @@ describe("parseURL", () => {
|
||||
expect(parseUrl(url)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe("guessWorldDimension", () => {
|
||||
const worlds: [string, LiveAtlasDimension][] = [
|
||||
['world', 'overworld'],
|
||||
['smp2022', 'overworld'],
|
||||
['DIM-1', 'nether'],
|
||||
['world_nether', 'nether'],
|
||||
['smp_nether', 'nether'],
|
||||
['smpnether', 'nether'],
|
||||
['nether_smp', 'nether'],
|
||||
['DIM1', 'end'],
|
||||
['world_the_end', 'end'],
|
||||
['end', 'end'],
|
||||
['smp_end', 'end'],
|
||||
['smpend', 'overworld'], //Would have too many false positives
|
||||
['end_smp', 'end'],
|
||||
];
|
||||
|
||||
test.each(worlds)('%s -> %s', (input: string, expected: LiveAtlasDimension) =>
|
||||
expect(guessWorldDimension(input)).toBe(expected))
|
||||
})
|
||||
|
||||
|
||||
test("getUrlForLocation", () => {
|
||||
const map = new LiveAtlasMapDefinition({
|
||||
name: 'test_map',
|
||||
world: {
|
||||
name: 'test_world',
|
||||
displayName: 'Test World',
|
||||
dimension: 'overworld',
|
||||
seaLevel: 64,
|
||||
maps: new Set()
|
||||
},
|
||||
baseUrl: 'test/',
|
||||
tileSize: 128,
|
||||
imageFormat: 'png',
|
||||
nativeZoomLevels: 1
|
||||
});
|
||||
|
||||
expect(getUrlForLocation(map, {x: 100, y: 68.5, z: -2300.3}, 3))
|
||||
.toEqual('#test_world;test_map;100,69,-2300;3')
|
||||
});
|
||||
|
||||
test("getMessages", () => {
|
||||
const expectedGlobal: LiveAtlasGlobalMessageConfig = globalMessages.reduce((result: any, key) => {
|
||||
result[key] = `Missing message: ${key}`;
|
||||
return result;
|
||||
}, {});
|
||||
const expectedMessages: LiveAtlasMessageConfig = Object.assign({}, expectedGlobal, serverMessages.reduce((result: any, key) => {
|
||||
result[key] = `Missing message: ${key}`;
|
||||
return result;
|
||||
}, {}));
|
||||
|
||||
const input: any = {
|
||||
extraProperty: true, //Invalid message key
|
||||
serversHeading: undefined, // Valid message key but undefined
|
||||
mapTitle: null, // Valid message key but null
|
||||
loginTitle: '', // Valid message key but empty string
|
||||
registerConfirmPasswordLabel: {invalid: true}, //Valid message key but not a string,
|
||||
chatErrorDisabled: 'test defined global message', // Valid global message
|
||||
chatPlayerQuit: 'test defined server message' // Valid server message
|
||||
};
|
||||
|
||||
expectedGlobal.chatErrorDisabled = expectedMessages.chatErrorDisabled = input.chatErrorDisabled;
|
||||
expectedMessages.chatPlayerQuit = input.chatPlayerQuit;
|
||||
|
||||
expect(getMessages(input)).toEqual(expectedMessages);
|
||||
expect(getGlobalMessages(input)).toEqual(expectedGlobal);
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user