1// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
2
3//go:build go1.16
4// +build go1.16
5
6package lexruntimev2
7
8import (
9	"bytes"
10	"context"
11	"io/ioutil"
12	"net/http"
13	"reflect"
14	"strings"
15	"sync"
16	"testing"
17	"time"
18
19	"github.com/aws/aws-sdk-go/aws"
20	"github.com/aws/aws-sdk-go/aws/awserr"
21	"github.com/aws/aws-sdk-go/aws/corehandlers"
22	"github.com/aws/aws-sdk-go/aws/request"
23	"github.com/aws/aws-sdk-go/awstesting/unit"
24	"github.com/aws/aws-sdk-go/private/protocol"
25	"github.com/aws/aws-sdk-go/private/protocol/eventstream"
26	"github.com/aws/aws-sdk-go/private/protocol/eventstream/eventstreamapi"
27	"github.com/aws/aws-sdk-go/private/protocol/eventstream/eventstreamtest"
28	"github.com/aws/aws-sdk-go/private/protocol/restjson"
29)
30
31var _ time.Time
32var _ awserr.Error
33var _ context.Context
34var _ sync.WaitGroup
35var _ strings.Reader
36
37func TestStartConversation_Read(t *testing.T) {
38	expectEvents, eventMsgs := mockStartConversationReadEvents()
39	sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t,
40		eventstreamtest.ServeEventStream{
41			T:      t,
42			Events: eventMsgs,
43		},
44		true,
45	)
46	if err != nil {
47		t.Fatalf("expect no error, %v", err)
48	}
49	defer cleanupFn()
50
51	svc := New(sess)
52	resp, err := svc.StartConversation(nil)
53	if err != nil {
54		t.Fatalf("expect no error got, %v", err)
55	}
56	defer resp.GetStream().Close()
57
58	var i int
59	for event := range resp.GetStream().Events() {
60		if event == nil {
61			t.Errorf("%d, expect event, got nil", i)
62		}
63		if e, a := expectEvents[i], event; !reflect.DeepEqual(e, a) {
64			t.Errorf("%d, expect %T %v, got %T %v", i, e, e, a, a)
65		}
66		i++
67	}
68
69	if err := resp.GetStream().Err(); err != nil {
70		t.Errorf("expect no error, %v", err)
71	}
72}
73
74func TestStartConversation_ReadClose(t *testing.T) {
75	_, eventMsgs := mockStartConversationReadEvents()
76	sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t,
77		eventstreamtest.ServeEventStream{
78			T:      t,
79			Events: eventMsgs,
80		},
81		true,
82	)
83	if err != nil {
84		t.Fatalf("expect no error, %v", err)
85	}
86	defer cleanupFn()
87
88	svc := New(sess)
89	resp, err := svc.StartConversation(nil)
90	if err != nil {
91		t.Fatalf("expect no error got, %v", err)
92	}
93
94	// Assert calling Err before close does not close the stream.
95	resp.GetStream().Err()
96	select {
97	case _, ok := <-resp.GetStream().Events():
98		if !ok {
99			t.Fatalf("expect stream not to be closed, but was")
100		}
101	default:
102	}
103
104	resp.GetStream().Close()
105	<-resp.GetStream().Events()
106
107	if err := resp.GetStream().Err(); err != nil {
108		t.Errorf("expect no error, %v", err)
109	}
110}
111
112func TestStartConversation_ReadUnknownEvent(t *testing.T) {
113	expectEvents, eventMsgs := mockStartConversationReadEvents()
114	var eventOffset int
115
116	unknownEvent := eventstream.Message{
117		Headers: eventstream.Headers{
118			eventstreamtest.EventMessageTypeHeader,
119			{
120				Name:  eventstreamapi.EventTypeHeader,
121				Value: eventstream.StringValue("UnknownEventName"),
122			},
123		},
124		Payload: []byte("some unknown event"),
125	}
126
127	eventMsgs = append(eventMsgs[:eventOffset],
128		append([]eventstream.Message{unknownEvent}, eventMsgs[eventOffset:]...)...)
129
130	expectEvents = append(expectEvents[:eventOffset],
131		append([]StartConversationResponseEventStreamEvent{
132			&StartConversationResponseEventStreamUnknownEvent{
133				Type:    "UnknownEventName",
134				Message: unknownEvent,
135			},
136		},
137			expectEvents[eventOffset:]...)...)
138
139	sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t,
140		eventstreamtest.ServeEventStream{
141			T:      t,
142			Events: eventMsgs,
143		},
144		true,
145	)
146	if err != nil {
147		t.Fatalf("expect no error, %v", err)
148	}
149	defer cleanupFn()
150
151	svc := New(sess)
152	resp, err := svc.StartConversation(nil)
153	if err != nil {
154		t.Fatalf("expect no error got, %v", err)
155	}
156	defer resp.GetStream().Close()
157
158	var i int
159	for event := range resp.GetStream().Events() {
160		if event == nil {
161			t.Errorf("%d, expect event, got nil", i)
162		}
163		if e, a := expectEvents[i], event; !reflect.DeepEqual(e, a) {
164			t.Errorf("%d, expect %T %v, got %T %v", i, e, e, a, a)
165		}
166		i++
167	}
168
169	if err := resp.GetStream().Err(); err != nil {
170		t.Errorf("expect no error, %v", err)
171	}
172}
173
174func BenchmarkStartConversation_Read(b *testing.B) {
175	_, eventMsgs := mockStartConversationReadEvents()
176	var buf bytes.Buffer
177	encoder := eventstream.NewEncoder(&buf)
178	for _, msg := range eventMsgs {
179		if err := encoder.Encode(msg); err != nil {
180			b.Fatalf("failed to encode message, %v", err)
181		}
182	}
183	stream := &loopReader{source: bytes.NewReader(buf.Bytes())}
184
185	sess := unit.Session
186	svc := New(sess, &aws.Config{
187		Endpoint:               aws.String("https://example.com"),
188		DisableParamValidation: aws.Bool(true),
189	})
190	svc.Handlers.Send.Swap(corehandlers.SendHandler.Name,
191		request.NamedHandler{Name: "mockSend",
192			Fn: func(r *request.Request) {
193				r.HTTPResponse = &http.Response{
194					Status:     "200 OK",
195					StatusCode: 200,
196					Header:     http.Header{},
197					Body:       ioutil.NopCloser(stream),
198				}
199			},
200		},
201	)
202
203	resp, err := svc.StartConversation(nil)
204	if err != nil {
205		b.Fatalf("failed to create request, %v", err)
206	}
207	defer resp.GetStream().Close()
208	b.ResetTimer()
209
210	for i := 0; i < b.N; i++ {
211		if err = resp.GetStream().Err(); err != nil {
212			b.Fatalf("expect no error, got %v", err)
213		}
214		event := <-resp.GetStream().Events()
215		if event == nil {
216			b.Fatalf("expect event, got nil, %v, %d", resp.GetStream().Err(), i)
217		}
218	}
219}
220
221func mockStartConversationReadEvents() (
222	[]StartConversationResponseEventStreamEvent,
223	[]eventstream.Message,
224) {
225	expectEvents := []StartConversationResponseEventStreamEvent{
226		&AudioResponseEvent{
227			AudioChunk:  []byte("blob value goes here"),
228			ContentType: aws.String("string value goes here"),
229			EventId:     aws.String("string value goes here"),
230		},
231		&HeartbeatEvent{
232			EventId: aws.String("string value goes here"),
233		},
234		&IntentResultEvent{
235			EventId:   aws.String("string value goes here"),
236			InputMode: aws.String("string value goes here"),
237			Interpretations: []*Interpretation{
238				{
239					Intent: &Intent{
240						ConfirmationState: aws.String("string value goes here"),
241						Name:              aws.String("string value goes here"),
242						Slots: map[string]*Slot{
243							"a": {
244								Shape: aws.String("string value goes here"),
245								Value: &Value{
246									InterpretedValue: aws.String("string value goes here"),
247									OriginalValue:    aws.String("string value goes here"),
248									ResolvedValues: []*string{
249										aws.String("string value goes here"),
250										aws.String("string value goes here"),
251										aws.String("string value goes here"),
252									},
253								},
254								Values: []*Slot{},
255							},
256							"b": {
257								Shape: aws.String("string value goes here"),
258								Value: &Value{
259									InterpretedValue: aws.String("string value goes here"),
260									OriginalValue:    aws.String("string value goes here"),
261									ResolvedValues: []*string{
262										aws.String("string value goes here"),
263										aws.String("string value goes here"),
264										aws.String("string value goes here"),
265									},
266								},
267								Values: []*Slot{},
268							},
269							"c": {
270								Shape: aws.String("string value goes here"),
271								Value: &Value{
272									InterpretedValue: aws.String("string value goes here"),
273									OriginalValue:    aws.String("string value goes here"),
274									ResolvedValues: []*string{
275										aws.String("string value goes here"),
276										aws.String("string value goes here"),
277										aws.String("string value goes here"),
278									},
279								},
280								Values: []*Slot{},
281							},
282						},
283						State: aws.String("string value goes here"),
284					},
285					NluConfidence: &ConfidenceScore{
286						Score: aws.Float64(123.45),
287					},
288					SentimentResponse: &SentimentResponse{
289						Sentiment: aws.String("string value goes here"),
290						SentimentScore: &SentimentScore{
291							Mixed:    aws.Float64(123.45),
292							Negative: aws.Float64(123.45),
293							Neutral:  aws.Float64(123.45),
294							Positive: aws.Float64(123.45),
295						},
296					},
297				},
298				{
299					Intent: &Intent{
300						ConfirmationState: aws.String("string value goes here"),
301						Name:              aws.String("string value goes here"),
302						Slots: map[string]*Slot{
303							"a": {
304								Shape: aws.String("string value goes here"),
305								Value: &Value{
306									InterpretedValue: aws.String("string value goes here"),
307									OriginalValue:    aws.String("string value goes here"),
308									ResolvedValues: []*string{
309										aws.String("string value goes here"),
310										aws.String("string value goes here"),
311										aws.String("string value goes here"),
312									},
313								},
314								Values: []*Slot{},
315							},
316							"b": {
317								Shape: aws.String("string value goes here"),
318								Value: &Value{
319									InterpretedValue: aws.String("string value goes here"),
320									OriginalValue:    aws.String("string value goes here"),
321									ResolvedValues: []*string{
322										aws.String("string value goes here"),
323										aws.String("string value goes here"),
324										aws.String("string value goes here"),
325									},
326								},
327								Values: []*Slot{},
328							},
329							"c": {
330								Shape: aws.String("string value goes here"),
331								Value: &Value{
332									InterpretedValue: aws.String("string value goes here"),
333									OriginalValue:    aws.String("string value goes here"),
334									ResolvedValues: []*string{
335										aws.String("string value goes here"),
336										aws.String("string value goes here"),
337										aws.String("string value goes here"),
338									},
339								},
340								Values: []*Slot{},
341							},
342						},
343						State: aws.String("string value goes here"),
344					},
345					NluConfidence: &ConfidenceScore{
346						Score: aws.Float64(123.45),
347					},
348					SentimentResponse: &SentimentResponse{
349						Sentiment: aws.String("string value goes here"),
350						SentimentScore: &SentimentScore{
351							Mixed:    aws.Float64(123.45),
352							Negative: aws.Float64(123.45),
353							Neutral:  aws.Float64(123.45),
354							Positive: aws.Float64(123.45),
355						},
356					},
357				},
358				{
359					Intent: &Intent{
360						ConfirmationState: aws.String("string value goes here"),
361						Name:              aws.String("string value goes here"),
362						Slots: map[string]*Slot{
363							"a": {
364								Shape: aws.String("string value goes here"),
365								Value: &Value{
366									InterpretedValue: aws.String("string value goes here"),
367									OriginalValue:    aws.String("string value goes here"),
368									ResolvedValues: []*string{
369										aws.String("string value goes here"),
370										aws.String("string value goes here"),
371										aws.String("string value goes here"),
372									},
373								},
374								Values: []*Slot{},
375							},
376							"b": {
377								Shape: aws.String("string value goes here"),
378								Value: &Value{
379									InterpretedValue: aws.String("string value goes here"),
380									OriginalValue:    aws.String("string value goes here"),
381									ResolvedValues: []*string{
382										aws.String("string value goes here"),
383										aws.String("string value goes here"),
384										aws.String("string value goes here"),
385									},
386								},
387								Values: []*Slot{},
388							},
389							"c": {
390								Shape: aws.String("string value goes here"),
391								Value: &Value{
392									InterpretedValue: aws.String("string value goes here"),
393									OriginalValue:    aws.String("string value goes here"),
394									ResolvedValues: []*string{
395										aws.String("string value goes here"),
396										aws.String("string value goes here"),
397										aws.String("string value goes here"),
398									},
399								},
400								Values: []*Slot{},
401							},
402						},
403						State: aws.String("string value goes here"),
404					},
405					NluConfidence: &ConfidenceScore{
406						Score: aws.Float64(123.45),
407					},
408					SentimentResponse: &SentimentResponse{
409						Sentiment: aws.String("string value goes here"),
410						SentimentScore: &SentimentScore{
411							Mixed:    aws.Float64(123.45),
412							Negative: aws.Float64(123.45),
413							Neutral:  aws.Float64(123.45),
414							Positive: aws.Float64(123.45),
415						},
416					},
417				},
418			},
419			RequestAttributes: map[string]*string{
420				"a": aws.String("string value goes here"),
421				"b": aws.String("string value goes here"),
422				"c": aws.String("string value goes here"),
423			},
424			SessionId: aws.String("string value goes here"),
425			SessionState: &SessionState{
426				ActiveContexts: []*ActiveContext{
427					{
428						ContextAttributes: map[string]*string{
429							"a": aws.String("string value goes here"),
430							"b": aws.String("string value goes here"),
431							"c": aws.String("string value goes here"),
432						},
433						Name: aws.String("string value goes here"),
434						TimeToLive: &ActiveContextTimeToLive{
435							TimeToLiveInSeconds: aws.Int64(123),
436							TurnsToLive:         aws.Int64(123),
437						},
438					},
439					{
440						ContextAttributes: map[string]*string{
441							"a": aws.String("string value goes here"),
442							"b": aws.String("string value goes here"),
443							"c": aws.String("string value goes here"),
444						},
445						Name: aws.String("string value goes here"),
446						TimeToLive: &ActiveContextTimeToLive{
447							TimeToLiveInSeconds: aws.Int64(123),
448							TurnsToLive:         aws.Int64(123),
449						},
450					},
451					{
452						ContextAttributes: map[string]*string{
453							"a": aws.String("string value goes here"),
454							"b": aws.String("string value goes here"),
455							"c": aws.String("string value goes here"),
456						},
457						Name: aws.String("string value goes here"),
458						TimeToLive: &ActiveContextTimeToLive{
459							TimeToLiveInSeconds: aws.Int64(123),
460							TurnsToLive:         aws.Int64(123),
461						},
462					},
463				},
464				DialogAction: &DialogAction{
465					SlotToElicit: aws.String("string value goes here"),
466					Type:         aws.String("string value goes here"),
467				},
468				Intent: &Intent{
469					ConfirmationState: aws.String("string value goes here"),
470					Name:              aws.String("string value goes here"),
471					Slots: map[string]*Slot{
472						"a": {
473							Shape: aws.String("string value goes here"),
474							Value: &Value{
475								InterpretedValue: aws.String("string value goes here"),
476								OriginalValue:    aws.String("string value goes here"),
477								ResolvedValues: []*string{
478									aws.String("string value goes here"),
479									aws.String("string value goes here"),
480									aws.String("string value goes here"),
481								},
482							},
483							Values: []*Slot{},
484						},
485						"b": {
486							Shape: aws.String("string value goes here"),
487							Value: &Value{
488								InterpretedValue: aws.String("string value goes here"),
489								OriginalValue:    aws.String("string value goes here"),
490								ResolvedValues: []*string{
491									aws.String("string value goes here"),
492									aws.String("string value goes here"),
493									aws.String("string value goes here"),
494								},
495							},
496							Values: []*Slot{},
497						},
498						"c": {
499							Shape: aws.String("string value goes here"),
500							Value: &Value{
501								InterpretedValue: aws.String("string value goes here"),
502								OriginalValue:    aws.String("string value goes here"),
503								ResolvedValues: []*string{
504									aws.String("string value goes here"),
505									aws.String("string value goes here"),
506									aws.String("string value goes here"),
507								},
508							},
509							Values: []*Slot{},
510						},
511					},
512					State: aws.String("string value goes here"),
513				},
514				OriginatingRequestId: aws.String("string value goes here"),
515				SessionAttributes: map[string]*string{
516					"a": aws.String("string value goes here"),
517					"b": aws.String("string value goes here"),
518					"c": aws.String("string value goes here"),
519				},
520			},
521		},
522		&PlaybackInterruptionEvent{
523			CausedByEventId: aws.String("string value goes here"),
524			EventId:         aws.String("string value goes here"),
525			EventReason:     aws.String("string value goes here"),
526		},
527		&TextResponseEvent{
528			EventId: aws.String("string value goes here"),
529			Messages: []*Message{
530				{
531					Content:     aws.String("string value goes here"),
532					ContentType: aws.String("string value goes here"),
533					ImageResponseCard: &ImageResponseCard{
534						Buttons: []*Button{
535							{
536								Text:  aws.String("string value goes here"),
537								Value: aws.String("string value goes here"),
538							},
539							{
540								Text:  aws.String("string value goes here"),
541								Value: aws.String("string value goes here"),
542							},
543							{
544								Text:  aws.String("string value goes here"),
545								Value: aws.String("string value goes here"),
546							},
547						},
548						ImageUrl: aws.String("string value goes here"),
549						Subtitle: aws.String("string value goes here"),
550						Title:    aws.String("string value goes here"),
551					},
552				},
553				{
554					Content:     aws.String("string value goes here"),
555					ContentType: aws.String("string value goes here"),
556					ImageResponseCard: &ImageResponseCard{
557						Buttons: []*Button{
558							{
559								Text:  aws.String("string value goes here"),
560								Value: aws.String("string value goes here"),
561							},
562							{
563								Text:  aws.String("string value goes here"),
564								Value: aws.String("string value goes here"),
565							},
566							{
567								Text:  aws.String("string value goes here"),
568								Value: aws.String("string value goes here"),
569							},
570						},
571						ImageUrl: aws.String("string value goes here"),
572						Subtitle: aws.String("string value goes here"),
573						Title:    aws.String("string value goes here"),
574					},
575				},
576				{
577					Content:     aws.String("string value goes here"),
578					ContentType: aws.String("string value goes here"),
579					ImageResponseCard: &ImageResponseCard{
580						Buttons: []*Button{
581							{
582								Text:  aws.String("string value goes here"),
583								Value: aws.String("string value goes here"),
584							},
585							{
586								Text:  aws.String("string value goes here"),
587								Value: aws.String("string value goes here"),
588							},
589							{
590								Text:  aws.String("string value goes here"),
591								Value: aws.String("string value goes here"),
592							},
593						},
594						ImageUrl: aws.String("string value goes here"),
595						Subtitle: aws.String("string value goes here"),
596						Title:    aws.String("string value goes here"),
597					},
598				},
599			},
600		},
601		&TranscriptEvent{
602			EventId:    aws.String("string value goes here"),
603			Transcript: aws.String("string value goes here"),
604		},
605	}
606
607	var marshalers request.HandlerList
608	marshalers.PushBackNamed(restjson.BuildHandler)
609	payloadMarshaler := protocol.HandlerPayloadMarshal{
610		Marshalers: marshalers,
611	}
612	_ = payloadMarshaler
613
614	eventMsgs := []eventstream.Message{
615		{
616			Headers: eventstream.Headers{
617				eventstreamtest.EventMessageTypeHeader,
618				{
619					Name:  eventstreamapi.EventTypeHeader,
620					Value: eventstream.StringValue("AudioResponseEvent"),
621				},
622			},
623			Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[0]),
624		},
625		{
626			Headers: eventstream.Headers{
627				eventstreamtest.EventMessageTypeHeader,
628				{
629					Name:  eventstreamapi.EventTypeHeader,
630					Value: eventstream.StringValue("HeartbeatEvent"),
631				},
632			},
633			Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[1]),
634		},
635		{
636			Headers: eventstream.Headers{
637				eventstreamtest.EventMessageTypeHeader,
638				{
639					Name:  eventstreamapi.EventTypeHeader,
640					Value: eventstream.StringValue("IntentResultEvent"),
641				},
642			},
643			Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[2]),
644		},
645		{
646			Headers: eventstream.Headers{
647				eventstreamtest.EventMessageTypeHeader,
648				{
649					Name:  eventstreamapi.EventTypeHeader,
650					Value: eventstream.StringValue("PlaybackInterruptionEvent"),
651				},
652			},
653			Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[3]),
654		},
655		{
656			Headers: eventstream.Headers{
657				eventstreamtest.EventMessageTypeHeader,
658				{
659					Name:  eventstreamapi.EventTypeHeader,
660					Value: eventstream.StringValue("TextResponseEvent"),
661				},
662			},
663			Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[4]),
664		},
665		{
666			Headers: eventstream.Headers{
667				eventstreamtest.EventMessageTypeHeader,
668				{
669					Name:  eventstreamapi.EventTypeHeader,
670					Value: eventstream.StringValue("TranscriptEvent"),
671				},
672			},
673			Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[5]),
674		},
675	}
676
677	return expectEvents, eventMsgs
678}
679func TestStartConversation_ReadException(t *testing.T) {
680	expectEvents := []StartConversationResponseEventStreamEvent{
681		&AccessDeniedException{
682			RespMetadata: protocol.ResponseMetadata{
683				StatusCode: 200,
684			},
685			Message_: aws.String("string value goes here"),
686		},
687	}
688
689	var marshalers request.HandlerList
690	marshalers.PushBackNamed(restjson.BuildHandler)
691	payloadMarshaler := protocol.HandlerPayloadMarshal{
692		Marshalers: marshalers,
693	}
694
695	eventMsgs := []eventstream.Message{
696		{
697			Headers: eventstream.Headers{
698				eventstreamtest.EventExceptionTypeHeader,
699				{
700					Name:  eventstreamapi.ExceptionTypeHeader,
701					Value: eventstream.StringValue("AccessDeniedException"),
702				},
703			},
704			Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[0]),
705		},
706	}
707
708	sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t,
709		eventstreamtest.ServeEventStream{
710			T:      t,
711			Events: eventMsgs,
712		},
713		true,
714	)
715	if err != nil {
716		t.Fatalf("expect no error, %v", err)
717	}
718	defer cleanupFn()
719
720	svc := New(sess)
721	resp, err := svc.StartConversation(nil)
722	if err != nil {
723		t.Fatalf("expect no error got, %v", err)
724	}
725
726	defer resp.GetStream().Close()
727
728	<-resp.GetStream().Events()
729
730	err = resp.GetStream().Err()
731	if err == nil {
732		t.Fatalf("expect err, got none")
733	}
734
735	expectErr := &AccessDeniedException{
736		RespMetadata: protocol.ResponseMetadata{
737			StatusCode: 200,
738		},
739		Message_: aws.String("string value goes here"),
740	}
741	aerr, ok := err.(awserr.Error)
742	if !ok {
743		t.Errorf("expect exception, got %T, %#v", err, err)
744	}
745	if e, a := expectErr.Code(), aerr.Code(); e != a {
746		t.Errorf("expect %v, got %v", e, a)
747	}
748	if e, a := expectErr.Message(), aerr.Message(); e != a {
749		t.Errorf("expect %v, got %v", e, a)
750	}
751
752	if e, a := expectErr, aerr; !reflect.DeepEqual(e, a) {
753		t.Errorf("expect error %+#v, got %+#v", e, a)
754	}
755}
756
757var _ awserr.Error = (*AccessDeniedException)(nil)
758var _ awserr.Error = (*BadGatewayException)(nil)
759var _ awserr.Error = (*ConflictException)(nil)
760var _ awserr.Error = (*DependencyFailedException)(nil)
761var _ awserr.Error = (*InternalServerException)(nil)
762var _ awserr.Error = (*ResourceNotFoundException)(nil)
763var _ awserr.Error = (*ThrottlingException)(nil)
764var _ awserr.Error = (*ValidationException)(nil)
765
766type loopReader struct {
767	source *bytes.Reader
768}
769
770func (c *loopReader) Read(p []byte) (int, error) {
771	if c.source.Len() == 0 {
772		c.source.Seek(0, 0)
773	}
774
775	return c.source.Read(p)
776}
777
778func TestStartConversation_Write(t *testing.T) {
779	clientEvents, expectedClientEvents := mockStartConversationWriteEvents()
780
781	sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t,
782		&eventstreamtest.ServeEventStream{
783			T:             t,
784			ClientEvents:  expectedClientEvents,
785			BiDirectional: true,
786		},
787		true)
788	defer cleanupFn()
789
790	svc := New(sess)
791	resp, err := svc.StartConversation(nil)
792	if err != nil {
793		t.Fatalf("expect no error, got %v", err)
794	}
795
796	stream := resp.GetStream()
797
798	for _, event := range clientEvents {
799		err = stream.Send(context.Background(), event)
800		if err != nil {
801			t.Fatalf("expect no error, got %v", err)
802		}
803	}
804
805	if err := stream.Close(); err != nil {
806		t.Errorf("expect no error, got %v", err)
807	}
808}
809
810func TestStartConversation_WriteClose(t *testing.T) {
811	sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t,
812		eventstreamtest.ServeEventStream{T: t, BiDirectional: true},
813		true,
814	)
815	if err != nil {
816		t.Fatalf("expect no error, %v", err)
817	}
818	defer cleanupFn()
819
820	svc := New(sess)
821	resp, err := svc.StartConversation(nil)
822	if err != nil {
823		t.Fatalf("expect no error got, %v", err)
824	}
825
826	// Assert calling Err before close does not close the stream.
827	resp.GetStream().Err()
828
829	err = resp.GetStream().Send(context.Background(), &AudioInputEvent{})
830	if err != nil {
831		t.Fatalf("expect no error, got %v", err)
832	}
833
834	resp.GetStream().Close()
835
836	if err := resp.GetStream().Err(); err != nil {
837		t.Errorf("expect no error, %v", err)
838	}
839}
840
841func TestStartConversation_WriteError(t *testing.T) {
842	sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t,
843		eventstreamtest.ServeEventStream{
844			T:               t,
845			BiDirectional:   true,
846			ForceCloseAfter: time.Millisecond * 500,
847		},
848		true,
849	)
850	if err != nil {
851		t.Fatalf("expect no error, %v", err)
852	}
853	defer cleanupFn()
854
855	svc := New(sess)
856	resp, err := svc.StartConversation(nil)
857	if err != nil {
858		t.Fatalf("expect no error got, %v", err)
859	}
860
861	defer resp.GetStream().Close()
862
863	for {
864		err = resp.GetStream().Send(context.Background(), &AudioInputEvent{})
865		if err != nil {
866			if strings.Contains("unable to send event", err.Error()) {
867				t.Errorf("expected stream closed error, got %v", err)
868			}
869			break
870		}
871	}
872}
873
874func TestStartConversation_ReadWrite(t *testing.T) {
875	expectedServiceEvents, serviceEvents := mockStartConversationReadEvents()
876	clientEvents, expectedClientEvents := mockStartConversationWriteEvents()
877
878	sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t,
879		&eventstreamtest.ServeEventStream{
880			T:             t,
881			ClientEvents:  expectedClientEvents,
882			Events:        serviceEvents,
883			BiDirectional: true,
884		},
885		true)
886	defer cleanupFn()
887
888	svc := New(sess)
889	resp, err := svc.StartConversation(nil)
890	if err != nil {
891		t.Fatalf("expect no error, got %v", err)
892	}
893
894	stream := resp.GetStream()
895	defer stream.Close()
896
897	var wg sync.WaitGroup
898
899	wg.Add(1)
900	go func() {
901		defer wg.Done()
902		var i int
903		for event := range resp.GetStream().Events() {
904			if event == nil {
905				t.Errorf("%d, expect event, got nil", i)
906			}
907			if e, a := expectedServiceEvents[i], event; !reflect.DeepEqual(e, a) {
908				t.Errorf("%d, expect %T %v, got %T %v", i, e, e, a, a)
909			}
910			i++
911		}
912	}()
913
914	for _, event := range clientEvents {
915		err = stream.Send(context.Background(), event)
916		if err != nil {
917			t.Errorf("expect no error, got %v", err)
918		}
919	}
920
921	resp.GetStream().Close()
922
923	wg.Wait()
924
925	if err := resp.GetStream().Err(); err != nil {
926		t.Errorf("expect no error, %v", err)
927	}
928}
929
930func mockStartConversationWriteEvents() (
931	[]StartConversationRequestEventStreamEvent,
932	[]eventstream.Message,
933) {
934	inputEvents := []StartConversationRequestEventStreamEvent{
935		&AudioInputEvent{
936			AudioChunk:            []byte("blob value goes here"),
937			ClientTimestampMillis: aws.Int64(1234),
938			ContentType:           aws.String("string value goes here"),
939			EventId:               aws.String("string value goes here"),
940		},
941		&ConfigurationEvent{
942			ClientTimestampMillis: aws.Int64(1234),
943			DisablePlayback:       aws.Bool(true),
944			EventId:               aws.String("string value goes here"),
945			RequestAttributes: map[string]*string{
946				"a": aws.String("string value goes here"),
947				"b": aws.String("string value goes here"),
948				"c": aws.String("string value goes here"),
949			},
950			ResponseContentType: aws.String("string value goes here"),
951			SessionState: &SessionState{
952				ActiveContexts: []*ActiveContext{
953					{
954						ContextAttributes: map[string]*string{
955							"a": aws.String("string value goes here"),
956							"b": aws.String("string value goes here"),
957							"c": aws.String("string value goes here"),
958						},
959						Name: aws.String("string value goes here"),
960						TimeToLive: &ActiveContextTimeToLive{
961							TimeToLiveInSeconds: aws.Int64(123),
962							TurnsToLive:         aws.Int64(123),
963						},
964					},
965					{
966						ContextAttributes: map[string]*string{
967							"a": aws.String("string value goes here"),
968							"b": aws.String("string value goes here"),
969							"c": aws.String("string value goes here"),
970						},
971						Name: aws.String("string value goes here"),
972						TimeToLive: &ActiveContextTimeToLive{
973							TimeToLiveInSeconds: aws.Int64(123),
974							TurnsToLive:         aws.Int64(123),
975						},
976					},
977					{
978						ContextAttributes: map[string]*string{
979							"a": aws.String("string value goes here"),
980							"b": aws.String("string value goes here"),
981							"c": aws.String("string value goes here"),
982						},
983						Name: aws.String("string value goes here"),
984						TimeToLive: &ActiveContextTimeToLive{
985							TimeToLiveInSeconds: aws.Int64(123),
986							TurnsToLive:         aws.Int64(123),
987						},
988					},
989				},
990				DialogAction: &DialogAction{
991					SlotToElicit: aws.String("string value goes here"),
992					Type:         aws.String("string value goes here"),
993				},
994				Intent: &Intent{
995					ConfirmationState: aws.String("string value goes here"),
996					Name:              aws.String("string value goes here"),
997					Slots: map[string]*Slot{
998						"a": {
999							Shape: aws.String("string value goes here"),
1000							Value: &Value{
1001								InterpretedValue: aws.String("string value goes here"),
1002								OriginalValue:    aws.String("string value goes here"),
1003								ResolvedValues: []*string{
1004									aws.String("string value goes here"),
1005									aws.String("string value goes here"),
1006									aws.String("string value goes here"),
1007								},
1008							},
1009							Values: []*Slot{},
1010						},
1011						"b": {
1012							Shape: aws.String("string value goes here"),
1013							Value: &Value{
1014								InterpretedValue: aws.String("string value goes here"),
1015								OriginalValue:    aws.String("string value goes here"),
1016								ResolvedValues: []*string{
1017									aws.String("string value goes here"),
1018									aws.String("string value goes here"),
1019									aws.String("string value goes here"),
1020								},
1021							},
1022							Values: []*Slot{},
1023						},
1024						"c": {
1025							Shape: aws.String("string value goes here"),
1026							Value: &Value{
1027								InterpretedValue: aws.String("string value goes here"),
1028								OriginalValue:    aws.String("string value goes here"),
1029								ResolvedValues: []*string{
1030									aws.String("string value goes here"),
1031									aws.String("string value goes here"),
1032									aws.String("string value goes here"),
1033								},
1034							},
1035							Values: []*Slot{},
1036						},
1037					},
1038					State: aws.String("string value goes here"),
1039				},
1040				OriginatingRequestId: aws.String("string value goes here"),
1041				SessionAttributes: map[string]*string{
1042					"a": aws.String("string value goes here"),
1043					"b": aws.String("string value goes here"),
1044					"c": aws.String("string value goes here"),
1045				},
1046			},
1047			WelcomeMessages: []*Message{
1048				{
1049					Content:     aws.String("string value goes here"),
1050					ContentType: aws.String("string value goes here"),
1051					ImageResponseCard: &ImageResponseCard{
1052						Buttons: []*Button{
1053							{
1054								Text:  aws.String("string value goes here"),
1055								Value: aws.String("string value goes here"),
1056							},
1057							{
1058								Text:  aws.String("string value goes here"),
1059								Value: aws.String("string value goes here"),
1060							},
1061							{
1062								Text:  aws.String("string value goes here"),
1063								Value: aws.String("string value goes here"),
1064							},
1065						},
1066						ImageUrl: aws.String("string value goes here"),
1067						Subtitle: aws.String("string value goes here"),
1068						Title:    aws.String("string value goes here"),
1069					},
1070				},
1071				{
1072					Content:     aws.String("string value goes here"),
1073					ContentType: aws.String("string value goes here"),
1074					ImageResponseCard: &ImageResponseCard{
1075						Buttons: []*Button{
1076							{
1077								Text:  aws.String("string value goes here"),
1078								Value: aws.String("string value goes here"),
1079							},
1080							{
1081								Text:  aws.String("string value goes here"),
1082								Value: aws.String("string value goes here"),
1083							},
1084							{
1085								Text:  aws.String("string value goes here"),
1086								Value: aws.String("string value goes here"),
1087							},
1088						},
1089						ImageUrl: aws.String("string value goes here"),
1090						Subtitle: aws.String("string value goes here"),
1091						Title:    aws.String("string value goes here"),
1092					},
1093				},
1094				{
1095					Content:     aws.String("string value goes here"),
1096					ContentType: aws.String("string value goes here"),
1097					ImageResponseCard: &ImageResponseCard{
1098						Buttons: []*Button{
1099							{
1100								Text:  aws.String("string value goes here"),
1101								Value: aws.String("string value goes here"),
1102							},
1103							{
1104								Text:  aws.String("string value goes here"),
1105								Value: aws.String("string value goes here"),
1106							},
1107							{
1108								Text:  aws.String("string value goes here"),
1109								Value: aws.String("string value goes here"),
1110							},
1111						},
1112						ImageUrl: aws.String("string value goes here"),
1113						Subtitle: aws.String("string value goes here"),
1114						Title:    aws.String("string value goes here"),
1115					},
1116				},
1117			},
1118		},
1119		&DTMFInputEvent{
1120			ClientTimestampMillis: aws.Int64(1234),
1121			EventId:               aws.String("string value goes here"),
1122			InputCharacter:        aws.String("string value goes here"),
1123		},
1124		&DisconnectionEvent{
1125			ClientTimestampMillis: aws.Int64(1234),
1126			EventId:               aws.String("string value goes here"),
1127		},
1128		&PlaybackCompletionEvent{
1129			ClientTimestampMillis: aws.Int64(1234),
1130			EventId:               aws.String("string value goes here"),
1131		},
1132		&TextInputEvent{
1133			ClientTimestampMillis: aws.Int64(1234),
1134			EventId:               aws.String("string value goes here"),
1135			Text:                  aws.String("string value goes here"),
1136		},
1137	}
1138
1139	var marshalers request.HandlerList
1140	marshalers.PushBackNamed(restjson.BuildHandler)
1141	payloadMarshaler := protocol.HandlerPayloadMarshal{
1142		Marshalers: marshalers,
1143	}
1144	_ = payloadMarshaler
1145
1146	eventMsgs := []eventstream.Message{
1147		{
1148			Headers: eventstream.Headers{
1149				eventstreamtest.EventMessageTypeHeader,
1150				{
1151					Name:  eventstreamapi.EventTypeHeader,
1152					Value: eventstream.StringValue("AudioInputEvent"),
1153				},
1154			},
1155			Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, inputEvents[0]),
1156		},
1157		{
1158			Headers: eventstream.Headers{
1159				eventstreamtest.EventMessageTypeHeader,
1160				{
1161					Name:  eventstreamapi.EventTypeHeader,
1162					Value: eventstream.StringValue("ConfigurationEvent"),
1163				},
1164			},
1165			Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, inputEvents[1]),
1166		},
1167		{
1168			Headers: eventstream.Headers{
1169				eventstreamtest.EventMessageTypeHeader,
1170				{
1171					Name:  eventstreamapi.EventTypeHeader,
1172					Value: eventstream.StringValue("DTMFInputEvent"),
1173				},
1174			},
1175			Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, inputEvents[2]),
1176		},
1177		{
1178			Headers: eventstream.Headers{
1179				eventstreamtest.EventMessageTypeHeader,
1180				{
1181					Name:  eventstreamapi.EventTypeHeader,
1182					Value: eventstream.StringValue("DisconnectionEvent"),
1183				},
1184			},
1185			Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, inputEvents[3]),
1186		},
1187		{
1188			Headers: eventstream.Headers{
1189				eventstreamtest.EventMessageTypeHeader,
1190				{
1191					Name:  eventstreamapi.EventTypeHeader,
1192					Value: eventstream.StringValue("PlaybackCompletionEvent"),
1193				},
1194			},
1195			Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, inputEvents[4]),
1196		},
1197		{
1198			Headers: eventstream.Headers{
1199				eventstreamtest.EventMessageTypeHeader,
1200				{
1201					Name:  eventstreamapi.EventTypeHeader,
1202					Value: eventstream.StringValue("TextInputEvent"),
1203				},
1204			},
1205			Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, inputEvents[5]),
1206		},
1207	}
1208
1209	return inputEvents, eventMsgs
1210}
1211