github.com/CyCoreSystems/ari@v4.8.4+incompatible/ext/play/play_test.go (about) 1 package play 2 3 import ( 4 "context" 5 "errors" 6 "testing" 7 8 "time" 9 10 "github.com/CyCoreSystems/ari" 11 "github.com/CyCoreSystems/ari/client/arimocks" 12 "github.com/stretchr/testify/mock" 13 ) 14 15 type playStagedTest struct { 16 playbackStartedChan chan ari.Event 17 playbackStarted *arimocks.Subscription 18 19 playbackEndChan chan ari.Event 20 playbackEnd *arimocks.Subscription 21 22 handleExec func(_ *ari.PlaybackHandle) error 23 24 playback *arimocks.Playback 25 26 key *ari.Key 27 28 handle *ari.PlaybackHandle 29 } 30 31 func (p *playStagedTest) Setup() { 32 33 p.playbackStarted = &arimocks.Subscription{} 34 p.playbackEnd = &arimocks.Subscription{} 35 p.playback = &arimocks.Playback{} 36 37 p.key = ari.NewKey(ari.PlaybackKey, "ph1") 38 39 p.playbackStartedChan = make(chan ari.Event) 40 p.playbackStarted.On("Events").Return((<-chan ari.Event)(p.playbackStartedChan)) 41 42 p.playbackStarted.On("Cancel").Times(1).Return(nil) 43 p.playback.On("Subscribe", p.key, ari.Events.PlaybackStarted).Return(p.playbackStarted) 44 p.playback.On("Stop", p.key).Times(1).Return(nil) 45 46 p.playbackEndChan = make(chan ari.Event) 47 p.playbackEnd.On("Events").Return((<-chan ari.Event)(p.playbackEndChan)) 48 p.playbackEnd.On("Cancel").Times(1).Return(nil) 49 p.playback.On("Subscribe", p.key, ari.Events.PlaybackFinished).Return(p.playbackEnd) 50 51 p.handle = ari.NewPlaybackHandle(p.key, p.playback, p.handleExec) 52 } 53 54 func TestPlayStaged(t *testing.T) { 55 t.Run("noEventTimeout", testPlayStagedNoEventTimeout) 56 t.Run("startFinishedEvent", testPlayStagedStartFinishedEvent) 57 t.Run("finishedBeforeStart", testPlayStagedFinishedEvent) 58 t.Run("failExec", testPlayStagedFailExec) 59 t.Run("cancel", testPlayStagedCancel) 60 t.Run("cancelAfterStart", testPlayStagedCancelAfterStart) 61 } 62 63 func testPlayStagedNoEventTimeout(t *testing.T) { 64 ctx, cancel := context.WithCancel(context.Background()) 65 defer cancel() 66 67 var p playStagedTest 68 p.Setup() 69 70 st, err := playStaged(ctx, p.handle, 0) 71 if err == nil || err.Error() != "timeout waiting for playback to start" { 72 t.Errorf("Expected error '%v', got '%v'", "timeout waiting for playback to start", err) 73 } 74 if st != Timeout { 75 t.Errorf("Expected status '%v', got '%v'", st, Timeout) 76 } 77 } 78 79 func testPlayStagedStartFinishedEvent(t *testing.T) { 80 ctx, cancel := context.WithCancel(context.Background()) 81 defer cancel() 82 83 var p playStagedTest 84 p.Setup() 85 86 go func() { 87 p.playbackStartedChan <- &ari.PlaybackStarted{} 88 time.After(10 * time.Millisecond) 89 p.playbackEndChan <- &ari.PlaybackFinished{} 90 }() 91 92 st, err := playStaged(ctx, p.handle, 20*time.Millisecond) 93 if err != nil { 94 t.Errorf("Unexpected error '%v'", err) 95 } 96 if st != Finished { 97 t.Errorf("Expected status '%v', got '%v'", st, Finished) 98 } 99 } 100 101 func testPlayStagedFinishedEvent(t *testing.T) { 102 ctx, cancel := context.WithCancel(context.Background()) 103 defer cancel() 104 105 var p playStagedTest 106 p.Setup() 107 108 go func() { 109 p.playbackEndChan <- &ari.PlaybackFinished{} 110 }() 111 112 st, err := playStaged(ctx, p.handle, 0) 113 if err != nil { 114 t.Errorf("Unexpected error '%v'", err) 115 } 116 if st != Finished { 117 t.Errorf("Expected status '%v', got '%v'", st, Finished) 118 } 119 } 120 121 func testPlayStagedFailExec(t *testing.T) { 122 ctx, cancel := context.WithCancel(context.Background()) 123 defer cancel() 124 125 var p playStagedTest 126 p.handleExec = func(_ *ari.PlaybackHandle) error { 127 return errors.New("err2") 128 } 129 p.Setup() 130 131 st, err := playStaged(ctx, p.handle, 0) 132 if err == nil || err.Error() != "failed to start playback: err2" { 133 t.Errorf("Expected error '%v', got '%v'", "failed to start playback: err2", err) 134 } 135 if st != Failed { 136 t.Errorf("Expected status '%v', got '%v'", st, Failed) 137 } 138 } 139 140 // nolint 141 func XXXtestPlayStagedFinishBeforeStart(t *testing.T) { 142 ctx, cancel := context.WithCancel(context.Background()) 143 defer cancel() 144 145 var p playStagedTest 146 p.Setup() 147 148 go func() { 149 time.After(100 * time.Millisecond) 150 p.playbackEndChan <- &ari.PlaybackFinished{} 151 }() 152 153 st, err := playStaged(ctx, p.handle, 0) 154 if err != nil { 155 t.Errorf("Unexpected error '%v'", err) 156 } 157 if st != Finished { 158 t.Errorf("Expected status '%v', got '%v'", st, Finished) 159 } 160 } 161 162 func testPlayStagedCancel(t *testing.T) { 163 ctx, cancel := context.WithCancel(context.Background()) 164 defer cancel() 165 166 var p playStagedTest 167 p.Setup() 168 169 go func() { 170 <-time.After(10 * time.Millisecond) 171 cancel() 172 }() 173 174 st, err := playStaged(ctx, p.handle, 20*time.Millisecond) 175 if err != nil { 176 t.Errorf("Unexpected error '%v'", err) 177 } 178 if st != Cancelled { 179 t.Errorf("Expected status '%v', got '%v'", st, Cancelled) 180 } 181 } 182 183 func testPlayStagedCancelAfterStart(t *testing.T) { 184 ctx, cancel := context.WithCancel(context.Background()) 185 defer cancel() 186 187 var p playStagedTest 188 p.Setup() 189 190 go func() { 191 p.playbackStartedChan <- &ari.PlaybackStarted{} 192 <-time.After(200 * time.Millisecond) 193 cancel() 194 }() 195 196 st, err := playStaged(ctx, p.handle, 0) 197 if err != nil { 198 t.Errorf("Unexpected error '%v'", err) 199 } 200 if st != Cancelled { 201 t.Errorf("Expected status '%v', got '%v'", st, Cancelled) 202 } 203 } 204 205 type playTest struct { 206 ps playStagedTest 207 208 dtmfChannel chan ari.Event 209 dtmfChannelSub *arimocks.Subscription 210 player *arimocks.Player 211 } 212 213 func (p *playTest) Setup() { 214 p.ps.Setup() 215 216 p.dtmfChannel = make(chan ari.Event) 217 p.dtmfChannelSub = &arimocks.Subscription{} 218 p.dtmfChannelSub.On("Events").Return((<-chan ari.Event)(p.dtmfChannel)) 219 p.dtmfChannelSub.On("Cancel").Return(nil) 220 221 p.player = &arimocks.Player{} 222 p.player.On("Subscribe", ari.Events.ChannelDtmfReceived).Return(p.dtmfChannelSub) 223 p.player.On("StagePlay", mock.Anything, "sound:1").Return(p.ps.handle, nil) 224 } 225 226 func TestPlay(t *testing.T) { 227 t.Run("testPlayNoURI", testPlayNoURI) 228 t.Run("testPlay", testPlay) 229 t.Run("testPlayDtmf", testPlayDtmf) 230 } 231 232 func testPlayNoURI(t *testing.T) { 233 ctx, cancel := context.WithCancel(context.Background()) 234 defer cancel() 235 236 var p playTest 237 p.Setup() 238 239 res, err := Play(ctx, p.player).Result() 240 if err == nil || err.Error() != "empty playback URI list" { 241 t.Errorf("Expected error '%v', got '%v'", "empty playback URI list", err) 242 } 243 if res.DTMF != "" { 244 t.Errorf("Unexpected DTMF: %s", res.DTMF) 245 } 246 } 247 248 func testPlay(t *testing.T) { 249 ctx, cancel := context.WithCancel(context.Background()) 250 defer cancel() 251 252 var p playTest 253 p.Setup() 254 255 go func() { 256 p.ps.playbackStartedChan <- &ari.PlaybackStarted{} 257 <-time.After(200 * time.Millisecond) 258 p.ps.playbackEndChan <- &ari.PlaybackFinished{} 259 }() 260 261 res, err := Play(ctx, p.player, URI("sound:1")).Result() 262 if err != nil { 263 t.Errorf("Unexpected error '%v'", err) 264 } 265 if res.Status != Finished { 266 t.Errorf("Expected status '%v', got '%v'", Finished, res.Status) 267 } 268 if res.DTMF != "" { 269 t.Errorf("Unexpected DTMF: %s", res.DTMF) 270 } 271 } 272 273 func testPlayDtmf(t *testing.T) { 274 ctx, cancel := context.WithCancel(context.Background()) 275 defer cancel() 276 277 var p playTest 278 p.Setup() 279 280 go func() { 281 p.ps.playbackStartedChan <- &ari.PlaybackStarted{} 282 <-time.After(200 * time.Millisecond) 283 284 p.dtmfChannel <- &ari.ChannelDtmfReceived{ 285 Digit: "1", 286 } 287 <-time.After(200 * time.Millisecond) 288 289 p.ps.playbackEndChan <- &ari.PlaybackFinished{} 290 }() 291 292 res, err := Prompt(ctx, p.player, URI("sound:1")).Result() 293 if err != nil { 294 t.Error("Unexpected error", err) 295 } 296 297 if res.MatchResult != Complete { 298 t.Errorf("Expected MatchResult '%v', got '%v'", Complete, res.MatchResult) 299 } 300 if res.DTMF != "1" { 301 t.Errorf("Expected DTMF %s, got DTMF %s", "1", res.DTMF) 302 } 303 }