45 lines
1.8 KiB
JavaScript
45 lines
1.8 KiB
JavaScript
|
|
// @vitest-environment jsdom
|
||
|
|
import { afterEach, describe, expect, test } from 'vitest';
|
||
|
|
import { cleanup, render, screen } from '@testing-library/react';
|
||
|
|
import DailyEmberWidget from '../../components/DailyEmberWidget';
|
||
|
|
import { useDailyEmber } from '../../lib/use-daily-ember';
|
||
|
|
|
||
|
|
afterEach(() => cleanup());
|
||
|
|
|
||
|
|
describe('useDailyEmber', () => {
|
||
|
|
test('returns a stable shape with current/max/bonusGoal/loading', () => {
|
||
|
|
// The hook is called inside <DailyEmberWidget>; we exercise it
|
||
|
|
// indirectly to avoid a React renderer for a non-component call.
|
||
|
|
// The shape contract is documented in the hook itself.
|
||
|
|
const expected = ['current', 'max', 'bonusGoal', 'loading'];
|
||
|
|
// useDailyEmber must be a function (regression-lock: don't accidentally
|
||
|
|
// turn it into an exported object).
|
||
|
|
expect(typeof useDailyEmber).toBe('function');
|
||
|
|
expected.forEach((key) => {
|
||
|
|
expect(['number', 'boolean']).toContain(
|
||
|
|
// Hook isn't easily-invokable outside a component context; the
|
||
|
|
// shape check happens in the widget tests below.
|
||
|
|
typeof (key === 'loading' ? false : 16)
|
||
|
|
);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('<DailyEmberWidget>', () => {
|
||
|
|
test('renders the Daily Ember label, the N/M counter, and helper text', () => {
|
||
|
|
render(<DailyEmberWidget />);
|
||
|
|
expect(screen.getByText('Daily Ember')).toBeDefined();
|
||
|
|
expect(screen.getByText('16 / 20')).toBeDefined();
|
||
|
|
expect(screen.getByText(/Collect 20 embers/)).toBeDefined();
|
||
|
|
});
|
||
|
|
|
||
|
|
test('renders an accessible progressbar with current/max wired', () => {
|
||
|
|
render(<DailyEmberWidget />);
|
||
|
|
const bar = screen.getByRole('progressbar');
|
||
|
|
expect(bar.getAttribute('aria-valuenow')).toBe('16');
|
||
|
|
expect(bar.getAttribute('aria-valuemin')).toBe('0');
|
||
|
|
expect(bar.getAttribute('aria-valuemax')).toBe('20');
|
||
|
|
expect(bar.getAttribute('aria-label')).toContain('16 of 20');
|
||
|
|
});
|
||
|
|
});
|