transcriptLines.test.ts2.7 KBView on GitHub import {
hasTimestamps,
parseTranscriptLines,
secondsAtOffset,
} from '@/modules/meetings/detail/transcript-lines';
/**
* A transcript reaches the client as one flat string, and the only reason the meeting view
* can hand the recording a second is that the string is re-parseable into the lines the
* server flattened. These cover the shapes the server actually writes plus the ones that
* would silently lose text if parsing were stricter.
*/
const TRANSCRIPT = [
'[00:00:12] Alice Chen: thanks for making the time',
'[00:01:05] Bob Ray: so the deal is: we sign Friday',
'[01:02:03] Alice Chen: perfect',
].join('\n');
describe('parseTranscriptLines', () => {
it('recovers the stamp, speaker and text from each flattened line', () => {
const lines = parseTranscriptLines(TRANSCRIPT);
expect(lines).toHaveLength(3);
expect(lines[0]).toMatchObject({
atSeconds: 12,
speaker: 'Alice Chen',
text: 'thanks for making the time',
});
expect(lines[1]!.atSeconds).toBe(65);
// An hour-long call stamps HH:MM:SS, which must not be read as MM:SS.
expect(lines[2]!.atSeconds).toBe(3723);
});
it('keeps a colon in the SPOKEN text out of the speaker name', () => {
const [, second] = parseTranscriptLines(TRANSCRIPT);
expect(second!.speaker).toBe('Bob Ray');
expect(second!.text).toBe('so the deal is: we sign Friday');
});
it('points textStart at the text inside the original string', () => {
const lines = parseTranscriptLines(TRANSCRIPT);
for (const line of lines) {
expect(TRANSCRIPT.slice(line.textStart, line.textEnd)).toBe(line.text);
}
});
it('keeps unstamped lines rather than dropping them', () => {
const lines = parseTranscriptLines('just some prose\n\nwith a blank line');
expect(lines.map((l) => l.text)).toEqual(['just some prose', 'with a blank line']);
expect(hasTimestamps(lines)).toBe(false);
});
it('reports timestamps only when at least one line carries one', () => {
expect(hasTimestamps(parseTranscriptLines(TRANSCRIPT))).toBe(true);
});
});
describe('secondsAtOffset', () => {
const lines = parseTranscriptLines(TRANSCRIPT);
it('returns the stamp of the line the offset falls in', () => {
const offset = TRANSCRIPT.indexOf('we sign Friday');
expect(secondsAtOffset(lines, offset)).toBe(65);
});
it('uses the line a quote STARTS in when it runs past that line', () => {
// A quote beginning in Bob's line and running into Alice's belongs to Bob's moment.
const offset = TRANSCRIPT.indexOf('so the deal is');
expect(secondsAtOffset(lines, offset)).toBe(65);
});
it('has no answer before the first stamped line', () => {
expect(secondsAtOffset(parseTranscriptLines('no stamps here'), 3)).toBeNull();
});
});