Skip to content

Commit

Permalink
3029: Fix cyclomatic dependency warning
Browse files Browse the repository at this point in the history
  • Loading branch information
steffenkleinle committed Feb 12, 2025
1 parent 538f9bb commit 30e7f1e
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 22 deletions.
44 changes: 23 additions & 21 deletions web/src/components/ChatConversation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ type ChatConversationProps = {
className?: string
}

const TYPING_INDICATOR_TIMEOUT = 60000
export const TYPING_INDICATOR_TIMEOUT = 60000

const ChatConversation = ({ messages, hasError, className }: ChatConversationProps): ReactElement => {
const { t } = useTranslation('chat')
Expand Down Expand Up @@ -64,32 +64,34 @@ const ChatConversation = ({ messages, hasError, className }: ChatConversationPro
return () => undefined
}, [waitingForAnswer])

return (
<Container className={className}>
{messages.length > 0 ? (
<>
{!hasError && <InitialMessage>{t('initialMessage')}</InitialMessage>}
{messages.map((message, index) => (
<ChatMessage
message={message}
key={message.id}
showIcon={messages[index - 1]?.userIsAuthor !== message.userIsAuthor}
/>
))}
{typingIndicatorVisible && (
<TypingIndicator>
<strong>...</strong>
</TypingIndicator>
)}
<div ref={messagesEndRef} />
</>
) : (
if (messages.length === 0) {
return (
<Container className={className}>
<div>
<b>{t('conversationTitle')}</b>
<br />
{t('conversationText')}
</div>
</Container>
)
}

return (
<Container className={className}>
{!hasError && <InitialMessage>{t('initialMessage')}</InitialMessage>}
{messages.map((message, index) => (
<ChatMessage
message={message}
key={message.id}
showIcon={messages[index - 1]?.userIsAuthor !== message.userIsAuthor}
/>
))}
{typingIndicatorVisible && (
<TypingIndicator>
<strong>...</strong>
</TypingIndicator>
)}
<div ref={messagesEndRef} />

Check warning on line 94 in web/src/components/ChatConversation.tsx

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

❌ New issue: Complex Method

ChatConversation has a cyclomatic complexity of 11, threshold = 10. This function has many conditional statements (e.g. if, for, while), leading to lower code health. Avoid adding more conditionals and code to it without refactoring.
{hasError && <ErrorSendingStatus role='alert'>{t('errorMessage')}</ErrorSendingStatus>}
</Container>
)
Expand Down
38 changes: 37 additions & 1 deletion web/src/components/__tests__/ChatConversation.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { act } from '@testing-library/react'
import React from 'react'

import ChatMessageModel from 'shared/api/models/ChatMessageModel'

import { renderWithRouterAndTheme } from '../../testing/render'
import ChatConversation from '../ChatConversation'
import ChatConversation, { TYPING_INDICATOR_TIMEOUT } from '../ChatConversation'

jest.mock('react-i18next')
window.HTMLElement.prototype.scrollIntoView = jest.fn()
jest.useFakeTimers()

const render = (messages: ChatMessageModel[], hasError: boolean) =>
renderWithRouterAndTheme(<ChatConversation messages={messages} hasError={hasError} />)
Expand All @@ -21,10 +23,22 @@ describe('ChatConversation', () => {
}),
new ChatMessageModel({
id: 2,
body: 'Willkommen in der Integreat Chat Testumgebung auf Deutsch. Unser Team antwortet werktags, während unser Chatbot zusammenfassende Antworten aus verlinkten Artikeln liefert, die Sie zur Überprüfung wichtiger Informationen lesen sollten.',
userIsAuthor: false,
automaticAnswer: true,
}),
new ChatMessageModel({
id: 3,
body: 'Informationen zu Ihrer Frage finden Sie auf folgenden Seiten:',
userIsAuthor: false,
automaticAnswer: false,
}),
new ChatMessageModel({
id: 4,
body: 'Wie kann ich mein Deutsch verbessern?',
userIsAuthor: true,
automaticAnswer: false,
}),
]

it('should display welcome text if conversation has not started', () => {
Expand All @@ -37,7 +51,29 @@ describe('ChatConversation', () => {
const { getByText, getByTestId } = render(testMessages, false)
expect(getByText('chat:initialMessage')).toBeTruthy()
expect(getByTestId(testMessages[0]!.id)).toBeTruthy()
expect(getByTestId(testMessages[2]!.id)).toBeTruthy()
})

it('should display typing indicator before the initial automatic answer and after for 60 seconds', () => {
const { getByText, queryByText, getByTestId } = render(testMessages, false)
expect(getByTestId(testMessages[0]!.id)).toBeTruthy()
expect(getByText('...')).toBeTruthy()
expect(getByTestId(testMessages[1]!.id)).toBeTruthy()
expect(getByText('...')).toBeTruthy()

act(() => {
jest.advanceTimersByTime(TYPING_INDICATOR_TIMEOUT)
})
expect(queryByText('...')).toBeNull()
})

it('should display typing indicator after opening the chatbot with existing conversation for unanswered user message', () => {
const { queryByText, getByTestId } = render(testMessages, false)
expect(getByTestId(testMessages[3]!.id)).toBeTruthy()
act(() => {
jest.advanceTimersByTime(TYPING_INDICATOR_TIMEOUT)
})
expect(queryByText('...')).toBeNull()
})

it('should display error messages if error occurs', () => {
Expand Down

0 comments on commit 30e7f1e

Please sign in to comment.