mirror of
https://github.com/Safe-Support-Chat/ocrcc-chatbox
synced 2024-11-01 00:55:26 +00:00
test main chatbox functionality
This commit is contained in:
parent
a97696f687
commit
c798700a20
@ -1,11 +1,69 @@
|
|||||||
export const mockCreateClient = jest.fn();
|
export const mockRegisterRequest = jest
|
||||||
export const mockStartClient = jest.fn();
|
.fn()
|
||||||
|
.mockImplementation((params) => {
|
||||||
|
if (!params.auth) {
|
||||||
|
return Promise.reject({
|
||||||
|
data: { session: "session_id_1234" }
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
return Promise.resolve({
|
||||||
|
data: {
|
||||||
|
device_id: 'device_id_1234',
|
||||||
|
access_token: 'token_1234',
|
||||||
|
user_id: 'user_id_1234',
|
||||||
|
session: "session_id_1234"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const mockMatrix = jest.fn().mockImplementation(() => {
|
export const mockLeave = jest.fn(() => {
|
||||||
return {
|
return Promise.resolve('value');
|
||||||
createClient: mockCreateClient,
|
|
||||||
startClient: mockStartClient
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
export const mockInitCrypto = jest.fn()
|
||||||
|
export const mockStartClient = jest.fn(() => {
|
||||||
|
return Promise.resolve('value');
|
||||||
|
});
|
||||||
|
export const mockOnce = jest.fn()
|
||||||
|
export const mockStopClient = jest.fn(() => {
|
||||||
|
return Promise.resolve('value');
|
||||||
|
});
|
||||||
|
export const mockClearStores = jest.fn(() => {
|
||||||
|
return Promise.resolve('value');
|
||||||
|
});
|
||||||
|
export const mockGetRoom = jest.fn()
|
||||||
|
export const mockDownloadKeys = jest.fn()
|
||||||
|
export const mockSetDeviceVerified = jest.fn()
|
||||||
|
export const mockIsCryptoEnabled = jest.fn()
|
||||||
|
export const mockCreateRoom = jest.fn().mockReturnValue({ room_id: 'room_id_1234' })
|
||||||
|
export const mockSetPowerLevel = jest.fn()
|
||||||
|
export const mockSendTextMessage = jest.fn(() => {
|
||||||
|
return Promise.resolve('value');
|
||||||
|
});
|
||||||
|
export const mockSetDeviceKnown = jest.fn()
|
||||||
|
export const mockDeactivateAccount = jest.fn(() => {
|
||||||
|
return Promise.resolve('value');
|
||||||
|
});
|
||||||
|
export const mockOn = jest.fn()
|
||||||
|
|
||||||
export default mockMatrix;
|
export const mockClient = {
|
||||||
|
registerRequest: mockRegisterRequest,
|
||||||
|
initCrypto: mockInitCrypto,
|
||||||
|
startClient: mockStartClient,
|
||||||
|
on: mockOn,
|
||||||
|
once: mockOnce,
|
||||||
|
leave: mockLeave,
|
||||||
|
stopClient: mockStopClient,
|
||||||
|
clearStores: mockClearStores,
|
||||||
|
getRoom: mockGetRoom,
|
||||||
|
downloadKeys: mockDownloadKeys,
|
||||||
|
setDeviceVerified: mockSetDeviceVerified,
|
||||||
|
setDeviceKnown: mockSetDeviceKnown,
|
||||||
|
isCryptoEnabled: mockIsCryptoEnabled,
|
||||||
|
createRoom: mockCreateRoom,
|
||||||
|
setPowerLevel: mockSetPowerLevel,
|
||||||
|
sendTextMessage: mockSendTextMessage,
|
||||||
|
deactivateAccount: mockDeactivateAccount,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createClient = jest.fn().mockReturnValue(mockClient)
|
||||||
|
@ -108,6 +108,7 @@
|
|||||||
"postcss-loader": "3.0.0",
|
"postcss-loader": "3.0.0",
|
||||||
"sass-loader": "8.0.0",
|
"sass-loader": "8.0.0",
|
||||||
"style-loader": "1.1.2",
|
"style-loader": "1.1.2",
|
||||||
|
"wait-for-expect": "^3.0.2",
|
||||||
"webpack": "4.41.5",
|
"webpack": "4.41.5",
|
||||||
"webpack-cli": "3.3.10",
|
"webpack-cli": "3.3.10",
|
||||||
"webpack-dev-server": "3.10.1",
|
"webpack-dev-server": "3.10.1",
|
||||||
|
@ -430,3 +430,7 @@
|
|||||||
height: calc(180px + 60vh);
|
height: calc(180px + 60vh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
@ -120,16 +120,17 @@ class ChatBox extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
initializeChat = () => {
|
initializeChat = () => {
|
||||||
// empty registration request to get session
|
|
||||||
this.setState({ ready: false })
|
this.setState({ ready: false })
|
||||||
let client;
|
let client;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
client = matrix.createClient(this.props.matrixServerUrl)
|
client = matrix.createClient(this.props.matrixServerUrl)
|
||||||
} catch {
|
} catch(error) {
|
||||||
|
console.log("Error creating client", error)
|
||||||
return this.handleInitError()
|
return this.handleInitError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// empty registration request to get session
|
||||||
return client.registerRequest({})
|
return client.registerRequest({})
|
||||||
.then(data => {
|
.then(data => {
|
||||||
console.log("Empty registration request to get session", data)
|
console.log("Empty registration request to get session", data)
|
||||||
@ -399,18 +400,12 @@ class ChatBox extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!prevState.ready && this.state.ready) {
|
|
||||||
this.chatboxInput.current.focus()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!prevState.opened && this.state.opened) {
|
|
||||||
this.chatboxInput.current.focus()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prevState.messages.length !== this.state.messages.length) {
|
if (prevState.messages.length !== this.state.messages.length) {
|
||||||
|
if (this.messageWindow.current.scrollTo) {
|
||||||
this.messageWindow.current.scrollTo(0, this.messageWindow.current.scrollHeight)
|
this.messageWindow.current.scrollTo(0, this.messageWindow.current.scrollHeight)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
document.addEventListener("keydown", this.handleEscape, false);
|
document.addEventListener("keydown", this.handleEscape, false);
|
||||||
@ -424,7 +419,7 @@ class ChatBox extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleInputChange = e => {
|
handleInputChange = e => {
|
||||||
this.setState({ inputValue: e.currentTarget.value })
|
this.setState({ inputValue: e.target.value })
|
||||||
}
|
}
|
||||||
|
|
||||||
handleAcceptTerms = () => {
|
handleAcceptTerms = () => {
|
||||||
@ -493,14 +488,13 @@ class ChatBox extends React.Component {
|
|||||||
<div role="status">{typingStatus}</div>
|
<div role="status">{typingStatus}</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
{
|
{ !ready && <div className={`loader`}>loading...</div> }
|
||||||
!ready && <div className="loader">loading...</div>
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="input-window">
|
<div className="input-window">
|
||||||
<form onSubmit={this.handleSubmit}>
|
<form onSubmit={this.handleSubmit}>
|
||||||
<input
|
<input
|
||||||
|
id="message-input"
|
||||||
type="text"
|
type="text"
|
||||||
onChange={this.handleInputChange}
|
onChange={this.handleInputChange}
|
||||||
value={inputValue}
|
value={inputValue}
|
||||||
@ -509,7 +503,7 @@ class ChatBox extends React.Component {
|
|||||||
autoFocus={true}
|
autoFocus={true}
|
||||||
ref={this.chatboxInput}
|
ref={this.chatboxInput}
|
||||||
/>
|
/>
|
||||||
<input type="submit" value="Send" />
|
<input type="submit" value="Send" id="submit" />
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,9 +1,25 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Chatbox from './chatbox';
|
import Chatbox from './chatbox';
|
||||||
import mockMatrix, { mockCreateClient } from "matrix-js-sdk";
|
import {
|
||||||
|
createClient,
|
||||||
|
mockClient,
|
||||||
|
mockRegisterRequest,
|
||||||
|
mockInitCrypto,
|
||||||
|
mockStartClient,
|
||||||
|
mockSetPowerLevel,
|
||||||
|
mockCreateRoom,
|
||||||
|
mockLeave,
|
||||||
|
mockDeactivateAccount,
|
||||||
|
mockStopClient,
|
||||||
|
mockClearStores,
|
||||||
|
mockOn,
|
||||||
|
mockOnce,
|
||||||
|
mockSendTextMessage
|
||||||
|
} from "matrix-js-sdk";
|
||||||
import { mount, shallow } from 'enzyme';
|
import { mount, shallow } from 'enzyme';
|
||||||
import { createWaitForElement } from 'enzyme-wait';
|
import { createWaitForElement } from 'enzyme-wait';
|
||||||
import { config } from 'react-transition-group';
|
import { config } from 'react-transition-group';
|
||||||
|
import waitForExpect from 'wait-for-expect'
|
||||||
|
|
||||||
config.disabled = true
|
config.disabled = true
|
||||||
|
|
||||||
@ -23,6 +39,21 @@ const testConfig = {
|
|||||||
|
|
||||||
describe('Chatbox', () => {
|
describe('Chatbox', () => {
|
||||||
|
|
||||||
|
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()
|
||||||
|
})
|
||||||
|
|
||||||
test('chat window should open and close', async () => {
|
test('chat window should open and close', async () => {
|
||||||
const chatbox = mount(<Chatbox {...testConfig} />)
|
const chatbox = mount(<Chatbox {...testConfig} />)
|
||||||
|
|
||||||
@ -61,107 +92,128 @@ describe('Chatbox', () => {
|
|||||||
expect(messages.text()).toContain(props.agreementMessage)
|
expect(messages.text()).toContain(props.agreementMessage)
|
||||||
});
|
});
|
||||||
|
|
||||||
test('#handleExitChat should call exitChat if the client has been initialized', () => {
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
test('#exitChat should leave the room and destroy client', () => {
|
|
||||||
// leave room
|
|
||||||
// deactivate account
|
|
||||||
// stop client
|
|
||||||
// clear stores
|
|
||||||
// reset initial state
|
|
||||||
})
|
|
||||||
|
|
||||||
test('agreeing to terms should start encrypted chat', async () => {
|
test('agreeing to terms should start encrypted chat', async () => {
|
||||||
const chatbox = mount(<Chatbox {...testConfig} />)
|
const chatbox = mount(<Chatbox {...testConfig} />)
|
||||||
const dock = chatbox.find('button.dock')
|
const dock = chatbox.find('button.dock')
|
||||||
|
|
||||||
dock.simulate('click')
|
dock.simulate('click')
|
||||||
|
|
||||||
const yesButton = chatbox.find('#accept')
|
const openChatWindow = await createWaitForElement('.widget-entered')(chatbox)
|
||||||
yesButton.simulate('click')
|
let acceptButton = await createWaitForElement('button#accept')(chatbox)
|
||||||
|
acceptButton = chatbox.find('button#accept')
|
||||||
|
|
||||||
expect(mockCreateClient).toHaveBeenCalled()
|
acceptButton.simulate('click')
|
||||||
|
|
||||||
|
const ready = await createWaitForElement('.loader')(chatbox)
|
||||||
|
expect(ready.length).toEqual(1)
|
||||||
|
|
||||||
|
expect(createClient).toHaveBeenCalled()
|
||||||
|
expect(mockInitCrypto).toHaveBeenCalled()
|
||||||
|
expect(mockStartClient).toHaveBeenCalled()
|
||||||
|
expect(mockCreateRoom).toHaveBeenCalled()
|
||||||
|
expect(mockSetPowerLevel).toHaveBeenCalled()
|
||||||
|
expect(mockSetPowerLevel).toHaveBeenCalled()
|
||||||
|
expect(mockOn).toHaveBeenCalled()
|
||||||
|
expect(mockOnce).toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
// test('rejecting terms should not start chat', async () => {
|
test('rejecting terms should not start chat', async () => {
|
||||||
// const chatbox = mount(<Chatbox {...testConfig} />)
|
const chatbox = mount(<Chatbox {...testConfig} />)
|
||||||
// const dock = chatbox.find('button.dock')
|
const dock = chatbox.find('button.dock')
|
||||||
|
|
||||||
// dock.simulate('click')
|
dock.simulate('click')
|
||||||
|
|
||||||
// const noButton = chatbox.find('#reject')
|
const openChatWindow = await createWaitForElement('.widget-entered')(chatbox)
|
||||||
// noButton.simulate('click')
|
let rejectButton = await createWaitForElement('button#reject')(chatbox)
|
||||||
|
rejectButton = chatbox.find('button#reject')
|
||||||
|
|
||||||
// expect(mockMatrix.mockCreateClient.mock.calls.length).toEqual(0)
|
rejectButton.simulate('click')
|
||||||
// })
|
|
||||||
|
|
||||||
test('#initializeChat should notify user if client fails to initialize', () => {
|
expect(createClient.mock.calls.length).toEqual(0)
|
||||||
// handleInitError
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test('#initializeChat should create unencypted chat if initCrypto fails', () => {
|
test('notification should appear when facilitator joins chat', () => {
|
||||||
// initializeUnencryptedChat
|
//
|
||||||
})
|
})
|
||||||
|
|
||||||
test('#initializeUnencryptedChat should initialize an unencrypted client', () => {
|
test('submitted messages should be sent to matrix', async () => {
|
||||||
// initializeUnencryptedChat
|
const chatbox = mount(<Chatbox {...testConfig} />)
|
||||||
|
const dock = chatbox.find('button.dock')
|
||||||
|
|
||||||
|
dock.simulate('click')
|
||||||
|
|
||||||
|
let acceptButton = await createWaitForElement('button#accept')(chatbox)
|
||||||
|
acceptButton = chatbox.find('button#accept')
|
||||||
|
|
||||||
|
acceptButton.simulate('click')
|
||||||
|
|
||||||
|
await waitForExpect(() => {
|
||||||
|
expect(mockCreateRoom).toHaveBeenCalled()
|
||||||
|
});
|
||||||
|
|
||||||
|
const input = chatbox.find('#message-input')
|
||||||
|
const form = chatbox.find('form')
|
||||||
|
const message = 'Hello'
|
||||||
|
|
||||||
|
input.simulate('change', { target: { value: message }})
|
||||||
|
|
||||||
|
await waitForExpect(() => {
|
||||||
|
chatbox.update()
|
||||||
|
expect(chatbox.state().inputValue).toEqual(message)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('#handleDecryptionError should restart client without encryption and notify user', () => {
|
form.simulate('submit')
|
||||||
// initializeUnencryptedChat
|
|
||||||
|
await waitForExpect(() => {
|
||||||
|
expect(mockSendTextMessage).toHaveBeenCalledWith(chatbox.state().roomId, message)
|
||||||
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
test('#verifyAllRoomDevices should mark all devices in the room as verified devices', () => {
|
test('received messages should appear in chat window', () => {
|
||||||
|
//
|
||||||
})
|
})
|
||||||
|
|
||||||
test('#createRoom should create a new encrypted room with bot as admin', () => {
|
test('decryption failure should lead to a new unencrypted chat', () => {
|
||||||
|
//
|
||||||
})
|
})
|
||||||
|
|
||||||
test('#createRoom should create a new unencrypted room if encryption is not enabled', () => {
|
test('exiting the chat should leave the room and destroy client', async () => {
|
||||||
|
const chatbox = mount(<Chatbox {...testConfig} />)
|
||||||
|
const dock = chatbox.find('button.dock')
|
||||||
|
|
||||||
})
|
dock.simulate('click')
|
||||||
|
|
||||||
test('#sendMessage should send text message with input value', () => {
|
const openChatWindow = await createWaitForElement('.widget-entered')(chatbox)
|
||||||
|
let acceptButton = await createWaitForElement('button#accept')(chatbox)
|
||||||
|
acceptButton = chatbox.find('button#accept')
|
||||||
|
|
||||||
})
|
acceptButton.simulate('click')
|
||||||
|
|
||||||
test('#sendMessage should mark devices as known and retry sending on UnknownDeviceError', () => {
|
await waitForExpect(() => {
|
||||||
|
expect(mockCreateRoom).toHaveBeenCalled()
|
||||||
|
});
|
||||||
|
|
||||||
})
|
const exitButton = chatbox.find('button.widget-header-close')
|
||||||
|
|
||||||
test('#sendMessage should mark devices as known and retry sending on UnknownDeviceError', () => {
|
exitButton.simulate('click')
|
||||||
|
|
||||||
})
|
let closed = await createWaitForElement('button.dock')
|
||||||
|
expect(closed.length).toEqual(1)
|
||||||
|
|
||||||
test('#displayFakeMessage should add a message object to message list', () => {
|
await waitForExpect(() => {
|
||||||
|
expect(mockLeave).toHaveBeenCalled()
|
||||||
|
});
|
||||||
|
|
||||||
})
|
await waitForExpect(() => {
|
||||||
|
expect(mockDeactivateAccount).toHaveBeenCalled()
|
||||||
|
});
|
||||||
|
|
||||||
test('#displayBotMessage should add a message object with bot as sender to message list', () => {
|
await waitForExpect(() => {
|
||||||
|
expect(mockStopClient).toHaveBeenCalled()
|
||||||
})
|
});
|
||||||
|
|
||||||
test('#handleMessageEvent should add received message to message list', () => {
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
test('#componentDidUpdate should set state listeners', () => {
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
test('#handleSubmit should listen for yes if awaiting agreement and initialize client', () => {
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
test('#handleSubmit should listen for no if awaiting agreement and do nothing', () => {
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
test('#handleSubmit should send message if awaitingAgreement is false', () => {
|
|
||||||
|
|
||||||
|
await waitForExpect(() => {
|
||||||
|
expect(mockClearStores).toHaveBeenCalled()
|
||||||
|
});
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -12157,6 +12157,11 @@ w3c-hr-time@^1.0.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
browser-process-hrtime "^0.1.2"
|
browser-process-hrtime "^0.1.2"
|
||||||
|
|
||||||
|
wait-for-expect@^3.0.2:
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/wait-for-expect/-/wait-for-expect-3.0.2.tgz#d2f14b2f7b778c9b82144109c8fa89ceaadaa463"
|
||||||
|
integrity sha512-cfS1+DZxuav1aBYbaO/kE06EOS8yRw7qOFoD3XtjTkYvCvh3zUvNST8DXK/nPaeqIzIv3P3kL3lRJn8iwOiSag==
|
||||||
|
|
||||||
walker@^1.0.7, walker@~1.0.5:
|
walker@^1.0.7, walker@~1.0.5:
|
||||||
version "1.0.7"
|
version "1.0.7"
|
||||||
resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb"
|
resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb"
|
||||||
|
Loading…
Reference in New Issue
Block a user