From 396cabb98b12507816b3c8ee9b25013606ade95d Mon Sep 17 00:00:00 2001 From: d-oit <6849456+d-oit@users.noreply.github.com> Date: Fri, 31 Jul 2026 19:43:19 +0200 Subject: [PATCH 1/4] test: expand library view branch coverage --- .../studio/views/library-view.test.tsx | 86 ++++++++++++++++++- 1 file changed, 84 insertions(+), 2 deletions(-) diff --git a/src/components/studio/views/library-view.test.tsx b/src/components/studio/views/library-view.test.tsx index eed1a606..5e40d602 100644 --- a/src/components/studio/views/library-view.test.tsx +++ b/src/components/studio/views/library-view.test.tsx @@ -1,6 +1,6 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' import type { ReactNode } from 'react' -import { render, screen } from '@testing-library/react' +import { fireEvent, render, screen, within } from '@testing-library/react' vi.mock('framer-motion', () => ({ motion: { @@ -101,6 +101,7 @@ let currentTypeFilter = 'all' let currentSortBy = 'updated' let currentSortDir = 'asc' let currentSearchQuery = '' +let currentRightPanelOpen = false let currentEntities = mockEntities let filteredEntities = mockEntities @@ -118,7 +119,7 @@ vi.mock('@/lib/studio/store', () => ({ startNew: mockStartNew, searchQuery: currentSearchQuery, setSearchQuery: mockSetSearchQuery, - rightPanelOpen: false, + rightPanelOpen: currentRightPanelOpen, }), useFilteredEntities: () => filteredEntities, })) @@ -134,6 +135,7 @@ describe('LibraryView', () => { currentSortBy = 'updated' currentSortDir = 'asc' currentSearchQuery = '' + currentRightPanelOpen = false }) it('renders empty state when no entities', () => { @@ -206,4 +208,84 @@ describe('LibraryView', () => { render() expect(screen.getByLabelText('Search library')).toBeDefined() }) + + it('updates the search query and clears an active search', () => { + currentSearchQuery = 'alpha' + render() + const searchInput = screen.getByLabelText('Search library') + fireEvent.change(searchInput, { target: { value: 'beta' } }) + expect(mockSetSearchQuery).toHaveBeenCalledWith('beta') + + fireEvent.click(screen.getByRole('button', { name: 'Clear search' })) + expect(mockSetSearchQuery).toHaveBeenCalledWith('') + }) + + it('clears all filters from the no-matches state', () => { + currentSearchQuery = 'missing' + currentTypeFilter = 'concept' + filteredEntities = [] + render() + fireEvent.click(screen.getByRole('button', { name: 'Clear all filters' })) + expect(mockSetSearchQuery).toHaveBeenCalledWith('') + expect(mockSetTypeFilter).toHaveBeenCalledWith('all') + }) + + it('changes type, sort, and sort direction controls', () => { + render() + fireEvent.click(screen.getByRole('button', { name: 'Notes' })) + expect(mockSetTypeFilter).toHaveBeenCalledWith('note') + + fireEvent.change(screen.getByRole('combobox', { name: 'Sort by' }), { + target: { value: 'name' }, + }) + expect(mockSetSortBy).toHaveBeenCalledWith('name') + + fireEvent.click(screen.getByRole('button', { name: 'Sort ascending' })) + expect(mockSetSortDir).toHaveBeenCalledWith('desc') + }) + + it('renders list view and opens entities by click and keyboard', () => { + render() + fireEvent.click(screen.getByRole('button', { name: 'List view' })) + + const rows = within(screen.getByRole('table')).getAllByRole('link') + expect(rows).toHaveLength(2) + fireEvent.click(rows[0]) + expect(mockStartEdit).toHaveBeenCalledWith('ent-1') + + fireEvent.keyDown(rows[1], { key: 'Enter' }) + fireEvent.keyDown(rows[1], { key: ' ' }) + expect(mockStartEdit).toHaveBeenCalledWith('ent-2') + expect(mockStartEdit).toHaveBeenCalledTimes(3) + }) + + it('renders tag overflow in grid view', () => { + currentEntities = [{ ...mockEntities[0], tags: ['one', 'two', 'three'] }] + filteredEntities = currentEntities + render() + expect(screen.getByText('+1')).toBeDefined() + }) + + it('uses the wider layout when the right panel is closed', () => { + currentRightPanelOpen = false + const { container, rerender } = render() + expect(container.firstElementChild).toHaveClass('max-w-6xl') + + currentRightPanelOpen = true + rerender() + expect(container.firstElementChild).toHaveClass('max-w-5xl') + }) + + it('starts a new entity from both New actions', () => { + const { unmount } = render() + fireEvent.click(screen.getByRole('button', { name: /^New$/ })) + expect(mockStartNew).toHaveBeenCalledTimes(1) + unmount() + + currentEntities = [] + filteredEntities = [] + render() + fireEvent.click(screen.getByRole('button', { name: /Create your first entity/ })) + expect(mockStartNew).toHaveBeenCalledTimes(2) + }) }) From ca4ea47633cdb6ab3784f0cab6ba4a6b5781d56f Mon Sep 17 00:00:00 2001 From: d-oit <6849456+d-oit@users.noreply.github.com> Date: Sat, 1 Aug 2026 10:08:06 +0200 Subject: [PATCH 2/4] chore: configure mimocode agents --- .mimocode/mimocode.jsonc | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/.mimocode/mimocode.jsonc b/.mimocode/mimocode.jsonc index 666ef14a..84ef5217 100644 --- a/.mimocode/mimocode.jsonc +++ b/.mimocode/mimocode.jsonc @@ -1,18 +1,34 @@ { "$schema": "https://mimo.xiaomi.com/mimocode/config.json", + "model": "xiaomi/mimo-v2.5", "provider": {}, "permission": { "edit": { - "packages/opencode/migration/*": "deny", - }, + "packages/opencode/migration/*": "deny" + } }, "mcp": {}, + "model_groups": { + "lite": "cline-pass/cline-pass/deepseek-v4-flash", + "standard": "xiaomi/mimo-v2.5", + "ultra": "cline-pass/cline-pass/mimo-v2.5-pro" + }, "agent": { - "build": { "model": "cline-pass/cline-pass/mimo-v2.5" }, - "explore": { "model": "cline-pass/cline-pass/mimo-v2.5" }, - "research": { "model": "cline-pass/cline-pass/mimo-v2.5-pro" }, + "build": { + "model": "standard", + "fallbacks": ["lite", "ultra"] + }, + "explore": { "model": "lite" }, + "research": { + "model": "ultra", + "fallbacks": ["standard"] + }, "design": { "model": "cline-pass/cline-pass/kimi-k3" }, - "reviewer": { "model": "cline-pass/cline-pass/mimo-v2.5-pro" }, - "vision": { "model": "cline-pass/cline-pass/mimo-v2.5" } - } -} \ No newline at end of file + "reviewer": { + "model": "ultra", + "fallbacks": ["standard"] + }, + "vision": { "model": "lite" } + }, + "plugin": ["opencode-rate-limit-fallback"] +} From fa665898e5b48c6e0d825b74828b9dff2202d2b9 Mon Sep 17 00:00:00 2001 From: d-oit <6849456+d-oit@users.noreply.github.com> Date: Sat, 1 Aug 2026 10:24:54 +0200 Subject: [PATCH 3/4] Revert "chore: configure mimocode agents" This reverts commit ca4ea47633cdb6ab3784f0cab6ba4a6b5781d56f. --- .mimocode/mimocode.jsonc | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/.mimocode/mimocode.jsonc b/.mimocode/mimocode.jsonc index 84ef5217..666ef14a 100644 --- a/.mimocode/mimocode.jsonc +++ b/.mimocode/mimocode.jsonc @@ -1,34 +1,18 @@ { "$schema": "https://mimo.xiaomi.com/mimocode/config.json", - "model": "xiaomi/mimo-v2.5", "provider": {}, "permission": { "edit": { - "packages/opencode/migration/*": "deny" - } + "packages/opencode/migration/*": "deny", + }, }, "mcp": {}, - "model_groups": { - "lite": "cline-pass/cline-pass/deepseek-v4-flash", - "standard": "xiaomi/mimo-v2.5", - "ultra": "cline-pass/cline-pass/mimo-v2.5-pro" - }, "agent": { - "build": { - "model": "standard", - "fallbacks": ["lite", "ultra"] - }, - "explore": { "model": "lite" }, - "research": { - "model": "ultra", - "fallbacks": ["standard"] - }, + "build": { "model": "cline-pass/cline-pass/mimo-v2.5" }, + "explore": { "model": "cline-pass/cline-pass/mimo-v2.5" }, + "research": { "model": "cline-pass/cline-pass/mimo-v2.5-pro" }, "design": { "model": "cline-pass/cline-pass/kimi-k3" }, - "reviewer": { - "model": "ultra", - "fallbacks": ["standard"] - }, - "vision": { "model": "lite" } - }, - "plugin": ["opencode-rate-limit-fallback"] -} + "reviewer": { "model": "cline-pass/cline-pass/mimo-v2.5-pro" }, + "vision": { "model": "cline-pass/cline-pass/mimo-v2.5" } + } +} \ No newline at end of file From c2f7231a9a691ee1272c4e2ee8165dd5a07cef39 Mon Sep 17 00:00:00 2001 From: d-oit <6849456+d-oit@users.noreply.github.com> Date: Sat, 1 Aug 2026 11:53:42 +0200 Subject: [PATCH 4/4] test(library-view): remove single-child fragment in AnimatePresence mock --- src/components/studio/views/library-view.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/studio/views/library-view.test.tsx b/src/components/studio/views/library-view.test.tsx index 5e40d602..8e9b95d7 100644 --- a/src/components/studio/views/library-view.test.tsx +++ b/src/components/studio/views/library-view.test.tsx @@ -11,7 +11,7 @@ vi.mock('framer-motion', () => ({
)}>{children}
), }, - AnimatePresence: ({ children }: { children?: ReactNode }) => <>{children}, + AnimatePresence: ({ children }: { children?: ReactNode }) => children, })) vi.mock('lucide-react', () => {