"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var path = _interopRequireWildcard(require("path")); var os = _interopRequireWildcard(require("os")); var fs = _interopRequireWildcard(require("fs")); var _waitForExpect = _interopRequireDefault(require("wait-for-expect")); var _matrixJsSdk = require("matrix-js-sdk"); var _bot = _interopRequireDefault(require("./bot")); require('dotenv').config(); 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_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_ROOM_ID, CHAT_OFFLINE_MESSAGE, CAPTURE_TRANSCRIPTS }; const mockAppendFileSync = jest.fn(); fs.appendFileSync = mockAppendFileSync; describe('OcrccBot', () => { beforeEach(() => { _matrixJsSdk.createClient.mockClear(); _matrixJsSdk.mockInitCrypto.mockClear(); _matrixJsSdk.mockStartClient.mockClear(); _matrixJsSdk.mockRegisterRequest.mockClear(); _matrixJsSdk.mockSetPowerLevel.mockClear(); _matrixJsSdk.mockCreateRoom.mockClear(); _matrixJsSdk.mockLeave.mockClear(); _matrixJsSdk.mockDeactivateAccount.mockClear(); _matrixJsSdk.mockStopClient.mockClear(); _matrixJsSdk.mockClearStores.mockClear(); _matrixJsSdk.mockOnce.mockClear(); _matrixJsSdk.mockOn.mockClear(); _matrixJsSdk.mockLogin.mockClear(); _matrixJsSdk.mockGetDevices.mockClear(); _matrixJsSdk.mockGetDeviceId.mockClear(); _matrixJsSdk.mockDeleteMultipleDevices.mockClear(); _matrixJsSdk.mockGetJoinedRooms.mockClear(); _matrixJsSdk.mockSetDeviceVerified.mockClear(); _matrixJsSdk.mockInvite.mockClear(); _matrixJsSdk.mockKick.mockClear(); _matrixJsSdk.mockGetJoinedRoomMembers.mockClear(); _matrixJsSdk.mockGetUser.mockClear(); _matrixJsSdk.mockSendMessage.mockClear(); _matrixJsSdk.mockSendTextMessage.mockClear(); mockAppendFileSync.mockClear(); _matrixJsSdk.mockGetGroupUsers.mockClear(); _matrixJsSdk.mockSendStateEvent.mockClear(); }); test('constructor should inititialize class variables', () => { const bot = new _bot.default(botConfig); expect(bot.joinedRooms).toEqual([]); }); test('#createLocalStorage should have correct storage location', () => { const bot = new _bot.default(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 _bot.default(botConfig); bot.start(); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockStartClient).toHaveBeenCalled(); }); const testRoom = 'room_id_1234'; const testMsg = 'test message'; bot.sendMessage(testRoom, testMsg); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockSetDeviceVerified).toHaveBeenCalledTimes(2); }); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockSendMessage).toHaveBeenCalledWith(testRoom, testMsg); }); }); test('#inviteUserToRoom should add member to room and retry on rate limit error', () => { const bot = new _bot.default(botConfig); bot.start(); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockStartClient).toHaveBeenCalled(); }); bot.inviteUserToRoom(bot.client, 'room_id_1234', process.env.BOT_USERNAME); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockInvite).toHaveBeenCalledTimes(2); }); }); test('#kickUserFromRoom should remove member from room and retry on rate limit error', () => { const bot = new _bot.default(botConfig); bot.start(); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockStartClient).toHaveBeenCalled(); }); bot.kickUserFromRoom(bot.client, 'room_id_1234', process.env.BOT_USERNAME); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockKick).toHaveBeenCalledTimes(2); }); }); test('#inviteFacilitators should invite all members from Facilitator room', () => { const bot = new _bot.default(botConfig); bot.start(); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockStartClient).toHaveBeenCalled(); }); bot.inviteFacilitators(); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockGetJoinedRoomMembers).toHaveBeenCalledWith(process.env.FACILITATOR_ROOM_ID); }); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockGetUser).toHaveBeenCalledTimes(2); }); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockInvite).toHaveBeenCalledTimes(2); }); }); test('#uninviteFacilitators should remove all members that have not accepted the invite', () => { const bot = new _bot.default(botConfig); bot.start(); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockStartClient).toHaveBeenCalled(); }); bot.uninviteFacilitators(); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockGetJoinedRoomMembers).toHaveBeenCalledWith(process.env.FACILITATOR_ROOM_ID); }); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockGetJoinedRoomMembers).toHaveBeenCalledWith('room_id_1234'); }); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockKick).toHaveBeenCalled(); }); }); test('#handleBotCrash should notify rooms', () => { const bot = new _bot.default(botConfig); bot.start(); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockStartClient).toHaveBeenCalled(); }); bot.handleBotCrash('test_room_id', 'test error message'); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockSendTextMessage).toHaveBeenCalledWith('test_room_id', "Something went wrong on our end, please restart the chat and try again."); }); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.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 _bot.default(botConfig); bot.start(); bot.localStorage.setItem(`test_room_id-transcript`, '__mocks__/test_transcript.txt'); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.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); (0, _waitForExpect.default)(() => { expect(mockAppendFileSync).toHaveBeenCalledWith('__mocks__/test_transcript.txt', 'test_sender [00:00:00]: test content', 'utf8'); }); }); test('#deleteOldDevices should delete old sessions', () => { const bot = new _bot.default(botConfig); bot.start(); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockStartClient).toHaveBeenCalled(); }); bot.deleteOldDevices(); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockGetDevices).toHaveBeenCalled(); }); (0, _waitForExpect.default)(() => { expect(mockGetDevicdId).toHaveBeenCalled(); }); (0, _waitForExpect.default)(() => { expect(deleteMultipleDevices).toHaveBeenCalled(); }); }); // TODO test listeners for membership events and message events test('#start should start bot and set up listeners', () => { const bot = new _bot.default(botConfig); bot.start(); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockLogin).toHaveBeenCalled(); }); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.WebStorageSessionStore).toHaveBeenCalled(); }); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.createClient).toHaveBeenCalled(); }); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockGetDevices).toHaveBeenCalled(); }); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockGetDeviceId).toHaveBeenCalled(); }); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockDeleteMultipleDevices).toHaveBeenCalled(); }); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockInitCrypto).toHaveBeenCalled(); }); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockGetJoinedRooms).toHaveBeenCalled(); }); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockOn).toHaveBeenCalled(); }); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockStartClient).toHaveBeenCalled(); }); }); test('#sendBotSignal should send custom state event', () => { const bot = new _bot.default(botConfig); bot.start(); const test_room_id = 'test_room_id'; const signal = 'END_CHAT'; bot.sendBotSignal(test_room_id, signal); (0, _waitForExpect.default)(() => { expect(_matrixJsSdk.mockSendStateEvent).toHaveBeenCalledWith(test_room_id, 'm.bot.signal', { signal }); }); }); });