/* vim: set ts=2 et sw=2 cindent fo=qroca: */
package com.globant.katari.shindig;
import static org.apache.shindig.config.ContainerConfig.DEFAULT_CONTAINER;
import static com.globant.katari.shindig
.SpringJsonContainerConfig.CONTAINER_KEY;
import static com.globant.katari.shindig
.SpringJsonContainerConfig.PARENT_KEY;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.matchers.JUnitMatchers.*;
import org.apache.shindig.config.ContainerConfig;
import org.apache.shindig.config.ContainerConfigException;
import org.apache.shindig.expressions.Expressions;
import org.json.JSONObject;
import org.junit.Test;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class SpringJsonContainerConfigTest {
private static final String TOP_LEVEL_NAME = "Top level name";
private static final String TOP_LEVEL_VALUE = "Top level value";
private static final String NESTED_KEY = "ne$ted";
private static final String NESTED_NAME = "Nested name";
private static final String NESTED_VALUE = "Nested value";
private static final String NESTED_ALT_VALUE = "Nested value alt";
private static final String CHILD_CONTAINER = "child";
private static final String CONTAINER_A = "container-a";
private static final String CONTAINER_B = "container-b";
private static final String ARRAY_NAME = "array value";
private static final String[] ARRAY_VALUE = {"Hello", "World"};
private static final String ARRAY_ALT_VALUE = "Not an array";
private File createContainer(JSONObject json) throws Exception {
File file = File.createTempFile(getClass().getName(), ".json");
file.deleteOnExit();
BufferedWriter out = new BufferedWriter(new FileWriter(file));
out.write(json.toString());
out.close();
return file;
}
private File createDefaultContainer() throws Exception {
// We use a JSON Object here to guarantee that we're well formed up front.
JSONObject json = new JSONObject();
json.put(CONTAINER_KEY, new String[]{DEFAULT_CONTAINER});
json.put(TOP_LEVEL_NAME, TOP_LEVEL_VALUE);
json.put(ARRAY_NAME, ARRAY_VALUE);
// small nested data.
JSONObject nested = new JSONObject();
nested.put(NESTED_NAME, NESTED_VALUE);
json.put(NESTED_KEY, nested);
return createContainer(json);
}
@Test
public void parseBasicConfig() throws Exception {
ContainerConfig config = new SpringJsonContainerConfig(
createDefaultContainer().getAbsolutePath(), "localhost:8098",
"/context", Expressions.forTesting());
assertEquals(1, config.getContainers().size());
for (String container : config.getContainers()) {
assertEquals(DEFAULT_CONTAINER, container);
}
String value = config.getString(DEFAULT_CONTAINER, TOP_LEVEL_NAME);
assertEquals(TOP_LEVEL_VALUE, value);
Map<String, Object> nested = config.getMap(DEFAULT_CONTAINER, NESTED_KEY);
String nestedValue = nested.get(NESTED_NAME).toString();
assertEquals(NESTED_VALUE, nestedValue);
}
@Test
public void aliasesArePopulated() throws Exception {
JSONObject json = new JSONObject()
.put(CONTAINER_KEY, new String[]{CONTAINER_A, CONTAINER_B})
.put(NESTED_KEY, NESTED_VALUE);
File parentFile = createDefaultContainer();
File childFile = createContainer(json);
ContainerConfig config = new SpringJsonContainerConfig(
childFile.getAbsolutePath() + SpringJsonContainerConfig.FILE_SEPARATOR
+ parentFile.getAbsolutePath(), "localhost:8098", "/context",
Expressions.forTesting());
assertEquals(NESTED_VALUE, config.getString(CONTAINER_A, NESTED_KEY));
assertEquals(NESTED_VALUE, config.getString(CONTAINER_B, NESTED_KEY));
}
@Test
public void parseWithDefaultInheritance() throws Exception {
JSONObject json = new JSONObject();
json.put(CONTAINER_KEY, new String[]{CHILD_CONTAINER});
json.put(PARENT_KEY, DEFAULT_CONTAINER);
json.put(ARRAY_NAME, ARRAY_ALT_VALUE);
// small nested data.
JSONObject nested = new JSONObject();
nested.put(NESTED_NAME, NESTED_ALT_VALUE);
json.put(NESTED_KEY, nested);
File childFile = createContainer(json);
File parentFile = createDefaultContainer();
ContainerConfig config = new SpringJsonContainerConfig(
childFile.getAbsolutePath() + SpringJsonContainerConfig.FILE_SEPARATOR
+ parentFile.getAbsolutePath(), "localhost:8098", "/context",
Expressions.forTesting());
String value = config.getString(CHILD_CONTAINER, TOP_LEVEL_NAME);
assertEquals(TOP_LEVEL_VALUE, value);
Map<String, Object> nestedObj = config.getMap(CHILD_CONTAINER, NESTED_KEY);
String nestedValue = nestedObj.get(NESTED_NAME).toString();
assertEquals(NESTED_ALT_VALUE, nestedValue);
String arrayValue = config.getString(CHILD_CONTAINER, ARRAY_NAME);
assertEquals(ARRAY_ALT_VALUE, arrayValue);
// Verify that the parent value wasn't overwritten as well.
List<String> actual = new ArrayList<String>();
for (Object val : config.getList(DEFAULT_CONTAINER, ARRAY_NAME)) {
actual.add(val.toString());
}
List<String> expected = Arrays.asList(ARRAY_VALUE);
assertEquals(expected, actual);
}
@Test
public void invalidContainerReturnsNull() throws Exception {
ContainerConfig config = new SpringJsonContainerConfig(
createDefaultContainer().getAbsolutePath(), "localhost:8098",
"/config", Expressions.forTesting());
assertNull("Did not return null for invalid container.",
config.getString("fake", PARENT_KEY));
}
@Test(expected = ContainerConfigException.class)
public void badConfigThrows() throws Exception {
JSONObject json = new JSONObject();
json.put(CONTAINER_KEY, new String[]{CHILD_CONTAINER});
json.put(PARENT_KEY, "bad bad bad parent!");
json.put(ARRAY_NAME, ARRAY_ALT_VALUE);
new SpringJsonContainerConfig(createContainer(json).getAbsolutePath(),
"localhost:8098", "/context", Expressions.forTesting());
}
@Test
public void pathQuery() throws Exception {
ContainerConfig config = new SpringJsonContainerConfig(
createDefaultContainer().getAbsolutePath(), "localhost:8098",
"/context", Expressions.forTesting());
String path = "${" + NESTED_KEY + "['" + NESTED_NAME + "']}";
String data = config.getString(DEFAULT_CONTAINER, path);
assertEquals(NESTED_VALUE, data);
}
@Test
public void expressionEvaluation() throws Exception {
// We use a JSON Object here to guarantee that we're well formed up front.
JSONObject json = new JSONObject();
json.put(CONTAINER_KEY, new String[]{DEFAULT_CONTAINER});
json.put("expression", "Hello, ${world}!");
json.put("world", "Earth");
ContainerConfig config = new SpringJsonContainerConfig(
createContainer(json).getAbsolutePath(), "localhost:8098", "/context",
Expressions.forTesting());
assertEquals("Hello, Earth!", config.getString(DEFAULT_CONTAINER,
"expression"));
}
@Test
public void expressionEvaluationUsingParent() throws Exception {
// We use a JSON Object here to guarantee that we're well formed up front.
JSONObject json = new JSONObject();
json.put(CONTAINER_KEY, new String[]{CHILD_CONTAINER});
json.put(PARENT_KEY, DEFAULT_CONTAINER);
json.put("parentExpression", "${parent['" + TOP_LEVEL_NAME + "']}");
File childFile = createContainer(json);
File parentFile = createDefaultContainer();
ContainerConfig config = new SpringJsonContainerConfig(
childFile.getAbsolutePath() + SpringJsonContainerConfig.FILE_SEPARATOR
+ parentFile.getAbsolutePath(), "localhost:8098", "/context",
Expressions.forTesting());
assertEquals(TOP_LEVEL_VALUE, config.getString(CHILD_CONTAINER,
"parentExpression"));
}
@Test
public void nullEntryEvaluation() throws Exception {
// We use a JSON Object here to guarantee that we're well formed up front.
JSONObject json = new JSONObject(
"{ 'gadgets.container' : ['default'], features : { osapi : null }}");
SpringJsonContainerConfig config = new SpringJsonContainerConfig(
createContainer(json).getAbsolutePath(), "localhost:8098", "/context",
Expressions.forTesting());
assertNull(config.getMap("default", "features").get("osapi"));
}
/* Test related to %context% replacement.
*/
/* Creates a container with a %context% val.
*/
private String createContextContainer() throws Exception {
// We use a JSON Object here to guarantee that we're well formed up front.
JSONObject json = new JSONObject();
json.put(CONTAINER_KEY, new String[]{DEFAULT_CONTAINER});
json.put(TOP_LEVEL_NAME, TOP_LEVEL_VALUE);
json.put(ARRAY_NAME, ARRAY_VALUE);
// small nested data.
JSONObject nestedJson = new JSONObject();
nestedJson.put(NESTED_NAME, "%context%/" + NESTED_VALUE);
nestedJson.put("endpoint", "%hostAndPort%/" + NESTED_VALUE);
json.put(NESTED_KEY, nestedJson);
File childFile = createContainer(json);
return childFile.getAbsolutePath();
}
@Test
public void constructor_context() throws Exception {
ContainerConfig config = new SpringJsonContainerConfig(
createContextContainer(), "localhost:8098", "/context",
Expressions.forTesting());
Map<String, Object> nested = config.getMap(DEFAULT_CONTAINER, NESTED_KEY);
String nestedValue = nested.get(NESTED_NAME).toString();
assertThat(nestedValue, containsString("/context/"));
}
@Test
public void constructor_contextNoSlash() throws Exception {
ContainerConfig config = new SpringJsonContainerConfig(
createContextContainer(), "localhost:8098", "context",
Expressions.forTesting());
Map<String, Object> nested = config.getMap(DEFAULT_CONTAINER, NESTED_KEY);
String nestedValue = nested.get(NESTED_NAME).toString();
assertThat(nestedValue, containsString("/context/"));
}
@Test
public void constructor_contextOnlyTrailing() throws Exception {
ContainerConfig config = new SpringJsonContainerConfig(
createContextContainer(), "localhost:8098", "context/",
Expressions.forTesting());
Map<String, Object> nested = config.getMap(DEFAULT_CONTAINER, NESTED_KEY);
String nestedValue = nested.get(NESTED_NAME).toString();
assertThat(nestedValue, containsString("/context/"));
}
@Test
public void constructor_contextTwoSlashes() throws Exception {
ContainerConfig config = new SpringJsonContainerConfig(
createContextContainer(), "localhost:8098", "context/",
Expressions.forTesting());
Map<String, Object> nested = config.getMap(DEFAULT_CONTAINER, NESTED_KEY);
String nestedValue = nested.get(NESTED_NAME).toString();
assertThat(nestedValue, containsString("/context/"));
nestedValue = nested.get("endpoint").toString();
assertThat(nestedValue, containsString("localhost:8098"));
}
}