diff --git a/web/app/components/base/audio-gallery/index.spec.tsx b/web/app/components/base/audio-gallery/index.spec.tsx new file mode 100644 index 0000000000..9039d4995c --- /dev/null +++ b/web/app/components/base/audio-gallery/index.spec.tsx @@ -0,0 +1,49 @@ +import { render, screen } from '@testing-library/react' +import * as React from 'react' +// AudioGallery.spec.tsx +import { describe, expect, it, vi } from 'vitest' + +import AudioGallery from './index' + +// Mock AudioPlayer so we only assert prop forwarding +const audioPlayerMock = vi.fn() + +vi.mock('./AudioPlayer', () => ({ + default: (props: { srcs: string[] }) => { + audioPlayerMock(props) + return
+ }, +})) + +describe('AudioGallery', () => { + afterEach(() => { + audioPlayerMock.mockClear() + vi.resetModules() + }) + + it('returns null when srcs array is empty', () => { + const { container } = render(
+
+
+ Caption Text
+
+
+ {children}
+ return{children}
} diff --git a/web/app/components/base/markdown-blocks/pre-code.spec.tsx b/web/app/components/base/markdown-blocks/pre-code.spec.tsx new file mode 100644 index 0000000000..a3cc234e8f --- /dev/null +++ b/web/app/components/base/markdown-blocks/pre-code.spec.tsx @@ -0,0 +1,61 @@ +import { render, screen } from '@testing-library/react' +import * as React from 'react' +import { describe, expect, it } from 'vitest' +import PreCode from './pre-code' + +describe('PreCode Component', () => { + it('renders children correctly inside the pre tag', () => { + const { container } = render( +console.log("hello world")
+ test content
+ element', () => {
+ const { container } = render(Content )
+ expect(container.querySelector('pre')).toBeInTheDocument()
+ })
+
+ it('handles multiple children correctly', () => {
+ render(
+
+ Line 1
+ Line 2
+ ,
+ )
+
+ expect(screen.getByText('Line 1')).toBeInTheDocument()
+ expect(screen.getByText('Line 2')).toBeInTheDocument()
+ })
+
+ it('correctly instantiates the pre element node', () => {
+ const { container } = render(Ref check )
+ const pre = container.querySelector('pre')
+
+ // Verifies the node is an actual HTMLPreElement,
+ // confirming the ref-linked element rendered correctly.
+ expect(pre).toBeInstanceOf(HTMLPreElement)
+ })
+})
diff --git a/web/app/components/base/radio-card/index.spec.tsx b/web/app/components/base/radio-card/index.spec.tsx
new file mode 100644
index 0000000000..f1368476bf
--- /dev/null
+++ b/web/app/components/base/radio-card/index.spec.tsx
@@ -0,0 +1,137 @@
+import { render, screen } from '@testing-library/react'
+import userEvent from '@testing-library/user-event'
+// index.spec.tsx
+import { describe, expect, it, vi } from 'vitest'
+import RadioCard from './index'
+
+describe('RadioCard', () => {
+ it('renders icon, title and description', () => {
+ render(
+ ICON}
+ title="Card Title"
+ description="Some description"
+ />,
+ )
+
+ expect(screen.getByTestId('icon')).toBeInTheDocument()
+ expect(screen.getByText('Card Title')).toBeInTheDocument()
+ expect(screen.getByText('Some description')).toBeInTheDocument()
+ })
+
+ it('calls onChosen when clicked', async () => {
+ const user = userEvent.setup()
+ const onChosen = vi.fn()
+
+ render(
+ i}
+ title="Clickable"
+ description="desc"
+ onChosen={onChosen}
+ />,
+ )
+
+ await user.click(screen.getByText('Clickable'))
+ expect(onChosen).toHaveBeenCalledTimes(1)
+ })
+
+ it('hides radio element when noRadio is true and still shows chosen-config area (wrapper)', () => {
+ const { container } = render(
+ i}
+ title="No Radio"
+ description="desc"
+ noRadio
+ />,
+ )
+
+ const radioWrapper = container.querySelector('.absolute.right-3.top-3')
+ expect(radioWrapper).toBeNull()
+
+ // chosen-config area should appear because noRadio true triggers the block
+ const chosenArea = container.querySelector('.mt-2')
+ expect(chosenArea).toBeTruthy()
+ })
+
+ it('shows radio checked styles when isChosen and shows chosenConfig', () => {
+ const { container } = render(
+ i}
+ title="Chosen"
+ description="desc"
+ isChosen
+ chosenConfig={config}
+ />,
+ )
+
+ // radio absolute wrapper exists
+ const radioWrapper = container.querySelector('.absolute.right-3.top-3')
+ expect(radioWrapper).toBeTruthy()
+
+ // inner circle div should have checked fragment in class list
+ const inner = radioWrapper?.querySelector('div')
+ expect(inner).toBeTruthy()
+ expect(inner?.className).toContain('border-components-radio-border-checked')
+
+ // chosenConfig rendered
+ expect(screen.getByTestId('chosen-config')).toBeInTheDocument()
+ })
+
+ it('applies custom className to root and merges chosenConfigWrapClassName', () => {
+ const { container } = render(
+ i}
+ title="Custom"
+ description="desc"
+ className="my-root-class"
+ isChosen
+ chosenConfig={cfg}
+ chosenConfigWrapClassName="my-config-wrap"
+ />,
+ )
+
+ const root = container.firstChild as HTMLElement
+ expect(root).toBeTruthy()
+ expect(root.className).toContain('my-root-class')
+ expect(root.className).toContain('border-[1.5px]')
+ expect(root.className).toContain('bg-components-option-card-option-selected-bg')
+
+ const chosenWrap = container.querySelector('.mt-2 .my-config-wrap')
+ expect(chosenWrap).toBeTruthy()
+ expect(chosenWrap?.textContent).toBe('cfg')
+ })
+
+ it('does not render radio when noRadio true and still allows clicking on whole card', async () => {
+ const user = userEvent.setup()
+ const onChosen = vi.fn()
+
+ const { container } = render(
+ i}
+ title="ClickNoRadio"
+ description="desc"
+ noRadio
+ onChosen={onChosen}
+ />,
+ )
+
+ // click title should trigger onChosen
+ await user.click(screen.getByText('ClickNoRadio'))
+ expect(onChosen).toHaveBeenCalledTimes(1)
+
+ // radio area should be absent
+ expect(container.querySelector('.absolute.right-3.top-3')).toBeNull()
+ })
+
+ it('memo export renders correctly', () => {
+ render(
+ i}
+ title="Memo"
+ description="desc"
+ />,
+ )
+ expect(screen.getByText('Memo')).toBeInTheDocument()
+ })
+})
diff --git a/web/app/components/base/radio-card/simple/index.spec.tsx b/web/app/components/base/radio-card/simple/index.spec.tsx
new file mode 100644
index 0000000000..42e03484e8
--- /dev/null
+++ b/web/app/components/base/radio-card/simple/index.spec.tsx
@@ -0,0 +1,137 @@
+import { render, screen } from '@testing-library/react'
+import userEvent from '@testing-library/user-event'
+// index.spec.tsx
+import { describe, expect, it, vi } from 'vitest'
+import RadioCard from './index'
+
+describe('RadioCard', () => {
+ it('renders title and description', () => {
+ render(
+ ,
+ )
+
+ expect(screen.getByText('Card Title')).toBeInTheDocument()
+ expect(screen.getByText('Card Description')).toBeInTheDocument()
+ })
+
+ it('renders JSX title correctly', () => {
+ render(
+ JSX Title}
+ description="Desc"
+ isChosen={false}
+ onChosen={vi.fn()}
+ />,
+ )
+
+ expect(screen.getByTestId('jsx-title')).toBeInTheDocument()
+ })
+
+ it('renders icon when provided', () => {
+ render(
+ ICON}
+ />,
+ )
+
+ expect(screen.getByTestId('icon')).toBeInTheDocument()
+ })
+
+ it('renders extra content when provided', () => {
+ render(
+ Extra Content