test(mobile): add note-prompts API client and prompt-store tests (G14)

This commit is contained in:
saravanakumardb1 2026-04-06 13:36:00 -07:00
parent 4fd6994fb0
commit 406153eeda
2 changed files with 177 additions and 0 deletions

View File

@ -0,0 +1,64 @@
import { describe, expect, it, vi, beforeEach } from 'vitest';
const fetchMock = vi.fn();
vi.mock('./client', () => ({
getApiClient: () => ({
fetch: fetchMock,
}),
}));
import {
listPromptTemplates,
runPrompt,
suggestTags,
extractFromUrl,
copilotTransform,
getReadingTime,
} from './note-prompts';
describe('note-prompts API client', () => {
beforeEach(() => {
fetchMock.mockReset();
});
it('listPromptTemplates returns items', async () => {
fetchMock.mockResolvedValue({ items: [{ id: 't1', slug: 'summarize' }] });
const result = await listPromptTemplates();
expect(result).toEqual([{ id: 't1', slug: 'summarize' }]);
expect(fetchMock).toHaveBeenCalledWith('/note-prompts');
});
it('runPrompt posts input', async () => {
fetchMock.mockResolvedValue({ content: 'Summary', templateSlug: 'summarize' });
const result = await runPrompt({ templateId: 'summarize', noteId: 'n1', workspaceId: 'ws1' });
expect(result.content).toBe('Summary');
expect(fetchMock).toHaveBeenCalledWith('/note-prompts/run', expect.objectContaining({ method: 'POST' }));
});
it('suggestTags returns tag array', async () => {
fetchMock.mockResolvedValue({ tags: ['tag1', 'tag2'] });
const tags = await suggestTags('n1', 'ws1');
expect(tags).toEqual(['tag1', 'tag2']);
});
it('extractFromUrl sends url and workspaceId', async () => {
fetchMock.mockResolvedValue({ title: 'Page', content: 'text', url: 'https://example.com', summarized: true });
const result = await extractFromUrl('https://example.com', 'ws1');
expect(result.title).toBe('Page');
expect(fetchMock).toHaveBeenCalledWith('/note-prompts/url-extract', expect.objectContaining({ method: 'POST' }));
});
it('copilotTransform sends action and text', async () => {
fetchMock.mockResolvedValue({ text: 'Transformed' });
const result = await copilotTransform('n1', 'ws1', 'shorten', 'Long text');
expect(result).toBe('Transformed');
});
it('getReadingTime returns word count and minutes', async () => {
fetchMock.mockResolvedValue({ wordCount: 500, readingTimeMinutes: 3 });
const result = await getReadingTime('n1', 'ws1');
expect(result.wordCount).toBe(500);
expect(result.readingTimeMinutes).toBe(3);
});
});

View File

@ -0,0 +1,113 @@
import { describe, expect, it, vi, beforeEach } from 'vitest';
const listPromptTemplatesMock = vi.fn();
const runPromptMock = vi.fn();
vi.mock('../api/note-prompts', () => ({
listPromptTemplates: (...args: unknown[]) => listPromptTemplatesMock(...args),
runPrompt: (...args: unknown[]) => runPromptMock(...args),
}));
import { usePromptStore } from './prompt-store';
function resetStore() {
usePromptStore.setState({
templates: [],
isLoading: false,
isRunning: false,
lastResult: null,
error: null,
});
}
describe('prompt-store', () => {
beforeEach(() => {
vi.clearAllMocks();
resetStore();
});
it('initial state is empty', () => {
const state = usePromptStore.getState();
expect(state.templates).toEqual([]);
expect(state.isLoading).toBe(false);
expect(state.isRunning).toBe(false);
expect(state.lastResult).toBeNull();
expect(state.error).toBeNull();
});
it('fetchTemplates populates templates on success', async () => {
listPromptTemplatesMock.mockResolvedValue([
{ id: 't1', slug: 'summarize', name: 'Summarize' },
]);
await usePromptStore.getState().fetchTemplates();
const state = usePromptStore.getState();
expect(state.templates).toHaveLength(1);
expect(state.templates[0].slug).toBe('summarize');
expect(state.isLoading).toBe(false);
});
it('fetchTemplates sets error on failure', async () => {
listPromptTemplatesMock.mockRejectedValue(new Error('Network error'));
await usePromptStore.getState().fetchTemplates();
const state = usePromptStore.getState();
expect(state.error).toBe('Network error');
expect(state.isLoading).toBe(false);
});
it('runPrompt stores result on success', async () => {
runPromptMock.mockResolvedValue({
content: 'Summary text',
templateSlug: 'summarize',
outputType: 'new_note',
});
const result = await usePromptStore.getState().runPrompt({
templateId: 'summarize',
noteId: 'n1',
workspaceId: 'ws1',
});
expect(result).toBeTruthy();
expect(result!.content).toBe('Summary text');
const state = usePromptStore.getState();
expect(state.lastResult!.content).toBe('Summary text');
expect(state.isRunning).toBe(false);
});
it('runPrompt sets error on failure', async () => {
runPromptMock.mockRejectedValue(new Error('LLM timeout'));
const result = await usePromptStore.getState().runPrompt({
templateId: 'summarize',
noteId: 'n1',
workspaceId: 'ws1',
});
expect(result).toBeNull();
const state = usePromptStore.getState();
expect(state.error).toBe('LLM timeout');
expect(state.isRunning).toBe(false);
});
it('clearResult resets lastResult', async () => {
runPromptMock.mockResolvedValue({ content: 'Result', templateSlug: 'x', outputType: 'new_note' });
await usePromptStore.getState().runPrompt({ templateId: 'x', noteId: 'n1', workspaceId: 'ws1' });
expect(usePromptStore.getState().lastResult).not.toBeNull();
usePromptStore.getState().clearResult();
expect(usePromptStore.getState().lastResult).toBeNull();
});
it('clearError resets error', async () => {
runPromptMock.mockRejectedValue(new Error('fail'));
await usePromptStore.getState().runPrompt({ templateId: 'x', noteId: 'n1', workspaceId: 'ws1' });
expect(usePromptStore.getState().error).toBe('fail');
usePromptStore.getState().clearError();
expect(usePromptStore.getState().error).toBeNull();
});
});