import { render, screen } from '@testing-library/react' import { beforeEach, describe, expect, test } from 'vitest' import { WidgetNoData } from './no-data' import { useWidgetStore } from '../stores/widget-store' describe('WidgetNoData', () => { const widgetId = 'test-no-data-widget' beforeEach(() => { useWidgetStore.getState().clearWidgets() }) describe('when sourceData is empty', () => { test('renders NoData UI with empty array', () => { useWidgetStore.getState().setWidget(widgetId, { isLoading: false, isFetching: false, sourceData: [], }) render(
Widget Content
, ) expect(screen.getByText('No data available')).toBeTruthy() expect( screen.getByText(/There are no results for the combination of filters/), ).toBeTruthy() expect(screen.queryByText('Widget Content')).toBeNull() }) test('renders NoData UI with null sourceData', () => { useWidgetStore.getState().setWidget(widgetId, { isLoading: false, isFetching: false, sourceData: null, }) render(
Widget Content
, ) expect(screen.getByText('No data available')).toBeTruthy() expect(screen.queryByText('Widget Content')).toBeNull() }) test('renders NoData UI with undefined sourceData', () => { useWidgetStore.getState().setWidget(widgetId, { isLoading: false, isFetching: false, sourceData: undefined, }) render(
Widget Content
, ) expect(screen.getByText('No data available')).toBeTruthy() expect(screen.queryByText('Widget Content')).toBeNull() }) test('renders NoData UI with array of empty arrays (CategoryWidget pattern)', () => { useWidgetStore.getState().setWidget(widgetId, { isLoading: false, isFetching: false, sourceData: [[], []], }) render(
Widget Content
, ) expect(screen.getByText('No data available')).toBeTruthy() expect(screen.queryByText('Widget Content')).toBeNull() }) test('renders NoData UI with empty object', () => { useWidgetStore.getState().setWidget(widgetId, { isLoading: false, isFetching: false, sourceData: {}, }) render(
Widget Content
, ) expect(screen.getByText('No data available')).toBeTruthy() expect(screen.queryByText('Widget Content')).toBeNull() }) }) describe('when sourceData exists', () => { test('renders children with array sourceData', () => { useWidgetStore.getState().setWidget(widgetId, { isLoading: false, isFetching: false, sourceData: [{ value: 1 }], }) render(
Widget Content
, ) expect(screen.getByText('Widget Content')).toBeTruthy() expect(screen.queryByText('No data available')).toBeNull() }) test('renders children with object sourceData', () => { useWidgetStore.getState().setWidget(widgetId, { isLoading: false, isFetching: false, sourceData: { content: 'Hello' }, }) render(
Widget Content
, ) expect(screen.getByText('Widget Content')).toBeTruthy() expect(screen.queryByText('No data available')).toBeNull() }) test('renders children with nested array sourceData', () => { useWidgetStore.getState().setWidget(widgetId, { isLoading: false, isFetching: false, sourceData: [[{ name: 'A', value: 1 }]], }) render(
Widget Content
, ) expect(screen.getByText('Widget Content')).toBeTruthy() expect(screen.queryByText('No data available')).toBeNull() }) test('renders children with primitive sourceData (number)', () => { useWidgetStore.getState().setWidget(widgetId, { isLoading: false, isFetching: false, sourceData: 0, }) render(
Widget Content
, ) expect(screen.getByText('Widget Content')).toBeTruthy() expect(screen.queryByText('No data available')).toBeNull() }) test('renders children with primitive sourceData (string)', () => { useWidgetStore.getState().setWidget(widgetId, { isLoading: false, isFetching: false, sourceData: 'test', }) render(
Widget Content
, ) expect(screen.getByText('Widget Content')).toBeTruthy() expect(screen.queryByText('No data available')).toBeNull() }) test('renders children with primitive sourceData (boolean)', () => { useWidgetStore.getState().setWidget(widgetId, { isLoading: false, isFetching: false, sourceData: false, }) render(
Widget Content
, ) expect(screen.getByText('Widget Content')).toBeTruthy() expect(screen.queryByText('No data available')).toBeNull() }) }) describe('when loading or fetching', () => { test('renders children when isLoading=true even if sourceData is empty', () => { useWidgetStore.getState().setWidget(widgetId, { isLoading: true, isFetching: false, }) render(
Widget Content
, ) expect(screen.getByText('Widget Content')).toBeTruthy() expect(screen.queryByText('No data available')).toBeNull() }) test('renders children when isFetching=true even if sourceData is empty', () => { useWidgetStore.getState().setWidget(widgetId, { isLoading: false, isFetching: true, }) render(
Widget Content
, ) expect(screen.getByText('Widget Content')).toBeTruthy() expect(screen.queryByText('No data available')).toBeNull() }) test('renders children when both isLoading and isFetching are true', () => { useWidgetStore.getState().setWidget(widgetId, { isLoading: true, isFetching: true, }) render(
Widget Content
, ) expect(screen.getByText('Widget Content')).toBeTruthy() expect(screen.queryByText('No data available')).toBeNull() }) }) describe('customization', () => { test('renders custom title', () => { useWidgetStore.getState().setWidget(widgetId, { isLoading: false, isFetching: false, sourceData: [], }) render(
Widget Content
, ) expect(screen.getByText('No results found')).toBeTruthy() expect(screen.queryByText('No data available')).toBeNull() }) test('renders custom description', () => { useWidgetStore.getState().setWidget(widgetId, { isLoading: false, isFetching: false, sourceData: [], }) render(
Widget Content
, ) expect(screen.getByText('Try adjusting your filters')).toBeTruthy() expect( screen.queryByText(/There are no results for the combination/), ).toBeNull() }) test('uses custom isEmpty function', () => { useWidgetStore.getState().setWidget(widgetId, { isLoading: false, isFetching: false, sourceData: { customField: 'value' }, }) // Custom isEmpty that treats this sourceData as empty const customIsEmpty = (data: unknown) => { const d = data as { customField: string } return d?.customField === 'value' } render(
Widget Content
, ) expect(screen.getByText('No data available')).toBeTruthy() expect(screen.queryByText('Widget Content')).toBeNull() }) test('custom isEmpty returning false renders children', () => { useWidgetStore.getState().setWidget(widgetId, { isLoading: false, isFetching: false, sourceData: [], }) // Custom isEmpty that treats empty array as having data const customIsEmpty = () => false render(
Widget Content
, ) expect(screen.getByText('Widget Content')).toBeTruthy() expect(screen.queryByText('No data available')).toBeNull() }) }) describe('when widget does not exist in store', () => { test('treats as empty and shows NoData UI', () => { // Widget not initialized in store render(
Widget Content
, ) expect(screen.getByText('No data available')).toBeTruthy() expect(screen.queryByText('Widget Content')).toBeNull() }) }) describe('sourceData vs pipeline-transformed data', () => { test('renders children when sourceData has data but pipeline data is empty', () => { useWidgetStore.getState().setWidget(widgetId, { isLoading: false, isFetching: false, sourceData: [{ value: 1 }, { value: 2 }], data: [], // pipeline filtered everything out }) render(
Widget Content
, ) // Should show children because sourceData is not empty expect(screen.getByText('Widget Content')).toBeTruthy() expect(screen.queryByText('No data available')).toBeNull() }) test('renders NoData when both sourceData and data are empty', () => { useWidgetStore.getState().setWidget(widgetId, { isLoading: false, isFetching: false, sourceData: [], }) render(
Widget Content
, ) expect(screen.getByText('No data available')).toBeTruthy() expect(screen.queryByText('Widget Content')).toBeNull() }) test('renders NoData when sourceData is null (API returned nothing)', () => { useWidgetStore.getState().setWidget(widgetId, { isLoading: false, isFetching: false, sourceData: null, }) render(
Widget Content
, ) expect(screen.getByText('No data available')).toBeTruthy() expect(screen.queryByText('Widget Content')).toBeNull() }) }) describe('reactivity to store changes', () => { test('updates from NoData to content when sourceData arrives', () => { useWidgetStore.getState().setWidget(widgetId, { isLoading: false, isFetching: false, }) const { rerender } = render(
Widget Content
, ) expect(screen.getByText('No data available')).toBeTruthy() expect(screen.queryByText('Widget Content')).toBeNull() // Update with sourceData useWidgetStore.getState().setWidget(widgetId, { sourceData: [{ value: 1 }], }) // Force rerender to pick up store changes rerender(
Widget Content
, ) expect(screen.getByText('Widget Content')).toBeTruthy() expect(screen.queryByText('No data available')).toBeNull() }) test('updates from content to NoData when sourceData becomes empty', () => { useWidgetStore.getState().setWidget(widgetId, { isLoading: false, isFetching: false, sourceData: [{ value: 1 }], }) const { rerender } = render(
Widget Content
, ) expect(screen.getByText('Widget Content')).toBeTruthy() expect(screen.queryByText('No data available')).toBeNull() // Clear sourceData useWidgetStore.getState().setWidget(widgetId, { sourceData: [] }) // Force rerender to pick up store changes rerender(
Widget Content
, ) expect(screen.getByText('No data available')).toBeTruthy() expect(screen.queryByText('Widget Content')).toBeNull() }) test('updates from NoData to content when loading starts', () => { useWidgetStore.getState().setWidget(widgetId, { isLoading: false, isFetching: false, }) const { rerender } = render(
Widget Content
, ) expect(screen.getByText('No data available')).toBeTruthy() // Start loading useWidgetStore.getState().setWidget(widgetId, { isLoading: true }) // Force rerender to pick up store changes rerender(
Widget Content
, ) expect(screen.getByText('Widget Content')).toBeTruthy() expect(screen.queryByText('No data available')).toBeNull() }) }) })