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  }