import { afterEach, describe, expect, it, vi } from 'vitest' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { Logs } from './Logs' import * as logs from '../../api/logs' import * as apps from '../../api/apps' import type { QueryLogEntry } from '../../api/logs' import { HandoffContext } from '../../app/handoff' /* The hub tags the rows it merged with the server they came from. */ afterEach(() => vi.restoreAllMocks()) function entry(rowNumber: number, extra: Partial = {}): QueryLogEntry { return { rowNumber, timestamp: '2026-08-26T05:32:14Z', clientIpAddress: '10.0.0.7', protocol: 'Udp', responseType: 'Recursive', rcode: 'NoError', qname: `r${rowNumber}.example`, qtype: 'A', qclass: 'IN', answer: null, ...extra, } } async function show(entries: QueryLogEntry[]) { vi.spyOn(apps, 'listApps').mockResolvedValue({ kind: 'ok', data: { status: 'ok', response: { apps: [ { name: 'Query Logs (Sqlite)', description: '', version: '8.0', dnsApps: [ { classPath: 'QueryLogsSqlite.App', description: '', recordDataTemplate: null, isAppRecordRequestHandler: false, isRequestController: false, isAuthoritativeRequestHandler: false, isRequestBlockingHandler: false, isQueryLogger: true, isQueryLogs: true, isPostProcessor: false, }, ], }, ], }, }, } as never) vi.spyOn(logs, 'queryLogs').mockResolvedValue({ kind: 'ok', data: { response: { pageNumber: 1, totalPages: 1, totalEntries: entries.length, entries } }, } as never) render( , ) await userEvent.click(await screen.findByRole('button', { name: 'Query' })) await screen.findByText('r1.example') } describe('Query Logs: the Server column', () => { it('appears, after Timestamp, when rows carry a node', async () => { await show([entry(1, { node: 'dns' }), entry(2, { node: 'ndns' })]) const headers = screen.getAllByRole('columnheader').map((h) => h.textContent) expect(headers.indexOf('Server')).toBe(headers.indexOf('Timestamp') + 1) expect(screen.getByText('dns')).toBeInTheDocument() expect(screen.getByText('ndns')).toBeInTheDocument() }) it('is absent when no row has one', async () => { await show([entry(1), entry(2)]) expect(screen.queryByRole('columnheader', { name: 'Server' })).not.toBeInTheDocument() }) })