const { mockClient } = require('aws-sdk-client-mock'); const { TranscribeClient, CreateVocabularyCommand, GetVocabularyCommand } = require('@aws-sdk/client-transcribe'); const { sanitizeTerm, buildVocabulary, writeVocabulary } = require('../src/vocab'); const { LocalFsStorage } = require('../src/storage'); const { createLogger } = require('../src/logger'); const fs = require('fs/promises'); const os = require('os'); const path = require('path'); const transcribe = mockClient(TranscribeClient); describe('vocabulary sanitizing', () => { it('hyphenates phrases and drops terms that cannot be made valid', () => { expect(sanitizeTerm('Los Angeles')).toBe('Los-Angeles'); expect(sanitizeTerm('Ada Lovelace')).toBe('Ada-Lovelace'); expect(sanitizeTerm('A.B.C.')).toBe('A.B.C.'); expect(sanitizeTerm('well--known')).toBe('well-known'); expect(sanitizeTerm('COVID-19')).toBe('COVID'); expect(sanitizeTerm('---')).toBe(null); expect(sanitizeTerm('123')).toBe(null); }); it('deduplicates and sorts', () => { const logger = { warn() {} }; const built = buildVocabulary( { bookCard: { title: 'Los Angeles', author: null, glossary: [{ term: 'Tide', definition: 'water' }], }, summaries: [{ entities: { people: ['Ada Lovelace'], places: ['Los Angeles'], terms: ['###'] } }], }, logger, ); expect(built.terms).toEqual(['Ada-Lovelace', 'Los-Angeles', 'Tide']); expect(built.dropped).toContain('###'); }); it('does not call Transcribe unless asked', async () => { transcribe.reset(); const dir = await fs.mkdtemp(path.join(os.tmpdir(), 'vocab-')); const storage = new LocalFsStorage(dir); const result = await writeVocabulary({ bookId: 3, bookCard: { title: 'Harbor', author: 'Ada', glossary: [] }, summaries: [], storage, transcribe: new TranscribeClient({ region: 'ap-south-1' }), languageCode: 'en-US', createVocabulary: false, logger: createLogger('silent'), }); expect(result.created).toBe(false); expect(transcribe.commandCalls(CreateVocabularyCommand)).toHaveLength(0); expect(await storage.getText('books/3/transcribe/vocab.txt')).toContain('Harbor'); await fs.rm(dir, { recursive: true, force: true }); }); it('polls until the vocabulary is READY', async () => { transcribe.reset(); transcribe.on(CreateVocabularyCommand).resolves({}); transcribe .on(GetVocabularyCommand) .resolvesOnce({ VocabularyState: 'PENDING' }) .resolvesOnce({ VocabularyState: 'READY' }); const dir = await fs.mkdtemp(path.join(os.tmpdir(), 'vocab-')); const storage = new LocalFsStorage(dir); const result = await writeVocabulary({ bookId: 8, bookCard: { title: 'Harbor', author: null, glossary: [] }, summaries: [], storage, transcribe: new TranscribeClient({ region: 'ap-south-1' }), languageCode: 'en-US', createVocabulary: true, logger: createLogger('silent'), sleep: async () => {}, }); expect(result.vocabularyName).toBe('book-8'); expect(transcribe.commandCalls(GetVocabularyCommand)).toHaveLength(2); await fs.rm(dir, { recursive: true, force: true }); }); });