|
| 1 | +/* |
| 2 | +CPAL-1.0 License |
| 3 | +
|
| 4 | +The contents of this file are subject to the Common Public Attribution License |
| 5 | +Version 1.0. (the "License"); you may not use this file except in compliance |
| 6 | +with the License. You may obtain a copy of the License at |
| 7 | +https://github.com/EtherealEngine/etherealengine/blob/dev/LICENSE. |
| 8 | +The License is based on the Mozilla Public License Version 1.1, but Sections 14 |
| 9 | +and 15 have been added to cover use of software over a computer network and |
| 10 | +provide for limited attribution for the Original Developer. In addition, |
| 11 | +Exhibit A has been modified to be consistent with Exhibit B. |
| 12 | +
|
| 13 | +Software distributed under the License is distributed on an "AS IS" basis, |
| 14 | +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the |
| 15 | +specific language governing rights and limitations under the License. |
| 16 | +
|
| 17 | +The Original Code is Ethereal Engine. |
| 18 | +
|
| 19 | +The Original Developer is the Initial Developer. The Initial Developer of the |
| 20 | +Original Code is the Ethereal Engine team. |
| 21 | +
|
| 22 | +All portions of the code written by the Ethereal Engine team are Copyright © 2021-2023 |
| 23 | +Ethereal Engine. All Rights Reserved. |
| 24 | +*/ |
| 25 | + |
| 26 | +import { act, render } from '@testing-library/react' |
| 27 | +import assert from 'assert' |
| 28 | +import React from 'react' |
| 29 | + |
| 30 | +import { UserID } from '@etherealengine/common/src/schema.type.module' |
| 31 | +import { |
| 32 | + Engine, |
| 33 | + SystemDefinitions, |
| 34 | + UUIDComponent, |
| 35 | + UndefinedEntity, |
| 36 | + createEntity, |
| 37 | + destroyEngine, |
| 38 | + removeEntity, |
| 39 | + setComponent |
| 40 | +} from '@etherealengine/ecs' |
| 41 | +import { PeerID, applyIncomingActions, dispatchAction, getState } from '@etherealengine/hyperflux' |
| 42 | +import { |
| 43 | + Network, |
| 44 | + NetworkPeerFunctions, |
| 45 | + NetworkState, |
| 46 | + NetworkTopics, |
| 47 | + NetworkWorldUserStateSystem |
| 48 | +} from '@etherealengine/network' |
| 49 | +import { createMockNetwork } from '../../../../network/tests/createMockNetwork' |
| 50 | +import { createEngine } from '../../initializeEngine' |
| 51 | +import { SpectateActions, SpectateEntityState } from './SpectateSystem' |
| 52 | + |
| 53 | +describe('SpectateSystem', async () => { |
| 54 | + let viewerEntity = UndefinedEntity |
| 55 | + |
| 56 | + describe('SpectateEntityState', async () => { |
| 57 | + beforeEach(async () => { |
| 58 | + createEngine() |
| 59 | + createMockNetwork() |
| 60 | + Engine.instance.store.defaultDispatchDelay = () => 0 |
| 61 | + viewerEntity = createEntity() |
| 62 | + setComponent(viewerEntity, UUIDComponent, UUIDComponent.generateUUID()) |
| 63 | + }) |
| 64 | + |
| 65 | + afterEach(() => { |
| 66 | + removeEntity(viewerEntity) |
| 67 | + return destroyEngine() |
| 68 | + }) |
| 69 | + |
| 70 | + const NetworkWorldUserStateSystemReactor = SystemDefinitions.get(NetworkWorldUserStateSystem)!.reactor! |
| 71 | + const tag = <NetworkWorldUserStateSystemReactor /> |
| 72 | + |
| 73 | + it('should start spectating an entity when the `spectateEntity` action is dispatched', async () => { |
| 74 | + const hostUserId = 'world' as UserID |
| 75 | + const userId = 'user id' as UserID |
| 76 | + const peerID = Engine.instance.store.peerID |
| 77 | + const peerID2 = 'peer id 2' as PeerID |
| 78 | + const peerID3 = 'peer id 3' as PeerID |
| 79 | + const spectatorID = 'spectator id' as UserID |
| 80 | + |
| 81 | + Engine.instance.userID = userId |
| 82 | + const network: Network = NetworkState.worldNetwork |
| 83 | + |
| 84 | + NetworkPeerFunctions.createPeer(network, peerID, 0, hostUserId, 0) |
| 85 | + NetworkPeerFunctions.createPeer(network, peerID2, 1, userId, 1) |
| 86 | + NetworkPeerFunctions.createPeer(network, peerID3, 2, userId, 2) |
| 87 | + |
| 88 | + const { rerender, unmount } = render(tag) |
| 89 | + await act(() => rerender(tag)) |
| 90 | + |
| 91 | + dispatchAction( |
| 92 | + SpectateActions.spectateEntity({ |
| 93 | + spectatorUserID: spectatorID, |
| 94 | + spectatingUserID: userId, |
| 95 | + $topic: NetworkTopics.world, |
| 96 | + $peer: Engine.instance.store.peerID |
| 97 | + }) |
| 98 | + ) |
| 99 | + applyIncomingActions() |
| 100 | + const state = getState(SpectateEntityState)[spectatorID] |
| 101 | + assert.notEqual(state, undefined, "The spectator's SpectateEntityState should not be undefined after `getState`") |
| 102 | + assert.equal(state.spectating, userId, 'The spectator is not spectating the correct userID') |
| 103 | + |
| 104 | + unmount() |
| 105 | + }) |
| 106 | + |
| 107 | + it('should stop spectating an entity when the `exitSpectate` action is dispatched', async () => { |
| 108 | + const hostUserId = 'world' as UserID |
| 109 | + const userId = 'user id' as UserID |
| 110 | + const peerID = Engine.instance.store.peerID |
| 111 | + const peerID2 = 'peer id 2' as PeerID |
| 112 | + const peerID3 = 'peer id 3' as PeerID |
| 113 | + const spectatorID = 'spectator id' as UserID |
| 114 | + |
| 115 | + Engine.instance.userID = userId |
| 116 | + const network: Network = NetworkState.worldNetwork |
| 117 | + |
| 118 | + NetworkPeerFunctions.createPeer(network, peerID, 0, hostUserId, 0) |
| 119 | + NetworkPeerFunctions.createPeer(network, peerID2, 1, userId, 1) |
| 120 | + NetworkPeerFunctions.createPeer(network, peerID3, 2, userId, 2) |
| 121 | + |
| 122 | + const { rerender, unmount } = render(tag) |
| 123 | + await act(() => rerender(tag)) |
| 124 | + |
| 125 | + dispatchAction( |
| 126 | + SpectateActions.spectateEntity({ |
| 127 | + spectatorUserID: spectatorID, |
| 128 | + spectatingUserID: userId, |
| 129 | + $topic: NetworkTopics.world, |
| 130 | + $peer: Engine.instance.store.peerID |
| 131 | + }) |
| 132 | + ) |
| 133 | + applyIncomingActions() |
| 134 | + const before = getState(SpectateEntityState)[spectatorID] |
| 135 | + assert.notEqual(before, undefined, "The spectator's SpectateEntityState should not be undefined after `getState`") |
| 136 | + assert.equal(before.spectating, userId, 'The spectator is not spectating the correct userID') |
| 137 | + |
| 138 | + dispatchAction( |
| 139 | + SpectateActions.exitSpectate({ |
| 140 | + spectatorUserID: spectatorID, |
| 141 | + $topic: NetworkTopics.world, |
| 142 | + $peer: Engine.instance.store.peerID |
| 143 | + }) |
| 144 | + ) |
| 145 | + applyIncomingActions() |
| 146 | + const after = getState(SpectateEntityState)[spectatorID] |
| 147 | + assert.equal(after, undefined, "The spectator's SpectateEntityState should be undefined after exitSpectate") |
| 148 | + |
| 149 | + unmount() |
| 150 | + }) |
| 151 | + }) |
| 152 | +}) |
0 commit comments