import {describe,it,expect} from "vitest"; import {assertAnalysisBinding} from "../src/media/analysis-binding.js"; const expected={analysisId:"analysis_real",dramaId:"drama_real",fetchedAt:"2026-09-14T00:00:00Z",title:"Actual title",synopsis:"Actual CMS synopsis",tags:["Mystery"],episodeCount:5, sources:[{episodeId:"e1",episodeNo:1,duration:30,subtitle:"WEBVTT\n\n00:00:01.000 --> 00:00:03.000\nWhere is she?",frames:[{id:"f1",time:2}]},{episodeId:"e3",episodeNo:3,duration:30,subtitle:"WEBVTT\n\n00:00:01.000 --> 00:00:03.000\nFind her.",frames:[{id:"f3",time:2}]},{episodeId:"e5",episodeNo:5,duration:30,subtitle:"WEBVTT\n\n00:00:01.000 --> 00:00:03.000\nWho did this?",frames:[{id:"f5",time:2}]}]}; function analysis(){return {analysis_id:"analysis_real",drama:{drama_id:"drama_real",title:"Actual title",synopsis:"Actual CMS synopsis",tags:["Mystery"],episode_count:5},cms_source:{fetched_at:expected.fetchedAt},evidence:{ frame_evidence:[{episode:1,episode_id:"e1",frame_id:"f1",time:2,claim:"A person stands"},{episode:3,episode_id:"e3",frame_id:"f3",time:2,claim:"A person speaks"}], subtitle_evidence:[{episode:1,episode_id:"e1",story_position:"opening",quote:"Where is she?"},{episode:3,episode_id:"e3",story_position:"middle",quote:"Find her."},{episode:5,episode_id:"e5",story_position:"late",quote:"Who did this?"}]}};} describe("analysis evidence binding",()=>{ it("accepts only the actual job identity, CMS record and registered frame/subtitle evidence",()=>{ expect(()=>assertAnalysisBinding(analysis(),expected)).not.toThrow(); const changed=analysis();changed.analysis_id="analysis_other"; expect(()=>assertAnalysisBinding(changed,expected)).toThrow(); changed.analysis_id="analysis_real";changed.drama.synopsis="Model invented synopsis"; expect(()=>assertAnalysisBinding(changed,expected)).toThrow(); }); it("rejects invented frames, mismatched timestamps, duplicate frames and invented subtitle quotes",()=>{ const unknown=analysis();unknown.evidence.frame_evidence[0]!.frame_id="unknown"; expect(()=>assertAnalysisBinding(unknown,expected)).toThrow(); const timestamp=analysis();timestamp.evidence.frame_evidence[0]!.time=29; expect(()=>assertAnalysisBinding(timestamp,expected)).toThrow(); const duplicate=analysis();duplicate.evidence.frame_evidence[1]=duplicate.evidence.frame_evidence[0]!; expect(()=>assertAnalysisBinding(duplicate,expected)).toThrow(); const quote=analysis();quote.evidence.subtitle_evidence[0]!.quote="Invented dialogue"; expect(()=>assertAnalysisBinding(quote,expected)).toThrow(); }); });