/* * Copyright (c) 2011 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.google.api.client.http; import com.google.api.client.util.Value; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import junit.framework.TestCase; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.SortedMap; /** * Tests {@link UriTemplate}. * * @author Ravi Mistry */ public class UriTemplateTest extends TestCase { public void testExpandTemplates_initialization() { SortedMap<String, Object> map = Maps.newTreeMap(); map.put("id", Arrays.asList("a", "b", "c")); // Make sure the UriTemplate.COMPOSITE_PREFIXES map is initialized correctly. assertEquals("/a/b/c", UriTemplate.expand("{/id*}", map, false)); assertEquals("/a/b/c", UriTemplate.expand("{/id*}", map, false)); } public void testExpandTemplates_basic() { SortedMap<String, Object> requestMap = Maps.newTreeMap(); requestMap.put("abc", "xyz"); requestMap.put("def", "123"); requestMap.put("unused", "unused parameter"); // Assert with addUnusedParamsAsQueryParams = false. assertEquals("foo/xyz/bar/123", UriTemplate.expand("foo/{abc}/bar/{def}", requestMap, false)); // Assert with addUnusedParamsAsQueryParams = true. assertEquals("foo/xyz/bar/123?unused=unused%20parameter", UriTemplate.expand("foo/{abc}/bar/{def}", requestMap, true)); // Assert the map has not changed. assertEquals(3, requestMap.size()); assertTrue(requestMap.containsKey("abc")); assertTrue(requestMap.containsKey("def")); assertTrue(requestMap.containsKey("unused")); } public void testExpandTemplates_noExpansionsWithQueryParams() { SortedMap<String, Object> requestMap = Maps.newTreeMap(); requestMap.put("abc", "xyz"); requestMap.put("def", "123"); assertEquals("foo/xyz/bar/123?abc=xyz&def=123", UriTemplate.expand("foo/xyz/bar/123", requestMap, true)); } public void testExpandTemplates_noExpansionsWithoutQueryParams() { SortedMap<String, Object> requestMap = Maps.newTreeMap(); requestMap.put("abc", "xyz"); requestMap.put("def", "123"); assertEquals("foo/xyz/bar/123", UriTemplate.expand("foo/xyz/bar/123", requestMap, false)); } public void testExpandTemplates_missingParameter() { SortedMap<String, Object> requestMap = Maps.newTreeMap(); requestMap.put("abc", "xyz"); assertEquals("foo/xyz/bar/", UriTemplate.expand("foo/{abc}/bar/{def}", requestMap, true)); } public void testExpandTemplates_nullValue() { SortedMap<String, Object> requestMap = Maps.newTreeMap(); requestMap.put("abc", "xyz"); requestMap.put("def", null); assertEquals("foo/xyz/bar/", UriTemplate.expand("foo/{abc}/bar/{def}", requestMap, true)); } public void testExpandTemplates_emptyAndNullRequestMap() { SortedMap<String, Object> requestMap = Maps.newTreeMap(); assertEquals("foo//bar/", UriTemplate.expand("foo/{abc}/bar/{def}", requestMap, true)); assertEquals("foo//bar/", UriTemplate.expand("foo/{abc}/bar/{def}", null, true)); } private Iterable<String> getListIterable() { return Arrays.asList("red", "green", "blue"); } // template, expected output. private static final String[][] LIST_TESTS = { {"{d}", "red,green,blue"}, {"{d*}", "red,green,blue"}, {"{+d}", "red,green,blue"}, {"{+d*}", "red,green,blue"}, {"{#d}", "#red,green,blue"}, {"{#d*}", "#red,green,blue"}, {"X{.d}", "X.red,green,blue"}, {"X{.d*}", "X.red.green.blue"}, {"{/d}", "/red,green,blue"}, {"{/d*}", "/red/green/blue"}, {"{;d}", ";d=red,green,blue"}, {"{;d*}", ";d=red;d=green;d=blue"}, {"{?d}", "?d=red,green,blue"}, {"{?d*}", "?d=red&d=green&d=blue"}, {"{&d}", "&d=red,green,blue"}, {"{&d*}", "&d=red&d=green&d=blue"}, }; public void testExpandTemplates_explodeIterator() { for (String[] test : LIST_TESTS) { SortedMap<String, Object> requestMap = Maps.newTreeMap(); requestMap.put("d", getListIterable().iterator()); assertEquals(test[1], UriTemplate.expand(test[0], requestMap, true)); } } public void testExpandTemplates_explodeIterable() { for (String[] test : LIST_TESTS) { SortedMap<String, Object> requestMap = Maps.newTreeMap(); requestMap.put("d", getListIterable()); assertEquals(test[1], UriTemplate.expand(test[0], requestMap, true)); } } enum testEnum { @Value ONE } public void testExpandTemplates_explodeEnum() { SortedMap<String, Object> requestMap = Maps.newTreeMap(); requestMap.put("d", testEnum.ONE); assertEquals(testEnum.ONE.toString(), UriTemplate.expand("{d}", requestMap, true)); } public void testExpandTemplates_missingCompositeParameter() { SortedMap<String, Object> requestMap = Maps.newTreeMap(); requestMap.put("abc", "xyz"); assertEquals("", UriTemplate.expand("{d}", requestMap, false)); assertEquals("?abc=xyz", UriTemplate.expand("{d}", requestMap, true)); } public void testExpandTemplates_emptyListParameter() { SortedMap<String, Object> requestMap = Maps.newTreeMap(); requestMap.put("d", Lists.newArrayList()); assertEquals("", UriTemplate.expand("{d}", requestMap, true)); } private Map<String, String> getMapParams() { Map<String, String> params = Maps.newLinkedHashMap(); params.put("semi", ";"); params.put("dot", "."); params.put("comma", ","); return params; } // template, expected output. private static final String[][] MAP_TESTS = { {"{d}", "semi,%3B,dot,.,comma,%2C"}, {"{d*}", "semi=%3B,dot=.,comma=%2C"}, {"{+d}", "semi,;,dot,.,comma,,"}, {"{+d*}", "semi=;,dot=.,comma=,"}, {"{#d}", "#semi,;,dot,.,comma,,"}, {"{#d*}", "#semi=;,dot=.,comma=,"}, {"X{.d}", "X.semi,%3B,dot,.,comma,%2C"}, {"X{.d*}", "X.semi=%3B.dot=..comma=%2C"}, {"{/d}", "/semi,%3B,dot,.,comma,%2C"}, {"{/d*}", "/semi=%3B/dot=./comma=%2C"}, {"{;d}", ";d=semi,%3B,dot,.,comma,%2C"}, {"{;d*}", ";semi=%3B;dot=.;comma=%2C"}, {"{?d}", "?d=semi,%3B,dot,.,comma,%2C"}, {"{?d*}", "?semi=%3B&dot=.&comma=%2C"}, {"{&d}", "&d=semi,%3B,dot,.,comma,%2C"}, {"{&d*}", "&semi=%3B&dot=.&comma=%2C"}, }; public void testExpandTemplates_explodeMap() { for (String[] test : MAP_TESTS) { SortedMap<String, Object> requestMap = Maps.newTreeMap(); requestMap.put("d", getMapParams()); assertEquals(test[1], UriTemplate.expand(test[0], requestMap, true)); } } public void testExpandTemplates_emptyMapParameter() { SortedMap<String, Object> requestMap = Maps.newTreeMap(); requestMap.put("d", Maps.newTreeMap()); assertEquals("", UriTemplate.expand("{d}", requestMap, true)); } public void testExpandTemplates_unusedQueryParametersEncoding() { Map<String, Object> requestMap = Maps.newLinkedHashMap(); // Add unused params. requestMap.put("unused1", "abc!1234?"); requestMap.put("unused2", "56$7 8"); requestMap.put("unused3", "9=&/:@."); assertEquals("?unused1=abc!1234?&unused2=56$7%208&unused3=9%3D%26/:@.", UriTemplate.expand("", requestMap, true)); } public void testExpandTemplates_unusedListQueryParameters() { Map<String, Object> requestMap = Maps.newLinkedHashMap(); // Add unused params. List<String> params = Lists.newArrayList(); params.add("value1"); params.add("value2"); requestMap.put("unused1", params); requestMap.put("unused2", "56$7 8"); requestMap.put("unused3", "9=&/:@."); assertEquals("?unused1=value1&unused1=value2&unused2=56$7%208&unused3=9%3D%26/:@.", UriTemplate.expand("", requestMap, true)); } public void testExpandTemplates_mixedBagParameters() { Map<String, Object> requestMap = Maps.newLinkedHashMap(); // Add list params. requestMap.put("iterator", getListIterable().iterator()); requestMap.put("iterable", getListIterable()); // Add map params. requestMap.put("map", getMapParams()); // Add enum param. requestMap.put("enum", testEnum.ONE); // Add normal params. requestMap.put("abc", "xyz"); // Add unused params. requestMap.put("unused1", "unused param"); requestMap.put("unused2", "unused=param"); assertEquals( "foo/xyz/red/green/blue&iterable=red&iterable=green&iterable=blue&map=semi,%3B,dot,.,comma" + ",%2CONE?unused1=unused%20param&unused2=unused%3Dparam", UriTemplate.expand("foo/{abc}{/iterator*}{&iterable*}{&map}{&enum}", requestMap, true)); // Assert the map has not changed. assertEquals(7, requestMap.size()); assertTrue(requestMap.containsKey("iterator")); assertTrue(requestMap.containsKey("iterable")); assertTrue(requestMap.containsKey("map")); assertTrue(requestMap.containsKey("abc")); assertTrue(requestMap.containsKey("unused1")); assertTrue(requestMap.containsKey("unused2")); } public void testExpandTemplates_withBaseUrl() { SortedMap<String, Object> requestMap = Maps.newTreeMap(); requestMap.put("abc", "xyz"); requestMap.put("def", "123"); // Expand with URI template not starting with "/". assertEquals("https://test/base/path/xyz/123/bar/", UriTemplate.expand("https://test/base/path/", "{abc}/{def}/bar/", requestMap, true)); // Expand with URI template starting with "/". assertEquals("https://test/xyz/123/bar/", UriTemplate.expand("https://test/base/path/", "/{abc}/{def}/bar/", requestMap, true)); // Expand with URI template as a full URL. assertEquals("http://test3/xyz/123/bar/", UriTemplate.expand("https://test/base/path/", "http://test3/{abc}/{def}/bar/", requestMap, true)); } public void testExpandNonReservedNonComposite() { SortedMap<String, Object> requestMap = Maps.newTreeMap(); requestMap.put("abc", "xyz"); requestMap.put("def", "a/b?c"); assertEquals("foo/xyz/bar/a%2Fb%3Fc", UriTemplate.expand("foo/{abc}/bar/{def}", requestMap, false)); assertEquals("foo/xyz/bar/a/b?c", UriTemplate.expand("foo/{abc}/bar/{+def}", requestMap, false)); } }