1- import { TestBed } from '@angular/core/testing' ;
1+ import { TestBed , fakeAsync , tick } from '@angular/core/testing' ;
22import { FastFeedbackService } from './fast-feedback.service' ;
3- import { of , throwError } from 'rxjs' ;
4- import { RequestService } from 'request' ;
3+ import { of } from 'rxjs' ;
54import { TestUtils } from '@testingv3/utils' ;
65import { NotificationsService } from '@v3/services/notifications.service' ;
76import { BrowserStorageService } from '@v3/services/storage.service' ;
87import { UtilsService } from '@v3/services/utils.service' ;
8+ import { DemoService } from './demo.service' ;
9+ import { ApolloService } from './apollo.service' ;
10+
11+ // helper to build a valid pulse check API response
12+ function makePulseCheckResponse ( questions : any [ ] = [ ] , meta : any = null ) {
13+ return {
14+ data : {
15+ pulseCheck : {
16+ questions,
17+ meta,
18+ }
19+ }
20+ } ;
21+ }
22+
23+ const VALID_QUESTIONS = [
24+ { id : 7 , name : 'Q1' , choices : [ { id : 1 , name : 'Yes' } , { id : 2 , name : 'No' } ] } ,
25+ { id : 8 , name : 'Q2' , choices : [ { id : 3 , name : 'Yes' } , { id : 4 , name : 'No' } ] } ,
26+ ] ;
27+
28+ const VALID_META = { teamId : 100 , teamName : 'Team A' , contextId : 200 } ;
929
1030describe ( 'FastFeedbackService' , ( ) => {
1131 let service : FastFeedbackService ;
12- let requestSpy : jasmine . SpyObj < RequestService > ;
32+ let apolloSpy : jasmine . SpyObj < ApolloService > ;
1333 let notificationSpy : jasmine . SpyObj < NotificationsService > ;
1434 let storageSpy : jasmine . SpyObj < BrowserStorageService > ;
15- const testUtils = new TestUtils ( ) ;
1635
1736 beforeEach ( ( ) => {
1837 TestBed . configureTestingModule ( {
@@ -23,21 +42,30 @@ describe('FastFeedbackService', () => {
2342 useClass : TestUtils ,
2443 } ,
2544 {
26- provide : RequestService ,
27- useValue : jasmine . createSpyObj ( 'RequestService' , [ 'get' , 'post' ] )
45+ provide : ApolloService ,
46+ useValue : jasmine . createSpyObj ( 'ApolloService' , {
47+ graphQLFetch : of ( { } ) ,
48+ graphQLMutate : of ( { } ) ,
49+ } ) ,
2850 } ,
2951 {
3052 provide : NotificationsService ,
31- useValue : jasmine . createSpyObj ( 'NotificationsService' , [ 'modal' ] )
53+ useValue : jasmine . createSpyObj ( 'NotificationsService' , {
54+ fastFeedbackModal : Promise . resolve ( ) ,
55+ } ) ,
3256 } ,
3357 {
3458 provide : BrowserStorageService ,
35- useValue : jasmine . createSpyObj ( 'BrowserStorageService' , [ 'set' , 'get' ] )
36- }
59+ useValue : jasmine . createSpyObj ( 'BrowserStorageService' , [ 'set' , 'get' ] ) ,
60+ } ,
61+ {
62+ provide : DemoService ,
63+ useValue : jasmine . createSpyObj ( 'DemoService' , [ 'fastFeedback' , 'normalResponse' ] ) ,
64+ } ,
3765 ]
3866 } ) ;
3967 service = TestBed . inject ( FastFeedbackService ) ;
40- requestSpy = TestBed . inject ( RequestService ) as jasmine . SpyObj < RequestService > ;
68+ apolloSpy = TestBed . inject ( ApolloService ) as jasmine . SpyObj < ApolloService > ;
4169 notificationSpy = TestBed . inject ( NotificationsService ) as jasmine . SpyObj < NotificationsService > ;
4270 storageSpy = TestBed . inject ( BrowserStorageService ) as jasmine . SpyObj < BrowserStorageService > ;
4371 } ) ;
@@ -46,99 +74,102 @@ describe('FastFeedbackService', () => {
4674 expect ( service ) . toBeTruthy ( ) ;
4775 } ) ;
4876
49- it ( 'should get fastfeedback from API' , ( ) => {
50- requestSpy . get . and . returnValue ( of ( { } ) ) ;
51- service [ " _getFastFeedback" ] ( ) . subscribe ( ) ;
52- expect ( requestSpy . get . calls . count ( ) ) . toBe ( 1 ) ;
77+ it ( 'should fetch pulse check data from API' , ( ) => {
78+ apolloSpy . graphQLFetch . and . returnValue ( of ( { } ) ) ;
79+ service [ ' _getFastFeedback' ] ( ) . subscribe ( ) ;
80+ expect ( apolloSpy . graphQLFetch ) . toHaveBeenCalledTimes ( 1 ) ;
5381 } ) ;
5482
55- /*it('should open fastfeedback modal', () => {
56- service.fastFeedbackModal();
57- expect(notificationSpy.modal.calls.count()).toBe(1);
58- });*/
59-
6083 describe ( 'when testing pullFastFeedback()' , ( ) => {
61- it ( 'should pop up modal' , ( ) => {
62- requestSpy . get . and . returnValue ( of ( {
63- data : {
64- slider : {
65- length : 1
66- } ,
67- meta : {
68- any : 'data'
69- }
70- }
71- } ) ) ;
72- storageSpy . get . and . returnValue ( false ) ;
73- service . pullFastFeedback ( ) . subscribe ( res => {
74- expect ( storageSpy . set . calls . count ( ) ) . toBe ( 1 ) ;
75- expect ( notificationSpy . modal . calls . count ( ) ) . toBe ( 1 ) ;
84+ it ( 'should open modal and set lock when pulse check data is valid' , ( ) => {
85+ apolloSpy . graphQLFetch . and . returnValue ( of ( makePulseCheckResponse ( VALID_QUESTIONS , VALID_META ) ) ) ;
86+ storageSpy . get . and . returnValue ( false ) ; // fastFeedbackOpening = false
87+
88+ service . pullFastFeedback ( ) . subscribe ( ( ) => {
89+ // should set fastFeedbackOpening = true
90+ expect ( storageSpy . set ) . toHaveBeenCalledWith ( 'fastFeedbackOpening' , true ) ;
91+ // should call fastFeedbackModal
92+ expect ( notificationSpy . fastFeedbackModal ) . toHaveBeenCalledTimes ( 1 ) ;
7693 } ) ;
7794 } ) ;
7895
79- it ( 'should not pop up modal when slider object length is 0' , ( ) => {
80- requestSpy . get . and . returnValue ( of ( {
81- data : {
82- slider : {
83- length : 0
84- }
85- }
86- } ) ) ;
96+ it ( 'should NOT release the lock after modal is opened (fire-and-forget)' , fakeAsync ( ( ) => {
97+ apolloSpy . graphQLFetch . and . returnValue ( of ( makePulseCheckResponse ( VALID_QUESTIONS , VALID_META ) ) ) ;
8798 storageSpy . get . and . returnValue ( false ) ;
88- service . pullFastFeedback ( ) . subscribe ( res => {
89- expect ( storageSpy . set . calls . count ( ) ) . toBe ( 0 ) ;
90- expect ( notificationSpy . modal . calls . count ( ) ) . toBe ( 0 ) ;
99+
100+ service . pullFastFeedback ( ) . subscribe ( ) ;
101+ tick ( ) ;
102+
103+ // lock is set to true and never released by the service
104+ const setCalls = storageSpy . set . calls . allArgs ( ) ;
105+ const lockCalls = setCalls . filter ( args => args [ 0 ] === 'fastFeedbackOpening' ) ;
106+ expect ( lockCalls . length ) . toBe ( 1 ) ;
107+ expect ( lockCalls [ 0 ] ) . toEqual ( [ 'fastFeedbackOpening' , true ] ) ;
108+ } ) ) ;
109+
110+ it ( 'should not open modal when fastFeedbackOpening is already true' , ( ) => {
111+ apolloSpy . graphQLFetch . and . returnValue ( of ( makePulseCheckResponse ( VALID_QUESTIONS , VALID_META ) ) ) ;
112+ storageSpy . get . and . returnValue ( true ) ; // lock already held
113+
114+ service . pullFastFeedback ( ) . subscribe ( ( ) => {
115+ expect ( notificationSpy . fastFeedbackModal ) . not . toHaveBeenCalled ( ) ;
91116 } ) ;
92117 } ) ;
93118
94- it ( 'should not pop up modal when get storage returns false ' , ( ) => {
95- requestSpy . get . and . returnValue ( throwError ( '' ) ) ;
119+ it ( 'should not open modal when pulseCheck data is empty ' , ( ) => {
120+ apolloSpy . graphQLFetch . and . returnValue ( of ( { data : { pulseCheck : null } } ) ) ;
96121 storageSpy . get . and . returnValue ( false ) ;
97- service . pullFastFeedback ( ) . subscribe ( res => {
98- expect ( storageSpy . set . calls . count ( ) ) . toBe ( 0 ) ;
99- expect ( notificationSpy . modal . calls . count ( ) ) . toBe ( 0 ) ;
122+
123+ service . pullFastFeedback ( ) . subscribe ( ( ) => {
124+ expect ( notificationSpy . fastFeedbackModal ) . not . toHaveBeenCalled ( ) ;
100125 } ) ;
101126 } ) ;
102127
103- it ( 'should not popup modal when slider & meta are not available' , ( ) => {
104- requestSpy . get . and . returnValue ( of ( {
105- data : {
106- slider : undefined ,
107- meta : undefined ,
108- }
109- } ) ) ;
128+ it ( 'should not open modal when questions are empty' , ( ) => {
129+ apolloSpy . graphQLFetch . and . returnValue ( of ( makePulseCheckResponse ( [ ] , VALID_META ) ) ) ;
130+ storageSpy . get . and . returnValue ( false ) ;
110131
111- service . pullFastFeedback ( ) . subscribe ( res => {
112- expect ( notificationSpy . modal ) . not . toHaveBeenCalled ( ) ;
132+ service . pullFastFeedback ( ) . subscribe ( ( ) => {
133+ expect ( notificationSpy . fastFeedbackModal ) . not . toHaveBeenCalled ( ) ;
113134 } ) ;
114135 } ) ;
115136
116- it ( 'should not popup modal when slider is not available' , ( ) => {
117- requestSpy . get . and . returnValue ( of ( {
118- data : {
119- slider : [ ] ,
120- meta : { hasValue : true } ,
121- }
122- } ) ) ;
137+ it ( 'should not open modal when meta is empty' , ( ) => {
138+ apolloSpy . graphQLFetch . and . returnValue ( of ( makePulseCheckResponse ( VALID_QUESTIONS , null ) ) ) ;
139+ storageSpy . get . and . returnValue ( false ) ;
123140
124- service . pullFastFeedback ( ) . subscribe ( res => {
125- expect ( notificationSpy . modal ) . not . toHaveBeenCalled ( ) ;
141+ service . pullFastFeedback ( ) . subscribe ( ( ) => {
142+ expect ( notificationSpy . fastFeedbackModal ) . not . toHaveBeenCalled ( ) ;
126143 } ) ;
127144 } ) ;
128145
129- it ( 'should not popup modal when meta is not available' , ( ) => {
130- requestSpy . get . and . returnValue ( of ( {
131- data : {
132- slider : [ 1 , 2 ] ,
133- meta : undefined ,
134- }
135- } ) ) ;
146+ it ( 'should release lock on modal open error' , fakeAsync ( ( ) => {
147+ apolloSpy . graphQLFetch . and . returnValue ( of ( makePulseCheckResponse ( VALID_QUESTIONS , VALID_META ) ) ) ;
148+ storageSpy . get . and . returnValue ( false ) ;
149+ notificationSpy . fastFeedbackModal . and . returnValue ( Promise . reject ( 'modal error' ) ) ;
150+
151+ service . pullFastFeedback ( ) . subscribe ( ) ;
152+ tick ( ) ; // resolve rejected promise
153+
154+ const setCalls = storageSpy . set . calls . allArgs ( ) ;
155+ const lockCalls = setCalls . filter ( args => args [ 0 ] === 'fastFeedbackOpening' ) ;
156+ // first set to true, then released to false on error
157+ expect ( lockCalls ) . toEqual ( [
158+ [ 'fastFeedbackOpening' , true ] ,
159+ [ 'fastFeedbackOpening' , false ] ,
160+ ] ) ;
161+ } ) ) ;
162+ } ) ;
163+
164+ describe ( 'when testing submit()' , ( ) => {
165+ it ( 'should call graphQLMutate with answers and params' , ( ) => {
166+ const answers = [ { questionId : 7 , choiceId : 1 } ] ;
167+ const params = { teamId : 100 , contextId : 200 } ;
168+ apolloSpy . graphQLMutate . and . returnValue ( of ( { data : { submitPulseCheck : true } } ) ) ;
136169
137- service . pullFastFeedback ( ) . subscribe ( res => {
138- expect ( notificationSpy . modal ) . not . toHaveBeenCalled ( ) ;
170+ service . submit ( answers , params ) . subscribe ( ( ) => {
171+ expect ( apolloSpy . graphQLMutate ) . toHaveBeenCalledTimes ( 1 ) ;
139172 } ) ;
140173 } ) ;
141174 } ) ;
142-
143-
144175} ) ;
0 commit comments