Added: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/MockServletContext.java URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/MockServletContext.java?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/MockServletContext.java (added) +++ sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/MockServletContext.java Mon Oct 13 11:54:39 2014 @@ -0,0 +1,301 @@ +/* + * 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.testing.mock.sling.servlet; + +import java.io.InputStream; +import java.net.URL; +import java.util.Enumeration; +import java.util.EventListener; +import java.util.Map; +import java.util.Set; + +import javax.servlet.Filter; +import javax.servlet.FilterRegistration; +import javax.servlet.RequestDispatcher; +import javax.servlet.Servlet; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRegistration; +import javax.servlet.ServletRegistration.Dynamic; +import javax.servlet.SessionCookieConfig; +import javax.servlet.SessionTrackingMode; +import javax.servlet.descriptor.JspConfigDescriptor; + +/** + * Mock {@link ServletContext} implementation. + */ +public final class MockServletContext implements ServletContext { + + @Override + public String getMimeType(final String file) { + return "application/octet-stream"; + } + + // --- unsupported operations --- + @Override + public Object getAttribute(final String name) { + throw new UnsupportedOperationException(); + } + + @Override + public Enumeration<String> getAttributeNames() { + throw new UnsupportedOperationException(); + } + + @Override + public ServletContext getContext(final String uriPath) { + throw new UnsupportedOperationException(); + } + + @Override + public String getContextPath() { + throw new UnsupportedOperationException(); + } + + @Override + public String getInitParameter(final String name) { + throw new UnsupportedOperationException(); + } + + @Override + public Enumeration<String> getInitParameterNames() { + throw new UnsupportedOperationException(); + } + + @Override + public int getMajorVersion() { + throw new UnsupportedOperationException(); + } + + @Override + public int getMinorVersion() { + throw new UnsupportedOperationException(); + } + + @Override + public RequestDispatcher getNamedDispatcher(final String name) { + throw new UnsupportedOperationException(); + } + + @Override + public String getRealPath(final String pPath) { + throw new UnsupportedOperationException(); + } + + @Override + public RequestDispatcher getRequestDispatcher(final String path) { + throw new UnsupportedOperationException(); + } + + @Override + public URL getResource(final String pPath) { + throw new UnsupportedOperationException(); + } + + @Override + public InputStream getResourceAsStream(final String path) { + throw new UnsupportedOperationException(); + } + + @Override + public Set<String> getResourcePaths(final String path) { + throw new UnsupportedOperationException(); + } + + @Override + public String getServerInfo() { + throw new UnsupportedOperationException(); + } + + @Override + public Servlet getServlet(final String name) { + throw new UnsupportedOperationException(); + } + + @Override + public String getServletContextName() { + throw new UnsupportedOperationException(); + } + + @Override + public Enumeration<String> getServletNames() { + throw new UnsupportedOperationException(); + } + + @Override + public Enumeration<Servlet> getServlets() { + throw new UnsupportedOperationException(); + } + + @Override + public void log(final String msg) { + throw new UnsupportedOperationException(); + } + + @Override + public void log(final Exception exception, final String msg) { + throw new UnsupportedOperationException(); + } + + @Override + public void log(final String msg, final Throwable throwable) { + throw new UnsupportedOperationException(); + } + + @Override + public void removeAttribute(final String name) { + throw new UnsupportedOperationException(); + } + + @Override + public void setAttribute(final String name, final Object object) { + throw new UnsupportedOperationException(); + } + + @Override + public int getEffectiveMajorVersion() { + throw new UnsupportedOperationException(); + } + + @Override + public int getEffectiveMinorVersion() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean setInitParameter(final String name, final String value) { + throw new UnsupportedOperationException(); + } + + @Override + public Dynamic addServlet(final String servletName, final String className) { + throw new UnsupportedOperationException(); + } + + @Override + public Dynamic addServlet(final String servletName, final Servlet servlet) { + throw new UnsupportedOperationException(); + } + + @Override + public Dynamic addServlet(final String servletName, final Class<? extends Servlet> servletClass) { + throw new UnsupportedOperationException(); + } + + @Override + public <T extends Servlet> T createServlet(final Class<T> clazz) throws ServletException { + throw new UnsupportedOperationException(); + } + + @Override + public ServletRegistration getServletRegistration(final String servletName) { + throw new UnsupportedOperationException(); + } + + @Override + public Map<String, ? extends ServletRegistration> getServletRegistrations() { + throw new UnsupportedOperationException(); + } + + @Override + public FilterRegistration.Dynamic addFilter(final String filterName, final String className) { + throw new UnsupportedOperationException(); + } + + @Override + public FilterRegistration.Dynamic addFilter(final String filterName, final Filter filter) { + throw new UnsupportedOperationException(); + } + + @Override + public FilterRegistration.Dynamic addFilter(final String filterName, final Class<? extends Filter> filterClass) { + throw new UnsupportedOperationException(); + } + + @Override + public <T extends Filter> T createFilter(final Class<T> clazz) throws ServletException { + throw new UnsupportedOperationException(); + } + + @Override + public FilterRegistration getFilterRegistration(final String filterName) { + throw new UnsupportedOperationException(); + } + + @Override + public Map<String, ? extends FilterRegistration> getFilterRegistrations() { + throw new UnsupportedOperationException(); + } + + @Override + public SessionCookieConfig getSessionCookieConfig() { + throw new UnsupportedOperationException(); + } + + @Override + public void setSessionTrackingModes(final Set<SessionTrackingMode> sessionTrackingModes) { + throw new UnsupportedOperationException(); + } + + @Override + public Set<SessionTrackingMode> getDefaultSessionTrackingModes() { + throw new UnsupportedOperationException(); + } + + @Override + public Set<SessionTrackingMode> getEffectiveSessionTrackingModes() { + throw new UnsupportedOperationException(); + } + + @Override + public void addListener(final String pClassName) { + throw new UnsupportedOperationException(); + } + + @Override + public <T extends EventListener> void addListener(final T listener) { + throw new UnsupportedOperationException(); + } + + @Override + public void addListener(final Class<? extends EventListener> listenerClass) { + throw new UnsupportedOperationException(); + } + + @Override + public <T extends EventListener> T createListener(final Class<T> clazz) { + throw new UnsupportedOperationException(); + } + + @Override + public JspConfigDescriptor getJspConfigDescriptor() { + throw new UnsupportedOperationException(); + } + + @Override + public ClassLoader getClassLoader() { + throw new UnsupportedOperationException(); + } + + @Override + public void declareRoles(final String... roleNames) { + throw new UnsupportedOperationException(); + } + +}
Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/MockServletContext.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/MockServletContext.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Mon Oct 13 11:54:39 2014 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/MockServletContext.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/MockSlingHttpServletRequest.java URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/MockSlingHttpServletRequest.java?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/MockSlingHttpServletRequest.java (added) +++ sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/MockSlingHttpServletRequest.java Mon Oct 13 11:54:39 2014 @@ -0,0 +1,696 @@ +/* + * 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.testing.mock.sling.servlet; + +import java.io.BufferedReader; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.security.Principal; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.ResourceBundle; + +import javax.servlet.AsyncContext; +import javax.servlet.DispatcherType; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletInputStream; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import javax.servlet.http.Part; + +import org.apache.commons.collections.IteratorUtils; +import org.apache.commons.lang3.CharEncoding; +import org.apache.commons.lang3.StringUtils; +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.adapter.SlingAdaptable; +import org.apache.sling.api.request.RequestDispatcherOptions; +import org.apache.sling.api.request.RequestParameter; +import org.apache.sling.api.request.RequestParameterMap; +import org.apache.sling.api.request.RequestPathInfo; +import org.apache.sling.api.request.RequestProgressTracker; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.resource.ResourceResolver; +import org.apache.sling.api.servlets.HttpConstants; +import org.apache.sling.testing.mock.sling.MockSling; + +/** + * Mock {@link SlingHttpServletRequest} implementation. + */ +public class MockSlingHttpServletRequest extends SlingAdaptable implements SlingHttpServletRequest { + + private ResourceResolver resourceResolver; + private RequestPathInfo requestPathInfo = new MockRequestPathInfo(); + private Map<String, Object> attributeMap = new HashMap<String, Object>(); + private Map<String, String[]> parameterMap = new LinkedHashMap<String, String[]>(); + private HttpSession session; + private Resource resource; + private String contextPath; + private String queryString; + private String scheme = "http"; + private String serverName = "localhost"; + private int serverPort = 80; + private String method = HttpConstants.METHOD_GET; + private final HeaderSupport headerSupport = new HeaderSupport(); + private final CookieSupport cookieSupport = new CookieSupport(); + + /** + * Instantiate with default resource resolver + */ + public MockSlingHttpServletRequest() { + this.resourceResolver = MockSling.newResourceResolver(); + } + + /** + * @param resourceResolver Resource resolver + */ + public MockSlingHttpServletRequest(ResourceResolver resourceResolver) { + this.resourceResolver = resourceResolver; + } + + @Override + public ResourceResolver getResourceResolver() { + return this.resourceResolver; + } + + @Override + public HttpSession getSession() { + return getSession(true); + } + + @Override + public HttpSession getSession(boolean create) { + if (this.session == null && create) { + this.session = new MockHttpSession(); + } + return this.session; + } + + @Override + public RequestPathInfo getRequestPathInfo() { + return this.requestPathInfo; + } + + @Override + public Object getAttribute(String name) { + return this.attributeMap.get(name); + } + + @SuppressWarnings("unchecked") + @Override + public Enumeration<String> getAttributeNames() { + return IteratorUtils.asEnumeration(this.attributeMap.keySet().iterator()); + } + + @Override + public void removeAttribute(String name) { + this.attributeMap.remove(name); + } + + @Override + public void setAttribute(String name, Object object) { + this.attributeMap.put(name, object); + } + + @Override + public Resource getResource() { + return this.resource; + } + + public void setResource(Resource resource) { + this.resource = resource; + } + + @Override + public String getParameter(String name) { + Object object = this.parameterMap.get(name); + if (object instanceof String) { + return (String) object; + } else if (object instanceof String[]) { + String[] values = (String[]) object; + if (values.length > 0) { + return values[0]; + } + } + return null; + } + + @Override + public Map<String, String[]> getParameterMap() { + return this.parameterMap; + } + + @SuppressWarnings("unchecked") + @Override + public Enumeration<String> getParameterNames() { + return IteratorUtils.asEnumeration(this.parameterMap.keySet().iterator()); + } + + @Override + public String[] getParameterValues(String name) { // NOPMD + Object object = this.parameterMap.get(name); + if (object instanceof String) { + return new String[] { (String) object }; + } else if (object instanceof String[]) { + return (String[]) object; + } + return null; // NOPMD + } + + /** + * @param parameterMap Map of parameters + */ + public void setParameterMap(Map<String, Object> parameterMap) { + this.parameterMap.clear(); + for (Map.Entry<String, Object> entry : parameterMap.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + if (value instanceof String[]) { + this.parameterMap.put(key, (String[]) value); + } else if (value != null) { + this.parameterMap.put(key, new String[] { value.toString() }); + } else { + this.parameterMap.put(key, null); + } + } + try { + this.queryString = formatQueryString(this.parameterMap); + } catch (UnsupportedEncodingException ex) { + throw new RuntimeException(ex); + } + } + + private String formatQueryString(Map<String, String[]> map) throws UnsupportedEncodingException { + StringBuilder querystring = new StringBuilder(); + for (Map.Entry<String, String[]> entry : this.parameterMap.entrySet()) { + if (entry.getValue() != null) { + for (String value : entry.getValue()) { + if (querystring.length() != 0) { + querystring.append('&'); + } + querystring.append(URLEncoder.encode(entry.getKey(), CharEncoding.UTF_8)); + querystring.append('='); + if (value != null) { + querystring.append(URLEncoder.encode(value, CharEncoding.UTF_8)); + } + } + } + } + if (querystring.length() > 0) { + return querystring.toString(); + } else { + return null; + } + } + + @Override + public Locale getLocale() { + return Locale.US; + } + + @Override + public String getContextPath() { + return this.contextPath; + } + + /** + * @param contextPath Webapp context path + */ + public void setContextPath(String contextPath) { + this.contextPath = contextPath; + } + + /** + * @param queryString Query string (with proper URL encoding) + */ + public void setQueryString(String queryString) { + this.queryString = queryString; + try { + parseQueryString(this.parameterMap, this.queryString); + } catch (UnsupportedEncodingException ex) { + throw new RuntimeException(ex); + } + } + + private void parseQueryString(Map<String, String[]> map, String query) throws UnsupportedEncodingException { + Map<String, List<String>> queryPairs = new LinkedHashMap<String, List<String>>(); + String[] pairs = query.split("&"); + for (String pair : pairs) { + int idx = pair.indexOf('='); + String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), CharEncoding.UTF_8) : pair; + if (!queryPairs.containsKey(key)) { + queryPairs.put(key, new ArrayList<String>()); + } + String value = idx > 0 && pair.length() > idx + 1 ? URLDecoder.decode(pair.substring(idx + 1), + CharEncoding.UTF_8) : null; + queryPairs.get(key).add(value); + } + map.clear(); + for (Map.Entry<String, List<String>> entry : queryPairs.entrySet()) { + map.put(entry.getKey(), entry.getValue().toArray(new String[entry.getValue().size()])); + } + } + + @Override + public String getQueryString() { + return this.queryString; + } + + @Override + public String getScheme() { + return this.scheme; + } + + public void setScheme(String scheme) { + this.scheme = scheme; + } + + @Override + public String getServerName() { + return this.serverName; + } + + public void setServerName(String serverName) { + this.serverName = serverName; + } + + @Override + public int getServerPort() { + return this.serverPort; + } + + public void setServerPort(int serverPort) { + this.serverPort = serverPort; + } + + @Override + public boolean isSecure() { + return StringUtils.equals("https", getScheme()); + } + + @Override + public String getMethod() { + return this.method; + } + + public void setMethod(String method) { + this.method = method; + } + + @Override + public long getDateHeader(String name) { + return headerSupport.getDateHeader(name); + } + + @Override + public String getHeader(String name) { + return headerSupport.getHeader(name); + } + + @Override + public Enumeration<String> getHeaderNames() { + return HeaderSupport.toEnumeration(headerSupport.getHeaderNames()); + } + + @Override + public Enumeration<String> getHeaders(String name) { + return HeaderSupport.toEnumeration(headerSupport.getHeaders(name)); + } + + @Override + public int getIntHeader(String name) { + return headerSupport.getIntHeader(name); + } + + /** + * Add header, keep existing ones with same name. + * @param name Header name + * @param value Header value + */ + public void addHeader(String name, String value) { + headerSupport.addHeader(name, value); + } + + /** + * Add header, keep existing ones with same name. + * @param name Header name + * @param value Header value + */ + public void addIntHeader(String name, int value) { + headerSupport.addIntHeader(name, value); + } + + /** + * Add header, keep existing ones with same name. + * @param name Header name + * @param date Header value + */ + public void addDateHeader(String name, long date) { + headerSupport.addDateHeader(name, date); + } + + /** + * Set header, overwrite existing ones with same name. + * @param name Header name + * @param value Header value + */ + public void setHeader(String name, String value) { + headerSupport.setHeader(name, value); + } + + /** + * Set header, overwrite existing ones with same name. + * @param name Header name + * @param value Header value + */ + public void setIntHeader(String name, int value) { + headerSupport.setIntHeader(name, value); + } + + /** + * Set header, overwrite existing ones with same name. + * @param name Header name + * @param date Header value + */ + public void setDateHeader(String name, long date) { + headerSupport.setDateHeader(name, date); + } + + @Override + public Cookie getCookie(String name) { + return cookieSupport.getCookie(name); + } + + @Override + public Cookie[] getCookies() { + return cookieSupport.getCookies(); + } + + /** + * Set cookie + * @param cookie Cookie + */ + public void addCookie(Cookie cookie) { + cookieSupport.addCookie(cookie); + } + + // --- unsupported operations --- + + @Override + public RequestDispatcher getRequestDispatcher(Resource dispatcherResource) { + throw new UnsupportedOperationException(); + } + + @Override + public RequestDispatcher getRequestDispatcher(String dispatcherPath, RequestDispatcherOptions options) { + throw new UnsupportedOperationException(); + } + + @Override + public RequestDispatcher getRequestDispatcher(Resource dispatcherResource, RequestDispatcherOptions options) { + throw new UnsupportedOperationException(); + } + + @Override + public RequestParameter getRequestParameter(String name) { + throw new UnsupportedOperationException(); + } + + @Override + public RequestParameterMap getRequestParameterMap() { + throw new UnsupportedOperationException(); + } + + @Override + public RequestParameter[] getRequestParameters(String name) { + throw new UnsupportedOperationException(); + } + + @Override + public RequestProgressTracker getRequestProgressTracker() { + throw new UnsupportedOperationException(); + } + + @Override + public ResourceBundle getResourceBundle(Locale pLocale) { + throw new UnsupportedOperationException(); + } + + @Override + public ResourceBundle getResourceBundle(String baseName, Locale locale) { + throw new UnsupportedOperationException(); + } + + @Override + public String getResponseContentType() { + throw new UnsupportedOperationException(); + } + + @Override + public Enumeration<String> getResponseContentTypes() { + throw new UnsupportedOperationException(); + } + + @Override + public String getAuthType() { + throw new UnsupportedOperationException(); + } + + @Override + public String getPathInfo() { + throw new UnsupportedOperationException(); + } + + @Override + public String getPathTranslated() { + throw new UnsupportedOperationException(); + } + + @Override + public String getRemoteUser() { + throw new UnsupportedOperationException(); + } + + @Override + public String getRequestURI() { + throw new UnsupportedOperationException(); + } + + @Override + public StringBuffer getRequestURL() { + throw new UnsupportedOperationException(); + } + + @Override + public String getRequestedSessionId() { + throw new UnsupportedOperationException(); + } + + @Override + public String getServletPath() { + throw new UnsupportedOperationException(); + } + + @Override + public Principal getUserPrincipal() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isRequestedSessionIdFromCookie() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isRequestedSessionIdFromURL() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isRequestedSessionIdFromUrl() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isRequestedSessionIdValid() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isUserInRole(String role) { + throw new UnsupportedOperationException(); + } + + @Override + public String getCharacterEncoding() { + throw new UnsupportedOperationException(); + } + + @Override + public int getContentLength() { + throw new UnsupportedOperationException(); + } + + @Override + public String getContentType() { + throw new UnsupportedOperationException(); + } + + @Override + public ServletInputStream getInputStream() { + throw new UnsupportedOperationException(); + } + + @Override + public String getLocalAddr() { + throw new UnsupportedOperationException(); + } + + @Override + public String getLocalName() { + throw new UnsupportedOperationException(); + } + + @Override + public int getLocalPort() { + throw new UnsupportedOperationException(); + } + + @Override + public Enumeration<Locale> getLocales() { + throw new UnsupportedOperationException(); + } + + @Override + public String getProtocol() { + throw new UnsupportedOperationException(); + } + + @Override + public BufferedReader getReader() { + throw new UnsupportedOperationException(); + } + + @Override + public String getRealPath(String path) { + throw new UnsupportedOperationException(); + } + + @Override + public String getRemoteAddr() { + throw new UnsupportedOperationException(); + } + + @Override + public String getRemoteHost() { + throw new UnsupportedOperationException(); + } + + @Override + public int getRemotePort() { + throw new UnsupportedOperationException(); + } + + @Override + public RequestDispatcher getRequestDispatcher(String path) { + throw new UnsupportedOperationException(); + } + + @Override + public void setCharacterEncoding(String env) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean authenticate(HttpServletResponse response) { + throw new UnsupportedOperationException(); + } + + @Override + public void login(String pUsername, String password) { + throw new UnsupportedOperationException(); + } + + @Override + public void logout() throws ServletException { + throw new UnsupportedOperationException(); + } + + @Override + public Collection<Part> getParts() { + throw new UnsupportedOperationException(); + } + + @Override + public Part getPart(String name) { + throw new UnsupportedOperationException(); + } + + @Override + public ServletContext getServletContext() { + throw new UnsupportedOperationException(); + } + + @Override + public AsyncContext startAsync() { + throw new UnsupportedOperationException(); + } + + @Override + public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isAsyncStarted() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isAsyncSupported() { + throw new UnsupportedOperationException(); + } + + @Override + public AsyncContext getAsyncContext() { + throw new UnsupportedOperationException(); + } + + @Override + public DispatcherType getDispatcherType() { + throw new UnsupportedOperationException(); + } + + // part of Sling API 2.7 + public List<RequestParameter> getRequestParameterList() { + throw new UnsupportedOperationException(); + } + +} Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/MockSlingHttpServletRequest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/MockSlingHttpServletRequest.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Mon Oct 13 11:54:39 2014 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/MockSlingHttpServletRequest.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/MockSlingHttpServletResponse.java URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/MockSlingHttpServletResponse.java?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/MockSlingHttpServletResponse.java (added) +++ sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/MockSlingHttpServletResponse.java Mon Oct 13 11:54:39 2014 @@ -0,0 +1,280 @@ +/* + * 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.testing.mock.sling.servlet; + +import java.io.PrintWriter; +import java.util.Collection; +import java.util.Locale; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.CharEncoding; +import org.apache.commons.lang3.StringUtils; +import org.apache.sling.api.SlingHttpServletResponse; +import org.apache.sling.api.adapter.SlingAdaptable; + +/** + * Mock {@link SlingHttpServletResponse} implementation. + */ +public class MockSlingHttpServletResponse extends SlingAdaptable implements SlingHttpServletResponse { + + private static final String CHARSET_SEPARATOR = ";charset="; + + private String contentType; + private String characterEncoding = CharEncoding.ISO_8859_1; + private int contentLength; + private int status = HttpServletResponse.SC_OK; + private int bufferSize = 1024 * 8; + private boolean isCommitted; + private final HeaderSupport headerSupport = new HeaderSupport(); + private final ResponseBodySupport bodySupport = new ResponseBodySupport(); + private final CookieSupport cookieSupport = new CookieSupport(); + + @Override + public String getContentType() { + if (this.contentType == null) { + return null; + } else { + return this.contentType + + (StringUtils.isNotBlank(characterEncoding) ? CHARSET_SEPARATOR + characterEncoding : ""); + } + } + + @Override + public void setContentType(String type) { + this.contentType = type; + if (StringUtils.contains(this.contentType, CHARSET_SEPARATOR)) { + this.characterEncoding = StringUtils.substringAfter(this.contentType, CHARSET_SEPARATOR); + this.contentType = StringUtils.substringBefore(this.contentType, CHARSET_SEPARATOR); + } + } + + @Override + public void setCharacterEncoding(String charset) { + this.characterEncoding = charset; + } + + @Override + public String getCharacterEncoding() { + return this.characterEncoding; + } + + @Override + public void setContentLength(int len) { + this.contentLength = len; + } + + public int getContentLength() { + return this.contentLength; + } + + @Override + public void setStatus(int sc, String sm) { + setStatus(sc); + } + + @Override + public void setStatus(int sc) { + this.status = sc; + } + + @Override + public int getStatus() { + return this.status; + } + + @Override + public void sendError(int sc, String msg) { + setStatus(sc); + } + + @Override + public void sendError(int sc) { + setStatus(sc); + } + + @Override + public void sendRedirect(String location) { + setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); + setHeader("Location", location); + } + + @Override + public void addHeader(String name, String value) { + headerSupport.addHeader(name, value); + } + + @Override + public void addIntHeader(String name, int value) { + headerSupport.addIntHeader(name, value); + } + + @Override + public void addDateHeader(String name, long date) { + headerSupport.addDateHeader(name, date); + } + + @Override + public void setHeader(String name, String value) { + headerSupport.setHeader(name, value); + } + + @Override + public void setIntHeader(String name, int value) { + headerSupport.setIntHeader(name, value); + } + + @Override + public void setDateHeader(String name, long date) { + headerSupport.setDateHeader(name, date); + } + + @Override + public boolean containsHeader(String name) { + return headerSupport.containsHeader(name); + } + + @Override + public String getHeader(String name) { + return headerSupport.getHeader(name); + } + + @Override + public Collection<String> getHeaders(String name) { + return headerSupport.getHeaders(name); + } + + @Override + public Collection<String> getHeaderNames() { + return headerSupport.getHeaderNames(); + } + + @Override + public PrintWriter getWriter() { + return bodySupport.getWriter(getCharacterEncoding()); + } + + @Override + public ServletOutputStream getOutputStream() { + return bodySupport.getOutputStream(); + } + + @Override + public void reset() { + if (isCommitted()) { + throw new IllegalStateException("Response already committed."); + } + bodySupport.reset(); + headerSupport.reset(); + cookieSupport.reset(); + status = HttpServletResponse.SC_OK; + contentLength = 0; + } + + @Override + public void resetBuffer() { + if (isCommitted()) { + throw new IllegalStateException("Response already committed."); + } + bodySupport.reset(); + } + + @Override + public int getBufferSize() { + return this.bufferSize; + } + + @Override + public void setBufferSize(int size) { + this.bufferSize = size; + } + + @Override + public void flushBuffer() { + isCommitted = true; + } + + @Override + public boolean isCommitted() { + return isCommitted; + } + + public byte[] getOutput() { + return bodySupport.getOutput(); + } + + public String getOutputAsString() { + return bodySupport.getOutputAsString(getCharacterEncoding()); + } + + @Override + public void addCookie(Cookie cookie) { + cookieSupport.addCookie(cookie); + } + + /** + * Get cookie + * @param name Cookie name + * @return Cookie or null + */ + public Cookie getCookie(String name) { + return cookieSupport.getCookie(name); + } + + /** + * Get cookies + * @return Cookies array or null if no cookie defined + */ + public Cookie[] getCookies() { + return cookieSupport.getCookies(); + } + + // --- unsupported operations --- + @Override + public Locale getLocale() { + throw new UnsupportedOperationException(); + } + + @Override + public void setLocale(Locale loc) { + throw new UnsupportedOperationException(); + } + + @Override + public String encodeRedirectUrl(String url) { + throw new UnsupportedOperationException(); + } + + @Override + public String encodeRedirectURL(String url) { + throw new UnsupportedOperationException(); + } + + @Override + public String encodeUrl(String url) { + throw new UnsupportedOperationException(); + } + + @Override + public String encodeURL(String url) { + throw new UnsupportedOperationException(); + } +} Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/MockSlingHttpServletResponse.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/MockSlingHttpServletResponse.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Mon Oct 13 11:54:39 2014 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/MockSlingHttpServletResponse.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/ResponseBodySupport.java URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/ResponseBodySupport.java?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/ResponseBodySupport.java (added) +++ sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/ResponseBodySupport.java Mon Oct 13 11:54:39 2014 @@ -0,0 +1,93 @@ +/* + * 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.testing.mock.sling.servlet; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; + +import javax.servlet.ServletOutputStream; + +/** + * Manage response body content. + */ +class ResponseBodySupport { + + private ByteArrayOutputStream outputStream; + private ServletOutputStream servletOutputStream; + private PrintWriter printWriter; + + public ResponseBodySupport() { + reset(); + } + + public void reset() { + outputStream = new ByteArrayOutputStream(); + servletOutputStream = null; + printWriter = null; + } + + public ServletOutputStream getOutputStream() { + if (servletOutputStream == null) { + servletOutputStream = new ServletOutputStream() { + @Override + public void write(int b) throws IOException { + outputStream.write(b); + } + }; + } + return servletOutputStream; + } + + public PrintWriter getWriter(String charset) { + if (printWriter == null) { + try { + printWriter = new PrintWriter(new OutputStreamWriter(getOutputStream(), charset)); + } catch (UnsupportedEncodingException ex) { + throw new RuntimeException("Unsupported encoding: " + charset, ex); + } + } + return printWriter; + } + + public byte[] getOutput() { + if (servletOutputStream != null) { + try { + servletOutputStream.flush(); + } catch (IOException ex) { + // ignore + } + } + return outputStream.toByteArray(); + } + + public String getOutputAsString(String charset) { + if (printWriter != null) { + printWriter.flush(); + } + try { + return new String(getOutput(), charset); + } catch (UnsupportedEncodingException ex) { + throw new RuntimeException("Unsupported encoding: " + charset, ex); + } + } + +} Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/ResponseBodySupport.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/ResponseBodySupport.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Mon Oct 13 11:54:39 2014 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/ResponseBodySupport.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/package-info.java URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/package-info.java?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/package-info.java (added) +++ sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/package-info.java Mon Oct 13 11:54:39 2014 @@ -0,0 +1,23 @@ +/* + * 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. + */ +/** + * Mock implementation of selected Servlet-related Sling APIs. + */ +package org.apache.sling.testing.mock.sling.servlet; + Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/package-info.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/package-info.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Mon Oct 13 11:54:39 2014 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/servlet/package-info.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/spi/ResourceResolverTypeAdapter.java URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/spi/ResourceResolverTypeAdapter.java?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/spi/ResourceResolverTypeAdapter.java (added) +++ sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/spi/ResourceResolverTypeAdapter.java Mon Oct 13 11:54:39 2014 @@ -0,0 +1,46 @@ +/* + * 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.testing.mock.sling.spi; + +import org.apache.sling.api.resource.ResourceResolverFactory; +import org.apache.sling.jcr.api.SlingRepository; + +/** + * SPI interface for resource resolver type implementations to provide a mock + * resource resolver factory. + */ +public interface ResourceResolverTypeAdapter { + + /** + * Gets resource resolver factory instance. Can be null if only a + * SlingRepository is provided, in this case the method + * {@link #newSlingRepository()} has to return a value. + * @return Resource resolver factory instance or null + */ + ResourceResolverFactory newResourceResolverFactory(); + + /** + * Get SlingRepository instance. Can be null if a resource resolver factory + * is provided, in this case the method + * {@link #newResourceResolverFactory()} has to return a value. + * @return Sling repository instance or null + */ + SlingRepository newSlingRepository(); + +} Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/spi/ResourceResolverTypeAdapter.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/spi/ResourceResolverTypeAdapter.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Mon Oct 13 11:54:39 2014 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/spi/ResourceResolverTypeAdapter.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/testing/sling-mock/src/site/markdown/index.md URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/site/markdown/index.md?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/site/markdown/index.md (added) +++ sling/trunk/testing/sling-mock/src/site/markdown/index.md Mon Oct 13 11:54:39 2014 @@ -0,0 +1,67 @@ +## About Sling Mocks + +Mock implementation of selected Sling APIs. + + +### Maven Dependency + +```xml +<dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.testing.sling-mock</artifactId> + <version>1.0.0-SNAPHOT</version> +</dependency> +``` + +### Documentation + +* [Sling Mocks Usage][usage-mocks] +* [Content Loader Usage][usage-content-loader] +* [API Documentation][apidocs] +* [Changelog][changelog] + + +### Implemented mock features + +The mock implementation supports: + +* `ResourceResolver` implementation for reading and writing resource data using the Sling Resource API + * Backed by a [mocked][jcr-mock] or real Jackrabbit JCR implementation + * Uses the productive [Sling JCR resource provider implementation][jcr-resource] internally to do the Resource-JCR mapping + * Alternatively the non-JCR mock implementation provided by the + [Sling resourceresolver-mock implementation][resourceresolver-mock] can be used +* `AdpaterManager` implementation for registering adapter factories and resolving adaptions + * The implementation is thread-safe so it can be used in parallel running unit tests +* `SlingScriptHelper` implementation providing access to mocked request/response objects and supports getting + OSGi services from the [mocked OSGi][osgi-mock] environment. +* Implementations of the servlet-related Sling API classes like `SlingHttpServletRequest` and `SlingHttpServletRequest` + * It is possible to set request data to simulate a certian Sling HTTP request +* Additional services like `MockModelAdapterFactory` and `MimeTypeService` + +[osgi-mock]: http://sling.apache.org/testing/osgi-mock/ +[jcr-mock]: http://sling.apache.org/testing/jcr-mock/ +[jcr-resource]: http://svn.apache.org/repos/asf/sling/trunk/bundles/jcr/resource +[resourceresolver-mock]: http://svn.eu.apache.org/repos/asf/sling/trunk/testing/resourceresolver-moc + +The following features are *not supported*: + +* It is not possible (nor intended) to really execute sling components/scripts and render their results. + * The goal is to test supporting classes in Sling context, not the sling components/scripts themselves + +See [Sling Mocks Usage][usage-mocks]. + + +### Additional features + +Additional features provided: + +* `ContentLoader` supports importing JSON data and binary data into the mock resource hierarchy to easily + prepare a test fixture consisting of a hierarchy of resources and properties. + * The same JSON format can be used that is provided by the Sling GET servlet for output + +See [Content Loader Usage][usage-content-loader]. + +[usage-mocks]: usage-mocks.html +[usage-content-loader]: usage-content-loader.html +[apidocs]: apidocs/ +[changelog]: changes-report.html Added: sling/trunk/testing/sling-mock/src/site/markdown/resource-resolver-types.md URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/site/markdown/resource-resolver-types.md?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/site/markdown/resource-resolver-types.md (added) +++ sling/trunk/testing/sling-mock/src/site/markdown/resource-resolver-types.md Mon Oct 13 11:54:39 2014 @@ -0,0 +1,53 @@ +## Resource Resolver Types + +The Sling Mocks resource resolver implementation supports different "types" of adapters for the mocks. +Depending on the type an underlying JCR repository is used or not, and the data ist stored in-memory or in a real +repository. + +This pages lists all resource resolver types currently supported. + +### RESOURCERESOLVER_MOCK (default) + +* Simulates an In-Memory resource tree, does not provide adaptions to JCR API. +* Based on the [Sling resourceresolver-mock implementation][resourceresolver-mock] implementation +* You can use it to make sure the code you want to test does not contain references to JCR API. +* Behaves slightly different from JCR resource mapping e.g. handling binary and date values. +* This resource resolver type is very fast because data is stored in memory and no JCR mapping is applied. + +### JCR_MOCK + +* Based on the [JCR Mocks][jcr-mock] implementation +* Uses the productive [Sling JCR resource provider implementation][jcr-resource] internally to do the Resource-JCR mapping +* Is quite fast because data is stored only in-memory + +### JCR_JACKRABBIT + +* Uses a real JCR Jackrabbit implementation (not Oak) as provided by [sling/commons/testing][sling-comons-testing] +* Full JCR/Sling features supported e.g. observations manager, transactions, versioning +* Uses the productive [Sling JCR resource provider implementation][jcr-resource] internally to do the Resource-JCR mapping +* Takes some seconds for startup on the first access +* All node types that are used when reading/writing data have to be registered + +_Warnings/Remarks_ + +* The repository is not cleared for each unit test, so make sure us use a unique node path for each unit test. +* To import Sling content you have to fully register all node types required for the data +* The [sling/commons/testing][sling-comons-testing] dependency introduces a lot of further dependencies from + jackrabbit and others, be careful that they do not conflict and are imported in the right order in your test project + +To use this type you have to declare an additional dependency in your test project: + +```xml +<dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.testing.sling-mock-jackrabbit</artifactId> + <version>1.0.0-SNAPHOT</version> + <scope>test</scope> +</dependency> +``` + + +[jcr-mock]: http://sling.apache.org/testing/jcr-mock/ +[jcr-resource]: http://svn.apache.org/repos/asf/sling/trunk/bundles/jcr/resource +[resourceresolver-mock]: http://svn.eu.apache.org/repos/asf/sling/trunk/testing/resourceresolver-moc +[sling-comons-testing]: http://svn.apache.org/repos/asf/sling/trunk/bundles/commons/testing Added: sling/trunk/testing/sling-mock/src/site/markdown/usage-content-loader.md URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/site/markdown/usage-content-loader.md?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/site/markdown/usage-content-loader.md (added) +++ sling/trunk/testing/sling-mock/src/site/markdown/usage-content-loader.md Mon Oct 13 11:54:39 2014 @@ -0,0 +1,59 @@ +## Usage + +### Import resource data from JSON file in classpath + +With the `ContentLoader` it is possible to import structured resource and property data from a JSON file stored +in the classpath beneath the unit tests. This data can be used as text fixture for unit tests. + +Example JSON data: + +```json +{ + "jcr:primaryType": "app:Page", + "jcr:content": { + "jcr:primaryType": "app:PageContent", + "jcr:title": "English", + "app:template": "/apps/sample/templates/homepage", + "sling:resourceType": "sample/components/homepage", + "jcr:createdBy": "admin", + "jcr:created": "Thu Aug 07 2014 16:32:59 GMT+0200", + "par": { + "jcr:primaryType": "nt:unstructured", + "sling:resourceType": "foundation/components/parsys", + "colctrl": { + "jcr:primaryType": "nt:unstructured", + "layout": "2;colctrl-lt0", + "sling:resourceType": "foundation/components/parsys/colctrl" + } + } + } +} +``` + +Example code to import the JSON data: + +```java +ResourceResolver resolver = MockSling.newResourceResolver(); +ContentLoader contentLoader = new ContentLoader(resolver); +contentLoader.json("/sample-data.json", "/content/sample/en"); +``` + +This codes creates a new resource at `/content/sample/en` (and - if not existent - the parent resources) and +imports the JSON data to this node. It can be accessed using the Sling Resource or JCR API afterwards. + + +### Import binary data from file in classpath + +With the `ContentLoader` it is possible to import a binary file stored in the classpath beneath the unit tests. +The data is stored usig a nt:file/nt:resource or nt:resource node type. + +Example code to import a binary file: + +```java +ResourceResolver resolver = MockSling.newResourceResolver(); +ContentLoader contentLoader = new ContentLoader(resolver); +contentLoader.binaryFile("/sample-file.gif", "/content/binary/sample-file.gif"); +``` + +This codes creates a new resource at `/content/binary/sample-file.gif` (and - if not existent - the parent +resources) and imports the binary data to a jcr:content subnode. Added: sling/trunk/testing/sling-mock/src/site/markdown/usage-mocks.md URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/site/markdown/usage-mocks.md?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/site/markdown/usage-mocks.md (added) +++ sling/trunk/testing/sling-mock/src/site/markdown/usage-mocks.md Mon Oct 13 11:54:39 2014 @@ -0,0 +1,130 @@ +## Usage + +The factory class `MockSling` allows to instantiate the different mock implementations. + +### Sling Resource Resolver + +Example: + +```java +// get a resource resolver +ResourceResolver resolver = MockSling.newResourceResolver(); + +// get a resource resolver backed by a specific repository type +ResourceResolver resolver = MockSling.newResourceResolver(ResourceResolverType.JCR_MOCK); +``` +The following types are supported currently: [Resource Resolver Types](resource-resolver-types.html) + +### Adapter Factories + +You can register your own or existing adapter factories to support adaptions e.g. for classes extending `SlingAdaptable`. + +Example: + +```java +// register adapter factory +BundleContext bundleContext = MockOsgi.newBundleContext(); +MockSling.setAdapterManagerBundleContext(bundleContext); +bundleContext.registerService(myAdapterFactory); + +// test adaption +MyClass object = resource.adaptTo(MyClass.class); + +// cleanup after unit test +MockSling.clearAdapterManagerBundleContext(); +``` + +Make sure you clean up the adapter manager bundle association after running the unit test otherwise it can +interfere with the following tests. If you use the `SlingContext` Junit rule this is done automatically for you. + + +### SlingScriptHelper + +Example: + +```java +// get script helper +SlingScriptHelper scriptHelper = MockSling.newSlingScriptHelper(); + +// get request +SlingHttpServletRequest request = scriptHelper.getRequest(); + +// get service +MyService object = scriptHelper.getService(MyService.class); +``` + +To support getting OSGi services you have to register them via the `BundleContext` interface of the +[JCR Mocks][jcr-mock] before. You can use an alternative factory method for the `SlingScriptHelper` providing +existing instances of request, response and bundle context. + + +### SlingHttpServletRequest + +Example for preparing a sling request with custom request data: + +```java +// prepare sling request +ResourceResolver resourceResolver = MockSling.newResourceResolver(); +MockSlingHttpServletRequest request = new MockSlingHttpServletRequest(resourceResolver); + +// simulate query string +request.setQueryString("param1=aaa¶m2=bbb"); + +// alternative - set query parameters as map +request.setParameterMap(ImmutableMap.<String,Object>builder() + .put("param1", "aaa") + .put("param2", "bbb") + .build()); + +// set current resource +request.setResource(resourceResolver.getResource("/content/sample")); + +// set sling request path info properties +MockRequestPathInfo requestPathInfo = (MockRequestPathInfo)request.getRequestPathInfo(); +requestPathInfo.setSelectorString("selector1.selector2"); +requestPathInfo.setExtension("html"); + +// set method +request.setMethod(HttpConstants.METHOD_POST); + +// set attributes +request.setAttribute("attr1", "value1"); + +// set headers +request.addHeader("header1", "value1"); + +// set cookies +request.addCookie(new Cookie("cookie1", "value1")); +``` + +### SlingHttpServletResponse + +Example for preparing a sling response which can collect the data that was written to it: + +```java +// prepare sling response +MockSlingHttpServletResponse response = new MockSlingHttpServletResponse(); + +// execute your unit test code that writes to the response... + +// validate status code +assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + +// validate content type and content length +assertEquals("text/plain;charset=UTF-8", response.getContentType()); +assertEquals(CharEncoding.UTF_8, response.getCharacterEncoding()); +assertEquals(55, response.getContentLength()); + +// validate headers +assertTrue(response.containsHeader("header1")); +assertEquals("5", response.getHeader("header2")); + +// validate response body as string +assertEquals(TEST_CONTENT, response.getOutputAsString()); + +// validate response body as binary data +assertArrayEquals(TEST_DATA, response.getOutput()); +``` + + +[jcr-mock]: http://sling.apache.org/testing/jcr-mock/ Added: sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/MockAdapterManagerTest.java URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/MockAdapterManagerTest.java?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/MockAdapterManagerTest.java (added) +++ sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/MockAdapterManagerTest.java Mon Oct 13 11:54:39 2014 @@ -0,0 +1,69 @@ +/* + * 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.testing.mock.sling; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.apache.sling.api.adapter.AdapterFactory; +import org.apache.sling.api.adapter.SlingAdaptable; +import org.apache.sling.testing.mock.osgi.MockOsgi; +import org.junit.Test; +import org.osgi.framework.BundleContext; + +public class MockAdapterManagerTest { + + @Test + public void test() { + AdaptableTest sampleObject = new AdaptableTest(); + assertNull(sampleObject.adaptTo(String.class)); + + BundleContext bundleContext = MockOsgi.newBundleContext(); + MockSling.setAdapterManagerBundleContext(bundleContext); + + bundleContext.registerService(AdapterFactory.class.getName(), new AdapterFactory() { + @SuppressWarnings("unchecked") + @Override + public <AdapterType> AdapterType getAdapter(final Object adaptable, final Class<AdapterType> type) { + if (adaptable instanceof AdaptableTest && type.isAssignableFrom(String.class)) { + return (AdapterType) ((AdaptableTest) adaptable).toString(); + } + return null; + } + }, null); + + sampleObject = new AdaptableTest(); + assertEquals("adaptedString", sampleObject.adaptTo(String.class)); + + MockSling.clearAdapterManagerBundleContext(); + + sampleObject = new AdaptableTest(); + assertNull(sampleObject.adaptTo(String.class)); + } + + private static class AdaptableTest extends SlingAdaptable { + + @Override + public String toString() { + return "adaptedString"; + } + + } + +} Propchange: sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/MockAdapterManagerTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/MockAdapterManagerTest.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Mon Oct 13 11:54:39 2014 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/MockAdapterManagerTest.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/MockSlingRepositoryTest.java URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/MockSlingRepositoryTest.java?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/MockSlingRepositoryTest.java (added) +++ sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/MockSlingRepositoryTest.java Mon Oct 13 11:54:39 2014 @@ -0,0 +1,46 @@ +/* + * 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.testing.mock.sling; + +import static org.junit.Assert.assertNotNull; + +import javax.jcr.RepositoryException; + +import org.apache.sling.jcr.api.SlingRepository; +import org.apache.sling.testing.mock.jcr.MockJcr; +import org.junit.Before; +import org.junit.Test; + +public class MockSlingRepositoryTest { + + private SlingRepository repository; + + @Before + public void setUp() { + this.repository = new MockSlingRepository(MockJcr.newRepository()); + } + + @SuppressWarnings("deprecation") + @Test + public void testLogin() throws RepositoryException { + assertNotNull(this.repository.loginAdministrative(MockJcr.DEFAULT_WORKSPACE)); + assertNotNull(this.repository.loginService("test", MockJcr.DEFAULT_WORKSPACE)); + } + +} Propchange: sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/MockSlingRepositoryTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/MockSlingRepositoryTest.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Mon Oct 13 11:54:39 2014 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/MockSlingRepositoryTest.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/MockSlingScriptHelperTest.java URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/MockSlingScriptHelperTest.java?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/MockSlingScriptHelperTest.java (added) +++ sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/MockSlingScriptHelperTest.java Mon Oct 13 11:54:39 2014 @@ -0,0 +1,79 @@ +/* + * 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.testing.mock.sling; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; + +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.SlingHttpServletResponse; +import org.apache.sling.api.resource.ResourceResolver; +import org.apache.sling.api.scripting.SlingScriptHelper; +import org.apache.sling.testing.mock.osgi.MockOsgi; +import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletRequest; +import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletResponse; +import org.junit.Before; +import org.junit.Test; +import org.osgi.framework.BundleContext; + +public class MockSlingScriptHelperTest { + + private ResourceResolver resourceResolver; + private SlingHttpServletRequest request; + private SlingHttpServletResponse response; + private BundleContext bundleContext; + private SlingScriptHelper scriptHelper; + + @Before + public void setUp() throws Exception { + this.resourceResolver = MockSling.newResourceResolver(); + this.request = new MockSlingHttpServletRequest(this.resourceResolver); + this.response = new MockSlingHttpServletResponse(); + this.bundleContext = MockOsgi.newBundleContext(); + this.scriptHelper = MockSling.newSlingScriptHelper(this.request, this.response, this.bundleContext); + } + + @Test + public void testRequest() { + assertSame(this.request, this.scriptHelper.getRequest()); + } + + @Test + public void testResponse() { + assertSame(this.response, this.scriptHelper.getResponse()); + } + + @Test + public void testGetService() { + this.bundleContext.registerService(String.class.getName(), "test", null); + assertEquals("test", this.scriptHelper.getService(String.class)); + } + + @Test + public void testGetServices() { + Integer[] services = new Integer[] { 1, 2, 3 }; + for (Integer service : services) { + this.bundleContext.registerService(Integer.class.getName(), service, null); + } + Integer[] servicesResult = this.scriptHelper.getServices(Integer.class, null); + assertArrayEquals(services, servicesResult); + } + +} Propchange: sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/MockSlingScriptHelperTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/MockSlingScriptHelperTest.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Mon Oct 13 11:54:39 2014 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/MockSlingScriptHelperTest.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/builder/ContentBuilderTest.java URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/builder/ContentBuilderTest.java?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/builder/ContentBuilderTest.java (added) +++ sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/builder/ContentBuilderTest.java Mon Oct 13 11:54:39 2014 @@ -0,0 +1,61 @@ +/* + * 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.testing.mock.sling.builder; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.resource.ResourceUtil; +import org.apache.sling.api.resource.ValueMap; +import org.apache.sling.testing.mock.sling.ResourceResolverType; +import org.apache.sling.testing.mock.sling.junit.SlingContext; +import org.junit.Rule; +import org.junit.Test; + +import com.google.common.collect.ImmutableMap; + +public class ContentBuilderTest { + + @Rule + public SlingContext context = new SlingContext(ResourceResolverType.RESOURCERESOLVER_MOCK); + + @Test + public void testResource() { + Resource resource = context.create().resource("/content/test1/resource1"); + assertNotNull(resource); + assertEquals("resource1", resource.getName()); + assertTrue(ResourceUtil.getValueMap(resource).isEmpty()); + } + + @Test + public void testResourceWithProperties() { + Resource resource = context.create().resource( + "/content/test1/resource2", + ImmutableMap.<String, Object> builder().put("jcr:title", "Test Title").put("stringProp", "value1") + .build()); + assertNotNull(resource); + assertEquals("resource2", resource.getName()); + ValueMap props = ResourceUtil.getValueMap(resource); + assertEquals("Test Title", props.get("jcr:title", String.class)); + assertEquals("value1", props.get("stringProp", String.class)); + } + +} Propchange: sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/builder/ContentBuilderTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/builder/ContentBuilderTest.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Mon Oct 13 11:54:39 2014 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/builder/ContentBuilderTest.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/context/SlingContextImplTest.java URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/context/SlingContextImplTest.java?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/context/SlingContextImplTest.java (added) +++ sling/trunk/testing/sling-mock/src/test/java/org/apache/sling/testing/mock/sling/context/SlingContextImplTest.java Mon Oct 13 11:54:39 2014 @@ -0,0 +1,224 @@ +/* + * 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.testing.mock.sling.context; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import javax.inject.Inject; + +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.resource.ResourceResolver; +import org.apache.sling.api.scripting.SlingBindings; +import org.apache.sling.commons.mime.MimeTypeService; +import org.apache.sling.models.annotations.Model; +import org.apache.sling.settings.SlingSettingsService; +import org.apache.sling.testing.mock.sling.MockSling; +import org.apache.sling.testing.mock.sling.ResourceResolverType; +import org.apache.sling.testing.mock.sling.loader.ContentLoader; +import org.apache.sling.testing.mock.sling.services.MockMimeTypeService; +import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletRequest; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.osgi.framework.ServiceReference; + +public class SlingContextImplTest { + + private SlingContextImpl context; + + @Before + public void setUp() throws Exception { + this.context = new SlingContextImpl(); + this.context.setResourceResolverType(ResourceResolverType.RESOURCERESOLVER_MOCK); + this.context.setUp(); + + ContentLoader contentLoader = this.context.load(); + contentLoader.json("/json-import-samples/content.json", "/content/sample/en"); + } + + @After + public void tearDown() throws Exception { + this.context.tearDown(); + } + + @Test + public void testContextObjects() { + assertNotNull(context.componentContext()); + assertNotNull(context.bundleContext()); + assertNotNull(context.resourceResolver()); + assertNotNull(context.request()); + assertNotNull(context.requestPathInfo()); + assertNotNull(context.response()); + assertNotNull(context.slingScriptHelper()); + } + + @Test + public void testSlingBindings() { + SlingBindings bindings = (SlingBindings) context.request().getAttribute(SlingBindings.class.getName()); + assertNotNull(bindings); + assertSame(context.request(), bindings.get(SlingBindings.REQUEST)); + assertSame(context.response(), bindings.get(SlingBindings.RESPONSE)); + assertSame(context.slingScriptHelper(), bindings.get(SlingBindings.SLING)); + } + + @Test + public void testRegisterService() { + Set<String> myService = new HashSet<String>(); + context.registerService(Set.class, myService); + + Set<?> serviceResult = context.getService(Set.class); + assertSame(myService, serviceResult); + } + + @Test + public void testRegisterServiceWithProperties() { + Map<String, Object> props = new HashMap<String, Object>(); + props.put("prop1", "value1"); + + Set<String> myService = new HashSet<String>(); + context.registerService(Set.class, myService, props); + + ServiceReference serviceReference = context.bundleContext().getServiceReference(Set.class.getName()); + Object serviceResult = context.bundleContext().getService(serviceReference); + assertSame(myService, serviceResult); + assertEquals("value1", serviceReference.getProperty("prop1")); + } + + @Test + public void testRegisterMultipleServices() { + Set<String> myService1 = new HashSet<String>(); + context.registerService(Set.class, myService1); + Set<String> myService2 = new HashSet<String>(); + context.registerService(Set.class, myService2); + + Set[] serviceResults = context.getServices(Set.class, null); + assertSame(myService1, serviceResults[0]); + assertSame(myService2, serviceResults[1]); + } + + @Test + public void testSetCurrentResource() { + context.currentResource("/content/sample/en/jcr:content/par/colctrl"); + assertEquals("/content/sample/en/jcr:content/par/colctrl", context.currentResource().getPath()); + + context.currentResource(context.resourceResolver().getResource("/content/sample/en/jcr:content/par")); + assertEquals("/content/sample/en/jcr:content/par", context.currentResource().getPath()); + + context.currentResource((Resource) null); + assertNull(context.request().getResource()); + + context.currentResource((String) null); + assertNull(context.request().getResource()); + } + + @Test(expected = IllegalArgumentException.class) + public void testSetCurrentResourceNonExisting() { + context.currentResource("/non/existing"); + } + + @Test + public void testSlingModelsRequestAttribute() { + context.request().setAttribute("prop1", "myValue"); + RequestAttributeModel model = context.request().adaptTo(RequestAttributeModel.class); + assertEquals("myValue", model.getProp1()); + } + + @Test + public void testSlingModelsOsgiService() { + context.registerService(new MockMimeTypeService()); + + ResourceResolver resolver = MockSling.newResourceResolver(); + OsgiServiceModel model = resolver.adaptTo(OsgiServiceModel.class); + assertNotNull(model.getMimeTypeService()); + assertEquals("text/html", model.getMimeTypeService().getMimeType("html")); + } + + @Test + public void testSlingModelsInvalidAdapt() { + OsgiServiceModel model = context.request().adaptTo(OsgiServiceModel.class); + assertNull(model); + } + + @Test + public void testAdaptToInterface() { + context.addModelsForPackage("org.apache.sling.testing.mock.sling.context"); + + MockSlingHttpServletRequest request = new MockSlingHttpServletRequest(); + request.setAttribute("prop1", "myValue"); + ServiceInterface model = request.adaptTo(ServiceInterface.class); + assertNotNull(model); + assertEquals("myValue", model.getPropValue()); + } + + @Test + public void testRegisterInjectActivate() { + context.registerInjectActivateService(new Object()); + } + + @Test + public void testRunModes() { + SlingSettingsService slingSettings = context.getService(SlingSettingsService.class); + assertEquals(SlingContextImpl.DEFAULT_RUN_MODES, slingSettings.getRunModes()); + + context.runMode("mode1", "mode2"); + Set<String> newRunModes = slingSettings.getRunModes(); + assertEquals(2, newRunModes.size()); + assertTrue(newRunModes.contains("mode1")); + assertTrue(newRunModes.contains("mode2")); + } + + @Model(adaptables = SlingHttpServletRequest.class) + public interface RequestAttributeModel { + @Inject + String getProp1(); + } + + @Model(adaptables = ResourceResolver.class) + public interface OsgiServiceModel { + @Inject + MimeTypeService getMimeTypeService(); + } + + public interface ServiceInterface { + String getPropValue(); + } + + @Model(adaptables = SlingHttpServletRequest.class, adapters = ServiceInterface.class) + public static class ServiceInterfaceImpl implements ServiceInterface { + + @Inject + private String prop1; + + @Override + public String getPropValue() { + return this.prop1; + } + } + +}