Files
SubMiner/src/main/runtime/anki-actions.test.ts

90 lines
3.1 KiB
TypeScript

import test from 'node:test';
import assert from 'node:assert/strict';
import {
createMarkLastCardAsAudioCardHandler,
createMineSentenceCardHandler,
createRefreshKnownWordCacheHandler,
createTriggerFieldGroupingHandler,
createUpdateLastCardFromClipboardHandler,
} from './anki-actions';
test('update last card handler forwards integration/clipboard/osd deps', async () => {
const calls: string[] = [];
const integration = {};
const updateLastCard = createUpdateLastCardFromClipboardHandler({
getAnkiIntegration: () => integration,
readClipboardText: () => 'clipboard-value',
showMpvOsd: (text) => calls.push(`osd:${text}`),
updateLastCardFromClipboardCore: async (options) => {
assert.equal(options.ankiIntegration, integration);
assert.equal(options.readClipboardText(), 'clipboard-value');
options.showMpvOsd('ok');
calls.push('core');
},
});
await updateLastCard();
assert.deepEqual(calls, ['osd:ok', 'core']);
});
test('refresh known word cache handler throws when Anki integration missing', async () => {
const refresh = createRefreshKnownWordCacheHandler({
getAnkiIntegration: () => null,
missingIntegrationMessage: 'AnkiConnect integration not enabled',
});
await assert.rejects(() => refresh(), /AnkiConnect integration not enabled/);
});
test('trigger and mark handlers delegate to core services', async () => {
const calls: string[] = [];
const integration = {};
const triggerFieldGrouping = createTriggerFieldGroupingHandler({
getAnkiIntegration: () => integration,
showMpvOsd: (text) => calls.push(`osd:${text}`),
triggerFieldGroupingCore: async (options) => {
assert.equal(options.ankiIntegration, integration);
options.showMpvOsd('group');
calls.push('group-core');
},
});
const markAudio = createMarkLastCardAsAudioCardHandler({
getAnkiIntegration: () => integration,
showMpvOsd: (text) => calls.push(`osd:${text}`),
markLastCardAsAudioCardCore: async (options) => {
assert.equal(options.ankiIntegration, integration);
options.showMpvOsd('mark');
calls.push('mark-core');
},
});
await triggerFieldGrouping();
await markAudio();
assert.deepEqual(calls, ['osd:group', 'group-core', 'osd:mark', 'mark-core']);
});
test('mine sentence handler records mined cards only when core returns true', async () => {
const calls: string[] = [];
const integration = {};
const mpvClient = {};
let created = false;
const mineSentenceCard = createMineSentenceCardHandler({
getAnkiIntegration: () => integration,
getMpvClient: () => mpvClient,
showMpvOsd: (text) => calls.push(`osd:${text}`),
mineSentenceCardCore: async (options) => {
assert.equal(options.ankiIntegration, integration);
assert.equal(options.mpvClient, mpvClient);
options.showMpvOsd('mine');
return created;
},
recordCardsMined: (count) => calls.push(`cards:${count}`),
});
created = false;
await mineSentenceCard();
created = true;
await mineSentenceCard();
assert.deepEqual(calls, ['osd:mine', 'osd:mine', 'cards:1']);
});