import { render, screen } from '@testing-library/react'
import { beforeEach, describe, expect, test } from 'vitest'
import { WidgetError } from './error'
import { useWidgetStore } from '../stores/widget-store'
describe('WidgetError', () => {
const widgetId = 'test-error-widget'
beforeEach(() => {
useWidgetStore.getState().clearWidgets()
})
describe('when error exists', () => {
test('renders Error UI with default title and message when error is empty object', () => {
useWidgetStore.getState().setWidget(widgetId, {
isLoading: false,
isFetching: false,
error: {},
})
render(
Widget Content
,
)
expect(screen.getByText('Error')).toBeTruthy()
expect(
screen.getByText(
'An error occurred while loading the widget. Please try again.',
),
).toBeTruthy()
expect(screen.queryByText('Widget Content')).toBeNull()
})
test('renders custom title with default message', () => {
useWidgetStore.getState().setWidget(widgetId, {
isLoading: false,
isFetching: false,
error: { title: 'Database Connection Failed' },
})
render(
Widget Content
,
)
expect(screen.getByText('Database Connection Failed')).toBeTruthy()
expect(
screen.getByText(
'An error occurred while loading the widget. Please try again.',
),
).toBeTruthy()
expect(screen.queryByText('Widget Content')).toBeNull()
})
test('renders default title with custom message', () => {
useWidgetStore.getState().setWidget(widgetId, {
isLoading: false,
isFetching: false,
error: { message: 'The server returned a 500 error.' },
})
render(
Widget Content
,
)
expect(screen.getByText('Error')).toBeTruthy()
expect(screen.getByText('The server returned a 500 error.')).toBeTruthy()
expect(screen.queryByText('Widget Content')).toBeNull()
})
test('renders both custom title and message', () => {
useWidgetStore.getState().setWidget(widgetId, {
isLoading: false,
isFetching: false,
error: {
title: 'Network Error',
message:
'Unable to connect to the API. Check your internet connection.',
},
})
render(
Widget Content
,
)
expect(screen.getByText('Network Error')).toBeTruthy()
expect(
screen.getByText(
'Unable to connect to the API. Check your internet connection.',
),
).toBeTruthy()
expect(screen.queryByText('Widget Content')).toBeNull()
})
test('uses defaults when title and message are empty strings', () => {
useWidgetStore.getState().setWidget(widgetId, {
isLoading: false,
isFetching: false,
error: {
title: 'Error',
message:
'An error occurred while loading the widget. Please try again.',
},
})
render(
Widget Content
,
)
expect(screen.getByText('Error')).toBeTruthy()
expect(
screen.getByText(
'An error occurred while loading the widget. Please try again.',
),
).toBeTruthy()
expect(screen.queryByText('Widget Content')).toBeNull()
})
})
describe('when no error exists', () => {
test('renders children when error is undefined', () => {
useWidgetStore.getState().setWidget(widgetId, {
isLoading: false,
isFetching: false,
error: undefined,
})
render(
Widget Content
,
)
expect(screen.getByText('Widget Content')).toBeTruthy()
expect(screen.queryByText('Error')).toBeNull()
})
test('renders children when widget has no error property', () => {
useWidgetStore.getState().setWidget(widgetId, {
isLoading: false,
isFetching: false,
})
render(
Widget Content
,
)
expect(screen.getByText('Widget Content')).toBeTruthy()
expect(screen.queryByText('Error')).toBeNull()
})
})
describe('loading states', () => {
test('renders children when isLoading is true, even with error', () => {
useWidgetStore.getState().setWidget(widgetId, {
isLoading: true,
isFetching: false,
error: { title: 'Some error' },
})
render(
Widget Content
,
)
expect(screen.getByText('Widget Content')).toBeTruthy()
expect(screen.queryByText('Error')).toBeNull()
})
test('renders children when isFetching is true, even with error', () => {
useWidgetStore.getState().setWidget(widgetId, {
isLoading: false,
isFetching: true,
error: { title: 'Some error' },
})
render(
Widget Content
,
)
expect(screen.getByText('Widget Content')).toBeTruthy()
expect(screen.queryByText('Error')).toBeNull()
})
test('renders children when both isLoading and isFetching are true, even with error', () => {
useWidgetStore.getState().setWidget(widgetId, {
isLoading: true,
isFetching: true,
error: { title: 'Some error' },
})
render(
Widget Content
,
)
expect(screen.getByText('Widget Content')).toBeTruthy()
expect(screen.queryByText('Error')).toBeNull()
})
})
describe('reactivity', () => {
test('updates when error appears', () => {
useWidgetStore.getState().setWidget(widgetId, {
isLoading: false,
isFetching: false,
error: undefined,
})
const { rerender } = render(
Widget Content
,
)
expect(screen.getByText('Widget Content')).toBeTruthy()
// Add error
useWidgetStore.getState().setWidget(widgetId, {
isLoading: false,
isFetching: false,
error: { title: 'Failed to load' },
})
rerender(
Widget Content
,
)
expect(screen.getByText('Failed to load')).toBeTruthy()
expect(screen.queryByText('Widget Content')).toBeNull()
})
test('updates when error clears', () => {
useWidgetStore.getState().setWidget(widgetId, {
isLoading: false,
isFetching: false,
error: { title: 'Failed to load' },
})
const { rerender } = render(
Widget Content
,
)
expect(screen.getByText('Failed to load')).toBeTruthy()
// Clear error
useWidgetStore.getState().setWidget(widgetId, {
isLoading: false,
isFetching: false,
error: undefined,
})
rerender(
Widget Content
,
)
expect(screen.getByText('Widget Content')).toBeTruthy()
expect(screen.queryByText('Failed to load')).toBeNull()
})
test('transitions from loading to error to success', () => {
// Start loading
useWidgetStore.getState().setWidget(widgetId, {
isLoading: true,
isFetching: false,
error: undefined,
})
const { rerender } = render(
Widget Content
,
)
expect(screen.getByText('Widget Content')).toBeTruthy()
// Error occurs
useWidgetStore.getState().setWidget(widgetId, {
isLoading: false,
isFetching: false,
error: { title: 'Network error' },
})
rerender(
Widget Content
,
)
expect(screen.getByText('Network error')).toBeTruthy()
expect(screen.queryByText('Widget Content')).toBeNull()
// Error clears on retry
useWidgetStore.getState().setWidget(widgetId, {
isLoading: false,
isFetching: false,
error: undefined,
})
rerender(
Widget Content
,
)
expect(screen.getByText('Widget Content')).toBeTruthy()
expect(screen.queryByText('Network error')).toBeNull()
})
})
})