@@ -21,6 +21,7 @@ import { history } from '../../lib/routers';
21
21
import { warning } from '../../lib/utils' ;
22
22
import { dynamicWidgets , hits , refinementList } from '../../widgets' ;
23
23
24
+ import type { InsightsProps } from '..' ;
24
25
import type { SearchClient } from '../../index.es' ;
25
26
import type { PlainSearchParameters } from 'algoliasearch-helper' ;
26
27
import type { JSDOM } from 'jsdom' ;
@@ -50,6 +51,10 @@ describe('insights', () => {
50
51
searchClient = searchClientWithCredentials ,
51
52
started = true ,
52
53
insights = false ,
54
+ } : {
55
+ searchClient ?: SearchClient ;
56
+ started ?: boolean ;
57
+ insights ?: InsightsProps | boolean ;
53
58
} = { } ) => {
54
59
castToJestMock ( searchClient . search ) . mockClear ( ) ;
55
60
const { analytics, insightsClient } = createInsights ( ) ;
@@ -437,37 +442,6 @@ describe('insights', () => {
437
442
) ;
438
443
} ) ;
439
444
440
- it ( 'warns when userToken is not set' , ( ) => {
441
- const { insightsClient, instantSearchInstance } = createTestEnvironment ( ) ;
442
-
443
- instantSearchInstance . use (
444
- createInsightsMiddleware ( {
445
- insightsClient,
446
- insightsInitParams : {
447
- useCookie : false ,
448
- anonymousUserToken : false ,
449
- } ,
450
- } )
451
- ) ;
452
-
453
- expect ( ( ) =>
454
- instantSearchInstance . sendEventToInsights ( {
455
- eventType : 'view' ,
456
- insightsMethod : 'viewedObjectIDs' ,
457
- payload : {
458
- eventName : 'Hits Viewed' ,
459
- index : '' ,
460
- objectIDs : [ '1' , '2' ] ,
461
- } ,
462
- widgetType : 'ais.hits' ,
463
- } )
464
- ) . toWarnDev (
465
- `[InstantSearch.js]: Cannot send event to Algolia Insights because \`userToken\` is not set.
466
-
467
- See documentation: https://www.algolia.com/doc/guides/building-search-ui/going-further/send-insights-events/js/#setting-the-usertoken`
468
- ) ;
469
- } ) ;
470
-
471
445
it ( 'applies clickAnalytics if $$automatic: undefined' , ( ) => {
472
446
const { insightsClient, instantSearchInstance } = createTestEnvironment ( ) ;
473
447
instantSearchInstance . use (
@@ -778,37 +752,34 @@ See documentation: https://www.algolia.com/doc/guides/building-search-ui/going-f
778
752
} ) ;
779
753
780
754
it ( 'handles multiple setUserToken calls before search.start()' , async ( ) => {
781
- const { insightsClient } = createInsights ( ) ;
782
- const indexName = 'my-index' ;
783
- const instantSearchInstance = instantsearch ( {
784
- searchClient : createSearchClient ( {
785
- // @ts -expect-error only available in search client v4
786
- transporter : {
787
- headers : {
788
- 'x-algolia-application-id' : 'myAppId' ,
789
- 'x-algolia-api-key' : 'myApiKey' ,
790
- } ,
791
- } ,
792
- } ) ,
793
- indexName,
794
- } ) ;
755
+ const { insightsClient, instantSearchInstance, getUserToken } =
756
+ createTestEnvironment ( ) ;
795
757
796
- const middleware = createInsightsMiddleware ( {
797
- insightsClient,
798
- } ) ;
799
- instantSearchInstance . use ( middleware ) ;
758
+ instantSearchInstance . use (
759
+ createInsightsMiddleware ( {
760
+ insightsClient,
761
+ } )
762
+ ) ;
800
763
801
764
insightsClient ( 'setUserToken' , 'abc' ) ;
802
765
insightsClient ( 'setUserToken' , 'def' ) ;
803
766
804
- instantSearchInstance . start ( ) ;
767
+ expect ( getUserToken ( ) ) . toEqual ( 'def' ) ;
805
768
806
- await wait ( 0 ) ;
769
+ instantSearchInstance . addWidgets ( [ connectSearchBox ( ( ) => ( { } ) ) ( { } ) ] ) ;
807
770
808
- expect (
809
- ( instantSearchInstance . mainHelper ! . state as PlainSearchParameters )
810
- . userToken
811
- ) . toEqual ( 'def' ) ;
771
+ await wait ( 0 ) ;
772
+ expect ( instantSearchInstance . client . search ) . toHaveBeenCalledTimes ( 1 ) ;
773
+ expect ( instantSearchInstance . client . search ) . toHaveBeenLastCalledWith ( [
774
+ {
775
+ indexName : 'my-index' ,
776
+ params : {
777
+ clickAnalytics : true ,
778
+ query : '' ,
779
+ userToken : getUserToken ( ) ,
780
+ } ,
781
+ } ,
782
+ ] ) ;
812
783
} ) ;
813
784
814
785
it ( 'searches once per unique userToken' , async ( ) => {
@@ -836,7 +807,8 @@ See documentation: https://www.algolia.com/doc/guides/building-search-ui/going-f
836
807
} ) ;
837
808
838
809
it ( "doesn't search when userToken is falsy" , async ( ) => {
839
- const { insightsClient, instantSearchInstance } = createTestEnvironment ( ) ;
810
+ const { insightsClient, instantSearchInstance, getUserToken } =
811
+ createTestEnvironment ( ) ;
840
812
841
813
instantSearchInstance . addWidgets ( [ connectSearchBox ( ( ) => ( { } ) ) ( { } ) ] ) ;
842
814
@@ -866,8 +838,8 @@ See documentation: https://www.algolia.com/doc/guides/building-search-ui/going-f
866
838
indexName : 'my-index' ,
867
839
params : {
868
840
clickAnalytics : true ,
869
-
870
841
query : '' ,
842
+ userToken : getUserToken ( ) ,
871
843
} ,
872
844
} ,
873
845
] ) ;
@@ -878,6 +850,81 @@ See documentation: https://www.algolia.com/doc/guides/building-search-ui/going-f
878
850
expect ( instantSearchInstance . client . search ) . toHaveBeenCalledTimes ( 2 ) ;
879
851
} ) ;
880
852
853
+ it ( 'sets an anonymous token as the userToken if none given' , async ( ) => {
854
+ const { instantSearchInstance, getUserToken } = createTestEnvironment ( {
855
+ insights : true ,
856
+ } ) ;
857
+
858
+ instantSearchInstance . addWidgets ( [ connectSearchBox ( ( ) => ( { } ) ) ( { } ) ] ) ;
859
+
860
+ await wait ( 0 ) ;
861
+ expect ( instantSearchInstance . client . search ) . toHaveBeenCalledTimes ( 1 ) ;
862
+ expect ( instantSearchInstance . client . search ) . toHaveBeenLastCalledWith ( [
863
+ {
864
+ indexName : 'my-index' ,
865
+ params : {
866
+ clickAnalytics : true ,
867
+ query : '' ,
868
+ userToken : getUserToken ( ) ,
869
+ } ,
870
+ } ,
871
+ ] ) ;
872
+
873
+ expect ( getUserToken ( ) ) . toEqual ( expect . stringMatching ( / ^ a n o n y m o u s - / ) ) ;
874
+ } ) ;
875
+
876
+ it ( 'saves an anonymous token to a cookie if useCookie is true in insights init props' , ( ) => {
877
+ const { getUserToken } = createTestEnvironment ( {
878
+ insights : {
879
+ insightsInitParams : {
880
+ useCookie : true ,
881
+ } ,
882
+ } ,
883
+ } ) ;
884
+
885
+ const userToken = getUserToken ( ) ;
886
+ expect ( userToken ) . toEqual ( expect . stringMatching ( / ^ a n o n y m o u s - / ) ) ;
887
+ expect ( document . cookie ) . toBe ( `_ALGOLIA=${ userToken } ` ) ;
888
+ } ) ;
889
+
890
+ it ( 'saves an anonymous token to a cookie if useCookie is true insights init method' , async ( ) => {
891
+ const { instantSearchInstance, insightsClient, getUserToken } =
892
+ createTestEnvironment ( {
893
+ insights : true ,
894
+ started : false ,
895
+ } ) ;
896
+
897
+ insightsClient ( 'init' , { partial : true , useCookie : true } ) ;
898
+
899
+ instantSearchInstance . start ( ) ;
900
+
901
+ await wait ( 0 ) ;
902
+ const userToken = getUserToken ( ) ;
903
+ expect ( userToken ) . toEqual ( expect . stringMatching ( / ^ a n o n y m o u s - / ) ) ;
904
+ expect ( document . cookie ) . toBe ( `_ALGOLIA=${ userToken } ` ) ;
905
+ } ) ;
906
+
907
+ it ( 'uses `userToken` from insights init props over anything else' , async ( ) => {
908
+ document . cookie = '_ALGOLIA=abc' ;
909
+
910
+ const { instantSearchInstance, insightsClient, getUserToken } =
911
+ createTestEnvironment ( {
912
+ insights : {
913
+ insightsInitParams : {
914
+ userToken : 'def' ,
915
+ } ,
916
+ } ,
917
+ started : false ,
918
+ } ) ;
919
+
920
+ insightsClient ( 'init' , { partial : true , userToken : 'ghi' } ) ;
921
+
922
+ instantSearchInstance . start ( ) ;
923
+
924
+ await wait ( 0 ) ;
925
+ expect ( getUserToken ( ) ) . toBe ( 'def' ) ;
926
+ } ) ;
927
+
881
928
describe ( 'authenticatedUserToken' , ( ) => {
882
929
describe ( 'before `init`' , ( ) => {
883
930
it ( 'uses the `authenticatedUserToken` as the `userToken` when defined' , ( ) => {
@@ -921,6 +968,39 @@ See documentation: https://www.algolia.com/doc/guides/building-search-ui/going-f
921
968
922
969
expect ( getUserToken ( ) ) . toEqual ( 'abc' ) ;
923
970
} ) ;
971
+
972
+ it ( 'uses the `authenticatedUserToken` when a `userToken` is set after' , ( ) => {
973
+ const { insightsClient, instantSearchInstance, getUserToken } =
974
+ createTestEnvironment ( ) ;
975
+
976
+ insightsClient ( 'setAuthenticatedUserToken' , 'def' ) ;
977
+
978
+ instantSearchInstance . use (
979
+ createInsightsMiddleware ( { insightsClient } )
980
+ ) ;
981
+
982
+ insightsClient ( 'setUserToken' , 'abc' ) ;
983
+
984
+ expect ( getUserToken ( ) ) . toEqual ( 'def' ) ;
985
+ } ) ;
986
+
987
+ it ( 'resets the token to the `userToken` when `authenticatedUserToken` is set as undefined' , ( ) => {
988
+ const { insightsClient, instantSearchInstance, getUserToken } =
989
+ createTestEnvironment ( ) ;
990
+
991
+ insightsClient ( 'setUserToken' , 'abc' ) ;
992
+ insightsClient ( 'setAuthenticatedUserToken' , 'def' ) ;
993
+
994
+ instantSearchInstance . use (
995
+ createInsightsMiddleware ( { insightsClient } )
996
+ ) ;
997
+
998
+ expect ( getUserToken ( ) ) . toEqual ( 'def' ) ;
999
+
1000
+ insightsClient ( 'setAuthenticatedUserToken' , undefined ) ;
1001
+
1002
+ expect ( getUserToken ( ) ) . toEqual ( 'abc' ) ;
1003
+ } ) ;
924
1004
} ) ;
925
1005
926
1006
describe ( 'after `init`' , ( ) => {
@@ -1361,13 +1441,15 @@ See documentation: https://www.algolia.com/doc/guides/building-search-ui/going-f
1361
1441
1362
1442
// Dynamic widgets will trigger 2 searches. To avoid missing the cache on the second search, createInsightsMiddleware delays setting the userToken.
1363
1443
1444
+ const userToken = getUserToken ( ) ;
1445
+
1364
1446
expect ( searchClient . search ) . toHaveBeenCalledTimes ( 2 ) ;
1365
- expect (
1366
- searchClient . search . mock . calls [ 0 ] [ 0 ] [ 0 ] . params . userToken
1367
- ) . toBeUndefined ( ) ;
1368
- expect (
1369
- searchClient . search . mock . calls [ 1 ] [ 0 ] [ 0 ] . params . userToken
1370
- ) . toBeUndefined ( ) ;
1447
+ expect ( searchClient . search . mock . calls [ 0 ] [ 0 ] [ 0 ] . params . userToken ) . toBe (
1448
+ userToken
1449
+ ) ;
1450
+ expect ( searchClient . search . mock . calls [ 1 ] [ 0 ] [ 0 ] . params . userToken ) . toBe (
1451
+ userToken
1452
+ ) ;
1371
1453
1372
1454
await wait ( 0 ) ;
1373
1455
@@ -1383,7 +1465,7 @@ See documentation: https://www.algolia.com/doc/guides/building-search-ui/going-f
1383
1465
expect ( searchClient . search ) . toHaveBeenCalledTimes ( 3 ) ;
1384
1466
expect ( searchClient . search ) . toHaveBeenLastCalledWith ( [
1385
1467
expect . objectContaining ( {
1386
- params : expect . objectContaining ( { userToken : getUserToken ( ) } ) ,
1468
+ params : expect . objectContaining ( { userToken } ) ,
1387
1469
} ) ,
1388
1470
] ) ;
1389
1471
} ) ;
0 commit comments