@@ -9,6 +9,16 @@ const queryHashValue = 'hash';
9
9
const testUserId = 'userId' ;
10
10
const testClassName = 'TestObject' ;
11
11
12
+ const ASYNC_TEST_WAIT_TIME = 100 ;
13
+
14
+ function resolveAfter ( result , msTimeout ) {
15
+ return new Promise ( res => {
16
+ setTimeout ( ( ) => {
17
+ res ( result ) ;
18
+ } , msTimeout ) ;
19
+ } ) ;
20
+ }
21
+
12
22
describe ( 'ParseLiveQueryServer' , function ( ) {
13
23
beforeEach ( function ( done ) {
14
24
// Mock ParseWebSocketServer
@@ -753,7 +763,7 @@ describe('ParseLiveQueryServer', function () {
753
763
setTimeout ( function ( ) {
754
764
expect ( client . pushDelete ) . toHaveBeenCalled ( ) ;
755
765
done ( ) ;
756
- } , jasmine . ASYNC_TEST_WAIT_TIME ) ;
766
+ } , ASYNC_TEST_WAIT_TIME ) ;
757
767
} ) ;
758
768
759
769
it ( 'has no subscription and can handle object save command' , async ( ) => {
@@ -792,7 +802,7 @@ describe('ParseLiveQueryServer', function () {
792
802
expect ( client . pushDelete ) . not . toHaveBeenCalled ( ) ;
793
803
expect ( client . pushLeave ) . not . toHaveBeenCalled ( ) ;
794
804
done ( ) ;
795
- } , jasmine . ASYNC_TEST_WAIT_TIME ) ;
805
+ } , ASYNC_TEST_WAIT_TIME ) ;
796
806
} ) ;
797
807
798
808
it ( 'can handle object enter command which matches some subscriptions' , async done => {
@@ -829,7 +839,7 @@ describe('ParseLiveQueryServer', function () {
829
839
expect ( client . pushDelete ) . not . toHaveBeenCalled ( ) ;
830
840
expect ( client . pushLeave ) . not . toHaveBeenCalled ( ) ;
831
841
done ( ) ;
832
- } , jasmine . ASYNC_TEST_WAIT_TIME ) ;
842
+ } , ASYNC_TEST_WAIT_TIME ) ;
833
843
} ) ;
834
844
835
845
it ( 'can handle object update command which matches some subscriptions' , async done => {
@@ -862,7 +872,7 @@ describe('ParseLiveQueryServer', function () {
862
872
expect ( client . pushDelete ) . not . toHaveBeenCalled ( ) ;
863
873
expect ( client . pushLeave ) . not . toHaveBeenCalled ( ) ;
864
874
done ( ) ;
865
- } , jasmine . ASYNC_TEST_WAIT_TIME ) ;
875
+ } , ASYNC_TEST_WAIT_TIME ) ;
866
876
} ) ;
867
877
868
878
it ( 'can handle object leave command which matches some subscriptions' , async done => {
@@ -899,7 +909,74 @@ describe('ParseLiveQueryServer', function () {
899
909
expect ( client . pushDelete ) . not . toHaveBeenCalled ( ) ;
900
910
expect ( client . pushLeave ) . toHaveBeenCalled ( ) ;
901
911
done ( ) ;
902
- } , jasmine . ASYNC_TEST_WAIT_TIME ) ;
912
+ } , ASYNC_TEST_WAIT_TIME ) ;
913
+ } ) ;
914
+
915
+ it ( 'can handle object multiple commands which matches some subscriptions' , async done => {
916
+ const parseLiveQueryServer = new ParseLiveQueryServer ( { } ) ;
917
+
918
+ Parse . Cloud . afterLiveQueryEvent ( 'TestObject' , ( ) => {
919
+ // Simulate delay due to trigger, auth, etc.
920
+ return resolveAfter ( null , 10 ) ;
921
+ } ) ;
922
+
923
+ // Make mock request message
924
+ const message = generateMockMessage ( true ) ;
925
+ // Add mock client
926
+ const clientId = 1 ;
927
+ const client = addMockClient ( parseLiveQueryServer , clientId ) ;
928
+ client . sessionToken = 'sessionToken' ;
929
+
930
+ // Mock queryHash for this special test
931
+ const mockQueryHash = jasmine . createSpy ( 'matchesQuery' ) . and . returnValue ( 'hash1' ) ;
932
+ jasmine . mockLibrary ( '../lib/LiveQuery/QueryTools' , 'queryHash' , mockQueryHash ) ;
933
+ // Add mock subscription 1
934
+ const requestId2 = 2 ;
935
+ await addMockSubscription ( parseLiveQueryServer , clientId , requestId2 , null , null , 'hash1' ) ;
936
+
937
+ // Mock queryHash for this special test
938
+ const mockQueryHash2 = jasmine . createSpy ( 'matchesQuery' ) . and . returnValue ( 'hash2' ) ;
939
+ jasmine . mockLibrary ( '../lib/LiveQuery/QueryTools' , 'queryHash' , mockQueryHash2 ) ;
940
+ // Add mock subscription 2
941
+ const requestId3 = 3 ;
942
+ await addMockSubscription ( parseLiveQueryServer , clientId , requestId3 , null , null , 'hash2' ) ;
943
+ // Mock _matchesSubscription to return matching
944
+ // In order to mimic a leave, then enter, we need original match return true
945
+ // and the current match return false, then the other way around
946
+ let counter = 0 ;
947
+ parseLiveQueryServer . _matchesSubscription = function ( parseObject ) {
948
+ if ( ! parseObject ) {
949
+ return false ;
950
+ }
951
+ counter += 1 ;
952
+ // true, false, false, true
953
+ return counter < 2 || counter > 3 ;
954
+ } ;
955
+ parseLiveQueryServer . _matchesACL = function ( ) {
956
+ // Simulate call
957
+ return resolveAfter ( true , 10 ) ;
958
+ } ;
959
+ parseLiveQueryServer . _onAfterSave ( message ) ;
960
+
961
+ // Make sure we send leave and enter command to client
962
+ setTimeout ( function ( ) {
963
+ expect ( client . pushCreate ) . not . toHaveBeenCalled ( ) ;
964
+ expect ( client . pushEnter ) . toHaveBeenCalledTimes ( 1 ) ;
965
+ expect ( client . pushEnter ) . toHaveBeenCalledWith (
966
+ requestId3 ,
967
+ { key : 'value' , className : 'TestObject' } ,
968
+ { key : 'originalValue' , className : 'TestObject' }
969
+ ) ;
970
+ expect ( client . pushUpdate ) . not . toHaveBeenCalled ( ) ;
971
+ expect ( client . pushDelete ) . not . toHaveBeenCalled ( ) ;
972
+ expect ( client . pushLeave ) . toHaveBeenCalledTimes ( 1 ) ;
973
+ expect ( client . pushLeave ) . toHaveBeenCalledWith (
974
+ requestId2 ,
975
+ { key : 'value' , className : 'TestObject' } ,
976
+ { key : 'originalValue' , className : 'TestObject' }
977
+ ) ;
978
+ done ( ) ;
979
+ } , ASYNC_TEST_WAIT_TIME ) ;
903
980
} ) ;
904
981
905
982
it ( 'can handle update command with original object' , async done => {
@@ -944,7 +1021,7 @@ describe('ParseLiveQueryServer', function () {
944
1021
expect ( toSend . object ) . toBeDefined ( ) ;
945
1022
expect ( toSend . original ) . toBeDefined ( ) ;
946
1023
done ( ) ;
947
- } , jasmine . ASYNC_TEST_WAIT_TIME ) ;
1024
+ } , ASYNC_TEST_WAIT_TIME ) ;
948
1025
} ) ;
949
1026
950
1027
it ( 'can handle object create command which matches some subscriptions' , async done => {
@@ -977,7 +1054,7 @@ describe('ParseLiveQueryServer', function () {
977
1054
expect ( client . pushDelete ) . not . toHaveBeenCalled ( ) ;
978
1055
expect ( client . pushLeave ) . not . toHaveBeenCalled ( ) ;
979
1056
done ( ) ;
980
- } , jasmine . ASYNC_TEST_WAIT_TIME ) ;
1057
+ } , ASYNC_TEST_WAIT_TIME ) ;
981
1058
} ) ;
982
1059
983
1060
it ( 'can handle create command with fields' , async done => {
@@ -1027,7 +1104,7 @@ describe('ParseLiveQueryServer', function () {
1027
1104
expect ( toSend . object ) . toBeDefined ( ) ;
1028
1105
expect ( toSend . original ) . toBeUndefined ( ) ;
1029
1106
done ( ) ;
1030
- } , jasmine . ASYNC_TEST_WAIT_TIME ) ;
1107
+ } , ASYNC_TEST_WAIT_TIME ) ;
1031
1108
} ) ;
1032
1109
1033
1110
it ( 'can match subscription for null or undefined parse object' , function ( ) {
@@ -1737,7 +1814,8 @@ describe('ParseLiveQueryServer', function () {
1737
1814
clientId ,
1738
1815
requestId ,
1739
1816
parseWebSocket ,
1740
- query
1817
+ query ,
1818
+ customQueryHashValue
1741
1819
) {
1742
1820
// If parseWebSocket is null, we use the default one
1743
1821
if ( ! parseWebSocket ) {
@@ -1765,12 +1843,12 @@ describe('ParseLiveQueryServer', function () {
1765
1843
// Make mock subscription
1766
1844
const subscription = parseLiveQueryServer . subscriptions
1767
1845
. get ( query . className )
1768
- . get ( queryHashValue ) ;
1846
+ . get ( customQueryHashValue || queryHashValue ) ;
1769
1847
subscription . hasSubscribingClient = function ( ) {
1770
1848
return false ;
1771
1849
} ;
1772
1850
subscription . className = query . className ;
1773
- subscription . hash = queryHashValue ;
1851
+ subscription . hash = customQueryHashValue || queryHashValue ;
1774
1852
if ( subscription . clientRequestIds && subscription . clientRequestIds . has ( clientId ) ) {
1775
1853
subscription . clientRequestIds . get ( clientId ) . push ( requestId ) ;
1776
1854
} else {
0 commit comments