Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
gonpombo8 committed Jun 19, 2023
1 parent 16c6a4d commit c5d9062
Show file tree
Hide file tree
Showing 16 changed files with 337 additions and 77 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ test:
make test-inspector

test-inspector:
cd ./packages/@dcl/inspector/; TS_JEST_TRANSFORMER=true ./../../../node_modules/.bin/jest --coverage --detectOpenHandles --colors --config ./jest.config.js $(FILES)
cd ./packages/@dcl/inspector/; TS_JEST_TRANSFORMER=true ./../../../node_modules/.bin/jest --coverage=false --detectOpenHandles --colors --config ./jest.config.js $(FILES)

test-cli:
@rm -rf tmp
Expand Down
64 changes: 64 additions & 0 deletions packages/@dcl/inspector/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion packages/@dcl/inspector/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@
"react-dom": "^18.2.0",
"react-icons": "^4.7.1",
"react-modal": "^3.16.1",
"react-resizable-panels": "^0.0.48",
"react-redux": "^8.1.0",
"react-resizable-panels": "^0.0.48",
"redux-saga": "^1.2.3",
"redux-saga-test-plan": "^4.0.6",
"typescript": "^5.0.2"
},
"files": [
Expand Down
4 changes: 3 additions & 1 deletion packages/@dcl/inspector/src/components/Warnings/Warnings.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React from 'react'

import { RotationGizmoLocalAlignmentDisabled } from './RotationGizmoLocalAlignmentDisabled'
import './Warnings.css'
import { SocketConnection } from './SocketConnection'

import './Warnings.css'

const Warnings: React.FC = () => {
return (
<div className="Warnings">
Expand Down
44 changes: 44 additions & 0 deletions packages/@dcl/inspector/src/lib/sdk/connect-stream.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { IEngine, Transport } from '@dcl/ecs'
import { AsyncQueue } from '@well-known-components/pushable-channel'

import { CrdtStreamMessage } from '../data-layer/remote-data-layer'
import { DataLayerRpcClient } from '../data-layer/types'
import { consumeAllMessagesInto } from '../logic/consume-stream'
import { serializeCrdtMessages } from './crdt-logger'

export function connectCrdtToEngine(
engine: IEngine,
dataLayerStream: DataLayerRpcClient['crdtStream'],
engineKey: string
) {
// <HERE BE DRAGONS (TRANSPORT)>
const outgoingMessagesStream = new AsyncQueue<CrdtStreamMessage>((_, _action) => {})

const transport: Transport = {
filter() {
return !outgoingMessagesStream.closed
},
async send(message) {
if (outgoingMessagesStream.closed) return
outgoingMessagesStream.enqueue({ data: message })
if (message.byteLength) {
Array.from(serializeCrdtMessages(`${engineKey}>Datalayer`, message, engine)).forEach(($) => console.log($))
}
}
}
Object.assign(transport, { name: `${engineKey}TransportClient` })
engine.addTransport(transport)

function onMessage(message: Uint8Array) {
if (message.byteLength) {
Array.from(serializeCrdtMessages(`DataLayer>${engineKey}`, message, engine)).forEach(($) => console.log($))
}
transport.onmessage!(message)
void engine.update(1)
}

consumeAllMessagesInto(dataLayerStream(outgoingMessagesStream), onMessage).catch((e) => {
console.error(`${engineKey} consumeAllMessagesInto failed: `, e)
outgoingMessagesStream.close()
})
}
6 changes: 1 addition & 5 deletions packages/@dcl/inspector/src/redux/data-layer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@ export enum ErrorType {
export interface DataLayerState {
dataLayer: DataLayerRpcClient | undefined
reconnectAttempts: number
ws: WebSocket | undefined
error: ErrorType | undefined
}

const initialState: DataLayerState = {
export const initialState: DataLayerState = {
dataLayer: undefined,
reconnectAttempts: 0,
ws: undefined,
error: undefined
}

Expand All @@ -33,7 +31,6 @@ export const dataLayer = createSlice({
console.log('[WS] Reconnecting')
state.error = ErrorType.Reconnecting
state.dataLayer = undefined
state.ws = undefined
},
connected: (state, { payload }: PayloadAction<{ dataLayer: DataLayerState['dataLayer'] }>) => {
console.log('[WS] Connected')
Expand All @@ -51,7 +48,6 @@ export const dataLayer = createSlice({
export const { connect, connected, reconnect, error } = dataLayer.actions
export const getError = (state: RootState) => state.dataLayer.error
export const getDataLayer = (state: RootState) => state.dataLayer.dataLayer
export const getDataLayerWs = (state: RootState) => state.dataLayer.ws
export const getDataLayerReconnectAttempts = (state: RootState) => state.dataLayer.reconnectAttempts

export default dataLayer.reducer
119 changes: 119 additions & 0 deletions packages/@dcl/inspector/src/redux/data-layer/sagas/connect.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/* eslint-disable @typescript-eslint/ban-types */
import { expectSaga, testSaga } from 'redux-saga-test-plan'
import * as codegen from '@dcl/rpc/dist/codegen'

import { connectSaga, createSocketChannel, createWebSocketConnection, getWsUrl } from './connect'
import { WebSocketTransport } from '@dcl/rpc/dist/transports/WebSocket'
import { RpcClient, RpcClientPort, Transport, createRpcClient } from '@dcl/rpc'
import { DataLayerRpcClient } from '../../../lib/data-layer/types'
import reducer, { connected, reconnect } from '..'
import { createLocalDataLayerRpcClient } from '../../../lib/data-layer/client/local-data-layer'
import { call } from 'redux-saga/effects'

describe('WebSocket Connection Saga', () => {
it('Should create LOCAL data-layer if no ws url is provided', async () => {
const dataLayer = { boedo: 'casla' } as any as DataLayerRpcClient

return expectSaga(connectSaga)
.withReducer(reducer)
.provide([
[call(getWsUrl), undefined],
[call(createLocalDataLayerRpcClient), dataLayer]
])
.put(connected({ dataLayer }))
.hasFinalState({
dataLayer,
error: undefined,
reconnectAttempts: 0
})
.run()
})

it('Should create remote data-layer with Ws', async () => {
const url = 'ws://boedo.com'
const ws = new MockWebSocket()
const channel = createSocketChannel(ws as any as WebSocket)
const clientTransport = {} as Transport
const client: RpcClient = { createPort: (_port: string) => {} } as RpcClient
const clientPort: RpcClientPort = {} as RpcClientPort
const dataLayer = { boedo: 'casla' } as any as DataLayerRpcClient
jest.spyOn(codegen, 'loadService').mockReturnValue(dataLayer as any)
const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {})

testSaga(connectSaga)
.next()
.call(getWsUrl)
.next(url)
.call(createWebSocketConnection, url)
.next(ws)
.call(createSocketChannel, ws)
.next(channel)
.take(channel as any)

// OPEN event. Connect data layer
.next({ type: 'WS_OPENED' })
.call(WebSocketTransport, ws)
.next(clientTransport)
.call(createRpcClient, clientTransport)
.next(client)
.call(client.createPort, 'scene-ctx')
.next(clientPort)
.put(connected({ dataLayer }))
.next()

// Error event. console.error (TODO: handle this)
.next({ type: 'WS_ERROR', error: 'some - error' })

// Break the connection. Should reconnect
.finish()
.put(reconnect())
.next()
.isDone()

// Error logic
expect(consoleSpy).toBeCalledWith('some - error')
})
})

// Mock WebSocket

class MockWebSocket {
listeners: { [key: string]: Function[] } = {}

addEventListener(event: string, callback: Function) {
if (!this.listeners[event]) {
this.listeners[event] = []
}
this.listeners[event].push(callback)
}

removeEventListener(event: string, callback: Function) {
if (this.listeners[event]) {
this.listeners[event] = this.listeners[event].filter((cb) => cb !== callback)
}
}

simulateOpen() {
if (this.listeners['open']) {
this.listeners['open'].forEach((callback) => callback())
}
}

simulateMessage(data: any) {
if (this.listeners['message']) {
this.listeners['message'].forEach((callback) => callback({ data }))
}
}

simulateClose() {
if (this.listeners['close']) {
this.listeners['close'].forEach((callback) => callback())
}
}

simulateError() {
if (this.listeners['error']) {
this.listeners['error'].forEach((callback) => callback())
}
}
}
Loading

0 comments on commit c5d9062

Please sign in to comment.