/**
* @jest-environment jsdom
*
* Daily-templates sidebar panel tests.
*/
const { renderDailyTemplatesPanel } = require('../src/sidebar/daily-templates-panel');
function mountPanel(deps = {}) {
const container = document.createElement('div');
document.body.appendChild(container);
const api = renderDailyTemplatesPanel(container, {
listTemplates: deps.listTemplates || jest.fn().mockResolvedValue([]),
saveTemplate: deps.saveTemplate || jest.fn().mockResolvedValue({ name: 'x.md', label: 'X', content: '' }),
deleteTemplate: deps.deleteTemplate || jest.fn().mockResolvedValue(true),
applyTemplate: deps.applyTemplate || jest.fn().mockResolvedValue({ path: '/d/2026-09-14.md', content: '', created: true }),
onOpenFile: deps.onOpenFile || jest.fn(),
...deps,
});
return { container, api };
}
async function flush() {
for (let i = 0; i < 5; i++) await Promise.resolve();
}
describe('renderDailyTemplatesPanel — mounting', () => {
test('mounts the panel structure', () => {
const { container } = mountPanel();
expect(container.querySelector('.daily-templates-panel')).not.toBeNull();
expect(container.querySelector('#daily-templates-new')).not.toBeNull();
expect(container.querySelector('#daily-templates-refresh')).not.toBeNull();
});
test('shows the empty state when there are no templates', async () => {
const { container } = mountPanel({ listTemplates: jest.fn().mockResolvedValue([]) });
await flush();
expect(container.querySelector('.daily-templates-empty')).not.toBeNull();
});
test('renders one row per template', async () => {
const { container } = mountPanel({
listTemplates: jest.fn().mockResolvedValue([
{ name: 'morning-pages.md', label: 'Morning Pages', content: '# Morning' },
{ name: 'evening.md', label: 'Evening', content: '# Evening' },
]),
});
await flush();
const items = container.querySelectorAll('.daily-templates-item');
expect(items).toHaveLength(2);
expect(items[0].textContent).toContain('Morning Pages');
expect(items[1].textContent).toContain('Evening');
});
test('escapeHtml-style safety: a label with ', content: '' },
]),
});
await flush();
expect(container.querySelector('script')).toBeNull();
// The literal text survives in the row (textContent keeps it visible as
// text rather than as a node — the safety we want).
expect(container.querySelector('.daily-templates-item').textContent).toContain('