1
1
import { CUSTOM_ELEMENTS_SCHEMA , SimpleChange } from '@angular/core' ;
2
- import { ComponentFixture , TestBed } from '@angular/core/testing' ;
2
+ import {
3
+ ComponentFixture ,
4
+ discardPeriodicTasks ,
5
+ fakeAsync ,
6
+ flush ,
7
+ TestBed ,
8
+ tick ,
9
+ } from '@angular/core/testing' ;
3
10
import { By } from '@angular/platform-browser' ;
4
11
import { TranslateModule } from '@ngx-translate/core' ;
5
12
import { BehaviorSubject , Subject } from 'rxjs' ;
@@ -25,6 +32,7 @@ describe('MessageInputComponent', () => {
25
32
let querySendButton : ( ) => HTMLButtonElement | null ;
26
33
let queryattachmentUploadButton : ( ) => HTMLElement | null ;
27
34
let queryFileInput : ( ) => HTMLInputElement | null ;
35
+ let queryCooldownTimer : ( ) => HTMLElement | null ;
28
36
let mockActiveChannel$ : BehaviorSubject < Channel > ;
29
37
let mockActiveParentMessageId$ : BehaviorSubject < string | undefined > ;
30
38
let sendMessageSpy : jasmine . Spy ;
@@ -45,6 +53,9 @@ describe('MessageInputComponent', () => {
45
53
let selectMessageToQuoteSpy : jasmine . Spy ;
46
54
let typingStartedSpy : jasmine . Spy ;
47
55
let typingStoppedSpy : jasmine . Spy ;
56
+ let latestMessageDateByUserByChannels$ : BehaviorSubject < {
57
+ [ key : string ] : Date ;
58
+ } > ;
48
59
49
60
beforeEach ( ( ) => {
50
61
appSettings$ = new Subject < AppSettings > ( ) ;
@@ -70,6 +81,7 @@ describe('MessageInputComponent', () => {
70
81
mockMessageToQuote$ = new BehaviorSubject < undefined | StreamMessage > (
71
82
undefined
72
83
) ;
84
+ latestMessageDateByUserByChannels$ = new BehaviorSubject ( { } ) ;
73
85
selectMessageToQuoteSpy = jasmine . createSpy ( ) ;
74
86
TestBed . overrideComponent ( MessageInputComponent , {
75
87
set : {
@@ -107,6 +119,7 @@ describe('MessageInputComponent', () => {
107
119
selectMessageToQuote : selectMessageToQuoteSpy ,
108
120
typingStarted : typingStartedSpy ,
109
121
typingStopped : typingStoppedSpy ,
122
+ latestMessageDateByUserByChannels$,
110
123
} ,
111
124
} ,
112
125
{
@@ -130,6 +143,8 @@ describe('MessageInputComponent', () => {
130
143
nativeElement . querySelector ( '[data-testid="file-upload-button"]' ) ;
131
144
queryFileInput = ( ) =>
132
145
nativeElement . querySelector ( '[data-testid="file-input"]' ) ;
146
+ queryCooldownTimer = ( ) =>
147
+ nativeElement . querySelector ( '[data-testid="cooldown-timer"]' ) ;
133
148
} ) ;
134
149
135
150
it ( 'should display textarea' , ( ) => {
@@ -803,4 +818,127 @@ describe('MessageInputComponent', () => {
803
818
804
819
expect ( typingStartedSpy ) . toHaveBeenCalledWith ( 'parentMessage' ) ;
805
820
} ) ;
821
+
822
+ it ( `shouldn't activate cooldown for users without 'slow-mode' restriction` , ( ) => {
823
+ const channel = generateMockChannels ( 1 ) [ 0 ] ;
824
+ channel . data ! . own_capabilities = [ ] ;
825
+ channel . data ! . cooldown = 3 ;
826
+ mockActiveChannel$ . next ( channel ) ;
827
+ latestMessageDateByUserByChannels$ . next ( {
828
+ [ channel . cid ] : new Date ( ) ,
829
+ } ) ;
830
+
831
+ expect ( component . isCooldownInProgress ) . toBeFalse ( ) ;
832
+ } ) ;
833
+
834
+ it ( 'should activate cooldown timer' , fakeAsync ( ( ) => {
835
+ const channel = generateMockChannels ( 1 ) [ 0 ] ;
836
+ channel . data ! . own_capabilities = [ 'slow-mode' ] ;
837
+ channel . data ! . cooldown = 30 ;
838
+ mockActiveChannel$ . next ( channel ) ;
839
+ latestMessageDateByUserByChannels$ . next ( {
840
+ [ channel . cid ] : new Date ( ) ,
841
+ } ) ;
842
+ const spy = jasmine . createSpy ( ) ;
843
+ component . cooldown$ ?. subscribe ( spy ) ;
844
+ tick ( 1 ) ;
845
+
846
+ expect ( spy ) . toHaveBeenCalledWith ( 30 ) ;
847
+
848
+ tick ( 1000 ) ;
849
+
850
+ expect ( spy ) . toHaveBeenCalledWith ( 29 ) ;
851
+
852
+ tick ( 1000 ) ;
853
+
854
+ expect ( spy ) . toHaveBeenCalledWith ( 28 ) ;
855
+
856
+ spy . calls . reset ( ) ;
857
+ tick ( 28000 ) ;
858
+
859
+ expect ( spy ) . toHaveBeenCalledWith ( 0 ) ;
860
+
861
+ discardPeriodicTasks ( ) ;
862
+ } ) ) ;
863
+
864
+ it ( 'should disable text input during cooldown period' , fakeAsync ( ( ) => {
865
+ const channel = generateMockChannels ( 1 ) [ 0 ] ;
866
+ channel . data ! . own_capabilities = [ 'slow-mode' , 'send-message' ] ;
867
+ channel . data ! . cooldown = 30 ;
868
+ mockActiveChannel$ . next ( channel ) ;
869
+ latestMessageDateByUserByChannels$ . next ( {
870
+ [ channel . cid ] : new Date ( ) ,
871
+ } ) ;
872
+ fixture . detectChanges ( ) ;
873
+
874
+ const textarea = nativeElement . querySelector (
875
+ '[data-testid="disabled-textarea"]'
876
+ ) as HTMLTextAreaElement ;
877
+
878
+ expect ( textarea ?. disabled ) . toBeTrue ( ) ;
879
+ expect ( textarea ?. value ) . toContain ( 'streamChat.Slow Mode ON' ) ;
880
+
881
+ discardPeriodicTasks ( ) ;
882
+ } ) ) ;
883
+
884
+ it ( 'should not display emoji picker and file upload button during cooldown period' , fakeAsync ( ( ) => {
885
+ const channel = generateMockChannels ( 1 ) [ 0 ] ;
886
+ channel . data ! . own_capabilities = [ 'slow-mode' , 'send-message' ] ;
887
+ channel . data ! . cooldown = 30 ;
888
+ mockActiveChannel$ . next ( channel ) ;
889
+ latestMessageDateByUserByChannels$ . next ( {
890
+ [ channel . cid ] : new Date ( ) ,
891
+ } ) ;
892
+ tick ( 1 ) ;
893
+ fixture . detectChanges ( ) ;
894
+
895
+ expect ( queryattachmentUploadButton ( ) ) . toBeNull ( ) ;
896
+ expect (
897
+ nativeElement . querySelector ( '[data-testid="emoji-picker"]' )
898
+ ) . toBeNull ( ) ;
899
+
900
+ flush ( ) ;
901
+ discardPeriodicTasks ( ) ;
902
+ } ) ) ;
903
+
904
+ it ( 'should display cooldown timer' , fakeAsync ( ( ) => {
905
+ const channel = generateMockChannels ( 1 ) [ 0 ] ;
906
+ channel . data ! . own_capabilities = [ 'slow-mode' , 'send-message' ] ;
907
+ channel . data ! . cooldown = 30 ;
908
+ mockActiveChannel$ . next ( channel ) ;
909
+ latestMessageDateByUserByChannels$ . next ( {
910
+ [ channel . cid ] : new Date ( ) ,
911
+ } ) ;
912
+ fixture . detectChanges ( ) ;
913
+ tick ( 1 ) ;
914
+ fixture . detectChanges ( ) ;
915
+
916
+ expect ( queryCooldownTimer ( ) ) . not . toBeNull ( ) ;
917
+ expect ( queryCooldownTimer ( ) ?. innerHTML ) . toContain ( 30 ) ;
918
+
919
+ discardPeriodicTasks ( ) ;
920
+ } ) ) ;
921
+
922
+ it ( 'should discard cooldown timer after channel is chnaged' , ( ) => {
923
+ component . isCooldownInProgress = true ;
924
+ const channel = generateMockChannels ( 1 ) [ 0 ] ;
925
+ channel . data ! . own_capabilities = [ 'slow-mode' , 'send-message' ] ;
926
+ channel . data ! . cooldown = 30 ;
927
+ channel . cid = 'newchannel' ;
928
+ mockActiveChannel$ . next ( channel ) ;
929
+
930
+ expect ( component . isCooldownInProgress ) . toBeFalse ( ) ;
931
+ } ) ;
932
+
933
+ it ( `shouldn't start a cooldown if message was sent in another channel` , ( ) => {
934
+ const channel = generateMockChannels ( 1 ) [ 0 ] ;
935
+ channel . data ! . own_capabilities = [ 'slow-mode' , 'send-message' ] ;
936
+ channel . data ! . cooldown = 30 ;
937
+ mockActiveChannel$ . next ( channel ) ;
938
+ latestMessageDateByUserByChannels$ . next ( {
939
+ [ channel . cid + 'not' ] : new Date ( ) ,
940
+ } ) ;
941
+
942
+ expect ( component . isCooldownInProgress ) . toBeFalse ( ) ;
943
+ } ) ;
806
944
} ) ;
0 commit comments