@@ -14,6 +14,7 @@ import { usersFixture } from '../fixture/user';
1414import { keywordsFixture } from '../fixture/keywords' ;
1515import { Autocomplete , AutocompleteType } from '../../src/entity/Autocomplete' ;
1616import { Company , CompanyType } from '../../src/entity/Company' ;
17+ import { DatasetLocation } from '../../src/entity/dataset/DatasetLocation' ;
1718import type { MapboxResponse } from '../../src/integrations/mapbox/types' ;
1819import nock from 'nock' ;
1920
@@ -807,6 +808,291 @@ describe('query autocompleteLocation', () => {
807808 expect ( res . errors ) . toBeFalsy ( ) ;
808809 expect ( res . data . autocompleteLocation ) . toEqual ( [ ] ) ;
809810 } ) ;
811+
812+ describe ( 'internal dataset' , ( ) => {
813+ const QUERY_WITH_DATASET = /* GraphQL */ `
814+ query AutocompleteLocation(
815+ $query: String!
816+ $dataset: LocationDataset
817+ $limit: Int
818+ ) {
819+ autocompleteLocation(query: $query, dataset: $dataset, limit: $limit) {
820+ id
821+ country
822+ city
823+ subdivision
824+ }
825+ }
826+ ` ;
827+
828+ beforeEach ( async ( ) => {
829+ await saveFixtures ( con , DatasetLocation , [
830+ {
831+ id : '550e8400-e29b-41d4-a716-446655440001' ,
832+ country : 'United States' ,
833+ subdivision : 'California' ,
834+ city : 'San Francisco' ,
835+ iso2 : 'US' ,
836+ iso3 : 'USA' ,
837+ } ,
838+ {
839+ id : '550e8400-e29b-41d4-a716-446655440002' ,
840+ country : 'United States' ,
841+ subdivision : 'New York' ,
842+ city : 'New York City' ,
843+ iso2 : 'US' ,
844+ iso3 : 'USA' ,
845+ } ,
846+ {
847+ id : '550e8400-e29b-41d4-a716-446655440003' ,
848+ country : 'Germany' ,
849+ subdivision : 'Bavaria' ,
850+ city : 'Munich' ,
851+ iso2 : 'DE' ,
852+ iso3 : 'DEU' ,
853+ } ,
854+ {
855+ id : '550e8400-e29b-41d4-a716-446655440004' ,
856+ country : 'Germany' ,
857+ subdivision : null ,
858+ city : 'Berlin' ,
859+ iso2 : 'DE' ,
860+ iso3 : 'DEU' ,
861+ } ,
862+ {
863+ id : '550e8400-e29b-41d4-a716-446655440005' ,
864+ country : 'United Kingdom' ,
865+ subdivision : null ,
866+ city : null ,
867+ iso2 : 'GB' ,
868+ iso3 : 'GBR' ,
869+ } ,
870+ ] ) ;
871+ } ) ;
872+
873+ it ( 'should return locations from internal database when dataset is internal' , async ( ) => {
874+ loggedUser = '1' ;
875+
876+ const res = await client . query ( QUERY_WITH_DATASET , {
877+ variables : { query : 'san francisco' , dataset : 'internal' } ,
878+ } ) ;
879+
880+ expect ( res . errors ) . toBeFalsy ( ) ;
881+ expect ( res . data . autocompleteLocation ) . toEqual ( [
882+ {
883+ id : '550e8400-e29b-41d4-a716-446655440001' ,
884+ country : 'United States' ,
885+ city : 'San Francisco' ,
886+ subdivision : 'California' ,
887+ } ,
888+ ] ) ;
889+ } ) ;
890+
891+ it ( 'should match by country name' , async ( ) => {
892+ loggedUser = '1' ;
893+
894+ const res = await client . query ( QUERY_WITH_DATASET , {
895+ variables : { query : 'germany' , dataset : 'internal' } ,
896+ } ) ;
897+
898+ expect ( res . errors ) . toBeFalsy ( ) ;
899+ expect ( res . data . autocompleteLocation ) . toHaveLength ( 2 ) ;
900+ // Note: ORDER BY subdivision ASC puts non-null values before null
901+ expect ( res . data . autocompleteLocation ) . toEqual ( [
902+ {
903+ id : '550e8400-e29b-41d4-a716-446655440003' ,
904+ country : 'Germany' ,
905+ city : 'Munich' ,
906+ subdivision : 'Bavaria' ,
907+ } ,
908+ {
909+ id : '550e8400-e29b-41d4-a716-446655440004' ,
910+ country : 'Germany' ,
911+ city : 'Berlin' ,
912+ subdivision : null ,
913+ } ,
914+ ] ) ;
915+ } ) ;
916+
917+ it ( 'should match by subdivision name' , async ( ) => {
918+ loggedUser = '1' ;
919+
920+ const res = await client . query ( QUERY_WITH_DATASET , {
921+ variables : { query : 'california' , dataset : 'internal' } ,
922+ } ) ;
923+
924+ expect ( res . errors ) . toBeFalsy ( ) ;
925+ expect ( res . data . autocompleteLocation ) . toEqual ( [
926+ {
927+ id : '550e8400-e29b-41d4-a716-446655440001' ,
928+ country : 'United States' ,
929+ city : 'San Francisco' ,
930+ subdivision : 'California' ,
931+ } ,
932+ ] ) ;
933+ } ) ;
934+
935+ it ( 'should match by city name' , async ( ) => {
936+ loggedUser = '1' ;
937+
938+ const res = await client . query ( QUERY_WITH_DATASET , {
939+ variables : { query : 'munich' , dataset : 'internal' } ,
940+ } ) ;
941+
942+ expect ( res . errors ) . toBeFalsy ( ) ;
943+ expect ( res . data . autocompleteLocation ) . toEqual ( [
944+ {
945+ id : '550e8400-e29b-41d4-a716-446655440003' ,
946+ country : 'Germany' ,
947+ city : 'Munich' ,
948+ subdivision : 'Bavaria' ,
949+ } ,
950+ ] ) ;
951+ } ) ;
952+
953+ it ( 'should be case insensitive' , async ( ) => {
954+ loggedUser = '1' ;
955+
956+ const res = await client . query ( QUERY_WITH_DATASET , {
957+ variables : { query : 'UNITED STATES' , dataset : 'internal' } ,
958+ } ) ;
959+
960+ expect ( res . errors ) . toBeFalsy ( ) ;
961+ expect ( res . data . autocompleteLocation ) . toHaveLength ( 2 ) ;
962+ } ) ;
963+
964+ it ( 'should return empty array when no matches found' , async ( ) => {
965+ loggedUser = '1' ;
966+
967+ const res = await client . query ( QUERY_WITH_DATASET , {
968+ variables : { query : 'nonexistent' , dataset : 'internal' } ,
969+ } ) ;
970+
971+ expect ( res . errors ) . toBeFalsy ( ) ;
972+ expect ( res . data . autocompleteLocation ) . toEqual ( [ ] ) ;
973+ } ) ;
974+
975+ it ( 'should handle null subdivision and city' , async ( ) => {
976+ loggedUser = '1' ;
977+
978+ const res = await client . query ( QUERY_WITH_DATASET , {
979+ variables : { query : 'united kingdom' , dataset : 'internal' } ,
980+ } ) ;
981+
982+ expect ( res . errors ) . toBeFalsy ( ) ;
983+ expect ( res . data . autocompleteLocation ) . toEqual ( [
984+ {
985+ id : '550e8400-e29b-41d4-a716-446655440005' ,
986+ country : 'United Kingdom' ,
987+ city : null ,
988+ subdivision : null ,
989+ } ,
990+ ] ) ;
991+ } ) ;
992+
993+ it ( 'should respect limit parameter' , async ( ) => {
994+ loggedUser = '1' ;
995+
996+ const res = await client . query ( QUERY_WITH_DATASET , {
997+ variables : { query : 'united' , dataset : 'internal' , limit : 1 } ,
998+ } ) ;
999+
1000+ expect ( res . errors ) . toBeFalsy ( ) ;
1001+ expect ( res . data . autocompleteLocation ) . toHaveLength ( 1 ) ;
1002+ } ) ;
1003+
1004+ it ( 'should return Europe as a country' , async ( ) => {
1005+ loggedUser = '1' ;
1006+
1007+ await con . getRepository ( DatasetLocation ) . save ( {
1008+ id : '550e8400-e29b-41d4-a716-446655440006' ,
1009+ country : 'Europe' ,
1010+ subdivision : null ,
1011+ city : null ,
1012+ iso2 : 'EU' ,
1013+ iso3 : 'EUR' ,
1014+ } ) ;
1015+
1016+ const res = await client . query ( QUERY_WITH_DATASET , {
1017+ variables : { query : 'europe' , dataset : 'internal' } ,
1018+ } ) ;
1019+
1020+ expect ( res . errors ) . toBeFalsy ( ) ;
1021+ expect ( res . data . autocompleteLocation ) . toEqual ( [
1022+ {
1023+ id : '550e8400-e29b-41d4-a716-446655440006' ,
1024+ country : 'Europe' ,
1025+ city : null ,
1026+ subdivision : null ,
1027+ } ,
1028+ ] ) ;
1029+ } ) ;
1030+
1031+ it ( 'should default to external (Mapbox) when dataset is not specified' , async ( ) => {
1032+ loggedUser = '1' ;
1033+
1034+ const mockMapboxResponse : MapboxResponse = {
1035+ type : 'FeatureCollection' ,
1036+ features : [
1037+ {
1038+ type : 'Feature' ,
1039+ geometry : {
1040+ coordinates : [ - 122.4194 , 37.7749 ] ,
1041+ type : 'Point' ,
1042+ } ,
1043+ properties : {
1044+ name : 'San Francisco' ,
1045+ mapbox_id : 'place.sf' ,
1046+ feature_type : 'place' ,
1047+ place_formatted : 'San Francisco, California, United States' ,
1048+ context : {
1049+ country : {
1050+ id : 'country.us' ,
1051+ name : 'United States' ,
1052+ country_code : 'US' ,
1053+ country_code_alpha_3 : 'USA' ,
1054+ } ,
1055+ region : {
1056+ id : 'region.ca' ,
1057+ name : 'California' ,
1058+ region_code : 'CA' ,
1059+ region_code_full : 'US-CA' ,
1060+ } ,
1061+ } ,
1062+ coordinates : {
1063+ latitude : 37.7749 ,
1064+ longitude : - 122.4194 ,
1065+ } ,
1066+ language : 'en' ,
1067+ maki : 'marker' ,
1068+ metadata : { } ,
1069+ } ,
1070+ } ,
1071+ ] ,
1072+ attribution : 'Mapbox' ,
1073+ response_id : 'test-response-id' ,
1074+ } ;
1075+
1076+ nock ( 'https://api.mapbox.com' )
1077+ . get ( '/search/geocode/v6/forward' )
1078+ . query ( {
1079+ q : 'san francisco' ,
1080+ types : 'country,region,place' ,
1081+ limit : 5 ,
1082+ access_token : process . env . MAPBOX_ACCESS_TOKEN ,
1083+ } )
1084+ . reply ( 200 , mockMapboxResponse ) ;
1085+
1086+ // Query without specifying dataset - should use Mapbox
1087+ const res = await client . query ( QUERY_WITH_DATASET , {
1088+ variables : { query : 'san francisco' } ,
1089+ } ) ;
1090+
1091+ expect ( res . errors ) . toBeFalsy ( ) ;
1092+ // Should return Mapbox ID, not internal database ID
1093+ expect ( res . data . autocompleteLocation [ 0 ] . id ) . toBe ( 'place.sf' ) ;
1094+ } ) ;
1095+ } ) ;
8101096} ) ;
8111097
8121098describe ( 'query autocompleteCompany' , ( ) => {
0 commit comments