330 lines
8.1 KiB
JavaScript
330 lines
8.1 KiB
JavaScript
require('dotenv').config()
|
|
|
|
import * as path from "path";
|
|
import * as os from "os";
|
|
import * as fs from "fs";
|
|
import waitForExpect from 'wait-for-expect'
|
|
|
|
import {
|
|
createClient,
|
|
WebStorageSessionStore,
|
|
mockClient,
|
|
mockRegisterRequest,
|
|
mockInitCrypto,
|
|
mockStartClient,
|
|
mockSetPowerLevel,
|
|
mockCreateRoom,
|
|
mockLeave,
|
|
mockDeactivateAccount,
|
|
mockStopClient,
|
|
mockClearStores,
|
|
mockOn,
|
|
mockOnce,
|
|
mockSendMessage,
|
|
mockSendTextMessage,
|
|
mockLogin,
|
|
mockGetDevices,
|
|
mockGetDeviceId,
|
|
mockDeleteMultipleDevices,
|
|
mockGetJoinedRooms,
|
|
mockSetDeviceVerified,
|
|
mockInvite,
|
|
mockKick,
|
|
mockGetJoinedRoomMembers,
|
|
mockGetUser,
|
|
mockGetGroupUsers
|
|
} from "matrix-js-sdk";
|
|
|
|
import OcrccBot from './bot'
|
|
|
|
const ENCRYPTION_CONFIG = { algorithm: "m.megolm.v1.aes-sha2" };
|
|
const KICK_REASON = "A facilitator has already joined this chat.";
|
|
const BOT_ERROR_MESSAGE =
|
|
"Something went wrong on our end, please restart the chat and try again.";
|
|
const MAX_RETRIES = 3;
|
|
const {
|
|
MATRIX_SERVER_URL,
|
|
BOT_USERNAME,
|
|
BOT_USERID,
|
|
BOT_PASSWORD,
|
|
BOT_DISPLAY_NAME,
|
|
FACILITATOR_GROUP_ID,
|
|
FACILITATOR_ROOM_ID,
|
|
CHAT_OFFLINE_MESSAGE,
|
|
CAPTURE_TRANSCRIPTS
|
|
} = process.env;
|
|
|
|
const botConfig = {
|
|
ENCRYPTION_CONFIG,
|
|
KICK_REASON,
|
|
BOT_ERROR_MESSAGE,
|
|
MAX_RETRIES,
|
|
MATRIX_SERVER_URL,
|
|
BOT_USERNAME,
|
|
BOT_USERID,
|
|
BOT_PASSWORD,
|
|
BOT_DISPLAY_NAME,
|
|
FACILITATOR_GROUP_ID,
|
|
FACILITATOR_ROOM_ID,
|
|
CHAT_OFFLINE_MESSAGE,
|
|
CAPTURE_TRANSCRIPTS
|
|
}
|
|
|
|
|
|
const mockAppendFileSync = jest.fn()
|
|
fs.appendFileSync = mockAppendFileSync
|
|
|
|
describe('OcrccBot', () => {
|
|
beforeEach(() => {
|
|
createClient.mockClear()
|
|
mockInitCrypto.mockClear()
|
|
mockStartClient.mockClear()
|
|
mockRegisterRequest.mockClear()
|
|
mockSetPowerLevel.mockClear()
|
|
mockCreateRoom.mockClear()
|
|
mockLeave.mockClear()
|
|
mockDeactivateAccount.mockClear()
|
|
mockStopClient.mockClear()
|
|
mockClearStores.mockClear()
|
|
mockOnce.mockClear()
|
|
mockOn.mockClear()
|
|
mockLogin.mockClear()
|
|
mockGetDevices.mockClear()
|
|
mockGetDeviceId.mockClear()
|
|
mockDeleteMultipleDevices.mockClear()
|
|
mockGetJoinedRooms.mockClear()
|
|
mockSetDeviceVerified.mockClear()
|
|
mockInvite.mockClear()
|
|
mockKick.mockClear()
|
|
mockGetJoinedRoomMembers.mockClear()
|
|
mockGetUser.mockClear()
|
|
mockSendMessage.mockClear()
|
|
mockSendTextMessage.mockClear()
|
|
mockAppendFileSync.mockClear()
|
|
mockGetGroupUsers.mockClear()
|
|
})
|
|
|
|
|
|
test('constructor should inititialize class variables', () => {
|
|
const bot = new OcrccBot(botConfig)
|
|
expect(bot.joinedRooms).toEqual([])
|
|
})
|
|
|
|
test('#createLocalStorage should have correct storage location', () => {
|
|
const bot = new OcrccBot(botConfig)
|
|
const localStorage = bot.createLocalStorage()
|
|
const localStoragePath = path.resolve(path.join(os.homedir(), ".local-storage", `matrix-chatbot-${process.env.BOT_USERNAME}`));
|
|
expect(localStorage._location).toBe(localStoragePath)
|
|
})
|
|
|
|
test('#sendMessage should send a text message', () => {
|
|
const bot = new OcrccBot(botConfig)
|
|
bot.start()
|
|
|
|
waitForExpect(() => {
|
|
expect(mockStartClient).toHaveBeenCalled()
|
|
})
|
|
|
|
const testRoom = 'room_id_1234'
|
|
const testMsg = 'test message'
|
|
|
|
bot.sendMessage(testRoom, testMsg)
|
|
|
|
waitForExpect(() => {
|
|
expect(mockSetDeviceVerified).toHaveBeenCalledTimes(2)
|
|
})
|
|
waitForExpect(() => {
|
|
expect(mockSendMessage).toHaveBeenCalledWith(testRoom, testMsg)
|
|
})
|
|
|
|
})
|
|
|
|
test('#inviteUserToRoom should add member to room and retry on rate limit error', () => {
|
|
const bot = new OcrccBot(botConfig)
|
|
bot.start()
|
|
|
|
waitForExpect(() => {
|
|
expect(mockStartClient).toHaveBeenCalled()
|
|
})
|
|
|
|
bot.inviteUserToRoom(bot.client, 'room_id_1234', process.env.BOT_USERNAME)
|
|
|
|
waitForExpect(() => {
|
|
expect(mockInvite).toHaveBeenCalledTimes(2)
|
|
})
|
|
})
|
|
|
|
test('#kickUserFromRoom should remove member from room and retry on rate limit error', () => {
|
|
const bot = new OcrccBot(botConfig)
|
|
bot.start()
|
|
|
|
waitForExpect(() => {
|
|
expect(mockStartClient).toHaveBeenCalled()
|
|
})
|
|
|
|
bot.kickUserFromRoom(bot.client, 'room_id_1234', process.env.BOT_USERNAME)
|
|
|
|
waitForExpect(() => {
|
|
expect(mockKick).toHaveBeenCalledTimes(2)
|
|
})
|
|
})
|
|
|
|
test('#inviteFacilitators should invite all members from Facilitator room', () => {
|
|
const bot = new OcrccBot(botConfig)
|
|
bot.start()
|
|
|
|
waitForExpect(() => {
|
|
expect(mockStartClient).toHaveBeenCalled()
|
|
})
|
|
|
|
bot.inviteFacilitators()
|
|
|
|
waitForExpect(() => {
|
|
expect(mockGetJoinedRoomMembers).toHaveBeenCalledWith(process.env.FACILITATOR_ROOM_ID)
|
|
})
|
|
|
|
waitForExpect(() => {
|
|
expect(mockGetUser).toHaveBeenCalledTimes(2)
|
|
})
|
|
|
|
waitForExpect(() => {
|
|
expect(mockInvite).toHaveBeenCalledTimes(2)
|
|
})
|
|
})
|
|
|
|
test('#uninviteFacilitators should remove all members that have not accepted the invite', () => {
|
|
const bot = new OcrccBot(botConfig)
|
|
bot.start()
|
|
|
|
waitForExpect(() => {
|
|
expect(mockStartClient).toHaveBeenCalled()
|
|
})
|
|
|
|
bot.uninviteFacilitators()
|
|
|
|
waitForExpect(() => {
|
|
expect(mockGetJoinedRoomMembers).toHaveBeenCalledWith(process.env.FACILITATOR_ROOM_ID)
|
|
})
|
|
|
|
waitForExpect(() => {
|
|
expect(mockGetJoinedRoomMembers).toHaveBeenCalledWith('room_id_1234')
|
|
})
|
|
|
|
waitForExpect(() => {
|
|
expect(mockKick).toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
test('#handleBotCrash should notify rooms', () => {
|
|
const bot = new OcrccBot(botConfig)
|
|
bot.start()
|
|
|
|
waitForExpect(() => {
|
|
expect(mockStartClient).toHaveBeenCalled()
|
|
})
|
|
|
|
bot.handleBotCrash('test_room_id', 'test error message')
|
|
|
|
waitForExpect(() => {
|
|
expect(mockSendTextMessage).toHaveBeenCalledWith('test_room_id', "Something went wrong on our end, please restart the chat and try again.")
|
|
})
|
|
|
|
waitForExpect(() => {
|
|
expect(mockSendTextMessage).toHaveBeenCalledWith(process.env.FACILITATOR_ROOM_ID, `The Help Bot ran into an error: test error message. Please verify that the chat service is working.`)
|
|
})
|
|
})
|
|
|
|
test('#writeToTranscript should parse event and write to transcript file', () => {
|
|
const bot = new OcrccBot(botConfig)
|
|
bot.start()
|
|
|
|
bot.localStorage.setItem(`test_room_id-transcript`, '__mocks__/test_transcript.txt')
|
|
|
|
waitForExpect(() => {
|
|
expect(mockStartClient).toHaveBeenCalled()
|
|
})
|
|
|
|
const mockEvent = {
|
|
getSender: () => 'test_sender',
|
|
getRoomId: () => 'test_room_id',
|
|
getContent: () => { return { body: 'test content' }},
|
|
getDate: () => { return new Date(2020,2,17,0,0,0,0) }
|
|
}
|
|
|
|
bot.writeToTranscript(mockEvent)
|
|
|
|
waitForExpect(() => {
|
|
expect(mockAppendFileSync).toHaveBeenCalledWith('__mocks__/test_transcript.txt', 'test_sender [00:00:00]: test content', 'utf8')
|
|
})
|
|
})
|
|
|
|
test('#deleteOldDevices should delete old sessions', () => {
|
|
const bot = new OcrccBot(botConfig)
|
|
bot.start()
|
|
|
|
waitForExpect(() => {
|
|
expect(mockStartClient).toHaveBeenCalled()
|
|
})
|
|
|
|
bot.deleteOldDevices()
|
|
|
|
waitForExpect(() => {
|
|
expect(mockGetDevices).toHaveBeenCalled()
|
|
})
|
|
|
|
waitForExpect(() => {
|
|
expect(mockGetDevicdId).toHaveBeenCalled()
|
|
})
|
|
|
|
waitForExpect(() => {
|
|
expect(deleteMultipleDevices).toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
// TODO test listeners for membership events and message events
|
|
|
|
test('#start should start bot and set up listeners', () => {
|
|
const bot = new OcrccBot(botConfig)
|
|
bot.start()
|
|
|
|
waitForExpect(() => {
|
|
expect(mockLogin).toHaveBeenCalled()
|
|
})
|
|
|
|
waitForExpect(() => {
|
|
expect(WebStorageSessionStore).toHaveBeenCalled()
|
|
})
|
|
|
|
waitForExpect(() => {
|
|
expect(createClient).toHaveBeenCalled()
|
|
})
|
|
|
|
waitForExpect(() => {
|
|
expect(mockGetDevices).toHaveBeenCalled()
|
|
})
|
|
|
|
waitForExpect(() => {
|
|
expect(mockGetDeviceId).toHaveBeenCalled()
|
|
})
|
|
|
|
waitForExpect(() => {
|
|
expect(mockDeleteMultipleDevices).toHaveBeenCalled()
|
|
})
|
|
|
|
waitForExpect(() => {
|
|
expect(mockInitCrypto).toHaveBeenCalled()
|
|
})
|
|
|
|
waitForExpect(() => {
|
|
expect(mockGetJoinedRooms).toHaveBeenCalled()
|
|
})
|
|
|
|
waitForExpect(() => {
|
|
expect(mockOn).toHaveBeenCalled()
|
|
})
|
|
|
|
waitForExpect(() => {
|
|
expect(mockStartClient).toHaveBeenCalled()
|
|
})
|
|
})
|
|
}) |