### Question:
S3V4Authentication { static void buildCanonicalQueryString(Map<String,String> parameters, StringBuilder sb) { boolean firstParam = true; for (String parameter : Ordering.natural().sortedCopy(parameters.keySet())) { if (SecurityParameter.X_Amz_Signature.parameter().equals(parameter)) continue; if (!firstParam) sb.append('&'); String value = parameters.get(parameter); sb.append(HmacLoginModuleSupport.urlencode(parameter)); sb.append('='); if (!Strings.isNullOrEmpty(value)) { Optional<SubResource> subResource = Enums.getIfPresent(SubResource.class, parameter); if (subResource.isPresent() && subResource.get().isObjectSubResource) sb.append(""); else sb.append(HmacLoginModuleSupport.urlencode(value)); } firstParam = false; } } private  S3V4Authentication();  static final String AWS_V4_AUTH_TYPE; static final String AWS_CONTENT_SHA_HEADER; static final String AWS_EXPIRES_PARAM; static final String AWS_DECODED_CONTENT_LEN; static final String STREAMING_PAYLOAD; static final String UNSIGNED_PAYLOAD; }### Answer:
@Test public void testBuildCanonicalQueryString() { StringBuilder sb = new StringBuilder(); S3V4Authentication.buildCanonicalQueryString(paramsRequest.getParameters(), sb); assertEquals(CANONICAL_QUERY_STRING, sb.toString()); }
@Test public void testBuildCanonicalQueryStringParameterEncoding() { StringBuilder sb = new StringBuilder(); S3V4Authentication.buildCanonicalQueryString( ImmutableMap.of( "x", "&#$", "A", "B", "p3", "_", "p1", "~", "p2", "-" ), sb); assertEquals("A=B&p1=~&p2=-&p3=_&x=%26%23%24", sb.toString()); }