11import { Engine , components } from '../../../packages/@dcl/ecs/src'
2+ import { CrdtMessageType } from '../../../packages/@dcl/ecs/src/serialization/crdt/types'
23import { testComponentSerialization } from './assertion'
34
45describe ( 'Generated AudioSource ProtoBuf' , ( ) => {
@@ -38,8 +39,9 @@ describe('Generated AudioSource ProtoBuf', () => {
3839 playing : true
3940 } )
4041
41- expect ( AudioSource . playSound ( entityWithoutAudioSource , 'some-src' ) ) . toBe ( false )
42+ // stopSound on an entity without AudioSource is a no-op.
4243 expect ( AudioSource . stopSound ( entityWithoutAudioSource ) ) . toBe ( false )
44+ expect ( AudioSource . getOrNull ( entityWithoutAudioSource ) ) . toBeNull ( )
4345
4446 // play sound with new "src" & reset cursor
4547 expect ( AudioSource . playSound ( entity , 'other-src' , true ) ) . toBe ( true )
@@ -60,4 +62,52 @@ describe('Generated AudioSource ProtoBuf', () => {
6062 expect ( AudioSource . stopSound ( entity , true ) ) . toBe ( true )
6163 expect ( AudioSource . getOrNull ( entity ) ) . toStrictEqual ( { audioClipUrl : 'other-src' , playing : false , currentTime : 0 } )
6264 } )
65+
66+ it ( 'should create the AudioSource component on entities that do not yet have one when playSound is called' , ( ) => {
67+ const newEngine = Engine ( )
68+ const AudioSource = components . AudioSource ( newEngine )
69+ const entity = newEngine . addEntity ( )
70+
71+ // Entity has no AudioSource component yet.
72+ expect ( AudioSource . getOrNull ( entity ) ) . toBeNull ( )
73+
74+ // playSound must create it and start playback.
75+ expect ( AudioSource . playSound ( entity , 'fresh.mp3' ) ) . toBe ( true )
76+ expect ( AudioSource . getOrNull ( entity ) ) . toStrictEqual ( {
77+ audioClipUrl : 'fresh.mp3' ,
78+ playing : true ,
79+ currentTime : 0
80+ } )
81+
82+ // And it must emit a CRDT PUT so the renderer hears about it.
83+ const messages = Array . from ( AudioSource . getCrdtUpdates ( ) )
84+ expect ( messages ) . toHaveLength ( 1 )
85+ expect ( messages [ 0 ] . type ) . toBe ( CrdtMessageType . PUT_COMPONENT )
86+ } )
87+
88+ it ( 'should emit a CRDT PUT on every playSound call, even with identical parameters (retrigger)' , ( ) => {
89+ const newEngine = Engine ( )
90+ const AudioSource = components . AudioSource ( newEngine )
91+ const entity = newEngine . addEntity ( )
92+
93+ AudioSource . create ( entity , { audioClipUrl : 'a.mp3' , playing : false } )
94+
95+ // Flush initial create
96+ const createMessages = Array . from ( AudioSource . getCrdtUpdates ( ) )
97+ expect ( createMessages ) . toHaveLength ( 1 )
98+ expect ( createMessages [ 0 ] . type ) . toBe ( CrdtMessageType . PUT_COMPONENT )
99+
100+ // First playSound call
101+ expect ( AudioSource . playSound ( entity , 'a.mp3' ) ) . toBe ( true )
102+ const firstPlayMessages = Array . from ( AudioSource . getCrdtUpdates ( ) )
103+ expect ( firstPlayMessages ) . toHaveLength ( 1 )
104+ expect ( firstPlayMessages [ 0 ] . type ) . toBe ( CrdtMessageType . PUT_COMPONENT )
105+
106+ // Second playSound call with identical parameters — must still emit a PUT
107+ expect ( AudioSource . playSound ( entity , 'a.mp3' ) ) . toBe ( true )
108+ const secondPlayMessages = Array . from ( AudioSource . getCrdtUpdates ( ) )
109+ expect ( secondPlayMessages ) . toHaveLength ( 1 )
110+ expect ( secondPlayMessages [ 0 ] . type ) . toBe ( CrdtMessageType . PUT_COMPONENT )
111+ } )
112+
63113} )
0 commit comments