blob: 91ffcd048f370670b4017a289541cbfec4dc176a [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.sling.jcr.contentloader.internal;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.LinkedHashMap;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonWriter;
import org.apache.sling.jcr.contentloader.ContentCreator;
import org.apache.sling.jcr.contentloader.internal.readers.JsonReader;
import org.jmock.Expectations;
import org.jmock.Sequence;
import org.jmock.integration.junit4.JUnitRuleMockery;
import org.junit.Rule;
public class JsonReaderTest {
protected JsonReader jsonReader;
@Rule
public final JUnitRuleMockery mockery = new JUnitRuleMockery();
protected ContentCreator creator;
protected Sequence mySequence;
protected void setReader() {
this.jsonReader = new JsonReader();
}
@org.junit.Before public void setUp() throws Exception {
setReader();
this.creator = this.mockery.mock(ContentCreator.class);
this.mySequence = this.mockery.sequence("my-sequence");
}
@org.junit.After public void tearDown() throws Exception {
this.jsonReader = null;
}
@org.junit.Test public void testEmptyObject() throws Exception {
this.mockery.checking(new Expectations() {{
allowing(creator).createNode(null, null, null); inSequence(mySequence);
allowing(creator).finishNode(); inSequence(mySequence);
}});
this.parse("");
}
@org.junit.Test public void testEmpty() throws IOException, RepositoryException {
this.mockery.checking(new Expectations() {{
allowing(creator).createNode(null, null, null); inSequence(mySequence);
allowing(creator).finishNode(); inSequence(mySequence);
}});
this.parse("{}");
}
@org.junit.Test public void testDefaultPrimaryNodeTypeWithSurroundWhitespace() throws Exception {
this.mockery.checking(new Expectations() {{
allowing(creator).createNode(null, null, null); inSequence(mySequence);
allowing(creator).finishNode(); inSequence(mySequence);
}});
String json = " { } ";
this.parse(json);
}
@org.junit.Test public void testDefaultPrimaryNodeTypeWithoutEnclosingBracesWithSurroundWhitespace() throws Exception {
this.mockery.checking(new Expectations() {{
allowing(creator).createNode(null, null, null); inSequence(mySequence);
allowing(creator).finishNode(); inSequence(mySequence);
}});
String json = " ";
this.parse(json);
}
@org.junit.Test public void testExplicitePrimaryNodeType() throws Exception {
final String type = "xyz:testType";
String json = "{ \"jcr:primaryType\": \"" + type + "\" }";
this.mockery.checking(new Expectations() {{
allowing(creator).createNode(null, type, null); inSequence(mySequence);
allowing(creator).finishNode(); inSequence(mySequence);
}});
this.parse(json);
}
@org.junit.Test public void testMixinNodeTypes1() throws Exception {
final String[] mixins = new String[]{ "xyz:mix1" };
String json = "{ \"jcr:mixinTypes\": " + this.toJsonArray(mixins) + "}";
this.mockery.checking(new Expectations() {{
allowing(creator).createNode(null, null, mixins); inSequence(mySequence);
allowing(creator).finishNode(); inSequence(mySequence);
}});
this.parse(json);
}
@org.junit.Test public void testMixinNodeTypes2() throws Exception {
final String[] mixins = new String[]{ "xyz:mix1", "abc:mix2" };
String json = "{ \"jcr:mixinTypes\": " + this.toJsonArray(mixins) + "}";
this.mockery.checking(new Expectations() {{
allowing(creator).createNode(null, null, mixins); inSequence(mySequence);
allowing(creator).finishNode(); inSequence(mySequence);
}});
this.parse(json);
}
@org.junit.Test public void testPropertiesEmpty() throws Exception {
String json = "{ \"property\": \"\"}";
this.mockery.checking(new Expectations() {{
allowing(creator).createNode(null, null, null); inSequence(mySequence);
allowing(creator).createProperty("property", PropertyType.UNDEFINED, ""); inSequence(mySequence);
allowing(creator).finishNode(); inSequence(mySequence);
}});
this.parse(json);
}
@org.junit.Test public void testPropertiesSingleValue() throws Exception {
String json = "{ \"p1\": \"v1\"}";
this.mockery.checking(new Expectations() {{
allowing(creator).createNode(null, null, null); inSequence(mySequence);
allowing(creator).createProperty("p1", PropertyType.UNDEFINED, "v1"); inSequence(mySequence);
allowing(creator).finishNode(); inSequence(mySequence);
}});
this.parse(json);
}
@org.junit.Test public void testPropertiesSingleDateValue() throws Exception {
String json = "{ \"p1\": \"2009-09-24T16:32:57.948-07:00\"}";
this.mockery.checking(new Expectations() {{
allowing(creator).createNode(null, null, null); inSequence(mySequence);
allowing(creator).createProperty("p1", PropertyType.DATE, "2009-09-24T16:32:57.948-07:00"); inSequence(mySequence);
allowing(creator).finishNode(); inSequence(mySequence);
}});
this.parse(json);
}
@org.junit.Test public void testPropertiesTwoSingleValue() throws Exception {
String json = "{ \"p1\": \"v1\", \"p2\": \"v2\"}";
this.mockery.checking(new Expectations() {{
allowing(creator).createNode(null, null, null); inSequence(mySequence);
allowing(creator).createProperty("p1", PropertyType.UNDEFINED, "v1"); inSequence(mySequence);
allowing(creator).createProperty("p2", PropertyType.UNDEFINED, "v2"); inSequence(mySequence);
allowing(creator).finishNode(); inSequence(mySequence);
}});
this.parse(json);
}
@org.junit.Test public void testPropertiesMultiValue() throws Exception {
String json = "{ \"p1\": [\"v1\"]}";
this.mockery.checking(new Expectations() {{
allowing(creator).createNode(null, null, null); inSequence(mySequence);
allowing(creator).createProperty("p1", PropertyType.UNDEFINED, new String[] {"v1"}); inSequence(mySequence);
allowing(creator).finishNode(); inSequence(mySequence);
}});
this.parse(json);
}
@org.junit.Test public void testPropertiesMultiDateValue() throws Exception {
String json = "{ \"p1\": [\"2009-09-24T16:32:57.948-07:00\"]}";
this.mockery.checking(new Expectations() {{
allowing(creator).createNode(null, null, null); inSequence(mySequence);
allowing(creator).createProperty("p1", PropertyType.DATE, new String[] {"2009-09-24T16:32:57.948-07:00"}); inSequence(mySequence);
allowing(creator).finishNode(); inSequence(mySequence);
}});
this.parse(json);
}
@org.junit.Test public void testPropertiesMultiValueEmpty() throws Exception {
String json = "{ \"p1\": []}";
this.mockery.checking(new Expectations() {{
allowing(creator).createNode(null, null, null); inSequence(mySequence);
allowing(creator).createProperty("p1", PropertyType.STRING, new String[0]); inSequence(mySequence);
allowing(creator).finishNode(); inSequence(mySequence);
}});
this.parse(json);
}
@org.junit.Test public void testChild() throws Exception {
String json = "{ " +
" \"c1\" : {}" +
"}";
this.mockery.checking(new Expectations() {{
allowing(creator).createNode(null, null, null); inSequence(mySequence);
allowing(creator).createNode("c1", null, null); inSequence(mySequence);
allowing(creator).finishNode(); inSequence(mySequence);
allowing(creator).finishNode(); inSequence(mySequence);
}});
this.parse(json);
}
@org.junit.Test public void testChildWithMixin() throws Exception {
String json = "{ " +
" \"c1\" : {" +
"\"jcr:mixinTypes\" : [\"xyz:TestType\"]" +
"}" +
"}";
this.mockery.checking(new Expectations() {{
allowing(creator).createNode(null, null, null); inSequence(mySequence);
allowing(creator).createNode("c1", null, new String[] {"xyz:TestType"}); inSequence(mySequence);
allowing(creator).finishNode(); inSequence(mySequence);
allowing(creator).finishNode(); inSequence(mySequence);
}});
this.parse(json);
}
@org.junit.Test public void testTwoChildren() throws Exception {
String json = "{ " +
" \"c1\" : {}," +
" \"c2\" : {}" +
"}";
this.mockery.checking(new Expectations() {{
allowing(creator).createNode(null, null, null); inSequence(mySequence);
allowing(creator).createNode("c1", null, null); inSequence(mySequence);
allowing(creator).finishNode(); inSequence(mySequence);
allowing(creator).createNode("c2", null, null); inSequence(mySequence);
allowing(creator).finishNode(); inSequence(mySequence);
allowing(creator).finishNode(); inSequence(mySequence);
}});
this.parse(json);
}
@org.junit.Test public void testChildWithProperty() throws Exception {
String json = "{ " +
" \"c1\" : {" +
" \"c1p1\" : \"v1\"" +
"}" +
"}";
this.mockery.checking(new Expectations() {{
allowing(creator).createNode(null, null, null); inSequence(mySequence);
allowing(creator).createNode("c1", null, null); inSequence(mySequence);
allowing(creator).createProperty("c1p1", PropertyType.UNDEFINED, "v1");
allowing(creator).finishNode(); inSequence(mySequence);
allowing(creator).finishNode(); inSequence(mySequence);
}});
this.parse(json);
}
@org.junit.Test public void testCreateOnePrincipal() throws Exception {
String json = "{\"security:principals\":{ " +
" \"name\" : \"username2\"," +
" \"password\" : \"pwd2\"" +
" }}";
final LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>();
map.put("foo","bar");
this.mockery.checking(new Expectations() {{
allowing(creator).createNode(null, null, null);
allowing(creator).createUser("username2", "pwd2",new LinkedHashMap<String, Object>());
allowing(creator).finishNode(); inSequence(mySequence);
}});
this.parse(json);
}
@org.junit.Test public void testCreatePrincipals() throws Exception {
String json = "{\"security:principals\":[ " +
" { " +
" \"name\" : \"username1\"," +
" \"password\" : \"pwd1\"," +
" \"foo\" : \"bar\"" +
" }," +
" { " +
" \"name\" : \"username2\"," +
" \"password\" : \"pwd2\"" +
" }," +
" { " +
" \"name\" : \"group1\"," +
" \"isgroup\" : true," +
" \"members\" : [\"username1\",\"username2\"]" +
" }]}";
final LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>();
map.put("foo","bar");
this.mockery.checking(new Expectations() {{
allowing(creator).createNode(null, null, null);
allowing(creator).createUser("username1", "pwd1", map);
allowing(creator).createUser("username2", "pwd2",new LinkedHashMap<String, Object>());
allowing(creator).createGroup("group1", new String[]{"username1","username2"}, new LinkedHashMap<String, Object>());
allowing(creator).finishNode(); inSequence(mySequence);
}});
this.parse(json);
}
@org.junit.Test public void testCreateAcl() throws Exception {
String json = " { " +
"\"security:acl\" : [ " +
" { " +
" \"principal\" : \"username1\"," +
" \"granted\" : [\"jcr:read\",\"jcr:write\"]," +
" \"denied\" : []" +
" }," +
" {" +
" \"principal\" : \"groupname1\"," +
" \"granted\" : [\"jcr:read\",\"jcr:write\"]" +
" }," +
" {" +
" \"principal\" : \"groupname2\"," +
" \"granted\" : [\"jcr:read\"]," +
" \"denied\" : [\"jcr:write\"]," +
" \"order\" : \"first\"" +
" }" +
"]" +
"}";
this.mockery.checking(new Expectations() {{
allowing(creator).createNode(null, null, null); inSequence(mySequence);
allowing(creator).createAce("username1",new String[]{"jcr:read","jcr:write"},new String[]{}, null); inSequence(mySequence);
allowing(creator).createAce("groupname1",new String[]{"jcr:read","jcr:write"},null, null); inSequence(mySequence);
allowing(creator).createAce("groupname2",new String[]{"jcr:read"},new String[]{"jcr:write"}, "first"); inSequence(mySequence);
allowing(creator).finishNode(); inSequence(mySequence);
}});
this.parse(json);
}
@org.junit.Test public void testCreateAclWithTickQuotes() throws Exception {
String json = " { " +
"'security:acl' : [ " +
" { " +
" 'principal' : 'username1'," +
" 'granted' : ['jcr:read','jcr:write']," +
" 'denied' : []" +
" }," +
" {" +
" 'principal' : 'groupname1'," +
" 'granted' : ['jcr:read','jcr:write']" +
" }," +
" {" +
" 'principal' : \"\\\"'groupname2'\"," +
" 'granted' : ['jcr:read']," +
" 'denied' : ['jcr:write']," +
" 'order' : 'first'" +
" }" +
"]" +
"}";
this.mockery.checking(new Expectations() {{
allowing(creator).createNode(null, null, null); inSequence(mySequence);
allowing(creator).createAce("username1",new String[]{"jcr:read","jcr:write"},new String[]{}, null); inSequence(mySequence);
allowing(creator).createAce("groupname1",new String[]{"jcr:read","jcr:write"},null, null); inSequence(mySequence);
allowing(creator).createAce("\"'groupname2'",new String[]{"jcr:read"},new String[]{"jcr:write"}, "first"); inSequence(mySequence);
allowing(creator).finishNode(); inSequence(mySequence);
}});
this.parse(json);
}
//---------- internal helper ----------------------------------------------
protected void parse(String json) throws IOException, RepositoryException {
String charSet = "ISO-8859-1";
json = "#" + charSet + "\r\n" + json;
InputStream ins = new ByteArrayInputStream(json.getBytes(charSet));
this.jsonReader.parse(ins, this.creator);
}
protected String toJsonArray(String[] array) {
JsonArrayBuilder builder = Json.createArrayBuilder();
for (String value : array)
{
builder.add(value);
}
StringWriter stringWriter = new StringWriter();
try (JsonWriter writer = Json.createWriter(stringWriter))
{
writer.writeArray(builder.build());
}
return stringWriter.toString();
}
}