-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2b8735e
commit e423af8
Showing
19 changed files
with
617 additions
and
113 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import { io } from 'socket.io-client' | ||
import { createAppInstance } from '@test/utils/server.test-utils' | ||
import { connectWrapperManager } from '@test/utils/socket.test-utils' | ||
import Bluebird from 'bluebird' | ||
import { createTestAxios } from '@test/utils/axios.test-utils' | ||
|
||
describe('socket-join', () => { | ||
const testAxios = createTestAxios(3001) | ||
const { connectWrapper, disconnectAll } = connectWrapperManager() | ||
afterEach(() => { | ||
disconnectAll() | ||
}) | ||
|
||
let serverCleanup: () => Promise<void> | ||
beforeAll(async () => { | ||
const { close } = await createAppInstance(3001) | ||
serverCleanup = close | ||
}) | ||
afterAll(async () => { | ||
await serverCleanup!() | ||
}) | ||
|
||
it('allows connecting', async () => { | ||
const { data } = await testAxios.post<{ id: string }>('/room') | ||
const roomId = data.id | ||
|
||
const client = io('http://localhost:3001', { | ||
query: { | ||
roomId, | ||
name: 'User 1', | ||
clientId: 'user-1', | ||
}, | ||
}) | ||
|
||
await expect(connectWrapper(client)).resolves.toBeTruthy() | ||
}) | ||
|
||
it('broadcasts joins/leaves to other people', async () => { | ||
const { data } = await testAxios.post<{ id: string }>('/room') | ||
const roomId = data.id | ||
|
||
const clientA = await connectWrapper( | ||
io('http://localhost:3001', { | ||
query: { | ||
roomId, | ||
name: 'User 1', | ||
clientId: 'user-1', | ||
}, | ||
}) | ||
) | ||
|
||
const serverEventSpy = jest.fn() | ||
clientA.on('SERVER', serverEventSpy) | ||
|
||
// role: joiner | ||
const clientB = await connectWrapper( | ||
io('http://localhost:3001', { | ||
query: { | ||
roomId, | ||
name: 'User 2', | ||
clientId: 'user-2', | ||
}, | ||
forceNew: true, | ||
}) | ||
) | ||
|
||
expect(serverEventSpy).toHaveBeenNthCalledWith(1, { | ||
CONN_ACTIVITY: expect.objectContaining({ | ||
id: 'user-2', | ||
name: 'User 2', | ||
action: 'join', | ||
}), | ||
}) | ||
|
||
clientB.disconnect() | ||
/* | ||
* Arbitray delay, we just want to wait for the server broadcast for disconnect | ||
* TODO find a better method than doing a delay. this is not going to be very consistent if the server takes longer than the delay to broadcast. | ||
* | ||
* Things tried before falling back to this: | ||
* - Listening for the disconnect event on clientB (`clientB.once('disconnect', ...)`). The event firing doesn't mean that the message has been | ||
* broadcasted. | ||
* - // add more here | ||
*/ | ||
await Bluebird.delay(1_000) | ||
expect(serverEventSpy).toHaveBeenNthCalledWith(2, { | ||
CONN_ACTIVITY: expect.objectContaining({ | ||
id: 'user-2', | ||
name: 'User 2', | ||
action: 'leave', | ||
}), | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import { Socket, io } from 'socket.io-client' | ||
import { createAppInstance } from '@test/utils/server.test-utils' | ||
import { connectWrapperManager } from '@test/utils/socket.test-utils' | ||
import Bluebird from 'bluebird' | ||
import { createTestAxios } from '@test/utils/axios.test-utils' | ||
|
||
describe('socket-join', () => { | ||
const testAxios = createTestAxios(3002) | ||
|
||
let serverCleanup: () => Promise<void> | ||
let roomId: string | ||
beforeAll(async () => { | ||
const { close } = await createAppInstance(3002) | ||
serverCleanup = close | ||
|
||
const { data } = await testAxios.post<{ | ||
id: string | ||
}>('/room') | ||
|
||
roomId = data.id | ||
}, 10_000) | ||
afterAll(async () => { | ||
await serverCleanup!() | ||
}) | ||
|
||
const { connectWrapper, disconnectAll } = connectWrapperManager() | ||
let clientA: Socket | ||
let clientB: Socket | ||
|
||
beforeEach(async () => { | ||
clientA = await connectWrapper( | ||
io('http://localhost:3002', { | ||
query: { | ||
roomId, | ||
clientId: 'user-a', | ||
nanme: 'User A', | ||
}, | ||
}) | ||
) | ||
|
||
clientB = await connectWrapper( | ||
io('http://localhost:3002', { | ||
query: { | ||
roomId, | ||
clientId: 'user-a', | ||
nanme: 'User A', | ||
}, | ||
}) | ||
) | ||
}) | ||
|
||
afterEach(() => { | ||
disconnectAll() | ||
}) | ||
|
||
it('broadcasts PAD events', async () => { | ||
const clientAHandler = jest.fn() | ||
const clientBHandler = jest.fn() | ||
|
||
clientA.on('PAD', clientAHandler) | ||
clientB.on('PAD', clientBHandler) | ||
|
||
clientA.emit('PAD', { | ||
DUMMY_MESSAGE: { | ||
foo: 'bar', | ||
}, | ||
}) | ||
|
||
await Bluebird.delay(1_000) | ||
expect(clientAHandler).not.toHaveBeenCalled() | ||
expect(clientBHandler).toHaveBeenCalledWith({ | ||
DUMMY_MESSAGE: { | ||
foo: 'bar', | ||
}, | ||
}) | ||
}) | ||
|
||
it('broadcasts PAD_TRANSIENT events', async () => { | ||
const clientAHandler = jest.fn() | ||
const clientBHandler = jest.fn() | ||
|
||
clientA.on('PAD_TRANSIENT', clientAHandler) | ||
clientB.on('PAD_TRANSIENT', clientBHandler) | ||
|
||
clientA.emit('PAD_TRANSIENT', { | ||
DUMMY_MESSAGE: { | ||
foo: 'bar', | ||
}, | ||
}) | ||
|
||
await Bluebird.delay(1_000) | ||
expect(clientAHandler).not.toHaveBeenCalled() | ||
expect(clientBHandler).toHaveBeenCalledWith({ | ||
DUMMY_MESSAGE: { | ||
foo: 'bar', | ||
}, | ||
}) | ||
}) | ||
}) |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import axios from 'axios' | ||
|
||
export function createTestAxios(port = 3000) { | ||
return axios.create({ | ||
baseURL: `http://localhost:${port}`, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { initServer } from '@/server' | ||
import { createHttpTerminator } from 'http-terminator' | ||
|
||
export async function createAppInstance(port = 3000) { | ||
const httpServer = initServer() | ||
|
||
const terminator = createHttpTerminator({ | ||
server: httpServer, | ||
}) | ||
|
||
async function close() { | ||
terminator.terminate() | ||
} | ||
|
||
await new Promise<void>((resolve, reject) => { | ||
try { | ||
httpServer.listen(port, () => { | ||
resolve() | ||
}) | ||
} catch (e) { | ||
// calling server.listen can throw, hence we have a try-catch here | ||
reject(e) | ||
} | ||
}) | ||
|
||
return { | ||
close, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { Socket } from 'socket.io-client' | ||
|
||
export function connectWrapper(socket: Socket) { | ||
const waiter = new Promise<Socket>((resolve, reject) => { | ||
socket.once('connect', () => { | ||
resolve(socket) | ||
}) | ||
socket.once('connect_error', reject) | ||
}) | ||
socket.connect() | ||
|
||
return waiter | ||
} | ||
|
||
export function connectWrapperManager() { | ||
let clients: Socket[] = [] | ||
|
||
async function connect(socket: Socket) { | ||
const client = await connectWrapper(socket) | ||
clients.push(client) | ||
return client | ||
} | ||
|
||
function disconnectAll() { | ||
clients.forEach((client) => client.disconnect()) | ||
clients = [] | ||
} | ||
|
||
return { | ||
connectWrapper: connect, | ||
disconnectAll, | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.