@stream-io/video-client 1.40.2 → 1.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/dist/index.browser.es.js +165 -30
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +172 -29
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +165 -30
- package/dist/index.es.js.map +1 -1
- package/dist/src/Call.d.ts +4 -4
- package/dist/src/devices/SpeakerManager.d.ts +0 -2
- package/dist/src/gen/coordinator/index.d.ts +269 -0
- package/dist/src/rtc/helpers/sdp.d.ts +8 -0
- package/dist/src/store/CallState.d.ts +21 -2
- package/dist/src/types.d.ts +29 -1
- package/package.json +1 -1
- package/src/Call.ts +27 -6
- package/src/__tests__/StreamVideoClient.ringing.test.ts +26 -0
- package/src/devices/SpeakerManager.ts +0 -2
- package/src/devices/__tests__/MicrophoneManager.test.ts +34 -23
- package/src/devices/__tests__/mocks.ts +14 -12
- package/src/events/__tests__/call.test.ts +4 -5
- package/src/gen/coordinator/index.ts +293 -0
- package/src/rtc/Publisher.ts +1 -1
- package/src/rtc/helpers/__tests__/sdp.startBitrate.test.ts +105 -0
- package/src/rtc/helpers/sdp.ts +30 -12
- package/src/store/CallState.ts +72 -9
- package/src/store/__tests__/CallState.test.ts +462 -106
- package/src/types.ts +42 -0
|
@@ -57,7 +57,9 @@ describe('CallState', () => {
|
|
|
57
57
|
it(`shouldn't emit when primitive (backstage) values didn't change`, () => {
|
|
58
58
|
const state = new CallState();
|
|
59
59
|
const updateWith = (value: boolean) => {
|
|
60
|
-
state.updateFromCallResponse(
|
|
60
|
+
state.updateFromCallResponse(
|
|
61
|
+
fromPartial({ backstage: value, egress: {} }),
|
|
62
|
+
);
|
|
61
63
|
};
|
|
62
64
|
|
|
63
65
|
updateWith(false);
|
|
@@ -138,7 +140,9 @@ describe('CallState', () => {
|
|
|
138
140
|
it(`shouldn't emit when string arrays (blockedUserIds) value didn't change`, () => {
|
|
139
141
|
const state = new CallState();
|
|
140
142
|
const updateWith = (value: string[]) => {
|
|
141
|
-
state.updateFromCallResponse(
|
|
143
|
+
state.updateFromCallResponse(
|
|
144
|
+
fromPartial({ blocked_user_ids: value, egress: {} }),
|
|
145
|
+
);
|
|
142
146
|
};
|
|
143
147
|
|
|
144
148
|
updateWith(['a', 'b']);
|
|
@@ -387,13 +391,12 @@ describe('CallState', () => {
|
|
|
387
391
|
describe('call.live and backstage events', () => {
|
|
388
392
|
it('handles call.live_started events', () => {
|
|
389
393
|
const state = new CallState();
|
|
390
|
-
state.updateFromEvent(
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
});
|
|
394
|
+
state.updateFromEvent(
|
|
395
|
+
fromPartial({
|
|
396
|
+
type: 'call.live_started',
|
|
397
|
+
call: fromPartial({ backstage: false, egress: {} }),
|
|
398
|
+
}),
|
|
399
|
+
);
|
|
397
400
|
expect(state.backstage).toBe(false);
|
|
398
401
|
});
|
|
399
402
|
});
|
|
@@ -402,17 +405,15 @@ describe('CallState', () => {
|
|
|
402
405
|
describe('call.updated', () => {
|
|
403
406
|
it(`will update the call's metadata`, () => {
|
|
404
407
|
const state = new CallState();
|
|
405
|
-
const event: CallUpdatedEvent = {
|
|
408
|
+
const event: CallUpdatedEvent = fromPartial({
|
|
406
409
|
type: 'call.updated',
|
|
407
410
|
call_cid: 'development:12345',
|
|
408
|
-
|
|
409
|
-
call: {
|
|
411
|
+
call: fromPartial({
|
|
410
412
|
cid: 'development:12345',
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
};
|
|
413
|
+
egress: {},
|
|
414
|
+
custom: { test: 'value' },
|
|
415
|
+
}),
|
|
416
|
+
});
|
|
416
417
|
|
|
417
418
|
// @ts-expect-error incomplete data
|
|
418
419
|
state.updateFromEvent(event);
|
|
@@ -423,15 +424,10 @@ describe('CallState', () => {
|
|
|
423
424
|
describe(`call.accepted`, () => {
|
|
424
425
|
it(`will update state`, () => {
|
|
425
426
|
const state = new CallState();
|
|
426
|
-
const event: CallAcceptedEvent = {
|
|
427
|
+
const event: CallAcceptedEvent = fromPartial({
|
|
427
428
|
type: 'call.accepted',
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
custom: {
|
|
431
|
-
test: 'value',
|
|
432
|
-
},
|
|
433
|
-
},
|
|
434
|
-
};
|
|
429
|
+
call: fromPartial({ egress: {}, custom: { test: 'value' } }),
|
|
430
|
+
});
|
|
435
431
|
// @ts-expect-error incomplete data
|
|
436
432
|
state.updateFromEvent(event);
|
|
437
433
|
|
|
@@ -442,15 +438,10 @@ describe('CallState', () => {
|
|
|
442
438
|
describe(`call.rejected`, () => {
|
|
443
439
|
it(`will update state`, () => {
|
|
444
440
|
const state = new CallState();
|
|
445
|
-
const event: CallEndedEvent = {
|
|
441
|
+
const event: CallEndedEvent = fromPartial({
|
|
446
442
|
type: 'call.rejected',
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
custom: {
|
|
450
|
-
test: 'value',
|
|
451
|
-
},
|
|
452
|
-
},
|
|
453
|
-
};
|
|
443
|
+
call: fromPartial({ egress: {}, custom: { test: 'value' } }),
|
|
444
|
+
});
|
|
454
445
|
// @ts-expect-error incomplete data
|
|
455
446
|
state.updateFromEvent(event);
|
|
456
447
|
|
|
@@ -461,15 +452,10 @@ describe('CallState', () => {
|
|
|
461
452
|
describe(`call.ended`, () => {
|
|
462
453
|
it(`will update state`, () => {
|
|
463
454
|
const state = new CallState();
|
|
464
|
-
const event: CallEndedEvent = {
|
|
455
|
+
const event: CallEndedEvent = fromPartial({
|
|
465
456
|
type: 'call.ended',
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
custom: {
|
|
469
|
-
test: 'value',
|
|
470
|
-
},
|
|
471
|
-
},
|
|
472
|
-
};
|
|
457
|
+
call: fromPartial({ egress: {}, custom: { test: 'value' } }),
|
|
458
|
+
});
|
|
473
459
|
// @ts-expect-error incomplete data
|
|
474
460
|
state.updateFromEvent(event);
|
|
475
461
|
|
|
@@ -525,7 +511,7 @@ describe('CallState', () => {
|
|
|
525
511
|
// @ts-expect-error incomplete data
|
|
526
512
|
members: [{ user_id: 'user1' }, { user_id: 'user2' }],
|
|
527
513
|
// @ts-expect-error incomplete data
|
|
528
|
-
call: {},
|
|
514
|
+
call: { egress: {} },
|
|
529
515
|
});
|
|
530
516
|
|
|
531
517
|
const updatedMembers = state.members;
|
|
@@ -551,7 +537,7 @@ describe('CallState', () => {
|
|
|
551
537
|
type: 'call.member_removed',
|
|
552
538
|
members: removedMembers,
|
|
553
539
|
// @ts-expect-error incomplete data
|
|
554
|
-
call: {},
|
|
540
|
+
call: { egress: {} },
|
|
555
541
|
});
|
|
556
542
|
|
|
557
543
|
const updatedMembers = state.members;
|
|
@@ -596,7 +582,7 @@ describe('CallState', () => {
|
|
|
596
582
|
},
|
|
597
583
|
],
|
|
598
584
|
// @ts-expect-error incomplete data
|
|
599
|
-
call: {},
|
|
585
|
+
call: { egress: {} },
|
|
600
586
|
});
|
|
601
587
|
|
|
602
588
|
const updatedMembers = state.members;
|
|
@@ -626,7 +612,7 @@ describe('CallState', () => {
|
|
|
626
612
|
// @ts-expect-error incomplete data
|
|
627
613
|
members: [{ ...user1, user: { name: 'John' } }],
|
|
628
614
|
// @ts-expect-error incomplete data
|
|
629
|
-
call: {},
|
|
615
|
+
call: { egress: {} },
|
|
630
616
|
});
|
|
631
617
|
|
|
632
618
|
const updatedMembers = state.members;
|
|
@@ -691,7 +677,7 @@ describe('CallState', () => {
|
|
|
691
677
|
it('handles call.hls_broadcasting_stopped events', () => {
|
|
692
678
|
const state = new CallState();
|
|
693
679
|
// @ts-expect-error incomplete data
|
|
694
|
-
state.updateFromCallResponse({});
|
|
680
|
+
state.updateFromCallResponse({ egress: {} });
|
|
695
681
|
// @ts-expect-error incomplete data
|
|
696
682
|
state.updateFromEvent({
|
|
697
683
|
type: 'call.hls_broadcasting_stopped',
|
|
@@ -709,20 +695,381 @@ describe('CallState', () => {
|
|
|
709
695
|
});
|
|
710
696
|
});
|
|
711
697
|
|
|
698
|
+
describe('updateFromRecordingEvent', () => {
|
|
699
|
+
describe('COMPOSITE recording type', () => {
|
|
700
|
+
it('should set recording to true when composite recording starts', () => {
|
|
701
|
+
const state = new CallState();
|
|
702
|
+
state.updateFromEvent(
|
|
703
|
+
fromPartial({
|
|
704
|
+
type: 'call.recording_started',
|
|
705
|
+
recording_type: 'composite',
|
|
706
|
+
}),
|
|
707
|
+
);
|
|
708
|
+
expect(state.recording).toBe(true);
|
|
709
|
+
expect(state.individualRecording).toBe(false);
|
|
710
|
+
expect(state.rawRecording).toBe(false);
|
|
711
|
+
});
|
|
712
|
+
|
|
713
|
+
it('should set recording to false when composite recording stops', () => {
|
|
714
|
+
const state = new CallState();
|
|
715
|
+
state.updateFromEvent(
|
|
716
|
+
fromPartial({
|
|
717
|
+
type: 'call.recording_started',
|
|
718
|
+
recording_type: 'composite',
|
|
719
|
+
}),
|
|
720
|
+
);
|
|
721
|
+
expect(state.recording).toBe(true);
|
|
722
|
+
|
|
723
|
+
state.updateFromEvent(
|
|
724
|
+
fromPartial({
|
|
725
|
+
type: 'call.recording_stopped',
|
|
726
|
+
recording_type: 'composite',
|
|
727
|
+
}),
|
|
728
|
+
);
|
|
729
|
+
expect(state.recording).toBe(false);
|
|
730
|
+
});
|
|
731
|
+
|
|
732
|
+
it('should set recording to false when composite recording fails', () => {
|
|
733
|
+
const state = new CallState();
|
|
734
|
+
state.updateFromEvent(
|
|
735
|
+
fromPartial({
|
|
736
|
+
type: 'call.recording_started',
|
|
737
|
+
recording_type: 'composite',
|
|
738
|
+
}),
|
|
739
|
+
);
|
|
740
|
+
expect(state.recording).toBe(true);
|
|
741
|
+
|
|
742
|
+
state.updateFromEvent(
|
|
743
|
+
fromPartial({
|
|
744
|
+
type: 'call.recording_failed',
|
|
745
|
+
recording_type: 'composite',
|
|
746
|
+
}),
|
|
747
|
+
);
|
|
748
|
+
expect(state.recording).toBe(false);
|
|
749
|
+
});
|
|
750
|
+
});
|
|
751
|
+
|
|
752
|
+
describe('INDIVIDUAL recording type', () => {
|
|
753
|
+
it('should set individualRecording to true when individual recording starts', () => {
|
|
754
|
+
const state = new CallState();
|
|
755
|
+
state.updateFromEvent(
|
|
756
|
+
fromPartial({
|
|
757
|
+
type: 'call.recording_started',
|
|
758
|
+
recording_type: 'individual',
|
|
759
|
+
}),
|
|
760
|
+
);
|
|
761
|
+
expect(state.individualRecording).toBe(true);
|
|
762
|
+
expect(state.recording).toBe(false);
|
|
763
|
+
expect(state.rawRecording).toBe(false);
|
|
764
|
+
});
|
|
765
|
+
|
|
766
|
+
it('should set individualRecording to false when individual recording stops', () => {
|
|
767
|
+
const state = new CallState();
|
|
768
|
+
state.updateFromEvent(
|
|
769
|
+
fromPartial({
|
|
770
|
+
type: 'call.recording_started',
|
|
771
|
+
recording_type: 'individual',
|
|
772
|
+
}),
|
|
773
|
+
);
|
|
774
|
+
expect(state.individualRecording).toBe(true);
|
|
775
|
+
|
|
776
|
+
state.updateFromEvent(
|
|
777
|
+
fromPartial({
|
|
778
|
+
type: 'call.recording_stopped',
|
|
779
|
+
recording_type: 'individual',
|
|
780
|
+
}),
|
|
781
|
+
);
|
|
782
|
+
expect(state.individualRecording).toBe(false);
|
|
783
|
+
});
|
|
784
|
+
|
|
785
|
+
it('should set individualRecording to false when individual recording fails', () => {
|
|
786
|
+
const state = new CallState();
|
|
787
|
+
state.updateFromEvent(
|
|
788
|
+
fromPartial({
|
|
789
|
+
type: 'call.recording_started',
|
|
790
|
+
recording_type: 'individual',
|
|
791
|
+
}),
|
|
792
|
+
);
|
|
793
|
+
expect(state.individualRecording).toBe(true);
|
|
794
|
+
|
|
795
|
+
state.updateFromEvent(
|
|
796
|
+
fromPartial({
|
|
797
|
+
type: 'call.recording_failed',
|
|
798
|
+
recording_type: 'individual',
|
|
799
|
+
}),
|
|
800
|
+
);
|
|
801
|
+
expect(state.individualRecording).toBe(false);
|
|
802
|
+
});
|
|
803
|
+
});
|
|
804
|
+
|
|
805
|
+
describe('RAW recording type', () => {
|
|
806
|
+
it('should set rawRecording to true when raw recording starts', () => {
|
|
807
|
+
const state = new CallState();
|
|
808
|
+
state.updateFromEvent(
|
|
809
|
+
fromPartial({
|
|
810
|
+
type: 'call.recording_started',
|
|
811
|
+
recording_type: 'raw',
|
|
812
|
+
}),
|
|
813
|
+
);
|
|
814
|
+
expect(state.rawRecording).toBe(true);
|
|
815
|
+
expect(state.recording).toBe(false);
|
|
816
|
+
expect(state.individualRecording).toBe(false);
|
|
817
|
+
});
|
|
818
|
+
|
|
819
|
+
it('should set rawRecording to false when raw recording stops', () => {
|
|
820
|
+
const state = new CallState();
|
|
821
|
+
state.updateFromEvent(
|
|
822
|
+
fromPartial({
|
|
823
|
+
type: 'call.recording_started',
|
|
824
|
+
recording_type: 'raw',
|
|
825
|
+
}),
|
|
826
|
+
);
|
|
827
|
+
expect(state.rawRecording).toBe(true);
|
|
828
|
+
|
|
829
|
+
state.updateFromEvent(
|
|
830
|
+
fromPartial({
|
|
831
|
+
type: 'call.recording_stopped',
|
|
832
|
+
recording_type: 'raw',
|
|
833
|
+
}),
|
|
834
|
+
);
|
|
835
|
+
expect(state.rawRecording).toBe(false);
|
|
836
|
+
});
|
|
837
|
+
|
|
838
|
+
it('should set rawRecording to false when raw recording fails', () => {
|
|
839
|
+
const state = new CallState();
|
|
840
|
+
state.updateFromEvent(
|
|
841
|
+
fromPartial({
|
|
842
|
+
type: 'call.recording_started',
|
|
843
|
+
recording_type: 'raw',
|
|
844
|
+
}),
|
|
845
|
+
);
|
|
846
|
+
expect(state.rawRecording).toBe(true);
|
|
847
|
+
|
|
848
|
+
state.updateFromEvent(
|
|
849
|
+
fromPartial({
|
|
850
|
+
type: 'call.recording_failed',
|
|
851
|
+
recording_type: 'raw',
|
|
852
|
+
}),
|
|
853
|
+
);
|
|
854
|
+
expect(state.rawRecording).toBe(false);
|
|
855
|
+
});
|
|
856
|
+
});
|
|
857
|
+
|
|
858
|
+
describe('Legacy (undefined) recording type', () => {
|
|
859
|
+
it('should set recording to true when recording starts with undefined type (legacy)', () => {
|
|
860
|
+
const state = new CallState();
|
|
861
|
+
state.updateFromEvent(
|
|
862
|
+
fromPartial({
|
|
863
|
+
type: 'call.recording_started',
|
|
864
|
+
recording_type: undefined,
|
|
865
|
+
}),
|
|
866
|
+
);
|
|
867
|
+
expect(state.recording).toBe(true);
|
|
868
|
+
expect(state.individualRecording).toBe(false);
|
|
869
|
+
expect(state.rawRecording).toBe(false);
|
|
870
|
+
});
|
|
871
|
+
|
|
872
|
+
it('should set recording to false when recording stops with undefined type (legacy)', () => {
|
|
873
|
+
const state = new CallState();
|
|
874
|
+
state.updateFromEvent(
|
|
875
|
+
fromPartial({
|
|
876
|
+
type: 'call.recording_started',
|
|
877
|
+
recording_type: undefined,
|
|
878
|
+
}),
|
|
879
|
+
);
|
|
880
|
+
expect(state.recording).toBe(true);
|
|
881
|
+
|
|
882
|
+
state.updateFromEvent(
|
|
883
|
+
fromPartial({
|
|
884
|
+
type: 'call.recording_stopped',
|
|
885
|
+
recording_type: undefined,
|
|
886
|
+
}),
|
|
887
|
+
);
|
|
888
|
+
expect(state.recording).toBe(false);
|
|
889
|
+
});
|
|
890
|
+
|
|
891
|
+
it('should set recording to false when recording fails with undefined type (legacy)', () => {
|
|
892
|
+
const state = new CallState();
|
|
893
|
+
state.updateFromEvent(
|
|
894
|
+
fromPartial({
|
|
895
|
+
type: 'call.recording_started',
|
|
896
|
+
recording_type: undefined,
|
|
897
|
+
}),
|
|
898
|
+
);
|
|
899
|
+
expect(state.recording).toBe(true);
|
|
900
|
+
|
|
901
|
+
state.updateFromEvent(
|
|
902
|
+
fromPartial({
|
|
903
|
+
type: 'call.recording_failed',
|
|
904
|
+
recording_type: undefined,
|
|
905
|
+
}),
|
|
906
|
+
);
|
|
907
|
+
expect(state.recording).toBe(false);
|
|
908
|
+
});
|
|
909
|
+
});
|
|
910
|
+
|
|
911
|
+
describe('Recording type isolation', () => {
|
|
912
|
+
it('should not affect other recording types when composite recording changes', () => {
|
|
913
|
+
const state = new CallState();
|
|
914
|
+
// Start all three types
|
|
915
|
+
state.updateFromEvent(
|
|
916
|
+
fromPartial({
|
|
917
|
+
type: 'call.recording_started',
|
|
918
|
+
recording_type: 'composite',
|
|
919
|
+
}),
|
|
920
|
+
);
|
|
921
|
+
state.updateFromEvent(
|
|
922
|
+
fromPartial({
|
|
923
|
+
type: 'call.recording_started',
|
|
924
|
+
recording_type: 'individual',
|
|
925
|
+
}),
|
|
926
|
+
);
|
|
927
|
+
state.updateFromEvent(
|
|
928
|
+
fromPartial({
|
|
929
|
+
type: 'call.recording_started',
|
|
930
|
+
recording_type: 'raw',
|
|
931
|
+
}),
|
|
932
|
+
);
|
|
933
|
+
|
|
934
|
+
expect(state.recording).toBe(true);
|
|
935
|
+
expect(state.individualRecording).toBe(true);
|
|
936
|
+
expect(state.rawRecording).toBe(true);
|
|
937
|
+
|
|
938
|
+
// Stop composite recording only
|
|
939
|
+
state.updateFromEvent(
|
|
940
|
+
fromPartial({
|
|
941
|
+
type: 'call.recording_stopped',
|
|
942
|
+
recording_type: 'composite',
|
|
943
|
+
}),
|
|
944
|
+
);
|
|
945
|
+
|
|
946
|
+
expect(state.recording).toBe(false);
|
|
947
|
+
expect(state.individualRecording).toBe(true);
|
|
948
|
+
expect(state.rawRecording).toBe(true);
|
|
949
|
+
});
|
|
950
|
+
|
|
951
|
+
it('should not affect other recording types when individual recording changes', () => {
|
|
952
|
+
const state = new CallState();
|
|
953
|
+
// Start all three types
|
|
954
|
+
state.updateFromEvent(
|
|
955
|
+
fromPartial({
|
|
956
|
+
type: 'call.recording_started',
|
|
957
|
+
recording_type: 'composite',
|
|
958
|
+
}),
|
|
959
|
+
);
|
|
960
|
+
state.updateFromEvent(
|
|
961
|
+
fromPartial({
|
|
962
|
+
type: 'call.recording_started',
|
|
963
|
+
recording_type: 'individual',
|
|
964
|
+
}),
|
|
965
|
+
);
|
|
966
|
+
state.updateFromEvent(
|
|
967
|
+
fromPartial({
|
|
968
|
+
type: 'call.recording_started',
|
|
969
|
+
recording_type: 'raw',
|
|
970
|
+
}),
|
|
971
|
+
);
|
|
972
|
+
|
|
973
|
+
// Stop individual recording only
|
|
974
|
+
state.updateFromEvent(
|
|
975
|
+
fromPartial({
|
|
976
|
+
type: 'call.recording_stopped',
|
|
977
|
+
recording_type: 'individual',
|
|
978
|
+
}),
|
|
979
|
+
);
|
|
980
|
+
|
|
981
|
+
expect(state.recording).toBe(true);
|
|
982
|
+
expect(state.individualRecording).toBe(false);
|
|
983
|
+
expect(state.rawRecording).toBe(true);
|
|
984
|
+
});
|
|
985
|
+
|
|
986
|
+
it('should not affect other recording types when raw recording changes', () => {
|
|
987
|
+
const state = new CallState();
|
|
988
|
+
// Start all three types
|
|
989
|
+
state.updateFromEvent(
|
|
990
|
+
fromPartial({
|
|
991
|
+
type: 'call.recording_started',
|
|
992
|
+
recording_type: 'composite',
|
|
993
|
+
}),
|
|
994
|
+
);
|
|
995
|
+
state.updateFromEvent(
|
|
996
|
+
fromPartial({
|
|
997
|
+
type: 'call.recording_started',
|
|
998
|
+
recording_type: 'individual',
|
|
999
|
+
}),
|
|
1000
|
+
);
|
|
1001
|
+
state.updateFromEvent(
|
|
1002
|
+
fromPartial({
|
|
1003
|
+
type: 'call.recording_started',
|
|
1004
|
+
recording_type: 'raw',
|
|
1005
|
+
}),
|
|
1006
|
+
);
|
|
1007
|
+
|
|
1008
|
+
// Stop raw recording only
|
|
1009
|
+
state.updateFromEvent(
|
|
1010
|
+
fromPartial({
|
|
1011
|
+
type: 'call.recording_stopped',
|
|
1012
|
+
recording_type: 'raw',
|
|
1013
|
+
}),
|
|
1014
|
+
);
|
|
1015
|
+
|
|
1016
|
+
expect(state.recording).toBe(true);
|
|
1017
|
+
expect(state.individualRecording).toBe(true);
|
|
1018
|
+
expect(state.rawRecording).toBe(false);
|
|
1019
|
+
});
|
|
1020
|
+
|
|
1021
|
+
it('should handle multiple recording types being active simultaneously', () => {
|
|
1022
|
+
const state = new CallState();
|
|
1023
|
+
|
|
1024
|
+
// Start composite and individual
|
|
1025
|
+
state.updateFromEvent(
|
|
1026
|
+
fromPartial({
|
|
1027
|
+
type: 'call.recording_started',
|
|
1028
|
+
recording_type: 'composite',
|
|
1029
|
+
}),
|
|
1030
|
+
);
|
|
1031
|
+
state.updateFromEvent(
|
|
1032
|
+
fromPartial({
|
|
1033
|
+
type: 'call.recording_started',
|
|
1034
|
+
recording_type: 'individual',
|
|
1035
|
+
}),
|
|
1036
|
+
);
|
|
1037
|
+
|
|
1038
|
+
expect(state.recording).toBe(true);
|
|
1039
|
+
expect(state.individualRecording).toBe(true);
|
|
1040
|
+
expect(state.rawRecording).toBe(false);
|
|
1041
|
+
|
|
1042
|
+
// Add raw recording
|
|
1043
|
+
state.updateFromEvent(
|
|
1044
|
+
fromPartial({
|
|
1045
|
+
type: 'call.recording_started',
|
|
1046
|
+
recording_type: 'raw',
|
|
1047
|
+
}),
|
|
1048
|
+
);
|
|
1049
|
+
|
|
1050
|
+
expect(state.recording).toBe(true);
|
|
1051
|
+
expect(state.individualRecording).toBe(true);
|
|
1052
|
+
expect(state.rawRecording).toBe(true);
|
|
1053
|
+
});
|
|
1054
|
+
});
|
|
1055
|
+
});
|
|
1056
|
+
|
|
712
1057
|
describe('call.session events', () => {
|
|
713
1058
|
it('should update the call metadata when a session starts', () => {
|
|
714
1059
|
const state = new CallState();
|
|
715
|
-
state.updateFromEvent(
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
1060
|
+
state.updateFromEvent(
|
|
1061
|
+
fromPartial({
|
|
1062
|
+
type: 'call.session_started',
|
|
1063
|
+
call: {
|
|
1064
|
+
egress: {},
|
|
1065
|
+
session: fromPartial({
|
|
1066
|
+
id: 'session-id',
|
|
1067
|
+
participants: [],
|
|
1068
|
+
participants_count_by_role: {},
|
|
1069
|
+
}),
|
|
723
1070
|
},
|
|
724
|
-
},
|
|
725
|
-
|
|
1071
|
+
}),
|
|
1072
|
+
);
|
|
726
1073
|
|
|
727
1074
|
expect(state.session).toEqual({
|
|
728
1075
|
id: 'session-id',
|
|
@@ -733,17 +1080,19 @@ describe('CallState', () => {
|
|
|
733
1080
|
|
|
734
1081
|
it('should update the call metadata when a session ends', () => {
|
|
735
1082
|
const state = new CallState();
|
|
736
|
-
state.updateFromEvent(
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
1083
|
+
state.updateFromEvent(
|
|
1084
|
+
fromPartial({
|
|
1085
|
+
type: 'call.session_ended',
|
|
1086
|
+
call: {
|
|
1087
|
+
egress: {},
|
|
1088
|
+
session: fromPartial({
|
|
1089
|
+
id: 'session-id',
|
|
1090
|
+
participants: [],
|
|
1091
|
+
participants_count_by_role: {},
|
|
1092
|
+
}),
|
|
744
1093
|
},
|
|
745
|
-
},
|
|
746
|
-
|
|
1094
|
+
}),
|
|
1095
|
+
);
|
|
747
1096
|
expect(state.session).toEqual({
|
|
748
1097
|
id: 'session-id',
|
|
749
1098
|
participants: [],
|
|
@@ -753,13 +1102,12 @@ describe('CallState', () => {
|
|
|
753
1102
|
|
|
754
1103
|
it('should update the call metadata when a participant joins', () => {
|
|
755
1104
|
const state = new CallState();
|
|
756
|
-
state.updateFromCallResponse(
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
});
|
|
1105
|
+
state.updateFromCallResponse(
|
|
1106
|
+
fromPartial({
|
|
1107
|
+
session: { participants: [], participants_count_by_role: {} },
|
|
1108
|
+
egress: {},
|
|
1109
|
+
}),
|
|
1110
|
+
);
|
|
763
1111
|
state.updateFromEvent({
|
|
764
1112
|
type: 'call.session_participant_joined',
|
|
765
1113
|
participant: {
|
|
@@ -781,19 +1129,21 @@ describe('CallState', () => {
|
|
|
781
1129
|
|
|
782
1130
|
it('should update the call metadata when a participant leaves', () => {
|
|
783
1131
|
const state = new CallState();
|
|
784
|
-
state.updateFromCallResponse(
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
1132
|
+
state.updateFromCallResponse(
|
|
1133
|
+
fromPartial({
|
|
1134
|
+
egress: {},
|
|
1135
|
+
session: {
|
|
1136
|
+
participants: [
|
|
1137
|
+
{
|
|
1138
|
+
joined_at: '2021-01-01T00:00:00.000Z',
|
|
1139
|
+
user: { id: 'user-id', role: 'user' },
|
|
1140
|
+
user_session_id: '123',
|
|
1141
|
+
},
|
|
1142
|
+
],
|
|
1143
|
+
participants_count_by_role: { user: 1 },
|
|
1144
|
+
},
|
|
1145
|
+
}),
|
|
1146
|
+
);
|
|
797
1147
|
state.updateFromEvent({
|
|
798
1148
|
type: 'call.session_participant_left',
|
|
799
1149
|
participant: {
|
|
@@ -810,18 +1160,20 @@ describe('CallState', () => {
|
|
|
810
1160
|
|
|
811
1161
|
it('should update existing participant', () => {
|
|
812
1162
|
const state = new CallState();
|
|
813
|
-
state.updateFromCallResponse(
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
1163
|
+
state.updateFromCallResponse(
|
|
1164
|
+
fromPartial({
|
|
1165
|
+
egress: {},
|
|
1166
|
+
session: {
|
|
1167
|
+
participants: [
|
|
1168
|
+
{
|
|
1169
|
+
user: { id: 'user-id', role: 'user' },
|
|
1170
|
+
user_session_id: '123',
|
|
1171
|
+
},
|
|
1172
|
+
],
|
|
1173
|
+
participants_count_by_role: { user: 1 },
|
|
1174
|
+
},
|
|
1175
|
+
}),
|
|
1176
|
+
);
|
|
825
1177
|
state.updateFromEvent({
|
|
826
1178
|
type: 'call.session_participant_joined',
|
|
827
1179
|
participant: {
|
|
@@ -843,10 +1195,12 @@ describe('CallState', () => {
|
|
|
843
1195
|
|
|
844
1196
|
it('should handle call.session_participant_updated events', () => {
|
|
845
1197
|
const state = new CallState();
|
|
846
|
-
state.updateFromCallResponse(
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
1198
|
+
state.updateFromCallResponse(
|
|
1199
|
+
fromPartial({
|
|
1200
|
+
session: { participants: [], participants_count_by_role: {} },
|
|
1201
|
+
egress: {},
|
|
1202
|
+
}),
|
|
1203
|
+
);
|
|
850
1204
|
// @ts-expect-error incomplete data
|
|
851
1205
|
state.updateFromEvent({
|
|
852
1206
|
type: 'call.session_participant_count_updated',
|
|
@@ -866,10 +1220,12 @@ describe('CallState', () => {
|
|
|
866
1220
|
|
|
867
1221
|
it('should not update the participant counts when call is joined', () => {
|
|
868
1222
|
const state = new CallState();
|
|
869
|
-
state.updateFromCallResponse(
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
1223
|
+
state.updateFromCallResponse(
|
|
1224
|
+
fromPartial({
|
|
1225
|
+
session: { participants: [], participants_count_by_role: {} },
|
|
1226
|
+
egress: {},
|
|
1227
|
+
}),
|
|
1228
|
+
);
|
|
873
1229
|
state.setCallingState(CallingState.JOINED);
|
|
874
1230
|
|
|
875
1231
|
// @ts-expect-error incomplete data
|