blob: eaffda2953e197da810f6f8fae3abab92f6d0d78 [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.oak.restrictions.impl;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.MockitoAnnotations.initMocks;
import java.util.Arrays;
import org.apache.commons.lang.StringUtils;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.api.Type;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
public class ResourceTypePatternTest {
private static final String TEST_PATH = "/content/path/to/test";
private static final String RESOURCE_TYPE_TEST_PATH = "myproj/comp1";
private static final String RESOURCE_TYPE_SUB1 = "myproj/comp2";
private static final String RESOURCE_TYPE_SUB2 = "myproj/comp3";
private static final String RESOURCE_TYPE_SUB3 = "myproj/comp4";
private static final String RESOURCE_TYPE_SUBSUB1 = "myproj/comp5";
private static final String RESOURCE_TYPE_OUTSIDE_SCOPE = "myproj/outsidescope";
private static final String TEST_NODE_SUB1 = "subfolder1";
private static final String TEST_NODE_SUB2 = "subfolder2";
private static final String TEST_NODE_SUB3 = "subfolder3";
private static final String TEST_NODE_SUBSUB1 = "subsubfolder1";
private static final String TEST_NODE_SUBSUB2 = "subsubfolder2";
@Mock
private Tree testTree;
@Mock
private Tree testTreeSub1;
@Mock
private Tree testTreeSub2;
@Mock
private Tree testTreeSub3;
@Mock
private Tree testTreeSub3Sub1;
@Mock
private Tree testTreeSub3Sub2;
@Mock
private Tree testTreeParentOutsideScope;
private ResourceTypePattern resourceTypePattern;
@Before
public void setup() {
initMocks(this);
setupTreeMock(testTreeParentOutsideScope, StringUtils.substringBeforeLast(TEST_PATH, "/"), null, RESOURCE_TYPE_OUTSIDE_SCOPE);
setupTreeMock(testTree, StringUtils.substringAfterLast(TEST_PATH, "/"), testTreeParentOutsideScope, RESOURCE_TYPE_TEST_PATH);
setupTreeMock(testTreeSub1, TEST_NODE_SUB1, testTree, RESOURCE_TYPE_SUB1);
setupTreeMock(testTreeSub2, TEST_NODE_SUB2, testTree, RESOURCE_TYPE_SUB2);
setupTreeMock(testTreeSub3, TEST_NODE_SUB3, testTree, RESOURCE_TYPE_SUB3);
setupTreeMock(testTreeSub3Sub1, TEST_NODE_SUBSUB1, testTreeSub3, RESOURCE_TYPE_SUBSUB1);
setupTreeMock(testTreeSub3Sub2, TEST_NODE_SUBSUB2, testTreeSub3, RESOURCE_TYPE_SUBSUB1);
}
@Test
public void testBasicMatchWithoutChildren() {
resourceTypePattern = new ResourceTypePattern(Arrays.asList(RESOURCE_TYPE_TEST_PATH, RESOURCE_TYPE_SUB1, RESOURCE_TYPE_SUB3), TEST_PATH, false);
assertNonTreeFunctionsReturnFalse();
assertTrue(resourceTypePattern.matches(testTree, null));
assertTrue(resourceTypePattern.matches(testTreeSub1, null));
assertFalse(resourceTypePattern.matches(testTreeSub2, null));
assertTrue(resourceTypePattern.matches(testTreeSub3, null));
assertFalse(resourceTypePattern.matches(testTreeSub3Sub1, null));
assertFalse(resourceTypePattern.matches(testTreeSub3Sub2, null));
}
@Test
public void testMatchWithoutChildren() {
String restrictionWithPath = RESOURCE_TYPE_SUB2+"@"+TEST_NODE_SUB2;
resourceTypePattern = new ResourceTypePattern(Arrays.asList(restrictionWithPath, RESOURCE_TYPE_SUB3), TEST_PATH, false);
assertNonTreeFunctionsReturnFalse();
assertTrue("Has to match because of @path usage "+restrictionWithPath, resourceTypePattern.matches(testTree, null));
assertFalse(resourceTypePattern.matches(testTreeSub1, null));
assertFalse("Must not match (although it has "+RESOURCE_TYPE_SUB2+", it does not have a child '"+TEST_NODE_SUB2+"' with this resource type)", resourceTypePattern.matches(testTreeSub2, null));
assertTrue("Has to match because of "+RESOURCE_TYPE_SUB3+" in list", resourceTypePattern.matches(testTreeSub3, null));
assertFalse(resourceTypePattern.matches(testTreeSub3Sub1, null));
assertFalse(resourceTypePattern.matches(testTreeSub3Sub2, null));
}
@Test
public void testMatchWithChildren() {
resourceTypePattern = new ResourceTypePattern(Arrays.asList(RESOURCE_TYPE_SUB3), TEST_PATH, true);
assertNonTreeFunctionsReturnFalse();
assertFalse("Not a node at or below "+RESOURCE_TYPE_SUB3, resourceTypePattern.matches(testTree, null));
assertFalse("Not a node at or below "+RESOURCE_TYPE_SUB3, resourceTypePattern.matches(testTreeSub1, null));
assertFalse("Not a node at or below "+RESOURCE_TYPE_SUB3, resourceTypePattern.matches(testTreeSub2, null));
assertTrue("The node with "+RESOURCE_TYPE_SUB3, resourceTypePattern.matches(testTreeSub3, null));
assertTrue("A node below a node with "+RESOURCE_TYPE_SUB3, resourceTypePattern.matches(testTreeSub3Sub1, null));
assertTrue("A node below a node with "+RESOURCE_TYPE_SUB3, resourceTypePattern.matches(testTreeSub3Sub2, null));
}
@Test
public void testMatchWithChildrenDoesNotLeaveBasePath() {
resourceTypePattern = new ResourceTypePattern(Arrays.asList(RESOURCE_TYPE_OUTSIDE_SCOPE), TEST_PATH, true);
assertNonTreeFunctionsReturnFalse();
// all false as RESOURCE_TYPE_OUTSIDE_SCOPE is only found above TEST_PATH
assertFalse(resourceTypePattern.matches(testTree, null));
assertFalse(resourceTypePattern.matches(testTreeSub1, null));
assertFalse(resourceTypePattern.matches(testTreeSub2, null));
assertFalse(resourceTypePattern.matches(testTreeSub3, null));
assertFalse(resourceTypePattern.matches(testTreeSub3Sub1, null));
assertFalse(resourceTypePattern.matches(testTreeSub3Sub2, null));
}
@Test
public void testMatchWithChildrenAndPathUsage() {
String restrictionWithPath = RESOURCE_TYPE_SUBSUB1+"@"+TEST_NODE_SUBSUB1;
resourceTypePattern = new ResourceTypePattern(Arrays.asList(restrictionWithPath), TEST_PATH, true);
assertNonTreeFunctionsReturnFalse();
assertFalse("This node or any of its parents do not have a sub node '"+TEST_NODE_SUBSUB1+"' with "+RESOURCE_TYPE_SUBSUB1, resourceTypePattern.matches(testTree, null));
assertFalse("This node or any of its parents do not have a sub node '"+TEST_NODE_SUBSUB1+"' with "+RESOURCE_TYPE_SUBSUB1, resourceTypePattern.matches(testTreeSub1, null));
assertFalse("This node or any of its parents do not have a sub node '"+TEST_NODE_SUBSUB1+"' with "+RESOURCE_TYPE_SUBSUB1,resourceTypePattern.matches(testTreeSub2, null));
assertTrue("This node does have a sub node '"+TEST_NODE_SUBSUB1+"' with "+RESOURCE_TYPE_SUBSUB1, resourceTypePattern.matches(testTreeSub3, null));
assertTrue("A node in parent hierarchy does have a sub node '"+TEST_NODE_SUBSUB1+"' with "+RESOURCE_TYPE_SUBSUB1, resourceTypePattern.matches(testTreeSub3Sub1, null));
assertTrue("A node in parent hierarchy does have a sub node '"+TEST_NODE_SUBSUB1+"' with "+RESOURCE_TYPE_SUBSUB1, resourceTypePattern.matches(testTreeSub3Sub2, null));
}
private void assertNonTreeFunctionsReturnFalse() {
assertFalse(resourceTypePattern.matches(TEST_PATH));
assertFalse(resourceTypePattern.matches());
}
private void setupTreeMock(Tree tree, String path, Tree parentTree, String resourceType) {
doReturn(parentTree==null).when(tree).isRoot();
doReturn(parentTree).when(tree).getParent();
mockGetStringProperty(tree, ResourceTypePattern.SLING_RESOURCE_TYPE, resourceType);
String effectivePath = path;
if(parentTree!=null) {
effectivePath = parentTree.getPath() + "/" + path;
String childNodeName = StringUtils.substringAfterLast(effectivePath, "/");
doReturn(tree).when(parentTree).getChild(childNodeName);
}
doReturn(effectivePath).when(tree).getPath();
// default for getChild
doThrow(new IllegalArgumentException()).when(tree).getChild(Mockito.anyString());
}
private void mockGetStringProperty(Tree tree, String propertyName, String value) {
PropertyState propertyState = mock(PropertyState.class);
doReturn(propertyState).when(tree).getProperty(propertyName);
doReturn(false).when(propertyState).isArray();
doReturn(value).when(propertyState).getValue(Type.STRING);
}
}