/*
* Copyright (c) 2014. Escalon System-Entwicklung, Dietrich Schulten
*
* 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 de.escalon.hypermedia.affordance;
import com.damnhandy.uri.template.UriTemplate;
import org.junit.Assert;
import org.junit.Test;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import static org.hamcrest.Matchers.contains;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
public class PartialUriTemplateTest {
final static String LAWNMOWER_TEMPLATE_STRING =
"http://localhost/things/{id}/widgets?type={widgetType}&redirect=http://example" +
".com/{widgetName}?preorder=true#/order/{widgetId}";
@Test
public void testToStringWithQueryVariablesContainingDot() throws Exception {
PartialUriTemplate partialUriTemplateComponents = new PartialUriTemplate
("http://localhost/events/query{?foo1,foo2,bar.baz,bars.empty,offset,size,strings.empty}");
assertThat(partialUriTemplateComponents.getVariableNames(), contains("foo1", "foo2", "bar.baz",
"bars.empty", "offset", "size", "strings.empty"));
}
@Test
public void testExpandAllComponents() throws Exception {
final PartialUriTemplate template = new PartialUriTemplate("http://example.com/events{/city}{?eventName," +
"location}{#section}");
Map<String, Object> val = new HashMap<String, Object>();
val.put("city", "Wiesbaden");
val.put("eventName", "Revo Tour");
val.put("location", "Schlachthof");
val.put("section", "description");
final PartialUriTemplateComponents expanded = template.expand(val);
Assert.assertEquals("http://example.com/events/Wiesbaden?eventName=Revo+Tour&location=Schlachthof#description",
expanded.toString());
}
@Test
public void testExpandQueryWithTwoVariables() throws Exception {
final PartialUriTemplate template = new PartialUriTemplate("http://example.com/events/Wiesbaden{?eventName," +
"location}");
Map<String, Object> val = new HashMap<String, Object>();
val.put("city", "Wiesbaden");
val.put("eventName", "Revo Tour");
val.put("location", "Schlachthof");
val.put("section", "description");
final PartialUriTemplateComponents expanded = template.expand(val);
Assert.assertEquals("http://example.com/events/Wiesbaden?eventName=Revo+Tour&location=Schlachthof",
expanded.toString());
}
@Test
public void testExpandQueryWithOneVariable() throws Exception {
final PartialUriTemplate template = new PartialUriTemplate("http://example.com/events/Wiesbaden{?eventName}");
Map<String, Object> val = new HashMap<String, Object>();
val.put("city", "Wiesbaden");
val.put("eventName", "Revo Tour");
val.put("location", "Schlachthof");
val.put("section", "description");
final PartialUriTemplateComponents expanded = template.expand(val);
Assert.assertEquals("http://example.com/events/Wiesbaden?eventName=Revo+Tour",
expanded.toString());
}
@Test
public void testExpandLevelOnePathSegment() throws Exception {
final PartialUriTemplate template = new PartialUriTemplate("http://example.com/events/{city}");
Map<String, Object> val = new HashMap<String, Object>();
val.put("city", "Wiesbaden");
final PartialUriTemplateComponents expanded = template.expand(val);
Assert.assertEquals("http://example.com/events/Wiesbaden",
expanded.toString());
}
@Test
public void testExpandLevelOnePathSegmentWithRegex() throws Exception {
final PartialUriTemplate template = new PartialUriTemplate("http://example.com/events/{city:+}");
Map<String, Object> val = new HashMap<String, Object>();
val.put("city", "Wiesbaden");
final PartialUriTemplateComponents expanded = template.expand(val);
Assert.assertEquals("http://example.com/events/Wiesbaden",
expanded.toString());
}
@Test
public void testExpandLevelOnePathSegmentWithPrefix() throws Exception {
final PartialUriTemplate template = new PartialUriTemplate("http://example.com/events/v{version}/Wiesbaden");
Map<String, Object> val = new HashMap<String, Object>();
val.put("version", "1.2.0");
final PartialUriTemplateComponents expanded = template.expand(val);
Assert.assertEquals("http://example.com/events/v1.2.0/Wiesbaden",
expanded.toString());
}
@Test
public void testExpandLevelOneQueryWithOneVariable() throws Exception {
final PartialUriTemplate template = new PartialUriTemplate("http://example" +
".com/events/Wiesbaden?eventName={eventName}");
Map<String, Object> val = new HashMap<String, Object>();
val.put("city", "Wiesbaden");
val.put("eventName", "Revo Tour");
val.put("location", "Schlachthof");
val.put("section", "description");
final PartialUriTemplateComponents expanded = template.expand(val);
Assert.assertEquals("http://example.com/events/Wiesbaden?eventName=Revo+Tour",
expanded.toString());
}
@Test
public void testExpandLevelOneQueryWithTwoVariables() throws Exception {
final PartialUriTemplate template = new PartialUriTemplate("http://example" +
".com/events/Wiesbaden?eventName={eventName}&location={location}");
Map<String, Object> val = new HashMap<String, Object>();
val.put("city", "Wiesbaden");
val.put("eventName", "Revo Tour");
val.put("location", "Schlachthof");
val.put("section", "description");
final PartialUriTemplateComponents expanded = template.expand(val);
Assert.assertEquals("http://example.com/events/Wiesbaden?eventName=Revo+Tour&location=Schlachthof",
expanded.toString());
}
@Test
public void testExpandDoesNotChangeUrlWithoutVariables() throws Exception {
final PartialUriTemplate template = new PartialUriTemplate("http://example" +
".com/events/Wiesbaden?eventName=Revo+Tour&location=Schlachthof#description");
Map<String, Object> val = new HashMap<String, Object>();
val.put("city", "Wiesbaden");
val.put("eventName", "Revo Tour");
val.put("location", "Schlachthof");
val.put("section", "description");
final PartialUriTemplateComponents expanded = template.expand(val);
Assert.assertEquals("http://example.com/events/Wiesbaden?eventName=Revo+Tour&location=Schlachthof#description",
expanded.toString());
}
@Test
public void testExpandWithFixedQuery() throws Exception {
final PartialUriTemplate template =
new PartialUriTemplate("http://example" +
".com/events{/city}?eventName=Revo+Tour&location=Schlachthof{#section}");
Map<String, Object> val = new HashMap<String, Object>();
val.put("city", "Wiesbaden");
val.put("eventName", "Revo Tour");
val.put("location", "Schlachthof");
val.put("section", "description");
final PartialUriTemplateComponents expanded = template.expand(val);
Assert.assertEquals("http://example.com/events/Wiesbaden?eventName=Revo+Tour&location=Schlachthof#description",
expanded.toString());
}
@Test
public void testExpandWithFixedFragmentIdentifier() throws Exception {
final PartialUriTemplate template = new PartialUriTemplate("http://example.com/events{/city}{?eventName," +
"location}#price");
Map<String, Object> val = new HashMap<String, Object>();
val.put("city", "Wiesbaden");
val.put("eventName", "Revo Tour");
val.put("location", "Schlachthof");
val.put("section", "description");
final PartialUriTemplateComponents expanded = template.expand(val);
Assert.assertEquals("http://example.com/events/Wiesbaden?eventName=Revo+Tour&location=Schlachthof#price",
expanded.toString());
}
@Test
public void testExpandAllComponentsButFragmentIdentifier() throws Exception {
final PartialUriTemplate template = new PartialUriTemplate("http://example.com/events{/city}{?eventName," +
"location}{#section}");
Map<String, Object> val = new HashMap<String, Object>();
val.put("city", "Wiesbaden");
val.put("eventName", "Revo Tour");
val.put("location", "Schlachthof");
final PartialUriTemplateComponents expanded = template.expand(val);
Assert.assertEquals("http://example.com/events/Wiesbaden?eventName=Revo+Tour&location=Schlachthof{#section}",
expanded.toString());
}
@Test
public void testExpandOneOfTwoQueryVariables() throws Exception {
final PartialUriTemplate template = new PartialUriTemplate("http://example" +
".com/events{/city}/concerts{?eventName,location}");
Map<String, Object> val = new HashMap<String, Object>();
val.put("location", "Schlachthof");
final PartialUriTemplateComponents expanded = template.expand(val);
Assert.assertEquals("http://example.com/events{/city}/concerts?location=Schlachthof{&eventName}", expanded
.toString());
}
@Test
public void testExpandSegmentVariable() throws Exception {
final PartialUriTemplate template = new PartialUriTemplate("http://example" +
".com/events/{city}/concerts{?eventName,location}");
Map<String, Object> val = new HashMap<String, Object>();
val.put("city", "Wiesbaden");
val.put("location", "Schlachthof");
final PartialUriTemplateComponents expanded = template.expand(val);
Assert.assertEquals("http://example.com/events/Wiesbaden/concerts?location=Schlachthof{&eventName}", expanded
.toString());
}
@Test
public void testExpandQueryContinuationTemplate() throws Exception {
final PartialUriTemplate template = new PartialUriTemplate("http://example" +
".com/events{/city}/concerts?eventName=Revo+Tour{&location}");
Map<String, Object> val = new HashMap<String, Object>();
val.put("location", "Schlachthof");
final PartialUriTemplateComponents expanded = template.expand(val);
Assert.assertEquals("http://example.com/events{/city}/concerts?eventName=Revo+Tour&location=Schlachthof",
expanded.toString());
}
@Test
public void testExpandQueryContinuationTemplateAfterFixedQueryContinuation() throws Exception {
final PartialUriTemplate template = new PartialUriTemplate("http://example" +
".com/events{/city}/concerts?eventName=Revo+Tour&foo=bar{&location}");
Map<String, Object> val = new HashMap<String, Object>();
val.put("location", "Schlachthof");
final PartialUriTemplateComponents expanded = template.expand(val);
Assert.assertEquals("http://example" +
".com/events{/city}/concerts?eventName=Revo+Tour&foo=bar&location=Schlachthof", expanded.toString());
}
@Test
public void testExpandQueryContinuationTemplatesAfterFixedQueryContinuation() throws Exception {
final PartialUriTemplate template = new PartialUriTemplate("http://example" +
".com/events{/city}/concerts?eventName=Revo+Tour&foo=bar{&location,baz}");
Map<String, Object> val = new HashMap<String, Object>();
val.put("baz", "Gnarf");
val.put("location", "Schlachthof");
final PartialUriTemplateComponents expanded = template.expand(val);
Assert.assertEquals("http://example" +
".com/events{/city}/concerts?eventName=Revo+Tour&foo=bar&location=Schlachthof&baz=Gnarf", expanded
.toString());
}
@Test
public void testExpandSimpleStringVariablesWithUrl() {
final PartialUriTemplate template = new PartialUriTemplate
("http://localhost/things/{id}/widgets?type={widgetType}&redirect={url}");
Map<String, Object> arguments = new HashMap<String, Object>();
arguments.put("id", 101);
assertEquals("http://localhost/things/22/widgets?type=ACME+lawn+mower&redirect=http%3A%2F%2Fexample" +
".com%2FLM%2B6000%3Fpreorder%3Dtrue%23%2Forder%2Facme-lm-6000",
template.expand("22", "ACME lawn mower",
"http://example.com/LM+6000?preorder=true#/order/acme-lm-6000")
.toString());
}
@Test
public void testExpandSimpleStringVariablesInUrl() throws URISyntaxException, UnsupportedEncodingException {
final PartialUriTemplate template = new PartialUriTemplate
(LAWNMOWER_TEMPLATE_STRING);
// The redirect url is not correctly encoded, but encoding of the redirect value is up to the
// template provider. We must ensure that we only encode variable values here and leave the rest alone.
String expandedUri = template.expand("22", "ACME lawn mower", "LM 6000",
"acme-lm-6000")
.toString();
assertEquals("http://localhost/things/22/widgets?type=ACME+lawn+mower&redirect=http://example" +
".com/LM+6000?preorder=true#/order/acme-lm-6000", expandedUri);
// make sure our query is equivalent to the one created by damnhandy template engine
Map<String, Object> arguments = new HashMap<String, Object>();
arguments.put("id", 22);
arguments.put("widgetType", "ACME lawn mower");
arguments.put("widgetName", "LM 6000");
arguments.put("widgetId", "acme-lm-6000");
String damnHandyExpandedUri = UriTemplate.fromTemplate
(LAWNMOWER_TEMPLATE_STRING)
.set(arguments)
.expandPartial();
URI myUriTemplate = new URI(expandedUri);
URI dhUriTemplate = new URI(damnHandyExpandedUri);
assertEquals(URLDecoder.decode("utf-8", myUriTemplate.getQuery()),
URLDecoder.decode("utf-8", dhUriTemplate.getQuery()));
}
@Test
public void testPreservesUnexpandedSimpleStringVariables() {
final PartialUriTemplate template = new PartialUriTemplate
(LAWNMOWER_TEMPLATE_STRING);
assertEquals("http://localhost/things/22/widgets?type={widgetType}&redirect=http://example" +
".com/{widgetName}?preorder=true#/order/{widgetId}", template.expand("22")
.toString());
}
@Test
public void testContextAbsolutePath() {
final PartialUriTemplate template = new PartialUriTemplate("/protected/res/documents/index" +
".html?focus={contractId}&caller=BLUE&referrer=/protected/res/my_contracts/index" +
".html&fragment=/contractDetails/{ref}");
assertEquals("/protected/res/documents/index" +
".html?focus={contractId}&caller=BLUE&referrer=/protected/res/my_contracts/index" +
".html&fragment=/contractDetails/{ref}", template.expand()
.toString());
}
}