Files
tolaria/src/hooks/useInboxOrganizeAdvance.test.ts
2026-05-12 02:27:53 +02:00

112 lines
3.2 KiB
TypeScript

import { act, renderHook } from '@testing-library/react'
import { describe, expect, it, vi } from 'vitest'
import { useRef } from 'react'
import { useInboxOrganizeAdvance } from './useInboxOrganizeAdvance'
import type { SidebarSelection, VaultEntry } from '../types'
function makeEntry(path: string, organized = false): VaultEntry {
const filename = path.split('/').pop() ?? path
return {
aliases: [],
archived: false,
belongsTo: [],
color: null,
createdAt: null,
favorite: false,
favoriteIndex: null,
fileSize: 0,
filename,
hasH1: true,
icon: null,
isA: 'Note',
listPropertiesDisplay: [],
modifiedAt: null,
order: null,
organized,
outgoingLinks: [],
path,
properties: {},
relatedTo: [],
relationships: {},
sidebarLabel: null,
snippet: '',
sort: null,
status: null,
template: null,
title: filename.replace(/\.md$/, ''),
view: null,
visible: null,
wordCount: 0,
}
}
function renderInboxAdvance(options: {
activePath?: string | null
autoAdvanceEnabled?: boolean
entries?: VaultEntry[]
onSelectNote?: (entry: VaultEntry) => void | Promise<void>
onToggleOrganized?: (path: string) => Promise<boolean>
selection?: SidebarSelection
visibleEntries?: VaultEntry[]
}) {
const entries = options.entries ?? [
makeEntry('/vault/first.md'),
makeEntry('/vault/second.md'),
]
const activePath = options.activePath ?? entries[0]?.path ?? null
return renderHook(() => {
const activeTabPathRef = useRef<string | null>(activePath)
const requestedActiveTabPathRef = useRef<string | null>(activePath)
const visibleNotesRef = useRef<VaultEntry[]>(options.visibleEntries ?? entries)
return {
organize: useInboxOrganizeAdvance({
activeTabPath: activePath,
activeTabPathRef,
autoAdvanceEnabled: options.autoAdvanceEnabled ?? true,
entries,
onSelectNote: options.onSelectNote ?? vi.fn(),
onToggleOrganized: options.onToggleOrganized ?? vi.fn().mockResolvedValue(true),
requestedActiveTabPathRef,
selection: options.selection ?? { kind: 'filter', filter: 'inbox' },
visibleNotesRef,
}),
requestedActiveTabPathRef,
}
})
}
describe('useInboxOrganizeAdvance', () => {
it('opens the next visible inbox note after organizing the active note', async () => {
const entries = [makeEntry('/vault/first.md'), makeEntry('/vault/second.md')]
const onSelectNote = vi.fn()
const { result } = renderInboxAdvance({ entries, onSelectNote })
await act(async () => {
await result.current.organize('/vault/first.md')
})
expect(onSelectNote).toHaveBeenCalledWith(entries[1])
})
it('does not advance when focus changed during organization', async () => {
const entries = [makeEntry('/vault/first.md'), makeEntry('/vault/second.md')]
const onSelectNote = vi.fn()
const hook = renderInboxAdvance({
entries,
onSelectNote,
onToggleOrganized: async () => {
hook.result.current.requestedActiveTabPathRef.current = '/vault/other.md'
return true
},
})
await act(async () => {
await hook.result.current.organize('/vault/first.md')
})
expect(onSelectNote).not.toHaveBeenCalled()
})
})