@@ -839,13 +839,13 @@ impl Client {
839839
840840#[ cfg( test) ]
841841mod tests {
842+ use assert_json_diff:: assert_json_eq;
842843 use crossbeam_channel:: Receiver ;
843844 use eval:: { ContextBuilder , MultiContextBuilder } ;
844845 use futures:: FutureExt ;
845846 use hyper:: client:: HttpConnector ;
846847 use launchdarkly_server_sdk_evaluation:: Reason ;
847848 use std:: collections:: HashMap ;
848-
849849 use tokio:: time:: Instant ;
850850
851851 use crate :: data_source:: MockDataSource ;
@@ -855,8 +855,8 @@ mod tests {
855855 use crate :: events:: processor_builders:: EventProcessorBuilder ;
856856 use crate :: stores:: store_types:: { PatchTarget , StorageItem } ;
857857 use crate :: test_common:: {
858- self , basic_flag, basic_flag_with_prereq, basic_int_flag , basic_migration_flag ,
859- basic_off_flag,
858+ self , basic_flag, basic_flag_with_prereq, basic_flag_with_prereqs_and_visibility ,
859+ basic_flag_with_visibility , basic_int_flag , basic_migration_flag , basic_off_flag,
860860 } ;
861861 use crate :: { ConfigBuilder , MigratorBuilder , Operation , Origin } ;
862862 use test_case:: test_case;
@@ -965,6 +965,212 @@ mod tests {
965965 ) ) ;
966966 }
967967
968+ #[ test]
969+ fn all_flags_detail_is_invalid_when_offline ( ) {
970+ let ( client, _event_rx) = make_mocked_offline_client ( ) ;
971+ client. start_with_default_executor ( ) ;
972+
973+ let context = ContextBuilder :: new ( "bob" )
974+ . build ( )
975+ . expect ( "Failed to create context" ) ;
976+
977+ let all_flags = client. all_flags_detail ( & context, FlagDetailConfig :: new ( ) ) ;
978+ assert_json_eq ! ( all_flags, json!( { "$valid" : false , "$flagsState" : { } } ) ) ;
979+ }
980+
981+ #[ test]
982+ fn all_flags_detail_is_invalid_when_not_initialized ( ) {
983+ let ( client, _event_rx) = make_mocked_client ( ) ;
984+
985+ let context = ContextBuilder :: new ( "bob" )
986+ . build ( )
987+ . expect ( "Failed to create context" ) ;
988+
989+ let all_flags = client. all_flags_detail ( & context, FlagDetailConfig :: new ( ) ) ;
990+ assert_json_eq ! ( all_flags, json!( { "$valid" : false , "$flagsState" : { } } ) ) ;
991+ }
992+
993+ #[ test]
994+ fn all_flags_detail_returns_flag_states ( ) {
995+ let ( client, _event_rx) = make_mocked_client ( ) ;
996+ client. start_with_default_executor ( ) ;
997+ client
998+ . data_store
999+ . write ( )
1000+ . upsert (
1001+ "myFlag1" ,
1002+ PatchTarget :: Flag ( StorageItem :: Item ( basic_flag ( "myFlag1" ) ) ) ,
1003+ )
1004+ . expect ( "patch should apply" ) ;
1005+ client
1006+ . data_store
1007+ . write ( )
1008+ . upsert (
1009+ "myFlag2" ,
1010+ PatchTarget :: Flag ( StorageItem :: Item ( basic_flag ( "myFlag2" ) ) ) ,
1011+ )
1012+ . expect ( "patch should apply" ) ;
1013+ let context = ContextBuilder :: new ( "bob" )
1014+ . build ( )
1015+ . expect ( "Failed to create context" ) ;
1016+
1017+ let all_flags = client. all_flags_detail ( & context, FlagDetailConfig :: new ( ) ) ;
1018+
1019+ client. close ( ) ;
1020+
1021+ assert_json_eq ! (
1022+ all_flags,
1023+ json!( {
1024+ "myFlag1" : true ,
1025+ "myFlag2" : true ,
1026+ "$flagsState" : {
1027+ "myFlag1" : {
1028+ "version" : 42 ,
1029+ "variation" : 1
1030+ } ,
1031+ "myFlag2" : {
1032+ "version" : 42 ,
1033+ "variation" : 1
1034+ } ,
1035+ } ,
1036+ "$valid" : true
1037+ } )
1038+ ) ;
1039+ }
1040+
1041+ #[ test]
1042+ fn all_flags_detail_returns_prerequisite_relations ( ) {
1043+ let ( client, _event_rx) = make_mocked_client ( ) ;
1044+ client. start_with_default_executor ( ) ;
1045+ client
1046+ . data_store
1047+ . write ( )
1048+ . upsert (
1049+ "prereq1" ,
1050+ PatchTarget :: Flag ( StorageItem :: Item ( basic_flag ( "prereq1" ) ) ) ,
1051+ )
1052+ . expect ( "patch should apply" ) ;
1053+ client
1054+ . data_store
1055+ . write ( )
1056+ . upsert (
1057+ "prereq2" ,
1058+ PatchTarget :: Flag ( StorageItem :: Item ( basic_flag ( "prereq2" ) ) ) ,
1059+ )
1060+ . expect ( "patch should apply" ) ;
1061+
1062+ client
1063+ . data_store
1064+ . write ( )
1065+ . upsert (
1066+ "toplevel" ,
1067+ PatchTarget :: Flag ( StorageItem :: Item ( basic_flag_with_prereqs_and_visibility (
1068+ "toplevel" ,
1069+ & [ "prereq1" , "prereq2" ] ,
1070+ false ,
1071+ ) ) ) ,
1072+ )
1073+ . expect ( "patch should apply" ) ;
1074+
1075+ let context = ContextBuilder :: new ( "bob" )
1076+ . build ( )
1077+ . expect ( "Failed to create context" ) ;
1078+
1079+ let all_flags = client. all_flags_detail ( & context, FlagDetailConfig :: new ( ) ) ;
1080+
1081+ client. close ( ) ;
1082+
1083+ assert_json_eq ! (
1084+ all_flags,
1085+ json!( {
1086+ "prereq1" : true ,
1087+ "prereq2" : true ,
1088+ "toplevel" : true ,
1089+ "$flagsState" : {
1090+ "toplevel" : {
1091+ "version" : 42 ,
1092+ "variation" : 1 ,
1093+ "prerequisites" : [ "prereq1" , "prereq2" ]
1094+ } ,
1095+ "prereq1" : {
1096+ "version" : 42 ,
1097+ "variation" : 1
1098+ } ,
1099+ "prereq2" : {
1100+ "version" : 42 ,
1101+ "variation" : 1
1102+ } ,
1103+ } ,
1104+ "$valid" : true
1105+ } )
1106+ ) ;
1107+ }
1108+
1109+ #[ test]
1110+ fn all_flags_detail_returns_prerequisite_relations_when_not_visible_to_clients ( ) {
1111+ let ( client, _event_rx) = make_mocked_client ( ) ;
1112+ client. start_with_default_executor ( ) ;
1113+ client
1114+ . data_store
1115+ . write ( )
1116+ . upsert (
1117+ "prereq1" ,
1118+ PatchTarget :: Flag ( StorageItem :: Item ( basic_flag_with_visibility (
1119+ "prereq1" , false ,
1120+ ) ) ) ,
1121+ )
1122+ . expect ( "patch should apply" ) ;
1123+ client
1124+ . data_store
1125+ . write ( )
1126+ . upsert (
1127+ "prereq2" ,
1128+ PatchTarget :: Flag ( StorageItem :: Item ( basic_flag_with_visibility (
1129+ "prereq2" , false ,
1130+ ) ) ) ,
1131+ )
1132+ . expect ( "patch should apply" ) ;
1133+
1134+ client
1135+ . data_store
1136+ . write ( )
1137+ . upsert (
1138+ "toplevel" ,
1139+ PatchTarget :: Flag ( StorageItem :: Item ( basic_flag_with_prereqs_and_visibility (
1140+ "toplevel" ,
1141+ & [ "prereq1" , "prereq2" ] ,
1142+ true ,
1143+ ) ) ) ,
1144+ )
1145+ . expect ( "patch should apply" ) ;
1146+
1147+ let context = ContextBuilder :: new ( "bob" )
1148+ . build ( )
1149+ . expect ( "Failed to create context" ) ;
1150+
1151+ let mut config = FlagDetailConfig :: new ( ) ;
1152+ config. client_side_only ( ) ;
1153+
1154+ let all_flags = client. all_flags_detail ( & context, config) ;
1155+
1156+ client. close ( ) ;
1157+
1158+ assert_json_eq ! (
1159+ all_flags,
1160+ json!( {
1161+ "toplevel" : true ,
1162+ "$flagsState" : {
1163+ "toplevel" : {
1164+ "version" : 42 ,
1165+ "variation" : 1 ,
1166+ "prerequisites" : [ "prereq1" , "prereq2" ]
1167+ } ,
1168+ } ,
1169+ "$valid" : true
1170+ } )
1171+ ) ;
1172+ }
1173+
9681174 #[ test]
9691175 fn variation_tracks_events_correctly ( ) {
9701176 let ( client, event_rx) = make_mocked_client ( ) ;
0 commit comments