162 lines
5.0 KiB
TypeScript
162 lines
5.0 KiB
TypeScript
import { expect, test } from 'vitest'
|
|
import _ from 'lodash'
|
|
import * as utils from './utils'
|
|
import * as config from './config'
|
|
import * as chat from '../src'
|
|
|
|
const apiUrl = config.get('API_URL')
|
|
|
|
const protocols = ['sse', 'websocket'] as const
|
|
|
|
test.each(protocols)('api allows adding and removing conversation participants', async (protocol) => {
|
|
const client = new chat.Client({ apiUrl })
|
|
|
|
const { key: userKey1 } = await client.createUser({})
|
|
const { user: user2, key: userKey2 } = await client.createUser({})
|
|
|
|
const { conversation } = await client.createConversation({ 'x-user-key': userKey1 })
|
|
|
|
const listener = await client.listenConversation({ id: conversation.id, 'x-user-key': userKey1, protocol })
|
|
|
|
await expect(
|
|
client.createMessage({
|
|
'x-user-key': userKey2,
|
|
conversationId: conversation.id,
|
|
payload: {
|
|
type: 'text',
|
|
text: 'hello world',
|
|
},
|
|
})
|
|
).rejects.toThrow(chat.ForbiddenError)
|
|
|
|
await Promise.all([
|
|
utils.waitFor(listener, 'participant_added'),
|
|
client.addParticipant({
|
|
'x-user-key': userKey1,
|
|
conversationId: conversation.id,
|
|
userId: user2.id,
|
|
}),
|
|
])
|
|
|
|
await expect(
|
|
client.createMessage({
|
|
'x-user-key': userKey2,
|
|
conversationId: conversation.id,
|
|
payload: {
|
|
type: 'text',
|
|
text: 'hello world',
|
|
},
|
|
})
|
|
).resolves.toBeTruthy()
|
|
|
|
await Promise.all([
|
|
utils.waitFor(listener, 'participant_removed'),
|
|
client.removeParticipant({
|
|
'x-user-key': userKey1,
|
|
conversationId: conversation.id,
|
|
userId: user2.id,
|
|
}),
|
|
])
|
|
|
|
await expect(
|
|
client.createMessage({
|
|
'x-user-key': userKey2,
|
|
conversationId: conversation.id,
|
|
payload: {
|
|
type: 'text',
|
|
text: 'hello world',
|
|
},
|
|
})
|
|
).rejects.toThrow(chat.ForbiddenError)
|
|
})
|
|
|
|
test('api forbids non-participants from listing participants', async () => {
|
|
const client = new chat.Client({ apiUrl })
|
|
|
|
const user1 = await client.createUser({})
|
|
const user2 = await client.createUser({})
|
|
const user3 = await client.createUser({})
|
|
|
|
const { conversation } = await client.createConversation({ 'x-user-key': user1.key })
|
|
await client.addParticipant({ 'x-user-key': user1.key, conversationId: conversation.id, userId: user2.user.id })
|
|
|
|
const promise1 = client.listParticipants({ 'x-user-key': user1.key, conversationId: conversation.id })
|
|
await expect(promise1).resolves.toBeTruthy()
|
|
const promise2 = client.listParticipants({ 'x-user-key': user2.key, conversationId: conversation.id })
|
|
await expect(promise2).resolves.toBeTruthy()
|
|
const promise3 = client.listParticipants({ 'x-user-key': user3.key, conversationId: conversation.id })
|
|
await expect(promise3).rejects.toThrow(chat.ForbiddenError)
|
|
})
|
|
|
|
test.each(protocols)('signal listener is disconnected when participant is removed', async (protocol) => {
|
|
const client = new chat.Client({ apiUrl })
|
|
|
|
const { user: user1, key: userKey1 } = await client.createUser({})
|
|
const { user: user2, key: userKey2 } = await client.createUser({})
|
|
|
|
const { conversation } = await client.createConversation({ 'x-user-key': userKey1 })
|
|
await client.addParticipant({ 'x-user-key': userKey1, conversationId: conversation.id, userId: user2.id })
|
|
|
|
const listener1 = await client.listenConversation({ id: conversation.id, 'x-user-key': userKey1, protocol })
|
|
const listener2 = await client.listenConversation({ id: conversation.id, 'x-user-key': userKey2, protocol })
|
|
|
|
const messages1: chat.Signals['message_created'][] = []
|
|
const messages2: chat.Signals['message_created'][] = []
|
|
|
|
listener1.on('message_created', (message) => messages1.push(message))
|
|
listener2.on('message_created', (message) => messages2.push(message))
|
|
|
|
await Promise.all([
|
|
utils.waitFor(listener1, 'message_created'),
|
|
client.createMessage({
|
|
'x-user-key': userKey1,
|
|
conversationId: conversation.id,
|
|
payload: {
|
|
type: 'text',
|
|
text: 'foo',
|
|
},
|
|
}),
|
|
])
|
|
|
|
await client.removeParticipant({ 'x-user-key': userKey1, conversationId: conversation.id, userId: user2.id })
|
|
|
|
await Promise.all([
|
|
utils.waitFor(listener1, 'message_created'),
|
|
client.createMessage({
|
|
'x-user-key': userKey1,
|
|
conversationId: conversation.id,
|
|
payload: {
|
|
type: 'text',
|
|
text: 'bar',
|
|
},
|
|
}),
|
|
])
|
|
|
|
const incomingMessages1 = messages1.filter((m) => !m.isBot)
|
|
const incomingMessages2 = messages2.filter((m) => !m.isBot)
|
|
expect(incomingMessages1.length).toBe(2)
|
|
expect(incomingMessages2.length).toBe(1)
|
|
|
|
await listener1.disconnect()
|
|
listener1.cleanup()
|
|
|
|
await listener2.disconnect()
|
|
listener2.cleanup()
|
|
})
|
|
|
|
test('api forbids removing owner from conversation participants', async () => {
|
|
const client = new chat.Client({ apiUrl })
|
|
|
|
const { user: user1, key: userKey1 } = await client.createUser({})
|
|
|
|
const { conversation } = await client.createConversation({ 'x-user-key': userKey1 })
|
|
|
|
await expect(
|
|
client.removeParticipant({
|
|
'x-user-key': userKey1,
|
|
conversationId: conversation.id,
|
|
userId: user1.id,
|
|
})
|
|
).rejects.toThrow(chat.InvalidPayloadError)
|
|
})
|