From 6b6e1716b7ca89854649b5376bed14b31e1a4a72 Mon Sep 17 00:00:00 2001 From: Alie Langston Date: Thu, 14 Nov 2024 14:32:50 -0500 Subject: [PATCH] feat: remove clear button from chat ui --- src/components/Sidebar/index.jsx | 35 +-------------- src/components/Sidebar/index.test.jsx | 41 ------------------ src/data/slice.js | 6 --- src/data/thunks.js | 8 ---- src/widgets/Xpert.test.jsx | 61 --------------------------- 5 files changed, 1 insertion(+), 150 deletions(-) diff --git a/src/components/Sidebar/index.jsx b/src/components/Sidebar/index.jsx index 70edc2b9..097397a3 100644 --- a/src/components/Sidebar/index.jsx +++ b/src/components/Sidebar/index.jsx @@ -1,16 +1,12 @@ import React, { useRef, useEffect } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import { useSelector } from 'react-redux'; import PropTypes from 'prop-types'; -import { sendTrackEvent } from '@edx/frontend-platform/analytics'; import { - Button, Icon, IconButton, } from '@openedx/paragon'; import { Close } from '@openedx/paragon/icons'; -import { clearMessages } from '../../data/thunks'; -import { OPTIMIZELY_PROMPT_EXPERIMENT_KEY } from '../../data/optimizely'; import showSurvey from '../../utils/surveyMonkey'; import APIError from '../APIError'; @@ -18,7 +14,6 @@ import ChatBox from '../ChatBox'; import Disclosure from '../Disclosure'; import MessageForm from '../MessageForm'; import './Sidebar.scss'; -import { usePromptExperimentDecision } from '../../experiments'; const Sidebar = ({ courseId, @@ -32,14 +27,6 @@ const Sidebar = ({ messageList, } = useSelector(state => state.learningAssistant); const chatboxContainerRef = useRef(null); - const dispatch = useDispatch(); - - const [decision] = usePromptExperimentDecision(); - const { enabled: enabledExperiment, variationKey } = decision || {}; - const experimentPayload = enabledExperiment ? { - experiment_name: OPTIMIZELY_PROMPT_EXPERIMENT_KEY, - variation_key: variationKey, - } : {}; // this use effect is intended to scroll to the bottom of the chat window, in the case // that a message is larger than the chat window height. @@ -83,14 +70,6 @@ const Sidebar = ({ } }; - const handleClearMessages = () => { - dispatch(clearMessages()); - sendTrackEvent('edx.ui.lms.learning_assistant.clear', { - course_id: courseId, - ...experimentPayload, - }); - }; - const getMessageForm = () => ( ); @@ -120,18 +99,6 @@ const Sidebar = ({ ) } {getMessageForm()} -
- -
); diff --git a/src/components/Sidebar/index.test.jsx b/src/components/Sidebar/index.test.jsx index 9a57c70e..210daf40 100644 --- a/src/components/Sidebar/index.test.jsx +++ b/src/components/Sidebar/index.test.jsx @@ -1,11 +1,9 @@ import React from 'react'; import { screen, act } from '@testing-library/react'; -import { sendTrackEvent } from '@edx/frontend-platform/analytics'; import { usePromptExperimentDecision } from '../../experiments'; import { render as renderComponent } from '../../utils/utils.test'; import { initialState } from '../../data/slice'; -import { OPTIMIZELY_PROMPT_EXPERIMENT_KEY, OPTIMIZELY_PROMPT_EXPERIMENT_VARIATION_KEYS } from '../../data/optimizely'; import showSurvey from '../../utils/surveyMonkey'; import Sidebar from '.'; @@ -35,11 +33,6 @@ jest.mock('../../experiments', () => ({ usePromptExperimentDecision: jest.fn(), })); -const clearMessagesAction = 'clear-messages-action'; -jest.mock('../../data/thunks', () => ({ - clearMessages: () => 'clear-messages-action', -})); - const defaultProps = { courseId: 'some-course-id', isOpen: true, @@ -88,17 +81,6 @@ describe('', () => { render(undefined, { disclosureAcknowledged: true }); expect(screen.queryByTestId('sidebar-xpert')).toBeInTheDocument(); }); - - it('should dispatch clearMessages() and call sendTrackEvent() with the expected props on clear', () => { - render(undefined, { disclosureAcknowledged: true }); - - act(() => { - screen.queryByTestId('sidebar-clear-btn').click(); - }); - - expect(mockDispatch).toHaveBeenCalledWith(clearMessagesAction); - expect(sendTrackEvent).toHaveBeenCalledWith('edx.ui.lms.learning_assistant.clear', { course_id: defaultProps.courseId }); - }); }); describe('when it\'s not open', () => { @@ -133,28 +115,5 @@ describe('', () => { expect(showSurvey).toHaveBeenCalled(); }); - - it('should dispatch clearMessages() and call sendTrackEvent() with the expected props on clear', () => { - usePromptExperimentDecision.mockReturnValue([{ - enabled: true, - variationKey: OPTIMIZELY_PROMPT_EXPERIMENT_VARIATION_KEYS.UPDATED_PROMPT, - }]); - - render(undefined, { - ...defaultState, - disclosureAcknowledged: true, - }); - - act(() => { - screen.queryByTestId('sidebar-clear-btn').click(); - }); - - expect(mockDispatch).toHaveBeenCalledWith(clearMessagesAction); - expect(sendTrackEvent).toHaveBeenCalledWith('edx.ui.lms.learning_assistant.clear', { - course_id: defaultProps.courseId, - experiment_name: OPTIMIZELY_PROMPT_EXPERIMENT_KEY, - variation_key: OPTIMIZELY_PROMPT_EXPERIMENT_VARIATION_KEYS.UPDATED_PROMPT, - }); - }); }); }); diff --git a/src/data/slice.js b/src/data/slice.js index 29dbd402..ffc981af 100644 --- a/src/data/slice.js +++ b/src/data/slice.js @@ -26,11 +26,6 @@ export const learningAssistantSlice = createSlice({ setMessageList: (state, { payload }) => { state.messageList = payload.messageList; }, - resetMessages: (state) => { - state.currentMessage = ''; - state.messageList = []; - state.apiError = false; - }, setApiError: (state) => { state.apiError = true; }, @@ -56,7 +51,6 @@ export const { setCurrentMessage, clearCurrentMessage, setMessageList, - resetMessages, setApiError, setApiIsLoading, resetApiError, diff --git a/src/data/thunks.js b/src/data/thunks.js index 891c0f4d..13c64e51 100644 --- a/src/data/thunks.js +++ b/src/data/thunks.js @@ -6,7 +6,6 @@ import { fetchChatResponse, fetchLearningAssistantMessageHistory, fetchLearningA import { setCurrentMessage, clearCurrentMessage, - resetMessages, setMessageList, setApiError, setApiIsLoading, @@ -74,13 +73,6 @@ export function getChatResponse(courseId, unitId, promptExperimentVariationKey = }; } -export function clearMessages() { - return (dispatch) => { - dispatch(resetMessages()); - dispatch(resetApiError()); - }; -} - export function getLearningAssistantMessageHistory(courseId) { return async (dispatch) => { dispatch(setApiIsLoading(true)); diff --git a/src/widgets/Xpert.test.jsx b/src/widgets/Xpert.test.jsx index ec6bef04..532669f3 100644 --- a/src/widgets/Xpert.test.jsx +++ b/src/widgets/Xpert.test.jsx @@ -44,7 +44,6 @@ const assertSidebarElementsNotInDOM = () => { expect(screen.queryByRole('button', { name: 'submit' })).not.toBeInTheDocument(); expect(screen.queryByTestId('close-button')).not.toBeInTheDocument(); - expect(screen.queryByRole('button', { name: 'clear' })).not.toBeInTheDocument(); }; beforeEach(() => { @@ -115,7 +114,6 @@ test('clicking the call to action opens the sidebar', async () => { expect(screen.getByRole('textbox')).toBeVisible(); expect(screen.getByRole('button', { name: 'submit' })).toBeVisible(); expect(screen.getByTestId('close-button')).toBeVisible(); - expect(screen.getByRole('button', { name: 'clear' })).toBeVisible(); // assert that text input has focus expect(screen.getByRole('textbox')).toHaveFocus(); @@ -135,7 +133,6 @@ test('clicking the toggle button opens the sidebar', async () => { expect(screen.getByRole('textbox')).toBeVisible(); expect(screen.getByRole('button', { name: 'submit' })).toBeVisible(); expect(screen.getByTestId('close-button')).toBeVisible(); - expect(screen.getByRole('button', { name: 'clear' })).toBeVisible(); // assert that text input has focus expect(screen.getByRole('textbox')).toHaveFocus(); @@ -190,34 +187,6 @@ test('response text appears as message in the sidebar', async () => { await screen.findByText(responseMessage.content); expect(screen.getByText(responseMessage.content)).toBeInTheDocument(); }); -test('clicking the clear button clears messages in the sidebar', async () => { - const user = userEvent.setup(); - const userMessage = 'Hello, Xpert!'; - - // re-mock the fetchChatResponse API function so that we can assert that the - // responseMessage appears in the DOM and then is successfully cleared - const responseMessage = createRandomResponseForTesting(); - jest.spyOn(api, 'fetchChatResponse').mockImplementation(() => responseMessage); - - render(, { preloadedState: initialState }); - - // wait for button to appear - await screen.findByTestId('toggle-button'); - - await user.click(screen.queryByTestId('toggle-button')); - - // type the user message - const input = screen.getByRole('textbox'); - await user.type(input, userMessage); - await user.click(screen.getByRole('button', { name: 'submit' })); - - await screen.findByText(responseMessage.content); - - await user.click(screen.getByRole('button', { name: 'clear' })); - - expect(screen.queryByText(userMessage)).not.toBeInTheDocument(); - expect(screen.queryByText(responseMessage.content)).not.toBeInTheDocument(); -}); test('clicking the close button closes the sidebar', async () => { const user = userEvent.setup(); render(, { preloadedState: initialState }); @@ -307,35 +276,6 @@ test('error message should disappear when dismissed', async () => { await user.click(screen.getByText('Dismiss')); expect(screen.queryByText('Please try again by sending another question.')).not.toBeInTheDocument(); }); -test('error message should disappear when messages cleared', async () => { - const user = userEvent.setup(); - - const errorState = { - learningAssistant: { - currentMessage: '', - messageList: [], - apiIsLoading: false, - apiError: true, - // TEMPORARY: This is simply to ensure that the tests pass by hiding the disclosure. - // I will remove this and write tests in a future pull request. - disclosureAcknowledged: true, - sidebarIsOpen: false, - }, - }; - render(, { preloadedState: errorState }); - - // wait for button to appear - await screen.findByTestId('toggle-button'); - - await user.click(screen.queryByTestId('toggle-button')); - - // assert that error message exists - expect(screen.queryByText('Please try again by sending another question.')).toBeInTheDocument(); - - // clear messages, assert that error message disappears - await user.click(screen.getByText('Clear')); - expect(screen.queryByText('Please try again by sending another question.')).not.toBeInTheDocument(); -}); test('popup modal should open chat', async () => { const user = userEvent.setup(); window.localStorage.clear(); @@ -357,7 +297,6 @@ test('popup modal should open chat', async () => { expect(screen.getByRole('textbox')).toBeVisible(); expect(screen.getByRole('button', { name: 'submit' })).toBeVisible(); expect(screen.getByTestId('close-button')).toBeVisible(); - expect(screen.getByRole('button', { name: 'clear' })).toBeVisible(); }); test('popup modal should close and display CTA', async () => { const user = userEvent.setup();