@@ -9,6 +9,8 @@ const queryHashValue = 'hash';
99const testUserId = 'userId' ;
1010const testClassName = 'TestObject' ;
1111
12+ const timeout = ( ) => jasmine . timeout ( 100 ) ;
13+
1214describe ( 'ParseLiveQueryServer' , function ( ) {
1315 beforeEach ( function ( done ) {
1416 // Mock ParseWebSocketServer
@@ -750,10 +752,10 @@ describe('ParseLiveQueryServer', function () {
750752
751753 // Make sure we send command to client, since _matchesACL is async, we have to
752754 // wait and check
753- setTimeout ( function ( ) {
754- expect ( client . pushDelete ) . toHaveBeenCalled ( ) ;
755- done ( ) ;
756- } , jasmine . ASYNC_TEST_WAIT_TIME ) ;
755+ await timeout ( ) ;
756+
757+ expect ( client . pushDelete ) . toHaveBeenCalled ( ) ;
758+ done ( ) ;
757759 } ) ;
758760
759761 it ( 'has no subscription and can handle object save command' , async ( ) => {
@@ -785,14 +787,14 @@ describe('ParseLiveQueryServer', function () {
785787 parseLiveQueryServer . _onAfterSave ( message ) ;
786788
787789 // Make sure we do not send command to client
788- setTimeout ( function ( ) {
789- expect ( client . pushCreate ) . not . toHaveBeenCalled ( ) ;
790- expect ( client . pushEnter ) . not . toHaveBeenCalled ( ) ;
791- expect ( client . pushUpdate ) . not . toHaveBeenCalled ( ) ;
792- expect ( client . pushDelete ) . not . toHaveBeenCalled ( ) ;
793- expect ( client . pushLeave ) . not . toHaveBeenCalled ( ) ;
794- done ( ) ;
795- } , jasmine . ASYNC_TEST_WAIT_TIME ) ;
790+ await timeout ( ) ;
791+
792+ expect ( client . pushCreate ) . not . toHaveBeenCalled ( ) ;
793+ expect ( client . pushEnter ) . not . toHaveBeenCalled ( ) ;
794+ expect ( client . pushUpdate ) . not . toHaveBeenCalled ( ) ;
795+ expect ( client . pushDelete ) . not . toHaveBeenCalled ( ) ;
796+ expect ( client . pushLeave ) . not . toHaveBeenCalled ( ) ;
797+ done ( ) ;
796798 } ) ;
797799
798800 it ( 'can handle object enter command which matches some subscriptions' , async done => {
@@ -822,14 +824,14 @@ describe('ParseLiveQueryServer', function () {
822824 parseLiveQueryServer . _onAfterSave ( message ) ;
823825
824826 // Make sure we send enter command to client
825- setTimeout ( function ( ) {
826- expect ( client . pushCreate ) . not . toHaveBeenCalled ( ) ;
827- expect ( client . pushEnter ) . toHaveBeenCalled ( ) ;
828- expect ( client . pushUpdate ) . not . toHaveBeenCalled ( ) ;
829- expect ( client . pushDelete ) . not . toHaveBeenCalled ( ) ;
830- expect ( client . pushLeave ) . not . toHaveBeenCalled ( ) ;
831- done ( ) ;
832- } , jasmine . ASYNC_TEST_WAIT_TIME ) ;
827+ await timeout ( ) ;
828+
829+ expect ( client . pushCreate ) . not . toHaveBeenCalled ( ) ;
830+ expect ( client . pushEnter ) . toHaveBeenCalled ( ) ;
831+ expect ( client . pushUpdate ) . not . toHaveBeenCalled ( ) ;
832+ expect ( client . pushDelete ) . not . toHaveBeenCalled ( ) ;
833+ expect ( client . pushLeave ) . not . toHaveBeenCalled ( ) ;
834+ done ( ) ;
833835 } ) ;
834836
835837 it ( 'can handle object update command which matches some subscriptions' , async done => {
@@ -855,14 +857,14 @@ describe('ParseLiveQueryServer', function () {
855857 parseLiveQueryServer . _onAfterSave ( message ) ;
856858
857859 // Make sure we send update command to client
858- setTimeout ( function ( ) {
859- expect ( client . pushCreate ) . not . toHaveBeenCalled ( ) ;
860- expect ( client . pushEnter ) . not . toHaveBeenCalled ( ) ;
861- expect ( client . pushUpdate ) . toHaveBeenCalled ( ) ;
862- expect ( client . pushDelete ) . not . toHaveBeenCalled ( ) ;
863- expect ( client . pushLeave ) . not . toHaveBeenCalled ( ) ;
864- done ( ) ;
865- } , jasmine . ASYNC_TEST_WAIT_TIME ) ;
860+ await timeout ( ) ;
861+
862+ expect ( client . pushCreate ) . not . toHaveBeenCalled ( ) ;
863+ expect ( client . pushEnter ) . not . toHaveBeenCalled ( ) ;
864+ expect ( client . pushUpdate ) . toHaveBeenCalled ( ) ;
865+ expect ( client . pushDelete ) . not . toHaveBeenCalled ( ) ;
866+ expect ( client . pushLeave ) . not . toHaveBeenCalled ( ) ;
867+ done ( ) ;
866868 } ) ;
867869
868870 it ( 'can handle object leave command which matches some subscriptions' , async done => {
@@ -892,14 +894,81 @@ describe('ParseLiveQueryServer', function () {
892894 parseLiveQueryServer . _onAfterSave ( message ) ;
893895
894896 // Make sure we send leave command to client
895- setTimeout ( function ( ) {
896- expect ( client . pushCreate ) . not . toHaveBeenCalled ( ) ;
897- expect ( client . pushEnter ) . not . toHaveBeenCalled ( ) ;
898- expect ( client . pushUpdate ) . not . toHaveBeenCalled ( ) ;
899- expect ( client . pushDelete ) . not . toHaveBeenCalled ( ) ;
900- expect ( client . pushLeave ) . toHaveBeenCalled ( ) ;
901- done ( ) ;
902- } , jasmine . ASYNC_TEST_WAIT_TIME ) ;
897+ await timeout ( ) ;
898+
899+ expect ( client . pushCreate ) . not . toHaveBeenCalled ( ) ;
900+ expect ( client . pushEnter ) . not . toHaveBeenCalled ( ) ;
901+ expect ( client . pushUpdate ) . not . toHaveBeenCalled ( ) ;
902+ expect ( client . pushDelete ) . not . toHaveBeenCalled ( ) ;
903+ expect ( client . pushLeave ) . toHaveBeenCalled ( ) ;
904+ done ( ) ;
905+ } ) ;
906+
907+ it ( 'sends correct events for object with multiple subscriptions' , async done => {
908+ const parseLiveQueryServer = new ParseLiveQueryServer ( { } ) ;
909+
910+ Parse . Cloud . afterLiveQueryEvent ( 'TestObject' , ( ) => {
911+ // Simulate delay due to trigger, auth, etc.
912+ return jasmine . timeout ( 10 ) ;
913+ } ) ;
914+
915+ // Make mock request message
916+ const message = generateMockMessage ( true ) ;
917+ // Add mock client
918+ const clientId = 1 ;
919+ const client = addMockClient ( parseLiveQueryServer , clientId ) ;
920+ client . sessionToken = 'sessionToken' ;
921+
922+ // Mock queryHash for this special test
923+ const mockQueryHash = jasmine . createSpy ( 'matchesQuery' ) . and . returnValue ( 'hash1' ) ;
924+ jasmine . mockLibrary ( '../lib/LiveQuery/QueryTools' , 'queryHash' , mockQueryHash ) ;
925+ // Add mock subscription 1
926+ const requestId2 = 2 ;
927+ await addMockSubscription ( parseLiveQueryServer , clientId , requestId2 , null , null , 'hash1' ) ;
928+
929+ // Mock queryHash for this special test
930+ const mockQueryHash2 = jasmine . createSpy ( 'matchesQuery' ) . and . returnValue ( 'hash2' ) ;
931+ jasmine . mockLibrary ( '../lib/LiveQuery/QueryTools' , 'queryHash' , mockQueryHash2 ) ;
932+ // Add mock subscription 2
933+ const requestId3 = 3 ;
934+ await addMockSubscription ( parseLiveQueryServer , clientId , requestId3 , null , null , 'hash2' ) ;
935+ // Mock _matchesSubscription to return matching
936+ // In order to mimic a leave, then enter, we need original match return true
937+ // and the current match return false, then the other way around
938+ let counter = 0 ;
939+ parseLiveQueryServer . _matchesSubscription = function ( parseObject ) {
940+ if ( ! parseObject ) {
941+ return false ;
942+ }
943+ counter += 1 ;
944+ // true, false, false, true
945+ return counter < 2 || counter > 3 ;
946+ } ;
947+ parseLiveQueryServer . _matchesACL = function ( ) {
948+ // Simulate call
949+ return jasmine . timeout ( 10 ) . then ( ( ) => true ) ;
950+ } ;
951+ parseLiveQueryServer . _onAfterSave ( message ) ;
952+
953+ // Make sure we send leave and enter command to client
954+ await timeout ( ) ;
955+
956+ expect ( client . pushCreate ) . not . toHaveBeenCalled ( ) ;
957+ expect ( client . pushEnter ) . toHaveBeenCalledTimes ( 1 ) ;
958+ expect ( client . pushEnter ) . toHaveBeenCalledWith (
959+ requestId3 ,
960+ { key : 'value' , className : 'TestObject' } ,
961+ { key : 'originalValue' , className : 'TestObject' }
962+ ) ;
963+ expect ( client . pushUpdate ) . not . toHaveBeenCalled ( ) ;
964+ expect ( client . pushDelete ) . not . toHaveBeenCalled ( ) ;
965+ expect ( client . pushLeave ) . toHaveBeenCalledTimes ( 1 ) ;
966+ expect ( client . pushLeave ) . toHaveBeenCalledWith (
967+ requestId2 ,
968+ { key : 'value' , className : 'TestObject' } ,
969+ { key : 'originalValue' , className : 'TestObject' }
970+ ) ;
971+ done ( ) ;
903972 } ) ;
904973
905974 it ( 'can handle update command with original object' , async done => {
@@ -936,15 +1005,15 @@ describe('ParseLiveQueryServer', function () {
9361005 parseLiveQueryServer . _onAfterSave ( message ) ;
9371006
9381007 // Make sure we send update command to client
939- setTimeout ( function ( ) {
940- expect ( client . pushUpdate ) . toHaveBeenCalled ( ) ;
941- const args = parseWebSocket . send . calls . mostRecent ( ) . args ;
942- const toSend = JSON . parse ( args [ 0 ] ) ;
1008+ await timeout ( ) ;
9431009
944- expect ( toSend . object ) . toBeDefined ( ) ;
945- expect ( toSend . original ) . toBeDefined ( ) ;
946- done ( ) ;
947- } , jasmine . ASYNC_TEST_WAIT_TIME ) ;
1010+ expect ( client . pushUpdate ) . toHaveBeenCalled ( ) ;
1011+ const args = parseWebSocket . send . calls . mostRecent ( ) . args ;
1012+ const toSend = JSON . parse ( args [ 0 ] ) ;
1013+
1014+ expect ( toSend . object ) . toBeDefined ( ) ;
1015+ expect ( toSend . original ) . toBeDefined ( ) ;
1016+ done ( ) ;
9481017 } ) ;
9491018
9501019 it ( 'can handle object create command which matches some subscriptions' , async done => {
@@ -970,14 +1039,14 @@ describe('ParseLiveQueryServer', function () {
9701039 parseLiveQueryServer . _onAfterSave ( message ) ;
9711040
9721041 // Make sure we send create command to client
973- setTimeout ( function ( ) {
974- expect ( client . pushCreate ) . toHaveBeenCalled ( ) ;
975- expect ( client . pushEnter ) . not . toHaveBeenCalled ( ) ;
976- expect ( client . pushUpdate ) . not . toHaveBeenCalled ( ) ;
977- expect ( client . pushDelete ) . not . toHaveBeenCalled ( ) ;
978- expect ( client . pushLeave ) . not . toHaveBeenCalled ( ) ;
979- done ( ) ;
980- } , jasmine . ASYNC_TEST_WAIT_TIME ) ;
1042+ await timeout ( ) ;
1043+
1044+ expect ( client . pushCreate ) . toHaveBeenCalled ( ) ;
1045+ expect ( client . pushEnter ) . not . toHaveBeenCalled ( ) ;
1046+ expect ( client . pushUpdate ) . not . toHaveBeenCalled ( ) ;
1047+ expect ( client . pushDelete ) . not . toHaveBeenCalled ( ) ;
1048+ expect ( client . pushLeave ) . not . toHaveBeenCalled ( ) ;
1049+ done ( ) ;
9811050 } ) ;
9821051
9831052 it ( 'can handle create command with fields' , async done => {
@@ -1020,14 +1089,14 @@ describe('ParseLiveQueryServer', function () {
10201089 parseLiveQueryServer . _onAfterSave ( message ) ;
10211090
10221091 // Make sure we send create command to client
1023- setTimeout ( function ( ) {
1024- expect ( client . pushCreate ) . toHaveBeenCalled ( ) ;
1025- const args = parseWebSocket . send . calls . mostRecent ( ) . args ;
1026- const toSend = JSON . parse ( args [ 0 ] ) ;
1027- expect ( toSend . object ) . toBeDefined ( ) ;
1028- expect ( toSend . original ) . toBeUndefined ( ) ;
1029- done ( ) ;
1030- } , jasmine . ASYNC_TEST_WAIT_TIME ) ;
1092+ await timeout ( ) ;
1093+
1094+ expect ( client . pushCreate ) . toHaveBeenCalled ( ) ;
1095+ const args = parseWebSocket . send . calls . mostRecent ( ) . args ;
1096+ const toSend = JSON . parse ( args [ 0 ] ) ;
1097+ expect ( toSend . object ) . toBeDefined ( ) ;
1098+ expect ( toSend . original ) . toBeUndefined ( ) ;
1099+ done ( ) ;
10311100 } ) ;
10321101
10331102 it ( 'can match subscription for null or undefined parse object' , function ( ) {
@@ -1737,7 +1806,8 @@ describe('ParseLiveQueryServer', function () {
17371806 clientId ,
17381807 requestId ,
17391808 parseWebSocket ,
1740- query
1809+ query ,
1810+ customQueryHashValue
17411811 ) {
17421812 // If parseWebSocket is null, we use the default one
17431813 if ( ! parseWebSocket ) {
@@ -1765,12 +1835,12 @@ describe('ParseLiveQueryServer', function () {
17651835 // Make mock subscription
17661836 const subscription = parseLiveQueryServer . subscriptions
17671837 . get ( query . className )
1768- . get ( queryHashValue ) ;
1838+ . get ( customQueryHashValue || queryHashValue ) ;
17691839 subscription . hasSubscribingClient = function ( ) {
17701840 return false ;
17711841 } ;
17721842 subscription . className = query . className ;
1773- subscription . hash = queryHashValue ;
1843+ subscription . hash = customQueryHashValue || queryHashValue ;
17741844 if ( subscription . clientRequestIds && subscription . clientRequestIds . has ( clientId ) ) {
17751845 subscription . clientRequestIds . get ( clientId ) . push ( requestId ) ;
17761846 } else {
0 commit comments