import { Mp4Capture } from '.' ; import { runComponentTests } from '../../utils/validate-component' ; import { MessageType , GenericMessage } from '../message' ; import { Source , Sink } from '../component' ; const MOCK_BUFFER_SIZE = 10 ; const MOCK_MOVIE_DATA = 0xff ; const MOCK_MOVIE_ENDING_DATA = 0xfe ; const MOCK_MOVIE = [ MessageType . ISOM , MessageType . ISOM ] . map ( ( type , idx ) => { if ( idx === 0 ) { return { type , tracks : [ ] , data : Buffer . allocUnsafe ( 1 ) . fill ( MOCK_MOVIE_DATA ) , } ; } return { type , data : Buffer . allocUnsafe ( 1 ) . fill ( MOCK_MOVIE_DATA ) } ; } ) ; const MOCK_MOVIE_BUFFER = Buffer . alloc ( 2 ) . fill ( MOCK_MOVIE_DATA ) ; const MOCK_MOVIE_ENDING = [ MessageType . ISOM , MessageType . ISOM , MessageType . ISOM , MessageType . ISOM , ] . map ( ( type ) => { return { type , data : Buffer . allocUnsafe ( 1 ) . fill ( MOCK_MOVIE_ENDING_DATA ) } ; } ) ; const MOCK_NOT_MOVIE = [ '' , '' ] . map ( ( type ) => { return { type : type as unknown as MessageType , data : Buffer . allocUnsafe ( 1 ) . fill ( 0 ) , } ; } ) ; const copySpies = ( type , messages ) => { return messages . filter ( ( msg ) => msg . type === type ) . map ( ( msg ) => jest . spyOn ( msg . data , 'copy' ) ) ; } ; param fragments return const pipelineFactory = ( ... fragments ) => { const sourceMessages = ( [ ] as GenericMessage [ ] ) . concat ( ... fragments ) ; const sinkHandler = jest . fn ( ) ; const source = Source . fromMessages ( sourceMessages ) ; const capture = new Mp4Capture ( MOCK_BUFFER_SIZE ) ; const sink = Sink . fromHandler ( sinkHandler ) ; return { source , capture , sink , sinkHandler , flow : ( ) => source . connect ( capture ) . connect ( sink ) , } ; } ; describe ( 'it should follow standard component rules' , ( ) => { const mp4capture = new Mp4Capture ( ) ; runComponentTests ( mp4capture , 'mp4capture component' ) ; } ) ; describe ( 'data copying' , ( ) => { test ( 'should not occur when capture inactive' , ( done ) => { const pipeline = pipelineFactory ( MOCK_MOVIE ) ; const shouldNotCopy = copySpies ( MessageType . ISOM , MOCK_MOVIE ) ; pipeline . flow ( ) ; pipeline . sink . incoming . on ( 'finish' , ( ) => { shouldNotCopy . forEach ( ( copy ) => expect ( copy ) . not . toHaveBeenCalled ( ) ) ; expect ( pipeline . sinkHandler . mock . calls . length ) . toBe ( MOCK_MOVIE . length ) ; done ( ) ; } ) ; } ) ; test ( 'should occur when capture active' , ( done ) => { const pipeline = pipelineFactory ( MOCK_MOVIE ) ; const shouldCopy = copySpies ( MessageType . ISOM , MOCK_MOVIE ) ; const captureHandler = jest . fn ( ) ; pipeline . capture . start ( captureHandler ) ; pipeline . flow ( ) ; pipeline . sink . incoming . on ( 'finish' , ( ) => { shouldCopy . forEach ( ( copy ) => expect ( copy ) . toHaveBeenCalled ( ) ) ; expect ( captureHandler ) . toHaveBeenCalledWith ( MOCK_MOVIE_BUFFER ) ; done ( ) ; } ) ; } ) ; test ( 'should only occur when new movie has started' , ( done ) => { const pipeline = pipelineFactory ( MOCK_MOVIE_ENDING , MOCK_MOVIE ) ; const shouldNotCopy = copySpies ( MessageType . ISOM , MOCK_MOVIE_ENDING ) ; const shouldCopy = copySpies ( MessageType . ISOM , MOCK_MOVIE ) ; const captureHandler = jest . fn ( ) ; pipeline . capture . start ( captureHandler ) ; pipeline . flow ( ) ; pipeline . sink . incoming . on ( 'finish' , ( ) => { shouldNotCopy . forEach ( ( copy ) => expect ( copy ) . not . toHaveBeenCalled ( ) ) ; shouldCopy . forEach ( ( copy ) => expect ( copy ) . toHaveBeenCalled ( ) ) ; expect ( captureHandler ) . toHaveBeenCalledWith ( MOCK_MOVIE_BUFFER ) ; done ( ) ; } ) ; } ) ; test ( 'should not occur when not a movie' , ( done ) => { const pipeline = pipelineFactory ( MOCK_MOVIE , MOCK_NOT_MOVIE ) ; const shouldCopy = copySpies ( MessageType . ISOM , MOCK_MOVIE ) ; const shouldNotCopy = copySpies ( MessageType . ISOM , MOCK_NOT_MOVIE ) ; const captureHandler = jest . fn ( ) ; pipeline . capture . start ( captureHandler ) ; pipeline . flow ( ) ; pipeline . sink . incoming . on ( 'finish' , ( ) => { shouldCopy . forEach ( ( copy ) => expect ( copy ) . toHaveBeenCalled ( ) ) ; shouldNotCopy . forEach ( ( copy ) => expect ( copy ) . not . toHaveBeenCalled ( ) ) ; expect ( captureHandler ) . toHaveBeenCalledWith ( MOCK_MOVIE_BUFFER ) ; done ( ) ; } ) ; } ) ; test ( 'should stop when requested' , ( done ) => { const pipeline = pipelineFactory ( MOCK_MOVIE , MOCK_MOVIE_ENDING ) ; const shouldCopy = copySpies ( MessageType . ISOM , MOCK_MOVIE ) ; const shouldNotCopy = copySpies ( MessageType . ISOM , MOCK_NOT_MOVIE ) ; const captureHandler = jest . fn ( ) ; pipeline . capture . start ( captureHandler ) ; pipeline . source . incoming . on ( 'data' , ( msg ) => { if ( msg . data [ 0 ] === 0xfe ) { pipeline . capture . stop ( ) ; } } ) ; pipeline . flow ( ) ; pipeline . sink . incoming . on ( 'finish' , ( ) => { shouldCopy . forEach ( ( copy ) => expect ( copy ) . toHaveBeenCalled ( ) ) ; shouldNotCopy . forEach ( ( copy ) => expect ( copy ) . not . toHaveBeenCalled ( ) ) ; expect ( captureHandler ) . toHaveBeenCalledWith ( MOCK_MOVIE_BUFFER ) ; done ( ) ; } ) ; } ) ; } ) ;