From 82d6c015609001df28667e3ec0bbf6a891b6cac4 Mon Sep 17 00:00:00 2001 From: James Hobin Date: Fri, 13 Sep 2024 13:15:58 -0400 Subject: [PATCH] Add tests of history api, spatial api, and mobile mode --- tests/history.test.js | 140 ++++++++++++++++++++++++++++++++++++++++++ tests/mobile.test.js | 86 ++++++++++++++++++++++++++ tests/spatial.test.js | 98 +++++++++++++++++++++++++++++ 3 files changed, 324 insertions(+) create mode 100644 tests/history.test.js create mode 100644 tests/mobile.test.js create mode 100644 tests/spatial.test.js diff --git a/tests/history.test.js b/tests/history.test.js new file mode 100644 index 000000000..16f083059 --- /dev/null +++ b/tests/history.test.js @@ -0,0 +1,140 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +/* global test, beforeAll, afterAll, expect */ +const { + sleep, + waitForObjects, + localServer, + fetchAgent, +} = require('./helpers.js'); + +const fetch = require('node-fetch'); + +let server; +beforeAll(async () => { + server = require('../server.js'); +}); + +afterAll(async () => { + await server.exit(); + await sleep(1000); +}); + +test('patches', async () => { + await waitForObjects(); + + let res = await fetch(`${localServer}/history/patches`, {agent: fetchAgent}); + const patches = await res.json(); + expect(patches).toEqual([]); + + res = await fetch(`${localServer}/history/patches`, { + headers: { + 'content-type': 'application/json' + }, + body: JSON.stringify({ + key: 'patch0', + data: 'testData', + }), + method: 'POST', + agent: fetchAgent + }); + expect(res.ok).toBeTruthy(); + + res = await fetch(`${localServer}/history/patches`, { + headers: { + 'content-type': 'application/json' + }, + body: JSON.stringify({ + key: 'patch0', + data: 'duplicate', + }), + method: 'POST', + agent: fetchAgent + }); + expect(res.ok).toBeTruthy(); + + + res = await fetch(`${localServer}/history/patches`, {agent: fetchAgent}); + const patchesCreated = await res.json(); + expect(patchesCreated.length).toEqual(1); + let patch = patchesCreated[0]; + expect(patch.key).toEqual('patch0'); + expect(patch.data).toEqual('testData'); + + res = await fetch(`${localServer}/history/patches/patch0`, { + method: 'DELETE', + agent: fetchAgent + }); + expect(res.ok).toBeTruthy(); + + res = await fetch(`${localServer}/history/patches`, {agent: fetchAgent}); + const patchesAfterDeletion = await res.json(); + expect(patchesAfterDeletion).toEqual([]); +}); + + +test('logs', async () => { + const recorder = require('../libraries/recorder.js'); + recorder.clearIntervals(); + + await waitForObjects(); + + // Create an object to make sure log has an interesting update + const resNew = await fetch(`${localServer}/`, { + headers: { + 'Content-type': 'application/x-www-form-urlencoded', + }, + 'body': 'action=new&name=historydummy&isWorld=null', + 'method': 'POST', + 'mode': 'cors', + agent: fetchAgent + }); + await resNew.text(); + + recorder.saveState(); + + let res = await fetch(`${localServer}/history/persist`, { + method: 'POST', + agent: fetchAgent + }); + const persistResult = await res.json(); + expect(persistResult.logName).toBeTruthy(); + + await fetch(`${localServer}/`, { + headers: { + 'Content-type': 'application/x-www-form-urlencoded', + }, + body: 'action=delete&name=historydummy&frame=', + method: 'POST', + agent: fetchAgent + }); + + res = await fetch(`${localServer}/history/logs`, { + agent: fetchAgent + }); + const logs = await res.json(); + expect(Array.isArray(logs)).toBeTruthy(); + expect(logs.length > 0).toBeTruthy(); + expect(logs.includes(persistResult.logName)).toBeTruthy(); + + res = await fetch(`${localServer}/history/logs/${persistResult.logName}`, { + agent: fetchAgent + }); + const persistedLog = await res.json(); + expect(persistedLog).toBeTruthy(); + + res = await fetch(`${localServer}/history/logs/${logs.at(-1)}`, { + agent: fetchAgent + }); + const latestLog = await res.json(); + expect(latestLog).toBeTruthy(); + + res = await fetch(`${localServer}/history/logs/missing`, { + agent: fetchAgent + }); + expect(res.status).toBe(404); +}); diff --git a/tests/mobile.test.js b/tests/mobile.test.js new file mode 100644 index 000000000..bdc3e9e7c --- /dev/null +++ b/tests/mobile.test.js @@ -0,0 +1,86 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +/* global test, beforeAll, afterAll, expect */ +const fetch = require('node-fetch'); + +process.env.FORCE_MOBILE = true; +const { + sleep, + fetchAgent, + waitForObjects, + getTestObjects, + localServer, +} = require('./helpers.js'); + +let server; +beforeAll(() => { + server = require('../server.js'); +}); + +afterAll(async () => { + process.env.FORCE_MOBILE = false; + await server.exit(); + await sleep(1000); +}); + +async function testObjectCreation() { + await waitForObjects(0); + + const allObjectsPre = await getTestObjects(); + expect(allObjectsPre).toEqual([]); + const resNew = await fetch(`${localServer}/`, { + headers: { + 'Content-type': 'application/x-www-form-urlencoded', + }, + 'body': 'action=new&name=fdsa&isWorld=null', + 'method': 'POST', + 'mode': 'cors', + agent: fetchAgent + }); + await resNew.text(); + const allObjectsCreated = await getTestObjects(); + + expect(allObjectsCreated.length).toBe(1); + const fdsaApi = allObjectsCreated[0]; + expect(fdsaApi.id).toMatch(/^fdsa/); + expect(fdsaApi.ip).toBeTruthy(); + expect(fdsaApi.port).toBe(server.serverPort); + expect(fdsaApi.vn).toBe(322); + expect(fdsaApi.pr).toBe('R2'); + expect(fdsaApi.tcs).toBe(0); + + return fdsaApi; +} + +test('mobile local world', async () => { + await waitForObjects(1); + + const allWorldObjects = await getTestObjects('_WORLD_local'); + expect(allWorldObjects.length).toBe(1); + const worldLocal = allWorldObjects[0]; + expect(worldLocal.id).toBe('_WORLD_local'); + expect(worldLocal.ip).toBe('localhost'); + expect(worldLocal.port).toBe(server.serverPort); + expect(worldLocal.vn).toBe(322); + expect(worldLocal.pr).toBe('R2'); +}); + +test('mobile object creation', async () => { + await testObjectCreation(); + + await fetch(`${localServer}/`, { + headers: { + 'Content-type': 'application/x-www-form-urlencoded', + }, + body: 'action=delete&name=fdsa&frame=', + method: 'POST', + agent: fetchAgent + }); + + const allObjectsDeleted = await getTestObjects(); + expect(allObjectsDeleted).toEqual([]); +}); diff --git a/tests/spatial.test.js b/tests/spatial.test.js new file mode 100644 index 000000000..451d97d52 --- /dev/null +++ b/tests/spatial.test.js @@ -0,0 +1,98 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +/* global test, beforeAll, afterAll, expect */ +const { + sleep, + waitForObjects, + localServer, + fetchAgent, +} = require('./helpers.js'); + +const fetch = require('node-fetch'); + +let server; +beforeAll(async () => { + server = require('../server.js'); +}); + +afterAll(async () => { + await server.exit(); + await sleep(1000); +}); + +test('spatial get scene graph', async () => { + await waitForObjects(); + + let res = await fetch(`${localServer}/spatial/sceneGraph`, {agent: fetchAgent}); + const sceneGraph = await res.json(); + + const rootNode = sceneGraph.ROOT; + expect(rootNode).toBeTruthy(); + expect(rootNode.localMatrix).toEqual([ + 1, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 1 + ]); + expect(rootNode.worldMatrix).toEqual([ + 1, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 1 + ]); + expect(rootNode.children).toEqual(['_WORLD_instantScanPJ1cgyrm_T6ijgnpsk1c']); + expect(rootNode.id).toBe('ROOT'); + expect(rootNode.parent).toBeFalsy(); + expect(rootNode.transformMatrix).toEqual([ + 1, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 1 + ]); + expect(rootNode.vehicleInfo).toEqual({name: 'ROOT', type: 'ROOT'}); + + console.log(rootNode); + const worldNode = sceneGraph._WORLD_instantScanPJ1cgyrm_T6ijgnpsk1c; + expect(worldNode).toBeTruthy(); + expect(worldNode.vehicleInfo).toEqual({ + name: '_WORLD_instantScanPJ1cgyrm_T6ijgnpsk1c', + type: 'object' + }); +}); + + +test('spatial searchFrames in range', async () => { + await waitForObjects(); + + const searchParams = new URLSearchParams({ + maxDistance: 20000, + clientX: 0, + clientY: 0, + clientZ: 0, + src: 'spatialDraw', + worldId: '_WORLD_instantScanPJ1cgyrm_T6ijgnpsk1c', + }); + let res = await fetch(`${localServer}/spatial/searchFrames?${searchParams}`, {agent: fetchAgent}); + const frames = await res.json(); + expect(frames.validAddresses).toEqual([{ + objectId: '_WORLD_instantScanPJ1cgyrm_T6ijgnpsk1c', + frameId: '_WORLD_instantScanPJ1cgyrm_T6ijgnpsk1cspatialDraw1mJx458y5jn9a' + }]); +}); + +test('spatial searchFrames out of range', async () => { + await waitForObjects(); + + const searchParams = new URLSearchParams({ + maxDistance: 10, + clientX: 0, + clientY: 0, + clientZ: 0, + src: 'spatialDraw', + worldId: '_WORLD_instantScanPJ1cgyrm_T6ijgnpsk1c', + }); + let res = await fetch(`${localServer}/spatial/searchFrames?${searchParams}`, {agent: fetchAgent}); + const frames = await res.json(); + expect(frames.validAddresses).toEqual([]); +});