Files
recap-relay/server/test/polish-speaker-labels.test.js
T

61 lines
2.5 KiB
JavaScript

// Re-polish bug fix: the summary-polish pass must label each transcript
// line with the operator's CORRECTED speaker name, so a re-polish after a
// legend rename actually re-attributes statements to the new name (rather
// than echoing the stale name baked into the original summaries).
import { test, describe } from "node:test";
import assert from "node:assert/strict";
import { formatSpeakerLabeledTranscript } from "../post-cluster-polish.js";
const SEGMENTS = [
{ start: 5, speaker: "Speaker_A", text: "Let's get started." },
{ start: 12, speaker: "Speaker_B", text: "Sounds good." },
{ start: 20, speaker: "Speaker_C", text: "One more thing." }, // unnamed
{ start: 30, speaker: "", text: "(crosstalk)" }, // no speaker
];
describe("formatSpeakerLabeledTranscript", () => {
test("without speakerNames: labels by chip letter (name-inference pass)", () => {
const out = formatSpeakerLabeledTranscript(SEGMENTS);
assert.match(out, /\[A 0:05\] Let's get started\./);
assert.match(out, /\[B 0:12\] Sounds good\./);
assert.match(out, /\[C 0:20\] One more thing\./);
// Segment with no speaker → "?" label.
assert.match(out, /\[\? 0:30\] \(crosstalk\)/);
});
test("with speakerNames: named speakers labeled by NAME, unnamed fall back to letter", () => {
const out = formatSpeakerLabeledTranscript(SEGMENTS, {
speakerNames: { Speaker_A: "Matt", Speaker_B: "Grant" },
});
assert.match(out, /\[Matt 0:05\] Let's get started\./);
assert.match(out, /\[Grant 0:12\] Sounds good\./);
// Speaker_C has no name → still the letter.
assert.match(out, /\[C 0:20\] One more thing\./);
// Crucially, the OLD letter labels for the named speakers are gone.
assert.doesNotMatch(out, /\[A 0:05\]/);
assert.doesNotMatch(out, /\[B 0:12\]/);
});
test("respects the time window (startSec/endSec)", () => {
const out = formatSpeakerLabeledTranscript(SEGMENTS, {
startSec: 10,
endSec: 25,
speakerNames: { Speaker_A: "Matt" },
});
assert.doesNotMatch(out, /Let's get started/); // 0:05, before window
assert.match(out, /Sounds good/); // 0:12, in window
assert.match(out, /One more thing/); // 0:20, in window
assert.doesNotMatch(out, /crosstalk/); // 0:30, after window
});
test("strips brackets from a name so the [label] frame can't break", () => {
const out = formatSpeakerLabeledTranscript(
[{ start: 0, speaker: "Speaker_A", text: "hi" }],
{ speakerNames: { Speaker_A: "Ma[t]t" } },
);
assert.match(out, /\[Matt 0:00\] hi/);
});
});