Skip to content

Commit 8fdf86b

Browse files
authored
chore: Add comprehensive test cases for RequestValidator to improve coverage and debugging #902 (#904)
1 parent 7e98bc3 commit 8fdf86b

File tree

1 file changed

+176
-0
lines changed

1 file changed

+176
-0
lines changed

src/test/java/com/twilio/security/RequestValidatorTest.java

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,180 @@ public void testValidateAddsPortHttp() {
114114
Assert.assertTrue("Validator did not add port 80 to http url", isValid);
115115
}
116116

117+
118+
@Test
119+
public void testValidateWithEmptyParams() {
120+
// Test with no form parameters - empty map
121+
Map<String, String> emptyParams = new HashMap<>();
122+
String expectedSignature = "zYQTYrRWXE7LtzbG4PfP7/bkkGo="; // hash of URL only
123+
boolean isValid = validator.validate(url, emptyParams, expectedSignature);
124+
125+
Assert.assertTrue("Validation should succeed with empty parameters", isValid);
126+
}
127+
128+
@Test
129+
public void testValidateWithNullParams() {
130+
// Test with null parameters
131+
String expectedSignature = "zYQTYrRWXE7LtzbG4PfP7/bkkGo="; // hash of URL only
132+
boolean isValid = validator.validate(url, (Map<String, String>) null, expectedSignature);
133+
134+
Assert.assertTrue("Validation should succeed with null parameters", isValid);
135+
}
136+
137+
@Test
138+
public void testValidateWithNoQueryParams() {
139+
// Test with URL that has no query parameters
140+
String urlNoQuery = "https://mycompany.com/myapp.php";
141+
String expectedSignature = "1xaxFBvyzXYvWplzNOSs28HWO94=";
142+
boolean isValid = validator.validate(urlNoQuery, params, expectedSignature);
143+
144+
Assert.assertTrue("Validation should succeed with URL without query parameters", isValid);
145+
}
146+
147+
@Test
148+
public void testValidateIgnoresNonTwilioQueryParams() {
149+
// Test that non-Twilio query parameters in the URL are included in signature generation
150+
// (they are NOT ignored - they're part of the URL that gets signed)
151+
String urlWithExtraParams = "https://mycompany.com/myapp.php?foo=1&bar=2&type=thiswontbeusedinthesignaturegeneratorandsoshouldbeignored";
152+
String expectedSignature = "hYkNsTBttoNGkyCS0p+wWmQoRTg=";
153+
boolean isValid = validator.validate(urlWithExtraParams, params, expectedSignature);
154+
155+
Assert.assertTrue("Validation should succeed - query params are part of URL signature", isValid);
156+
}
157+
158+
@Test
159+
public void testValidateWithUrlEncodedQueryParams() {
160+
// Test with URL encoded query parameters
161+
String urlEncoded = "https://mycompany.com/myapp.php?foo=hello%20world&bar=test%2Bvalue";
162+
String expectedSignature = "er2tvAP1Wx+iuTTE2BPgvEaN1cs=";
163+
boolean isValid = validator.validate(urlEncoded, params, expectedSignature);
164+
165+
Assert.assertTrue("Validation should succeed with URL encoded query parameters", isValid);
166+
}
167+
168+
@Test
169+
public void testValidateWithSpecialCharactersInParams() {
170+
// Test with special characters in parameter values
171+
Map<String, String> specialParams = new HashMap<>();
172+
specialParams.put("Message", "Hello & goodbye! @#$%^*()");
173+
specialParams.put("From", "+1 (415) 867-5309");
174+
specialParams.put("Special", "unicode: ñáéíóú");
175+
176+
String expectedSignature = "dCPiR4WtQ6QFN6pJh81CtlCcWLQ=";
177+
boolean isValid = validator.validate(url, specialParams, expectedSignature);
178+
179+
Assert.assertTrue("Validation should succeed with special characters in parameters", isValid);
180+
}
181+
182+
@Test
183+
public void testValidateWithEmptyParameterValues() {
184+
// Test with empty string parameter values
185+
Map<String, String> emptyValueParams = new HashMap<>();
186+
emptyValueParams.put("Digits", "");
187+
emptyValueParams.put("CallSid", "CA1234567890ABCDE");
188+
emptyValueParams.put("EmptyParam", "");
189+
190+
String expectedSignature = "9HHp/OqQMEwdrVebHDdA/+tqjX8=";
191+
boolean isValid = validator.validate(url, emptyValueParams, expectedSignature);
192+
193+
Assert.assertTrue("Validation should succeed with empty parameter values", isValid);
194+
}
195+
196+
@Test
197+
public void testValidateWithNullParameterValues() {
198+
// Test with null parameter values (treated as empty strings)
199+
Map<String, String> nullValueParams = new HashMap<>();
200+
nullValueParams.put("Digits", null);
201+
nullValueParams.put("CallSid", "CA1234567890ABCDE");
202+
nullValueParams.put("NullParam", null);
203+
204+
String expectedSignature = "L9lTTwIlxM1xGAtLRwhOSZggRhM=";
205+
boolean isValid = validator.validate(url, nullValueParams, expectedSignature);
206+
207+
Assert.assertTrue("Validation should succeed with null parameter values", isValid);
208+
}
209+
210+
@Test
211+
public void testValidateParameterKeySorting() {
212+
// Test that parameter keys are properly sorted alphabetically
213+
Map<String, String> unsortedParams = new HashMap<>();
214+
unsortedParams.put("Zebra", "last");
215+
unsortedParams.put("Alpha", "first");
216+
unsortedParams.put("Beta", "second");
217+
unsortedParams.put("Gamma", "third");
218+
219+
String expectedSignature = "enveUe73ZTVLAekHxez3Qx6JuuQ=";
220+
boolean isValid = validator.validate(url, unsortedParams, expectedSignature);
221+
222+
Assert.assertTrue("Validation should succeed with alphabetically sorted parameters", isValid);
223+
}
224+
225+
@Test
226+
public void testValidateWithInternationalCharactersInUrl() {
227+
// Test with international characters in URL
228+
String intlUrl = "https://mycompany.com/webhook/España?año=2023";
229+
String expectedSignature = "G/Hx6mqqnjUNlPAoi2Sp9bGst0g=";
230+
boolean isValid = validator.validate(intlUrl, params, expectedSignature);
231+
232+
Assert.assertTrue("Validation should succeed with international characters in URL", isValid);
233+
}
234+
235+
@Test
236+
public void testValidateWithCaseSensitiveParameterKeys() {
237+
// Test that parameter keys are case sensitive
238+
Map<String, String> caseParams = new HashMap<>();
239+
caseParams.put("callSid", "lowercase");
240+
caseParams.put("CallSid", "uppercase"); // Different from callSid
241+
caseParams.put("CALLSID", "allcaps");
242+
243+
String expectedSignature = "jDK7WKT8wiNrwggd4ceTv4e1MJ4=";
244+
boolean isValid = validator.validate(url, caseParams, expectedSignature);
245+
246+
Assert.assertTrue("Validation should succeed with case-sensitive parameter keys", isValid);
247+
}
248+
249+
@Test
250+
public void testValidateWithMalformedUrlStillWorks() {
251+
// Test that validation handles URLs gracefully even with unusual formatting
252+
String malformedUrl = "https://mycompany.com:443//myapp.php?foo=1&bar=2";
253+
String expectedSignature = "A9lH3u16NjyiiM/+wylw5rirFUs="; // Signature for the malformed URL as-is
254+
boolean isValid = validator.validate(malformedUrl, params, expectedSignature);
255+
256+
Assert.assertTrue("Validation should handle malformed URLs gracefully", isValid);
257+
}
258+
259+
@Test
260+
public void testValidateWithDifferentProtocols() {
261+
// Test validation with different protocols
262+
String httpUrl = url.replace("https", "http");
263+
String expectedSignature = "0ZXoZLH/DfblKGATFgpif+LLRf4=";
264+
boolean isValid = validator.validate(httpUrl, params, expectedSignature);
265+
266+
Assert.assertTrue("Validation should work with HTTP protocol", isValid);
267+
}
268+
269+
@Test
270+
public void testValidateFailsWithWrongSignature() {
271+
// Test that validation properly fails with incorrect signature
272+
String wrongSignature = "IncorrectSignatureValue123=";
273+
boolean isValid = validator.validate(url, params, wrongSignature);
274+
275+
Assert.assertFalse("Validation should fail with incorrect signature", isValid);
276+
}
277+
278+
@Test
279+
public void testValidateFailsWithNullSignature() {
280+
// Test that validation properly fails with null signature
281+
boolean isValid = validator.validate(url, params, null);
282+
283+
Assert.assertFalse("Validation should fail with null signature", isValid);
284+
}
285+
286+
@Test
287+
public void testValidateFailsWithEmptySignature() {
288+
// Test that validation properly fails with empty signature
289+
boolean isValid = validator.validate(url, params, "");
290+
Assert.assertFalse("Validation should fail with empty signature", isValid);
291+
}
292+
117293
}

0 commit comments

Comments
 (0)