Show belongsTo and relatedTo from frontmatter as clickable links that navigate to the referenced note. Empty state when no relationships exist. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
120 lines
4.4 KiB
TypeScript
120 lines
4.4 KiB
TypeScript
import { render, screen, fireEvent } from '@testing-library/react'
|
|
import { describe, it, expect, vi } from 'vitest'
|
|
import { Inspector } from './Inspector'
|
|
import type { VaultEntry } from '../types'
|
|
|
|
const mockEntry: VaultEntry = {
|
|
path: '/vault/project/test.md',
|
|
filename: 'test.md',
|
|
title: 'Test Project',
|
|
isA: 'Project',
|
|
aliases: [],
|
|
belongsTo: ['[[responsibility/grow-newsletter]]'],
|
|
relatedTo: ['[[topic/software-development]]'],
|
|
status: 'Active',
|
|
owner: 'Luca Rossi',
|
|
cadence: null,
|
|
modifiedAt: 1707900000,
|
|
fileSize: 1024,
|
|
}
|
|
|
|
const mockContent = `---
|
|
title: Test Project
|
|
is_a: Project
|
|
status: Active
|
|
---
|
|
|
|
# Test Project
|
|
|
|
This is a test note with some words to count.
|
|
`
|
|
|
|
const defaultProps = {
|
|
collapsed: false,
|
|
onToggle: () => {},
|
|
entry: null as VaultEntry | null,
|
|
content: null as string | null,
|
|
entries: [] as VaultEntry[],
|
|
onNavigate: () => {},
|
|
}
|
|
|
|
describe('Inspector', () => {
|
|
it('renders expanded state with "no note selected"', () => {
|
|
render(<Inspector {...defaultProps} />)
|
|
expect(screen.getByText('Inspector')).toBeInTheDocument()
|
|
expect(screen.getByText('Properties')).toBeInTheDocument()
|
|
expect(screen.getByText('No note selected')).toBeInTheDocument()
|
|
})
|
|
|
|
it('renders collapsed state without sections', () => {
|
|
render(<Inspector {...defaultProps} collapsed={true} />)
|
|
expect(screen.queryByText('Inspector')).not.toBeInTheDocument()
|
|
expect(screen.queryByText('Properties')).not.toBeInTheDocument()
|
|
})
|
|
|
|
it('calls onToggle when toggle button clicked', () => {
|
|
const onToggle = vi.fn()
|
|
render(<Inspector {...defaultProps} onToggle={onToggle} />)
|
|
fireEvent.click(screen.getByRole('button'))
|
|
expect(onToggle).toHaveBeenCalledOnce()
|
|
})
|
|
|
|
it('shows properties when a note is selected', () => {
|
|
render(<Inspector {...defaultProps} entry={mockEntry} content={mockContent} />)
|
|
expect(screen.getByText('Project')).toBeInTheDocument()
|
|
expect(screen.getByText('Active')).toBeInTheDocument()
|
|
expect(screen.getByText('Luca Rossi')).toBeInTheDocument()
|
|
expect(screen.getByText('Type')).toBeInTheDocument()
|
|
expect(screen.getByText('Status')).toBeInTheDocument()
|
|
expect(screen.getByText('Owner')).toBeInTheDocument()
|
|
expect(screen.getByText('Words')).toBeInTheDocument()
|
|
})
|
|
|
|
it('renders status as a colored pill', () => {
|
|
render(<Inspector {...defaultProps} entry={mockEntry} content={mockContent} />)
|
|
const pill = screen.getByText('Active')
|
|
expect(pill).toHaveClass('inspector__status-pill')
|
|
expect(pill).toHaveStyle({ backgroundColor: '#4caf50' })
|
|
})
|
|
|
|
it('computes word count from content minus frontmatter', () => {
|
|
render(<Inspector {...defaultProps} entry={mockEntry} content={mockContent} />)
|
|
// "# Test Project" + "This is a test note with some words to count." = 13 words
|
|
expect(screen.getByText('13')).toBeInTheDocument()
|
|
})
|
|
|
|
it('shows "Add property" button as disabled placeholder', () => {
|
|
render(<Inspector {...defaultProps} entry={mockEntry} content={mockContent} />)
|
|
const btn = screen.getByText('+ Add property')
|
|
expect(btn).toBeDisabled()
|
|
})
|
|
|
|
it('shows cadence when present', () => {
|
|
const entryWithCadence = { ...mockEntry, cadence: 'Weekly' }
|
|
render(<Inspector {...defaultProps} entry={entryWithCadence} content={mockContent} />)
|
|
expect(screen.getByText('Cadence')).toBeInTheDocument()
|
|
expect(screen.getByText('Weekly')).toBeInTheDocument()
|
|
})
|
|
|
|
it('shows relationships with clickable links', () => {
|
|
render(<Inspector {...defaultProps} entry={mockEntry} content={mockContent} />)
|
|
expect(screen.getByText('Belongs to')).toBeInTheDocument()
|
|
expect(screen.getByText('Grow Newsletter')).toBeInTheDocument()
|
|
expect(screen.getByText('Related to')).toBeInTheDocument()
|
|
expect(screen.getByText('Software Development')).toBeInTheDocument()
|
|
})
|
|
|
|
it('navigates when a relationship link is clicked', () => {
|
|
const onNavigate = vi.fn()
|
|
render(<Inspector {...defaultProps} entry={mockEntry} content={mockContent} onNavigate={onNavigate} />)
|
|
fireEvent.click(screen.getByText('Grow Newsletter'))
|
|
expect(onNavigate).toHaveBeenCalledWith('grow newsletter')
|
|
})
|
|
|
|
it('shows "No relationships" when entry has no belongsTo/relatedTo', () => {
|
|
const noRels = { ...mockEntry, belongsTo: [], relatedTo: [] }
|
|
render(<Inspector {...defaultProps} entry={noRels} content={mockContent} />)
|
|
expect(screen.getByText('No relationships')).toBeInTheDocument()
|
|
})
|
|
})
|