Slingshot: add tests based on Sling Mocks

git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1705300 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/slingshot/pom.xml b/slingshot/pom.xml
index 90bb7c0..6f228ea 100644
--- a/slingshot/pom.xml
+++ b/slingshot/pom.xml
@@ -73,10 +73,29 @@
                         <exclude>src/main/resources/SLING-INF/content/slingshot/resources/fonts/*.svg</exclude>
                         <exclude>src/main/resources/SLING-INF/content/slingshot/resources/js/jquery*.js</exclude>
                         <exclude>src/main/resources/SLING-INF/content/slingshot/resources/js/metro.min.js</exclude>
+                        <exclude>src/test/resources/**.json</exclude>
                     </excludes>
                 </configuration>
             </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-failsafe-plugin</artifactId>
+                <!-- 
+                <configuration>
+                    <testSourceDirectory>src/main/it</testSourceDirectory>
+                </configuration>
+                 -->
+                <executions>
+                  <execution>
+                    <goals>
+                      <goal>integration-test</goal>
+                      <goal>verify</goal>
+                    </goals>
+                  </execution>
+                </executions>                
+            </plugin>
         </plugins>
+        
     </build>
 
     <profiles>
@@ -142,7 +161,7 @@
         <dependency>
             <groupId>org.apache.jackrabbit</groupId>
             <artifactId>jackrabbit-api</artifactId>
-            <version>2.0.0</version>
+            <version>2.2.0</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
@@ -154,5 +173,52 @@
         	<groupId>org.slf4j</groupId>
         	<artifactId>slf4j-api</artifactId>
         </dependency>
+        
+        <!-- test dependencies -->
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-library</artifactId>
+            <version>1.3</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>1.10.19</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.testing.osgi-mock</artifactId>
+            <version>1.5.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.testing.sling-mock</artifactId>
+            <version>1.5.1-SNAPSHOT</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.testing.sling-mock-jackrabbit</artifactId>
+            <version>0.1.3-SNAPSHOT</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.testing.hamcrest</artifactId>
+            <version>0.9.0-SNAPSHOT</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+          <groupId>org.slf4j</groupId>
+          <artifactId>slf4j-simple</artifactId>
+          <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
diff --git a/slingshot/src/test/java/org/apache/sling/sample/slingshot/SlingshotUtilTest.java b/slingshot/src/test/java/org/apache/sling/sample/slingshot/SlingshotUtilTest.java
new file mode 100644
index 0000000..991755d
--- /dev/null
+++ b/slingshot/src/test/java/org/apache/sling/sample/slingshot/SlingshotUtilTest.java
@@ -0,0 +1,78 @@
+/*
+ * 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.sample.slingshot;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.nullValue;
+import static org.junit.Assert.assertThat;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class SlingshotUtilTest {
+
+    @Rule
+    public final SlingContext context = new SlingContext();
+
+    @Before
+    public void loadData() {
+        context.load().json("/slingshot.json", SlingshotConstants.APP_ROOT_PATH);
+    }
+    
+    @Test
+    public void getUserId_deepPath() {
+        
+        Resource resource = context.resourceResolver().getResource("/slingshot/users/admin/content");
+        
+        assertThat(SlingshotUtil.getUserId(resource), equalTo("admin"));
+    }
+
+    @Test
+    public void getUserId_exactPath() {
+        
+        Resource resource = context.resourceResolver().getResource("/slingshot/users/admin");
+        
+        assertThat(SlingshotUtil.getUserId(resource), equalTo("admin"));
+    }
+    
+    @Test
+    public void getUserId_noMatch() {
+        
+        Resource resource = context.resourceResolver().getResource("/slingshot/users");
+        
+        assertThat(SlingshotUtil.getUserId(resource), nullValue());
+    }
+    
+    @Test
+    public void getContentPath_match() {
+        
+        Resource resource = context.resourceResolver().getResource("/slingshot/users/admin/content/hobby");
+        
+        assertThat(SlingshotUtil.getContentPath(resource), equalTo("/hobby"));
+    }
+    
+    @Test
+    public void getContentPath_noMatch() {
+        
+        Resource resource = context.resourceResolver().getResource("/slingshot/users/admin");
+        
+        assertThat(SlingshotUtil.getContentPath(resource), nullValue());
+    }
+}
diff --git a/slingshot/src/test/java/org/apache/sling/sample/slingshot/impl/SetupServiceTest.java b/slingshot/src/test/java/org/apache/sling/sample/slingshot/impl/SetupServiceTest.java
new file mode 100644
index 0000000..d20e7b6
--- /dev/null
+++ b/slingshot/src/test/java/org/apache/sling/sample/slingshot/impl/SetupServiceTest.java
@@ -0,0 +1,100 @@
+/*
+ * 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.sample.slingshot.impl;
+
+import static org.apache.sling.hamcrest.ResourceMatchers.hasChildren;
+import static org.apache.sling.hamcrest.ResourceMatchers.resourceOfType;
+import static org.apache.sling.sample.slingshot.SlingshotConstants.RESOURCETYPE_USER;
+import static org.apache.sling.sample.slingshot.impl.InternalConstants.RESOURCETYPE_HOME;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.commons.testing.jcr.RepositoryUtil;
+import org.apache.sling.jcr.base.util.AccessControlUtil;
+import org.apache.sling.sample.slingshot.SlingshotConstants;
+import org.apache.sling.sample.slingshot.impl.InternalConstants;
+import org.apache.sling.sample.slingshot.impl.SetupService;
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+public class SetupServiceTest {
+    
+    @Rule
+    public SlingContext context = new SlingContext(ResourceResolverType.JCR_JACKRABBIT);
+    
+    @Before
+    public void cleanupIfNeeded() throws IOException {
+        FileUtils.deleteDirectory(new File("target/repository"));
+    }
+    
+    @Test
+    public void setup() throws Exception{
+        
+        RepositoryUtil.registerSlingNodeTypes(context.resourceResolver().adaptTo(Session.class));
+        
+        // create expected content structure
+        context.load().json("/slingshot.json", SlingshotConstants.APP_ROOT_PATH);
+        
+        // create a dummy config admin to prevent registration of service user amendments
+        ConfigurationAdmin configAdmin = mock(ConfigurationAdmin.class);
+        when(configAdmin.listConfigurations(anyString())).thenReturn(new Configuration[] { null });
+        context.registerService(ConfigurationAdmin.class, configAdmin);
+        
+        // run the activation code
+        context.registerInjectActivateService(new SetupService());
+        
+        // validate that the expected users are created
+        Session adminSession = context.resourceResolver().adaptTo(Session.class);
+        UserManager userManager = AccessControlUtil.getUserManager(adminSession);
+        for ( String user : new String[] { "slingshot1", "slingshot2", InternalConstants.SERVICE_USER_NAME } ) {
+            assertThat(userManager.getAuthorizable(user), notNullValue());    
+        }
+        
+        // validate content structure
+        Resource resource = context.resourceResolver().getResource(SlingshotConstants.APP_ROOT_PATH);
+        
+        assertThat(resource, resourceOfType(RESOURCETYPE_HOME));
+        assertThat(resource.getChild("users"), notNullValue());
+        assertThat(resource.getChild("users/slingshot1"), resourceOfType(RESOURCETYPE_USER));
+        assertThat(resource.getChild("users/slingshot1"), hasChildren("info", "profile", "ugc"));
+        
+        // validate access control entries
+        
+        Session user = adminSession.impersonate(new SimpleCredentials("slingshot1", "slingshot1".toCharArray()));
+        
+        assertThat(user.hasPermission(SlingshotConstants.APP_ROOT_PATH+"/users/slingshot1/info", "read,add_node,set_property"), equalTo(true));
+    }
+
+}
diff --git a/slingshot/src/test/java/org/apache/sling/sample/slingshot/impl/UtilTest.java b/slingshot/src/test/java/org/apache/sling/sample/slingshot/impl/UtilTest.java
new file mode 100644
index 0000000..f366119
--- /dev/null
+++ b/slingshot/src/test/java/org/apache/sling/sample/slingshot/impl/UtilTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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.sample.slingshot.impl;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.junit.Assert.assertThat;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class UtilTest {
+    
+    @Parameters
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][] {     
+                 {"valid_name", "valid_name"}, 
+                 {"hyphen-included", "hyphen_included"},
+                 {"multiple---replacements", "multiple_replacements"},
+                 {"MixedCase", "mixedcase"},
+                 {"0leadingdigit", "_0leadingdigit"}
+           });
+    }
+
+    private final String input;
+    private final String output;
+    
+    public UtilTest(String input, String output) {
+        this.input = input;
+        this.output = output;
+    }
+    
+    @Test
+    public void filter() {
+        
+        assertThat(output, equalTo(Util.filter(input)));
+    }
+
+}
diff --git a/slingshot/src/test/java/org/apache/sling/sample/slingshot/ratings/impl/RatingPostServletTest.java b/slingshot/src/test/java/org/apache/sling/sample/slingshot/ratings/impl/RatingPostServletTest.java
new file mode 100644
index 0000000..7866d4c
--- /dev/null
+++ b/slingshot/src/test/java/org/apache/sling/sample/slingshot/ratings/impl/RatingPostServletTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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.sample.slingshot.ratings.impl;
+
+import static javax.servlet.http.HttpServletResponse.SC_OK;
+import static org.hamcrest.Matchers.equalTo;
+import static org.junit.Assert.assertThat;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.sling.sample.slingshot.SlingshotConstants;
+import org.apache.sling.sample.slingshot.ratings.RatingsService;
+import org.apache.sling.sample.slingshot.ratings.RatingsUtil;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletRequest;
+import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletResponse;
+import org.hamcrest.Matchers;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+public class RatingPostServletTest {
+    
+    @Rule
+    public final SlingContext context = new SlingContext();
+    
+    @Test
+    public void successfulSave() throws Exception {
+
+        Map<String, Object> params = new HashMap<String, Object>();
+        params.put(RatingsUtil.PROPERTY_RATING, "5");
+        
+        context.registerService(RatingsService.class, Mockito.mock(RatingsService.class));
+        
+        RatingPostServlet servlet = context.registerInjectActivateService(new RatingPostServlet());
+
+        MockSlingHttpServletRequest request = context.request();
+        request.setRemoteUser("admin");
+        request.setParameterMap(params);
+        request.setResource(context.create().resource(SlingshotConstants.APP_ROOT_PATH+"/content/admin/travel"));
+
+        MockSlingHttpServletResponse response = new MockSlingHttpServletResponse();
+        
+        servlet.doPost(request, response);
+        
+        assertThat(response.getStatus(), Matchers.equalTo(SC_OK));
+        String output = response.getOutputAsString();
+        
+        assertThat(output, equalTo("{  \"rating\" : 0}\n"));
+        
+    }
+
+}
diff --git a/slingshot/src/test/java/org/apache/sling/sample/slingshot/ratings/impl/RatingServiceImplTest.java b/slingshot/src/test/java/org/apache/sling/sample/slingshot/ratings/impl/RatingServiceImplTest.java
new file mode 100644
index 0000000..f0f53e6
--- /dev/null
+++ b/slingshot/src/test/java/org/apache/sling/sample/slingshot/ratings/impl/RatingServiceImplTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.sample.slingshot.ratings.impl;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.nullValue;
+import static org.junit.Assert.assertThat;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.sample.slingshot.SlingshotConstants;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class RatingServiceImplTest {
+    
+    @Rule
+    public SlingContext context = new SlingContext();
+    
+    @Test
+    public void getRatingsResourcePath() {
+        
+        context.load().json("/slingshot.json", SlingshotConstants.APP_ROOT_PATH);
+        
+        RatingsServiceImpl service = new RatingsServiceImpl();
+        Resource resource = context.resourceResolver().getResource(SlingshotConstants.APP_ROOT_PATH+"/users/admin/content/hobby");
+        
+        String ratingsResourcePath = service.getRatingsResourcePath(resource);
+        assertThat(ratingsResourcePath, equalTo("/slingshot/users/admin/ugc/ratings/hobby"));
+    }
+
+    @Test
+    public void getRatingsResourcePath_missing() {
+        
+        context.load().json("/slingshot.json", SlingshotConstants.APP_ROOT_PATH);
+        
+        RatingsServiceImpl service = new RatingsServiceImpl();
+        Resource resource = context.resourceResolver().getResource(SlingshotConstants.APP_ROOT_PATH+"/users/admin");
+        
+        String ratingsResourcePath = service.getRatingsResourcePath(resource);
+        assertThat(ratingsResourcePath, nullValue());
+    }
+    
+
+}
diff --git a/slingshot/src/test/resources/slingshot.json b/slingshot/src/test/resources/slingshot.json
new file mode 100644
index 0000000..e33eb7c
--- /dev/null
+++ b/slingshot/src/test/resources/slingshot.json
@@ -0,0 +1,31 @@
+{
+  "jcr:primaryType": "nt:unstructured",
+  "users": {
+    "jcr:primaryType": "sling:Folder",
+    "admin": {
+      "jcr:primaryType": "nt:unstructured",
+      "sling:resourceType": "slingshot/User",
+      "content": {
+        "jcr:primaryType": "nt:unstructured",
+        "sling:resourceType": "slingshot/Content",
+        "hobby": {
+          "jcr:primaryType": "nt:unstructured"
+        }
+      },
+      "ugc": {
+        "jcr:primaryType": "sling:Folder",
+        "rating": {
+          "jcr:primaryType": "nt:unstructured",
+        }
+      }
+    },
+    "slingshot1": {
+      "jcr:primaryType": "nt:unstructured",
+      "sling:resourceType": "slingshot/User",
+    },
+    "slingshot2": {
+      "jcr:primaryType": "nt:unstructured",
+      "sling:resourceType": "slingshot/User",
+    }
+  }
+}
\ No newline at end of file