@@ -287,4 +287,78 @@ module('Unit | Service | audio', function (hooks) {
287287 ) ;
288288 } ) ;
289289 } ) ;
290+
291+ module ( 'startNoiseTask' , function ( ) {
292+ test ( 'does not create or start noise when the exercise has no noise level' , async function ( assert ) {
293+ class TestAudioService extends AudioService {
294+ get currentExerciseNoiseLevel ( ) {
295+ return 0 ;
296+ }
297+ get currentExerciseNoiseUrl ( ) {
298+ return null ;
299+ }
300+ async getNoise ( ) {
301+ assert . step ( 'getNoise' ) ;
302+ return { source : { start ( ) { } , stop ( ) { } } , gainNode : { } } ;
303+ }
304+ }
305+ this . owner . register ( 'service:audio' , TestAudioService ) ;
306+ const service = this . owner . lookup ( 'service:audio' ) ;
307+
308+ await service . startNoiseTask . perform ( ) ;
309+
310+ assert . verifySteps ( [ ] , 'no noise is created when the level is 0' ) ;
311+ } ) ;
312+
313+ test ( 'creates and starts the noise source when the exercise has a noise level' , async function ( assert ) {
314+ class TestAudioService extends AudioService {
315+ get currentExerciseNoiseLevel ( ) {
316+ return 50 ;
317+ }
318+ get currentExerciseNoiseUrl ( ) {
319+ return 'http://example.com/noise.mp3' ;
320+ }
321+ async getNoise ( ) {
322+ assert . step ( 'getNoise' ) ;
323+ return {
324+ source : {
325+ start ( ) {
326+ assert . step ( 'start' ) ;
327+ } ,
328+ stop ( ) {
329+ assert . step ( 'stop' ) ;
330+ } ,
331+ } ,
332+ gainNode : { } ,
333+ } ;
334+ }
335+ }
336+ this . owner . register ( 'service:audio' , TestAudioService ) ;
337+ const service = this . owner . lookup ( 'service:audio' ) ;
338+ // A running context is the post-restart case; the suspended-context
339+ // resume is production-only (guarded by !isTesting()). close() is needed
340+ // because the service's willDestroy() closes the context on teardown.
341+ service . context = {
342+ state : 'running' ,
343+ resume : ( ) => Promise . resolve ( ) ,
344+ close : ( ) => Promise . resolve ( ) ,
345+ } ;
346+
347+ const instance = service . startNoiseTask . perform ( ) ;
348+ // The task loops on timeout(6000) after starting; cancel once started.
349+ await new Promise ( ( resolve ) => setTimeout ( resolve , 20 ) ) ;
350+ instance . cancel ( ) ;
351+ try {
352+ await instance ;
353+ } catch ( _e ) {
354+ // cancellation is expected
355+ }
356+
357+ // Ordered: the source is created, then started, then stopped on cancel.
358+ assert . verifySteps (
359+ [ 'getNoise' , 'start' , 'stop' ] ,
360+ 'noise is created before it is started, and stopped on cancellation' ,
361+ ) ;
362+ } ) ;
363+ } ) ;
290364} ) ;
0 commit comments