77import org .junit .Before ;
88import org .junit .Test ;
99
10+ import java .util .Deque ;
1011import java .util .HashMap ;
1112import java .util .Map ;
1213
14+ import io .split .android .client .utils .logger .LogPrinterStub ;
15+ import io .split .android .client .utils .logger .Logger ;
16+ import io .split .android .client .utils .logger .SplitLogLevel ;
17+
1318public class FallbacksSanitizerImplTest {
1419
1520 private FallbacksSanitizerImpl mSanitizer ;
21+ private LogPrinterStub mLogPrinter ;
1622
1723 private static final String VALID_FLAG = "my_flag" ;
1824 private static final String INVALID_FLAG_WITH_SPACE = "my flag" ;
@@ -26,6 +32,9 @@ public class FallbacksSanitizerImplTest {
2632 @ Before
2733 public void setUp () {
2834 mSanitizer = new FallbacksSanitizerImpl ();
35+ mLogPrinter = new LogPrinterStub ();
36+ Logger .instance ().setLevel (SplitLogLevel .VERBOSE );
37+ Logger .instance ().setPrinter (mLogPrinter );
2938 }
3039
3140 @ Test
@@ -43,7 +52,15 @@ public void dropsInvalidFlagNamesAndTreatments() {
4352
4453 FallbackConfiguration sanitized = mSanitizer .sanitize (config );
4554
46- // only VALID_FLAG should remain
55+ Deque <String > errors = mLogPrinter .getLoggedMessages ().get (android .util .Log .ERROR );
56+ assertTrue ("Expected ERROR logs to be present" , errors != null && !errors .isEmpty ());
57+ long invalidFlagNameCount = errors .stream ().filter (m -> m .contains ("Invalid flag name" )).count ();
58+ assertEquals (2 , invalidFlagNameCount );
59+ assertTrue (errors .stream ().anyMatch (m -> m .contains ("Discarded flag 'my flag'" )));
60+ // invalid treatment for a specific flag name and contains the full expected message
61+ assertTrue (errors .stream ().anyMatch (m -> m .contains ("Discarded treatment for flag 'tooLongTreatment'" )));
62+ assertTrue (errors .stream ().anyMatch (m -> m .contains ("Invalid treatment (max 100 chars and comply with ^[0-9]+[.a-zA-Z0-9_-]*$|^[a-zA-Z]+[a-zA-Z0-9_-]*$)" )));
63+
4764 assertEquals (1 , sanitized .getByFlag ().size ());
4865 assertEquals ("on" , sanitized .getByFlag ().get (VALID_FLAG ).getTreatment ());
4966 }
@@ -57,6 +74,11 @@ public void dropsInvalidGlobalTreatment() {
5774
5875 FallbackConfiguration sanitized = mSanitizer .sanitize (config );
5976
77+ // Assert error log for discarded global fallback only
78+ Deque <String > errors = mLogPrinter .getLoggedMessages ().get (android .util .Log .ERROR );
79+ assertTrue ("Expected ERROR logs to be present" , errors != null && !errors .isEmpty ());
80+ assertTrue (errors .stream ().anyMatch (m -> m .contains ("Discarded global fallback" )));
81+
6082 assertNull (sanitized .getGlobal ());
6183 assertEquals (0 , sanitized .getByFlag ().size ());
6284 }
@@ -75,6 +97,15 @@ public void byFlagTreatmentIsDroppedWhenInvalidFormat() {
7597
7698 FallbackConfiguration sanitized = mSanitizer .sanitize (config );
7799
100+ // Assert error logs for invalid treatments under flags
101+ Deque <String > errors = mLogPrinter .getLoggedMessages ().get (android .util .Log .ERROR );
102+ assertTrue ("Expected ERROR logs to be present" , errors != null && !errors .isEmpty ());
103+ assertTrue (errors .stream ().anyMatch (m -> m .contains ("Discarded treatment for flag '" + VALID_FLAG + "'" )));
104+ assertTrue (errors .stream ().anyMatch (m -> m .contains ("Invalid treatment (max 100 chars and comply with ^[0-9]+[.a-zA-Z0-9_-]*$|^[a-zA-Z]+[a-zA-Z0-9_-]*$)" )));
105+ assertTrue (errors .stream ().anyMatch (m -> m .contains ("Discarded treatment for flag 'null_treatment'" )));
106+ // Ensure no error for valid flag/treatment
107+ assertTrue (errors .stream ().noneMatch (m -> m .contains ("Discarded treatment for flag 'valid_num_dot'" )));
108+
78109 // Only the valid one should remain
79110 assertEquals (1 , sanitized .getByFlag ().size ());
80111 assertEquals ("123.on" , sanitized .getByFlag ().get ("valid_num_dot" ).getTreatment ());
@@ -94,6 +125,22 @@ public void globalTreatmentIsDroppedWhenInvalidFormat() {
94125
95126 FallbackConfiguration sanitized = mSanitizer .sanitize (config );
96127
128+ // Assert error logs were emitted for invalid entries
129+ Deque <String > errorLogs = mLogPrinter .getLoggedMessages ().get (android .util .Log .ERROR );
130+ assertTrue ("Expected ERROR logs to be present" , errorLogs != null && !errorLogs .isEmpty ());
131+ boolean hasGlobalDiscard = false ;
132+ boolean hasNullFlagDiscard = false ;
133+ for (String msg : errorLogs ) {
134+ if (msg .contains ("Discarded global fallback" )) {
135+ hasGlobalDiscard = true ;
136+ }
137+ if (msg .contains ("Discarded treatment for flag 'null_treatment'" )) {
138+ hasNullFlagDiscard = true ;
139+ }
140+ }
141+ assertTrue ("Expected an error about discarded global fallback" , hasGlobalDiscard );
142+ assertTrue ("Expected an error about discarded treatment for flag 'null_treatment'" , hasNullFlagDiscard );
143+
97144 assertNull (sanitized .getGlobal ());
98145 // Ensure only the valid by-flag entry is preserved
99146 assertEquals (1 , sanitized .getByFlag ().size ());
@@ -118,5 +165,9 @@ public void validFormatTreatmentIsNotDropped() {
118165 assertEquals ("123.on" , sanitized .getByFlag ().get ("numWithDot" ).getTreatment ());
119166 assertEquals ("on_1-2" , sanitized .getByFlag ().get (VALID_FLAG ).getTreatment ());
120167 assertEquals ("on" , sanitized .getGlobal ().getTreatment ());
168+
169+ // No ERROR logs expected for valid-only case
170+ Deque <String > errors4 = mLogPrinter .getLoggedMessages ().get (android .util .Log .ERROR );
171+ assertTrue (errors4 == null || errors4 .isEmpty ());
121172 }
122173}
0 commit comments