This is an automated email from the ASF dual-hosted git repository. sseifert pushed a commit to branch feature/SLING-13079-integration-tests in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-models-jacksonexporter.git
commit f9bf9cf422dfb0a5c46c1a34837ccccd0f9351b8 Author: Stefan Seifert <[email protected]> AuthorDate: Wed Jan 28 14:18:04 2026 +0100 SLING-13079 add it java classes --- pom.xml | 69 ++++- .../it/testbundle/exporter/BaseComponent.java | 59 ++++ .../testbundle/exporter/BaseRequestComponent.java | 101 ++++++ .../models/it/testbundle/exporter/Component.java | 26 ++ .../it/testbundle/exporter/ComponentImpl.java | 50 +++ .../testbundle/exporter/DoubledFirstComponent.java | 34 ++ .../exporter/DoubledSecondComponent.java | 34 ++ .../it/testbundle/exporter/ExtendedComponent.java | 53 ++++ .../exporter/ExtendedRequestComponent.java | 59 ++++ .../testbundle/exporter/RequestComponentImpl.java | 59 ++++ .../it/testbundle/exporter/package-info.java | 21 ++ .../models/it/testing/exporter/ExporterIT.java | 344 +++++++++++++++++++++ 12 files changed, 906 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 25e4e77..56bb4f3 100644 --- a/pom.xml +++ b/pom.xml @@ -39,8 +39,10 @@ </scm> <properties> - <sling.java.version>11</sling.java.version> <project.build.outputTimestamp>2025-06-25T07:05:44Z</project.build.outputTimestamp> + <sling.java.version>11</sling.java.version> + <models.api.version>1.3.0</models.api.version> + <models.impl.version>2.0.1-SNAPSHOT</models.impl.version> <version.jackson>2.15.0</version.jackson> </properties> @@ -71,13 +73,12 @@ <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.models.api</artifactId> - <version>1.3.0</version> + <version>${models.api.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> - <version>2.0.17</version> <scope>provided</scope> </dependency> @@ -170,6 +171,68 @@ <scope>test</scope> </dependency> + <!-- Integration test dependencies --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.junit.core</artifactId> + <version>1.2.0</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.testing.rules</artifactId> + <version>2.0.2</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.testing.clients</artifactId> + <version>3.1.0</version> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>javax.servlet</groupId> + <artifactId>servlet-api</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.junit.teleporter</artifactId> + <version>1.1.0</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.commons.johnzon</artifactId> + <version>2.0.0</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.engine</artifactId> + <version>3.0.0</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>io.github.classgraph</groupId> + <artifactId>classgraph</artifactId> + <version>4.8.184</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.models.impl</artifactId> + <version>${models.impl.version}</version> + <classifier>tests</classifier> + <scope>test</scope> + </dependency> + </dependencies> </project> diff --git a/src/test/java/org/apache/sling/models/it/testbundle/exporter/BaseComponent.java b/src/test/java/org/apache/sling/models/it/testbundle/exporter/BaseComponent.java new file mode 100644 index 0000000..92fcd50 --- /dev/null +++ b/src/test/java/org/apache/sling/models/it/testbundle/exporter/BaseComponent.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.models.it.testbundle.exporter; + +import javax.inject.Inject; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.models.annotations.Exporter; +import org.apache.sling.models.annotations.Model; + +@Model( + adaptables = {Resource.class}, + resourceType = "sling/exp/base") +@Exporter(name = "jackson", extensions = "json") +public class BaseComponent { + + private final Resource resource; + + @Inject + private String sampleValue; + + public BaseComponent(Resource resource) { + this.resource = resource; + } + + public String getId() { + return this.resource.getPath(); + } + + public String getSampleValue() { + return sampleValue; + } + + @JsonProperty(value = "UPPER") + public String getSampleValueToUpperCase() { + return sampleValue.toUpperCase(); + } + + public Resource getResource() { + return resource; + } +} diff --git a/src/test/java/org/apache/sling/models/it/testbundle/exporter/BaseRequestComponent.java b/src/test/java/org/apache/sling/models/it/testbundle/exporter/BaseRequestComponent.java new file mode 100644 index 0000000..b4e868e --- /dev/null +++ b/src/test/java/org/apache/sling/models/it/testbundle/exporter/BaseRequestComponent.java @@ -0,0 +1,101 @@ +/* + * 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.models.it.testbundle.exporter; + +import javax.inject.Inject; +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; + +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.models.annotations.Exporter; +import org.apache.sling.models.annotations.ExporterOption; +import org.apache.sling.models.annotations.Model; +import org.apache.sling.models.annotations.Via; +import org.apache.sling.models.annotations.injectorspecific.SlingObject; + +@Model( + adaptables = {SlingHttpServletRequest.class}, + resourceType = "sling/exp-request/base") +@Exporter( + name = "jackson", + extensions = "json", + options = {@ExporterOption(name = "MapperFeature.SORT_PROPERTIES_ALPHABETICALLY", value = "true")}) +public class BaseRequestComponent { + + @Inject + @SlingObject + private Resource resource; + + @Inject + @Via("resource") + private String sampleValue; + + @Inject + private Map<String, Object> testBindingsObject; + + @Inject + private Map<String, Object> testBindingsObject2; + + private final SlingHttpServletRequest request; + + public BaseRequestComponent(SlingHttpServletRequest request) { + this.request = request; + } + + public String getId() { + return this.resource.getPath(); + } + + public String getSampleValue() { + return sampleValue; + } + + @JsonProperty(value = "UPPER") + public String getSampleValueToUpperCase() { + return sampleValue.toUpperCase(); + } + + public Resource getResource() { + return resource; + } + + public Map<String, Object> getTestBindingsObject() { + return testBindingsObject; + } + + public Map<String, Object> getTestBindingsObject2() { + return testBindingsObject2; + } + + public SlingHttpServletRequest getSlingHttpServletRequest() { + return request; + } + + public HttpServletRequest getHttpServletRequest() { + return request; + } + + public ServletRequest getServletRequest() { + return request; + } +} diff --git a/src/test/java/org/apache/sling/models/it/testbundle/exporter/Component.java b/src/test/java/org/apache/sling/models/it/testbundle/exporter/Component.java new file mode 100644 index 0000000..c022945 --- /dev/null +++ b/src/test/java/org/apache/sling/models/it/testbundle/exporter/Component.java @@ -0,0 +1,26 @@ +/* + * 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.models.it.testbundle.exporter; + +public interface Component { + + String getId(); + + String getSampleValue(); +} diff --git a/src/test/java/org/apache/sling/models/it/testbundle/exporter/ComponentImpl.java b/src/test/java/org/apache/sling/models/it/testbundle/exporter/ComponentImpl.java new file mode 100644 index 0000000..ad55a83 --- /dev/null +++ b/src/test/java/org/apache/sling/models/it/testbundle/exporter/ComponentImpl.java @@ -0,0 +1,50 @@ +/* + * 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.models.it.testbundle.exporter; + +import javax.inject.Inject; + +import org.apache.sling.api.resource.Resource; +import org.apache.sling.models.annotations.Exporter; +import org.apache.sling.models.annotations.Model; + +@Model( + adaptables = {Resource.class}, + adapters = Component.class, + resourceType = "sling/exp/interface") +@Exporter(name = "jackson", extensions = "json") +public class ComponentImpl implements Component { + + private final Resource resource; + + @Inject + private String sampleValue; + + public ComponentImpl(Resource resource) { + this.resource = resource; + } + + public String getId() { + return this.resource.getPath(); + } + + public String getSampleValue() { + return sampleValue; + } +} diff --git a/src/test/java/org/apache/sling/models/it/testbundle/exporter/DoubledFirstComponent.java b/src/test/java/org/apache/sling/models/it/testbundle/exporter/DoubledFirstComponent.java new file mode 100644 index 0000000..58d676f --- /dev/null +++ b/src/test/java/org/apache/sling/models/it/testbundle/exporter/DoubledFirstComponent.java @@ -0,0 +1,34 @@ +/* + * 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.models.it.testbundle.exporter; + +import org.apache.sling.api.resource.Resource; +import org.apache.sling.models.annotations.Exporter; +import org.apache.sling.models.annotations.Model; + +@Model( + adaptables = {Resource.class}, + resourceType = "sling/exp/doubled") +@Exporter(name = "jackson", extensions = "json", selector = "firstmodel") +public class DoubledFirstComponent { + + public String getValue() { + return "first"; + } +} diff --git a/src/test/java/org/apache/sling/models/it/testbundle/exporter/DoubledSecondComponent.java b/src/test/java/org/apache/sling/models/it/testbundle/exporter/DoubledSecondComponent.java new file mode 100644 index 0000000..bbabb29 --- /dev/null +++ b/src/test/java/org/apache/sling/models/it/testbundle/exporter/DoubledSecondComponent.java @@ -0,0 +1,34 @@ +/* + * 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.models.it.testbundle.exporter; + +import org.apache.sling.api.resource.Resource; +import org.apache.sling.models.annotations.Exporter; +import org.apache.sling.models.annotations.Model; + +@Model( + adaptables = {Resource.class}, + resourceType = "sling/exp/doubled") +@Exporter(name = "jackson", extensions = "json", selector = "secondmodel") +public class DoubledSecondComponent { + + public String getValue() { + return "second"; + } +} diff --git a/src/test/java/org/apache/sling/models/it/testbundle/exporter/ExtendedComponent.java b/src/test/java/org/apache/sling/models/it/testbundle/exporter/ExtendedComponent.java new file mode 100644 index 0000000..683dc0a --- /dev/null +++ b/src/test/java/org/apache/sling/models/it/testbundle/exporter/ExtendedComponent.java @@ -0,0 +1,53 @@ +/* + * 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.models.it.testbundle.exporter; + +import javax.inject.Inject; + +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; + +import org.apache.sling.api.resource.Resource; +import org.apache.sling.models.annotations.Exporter; +import org.apache.sling.models.annotations.Model; + +@Model( + adaptables = {Resource.class}, + resourceType = "sling/exp/extended") +@Exporter(name = "jackson", extensions = "json") +public class ExtendedComponent extends BaseComponent { + + @Inject + private Date date; + + public ExtendedComponent(Resource resource) { + super(resource); + } + + public Calendar getDateByCalendar() { + Calendar cal = new GregorianCalendar(); + cal.setTime(date); + return cal; + } + + public Date getDate() { + return date; + } +} diff --git a/src/test/java/org/apache/sling/models/it/testbundle/exporter/ExtendedRequestComponent.java b/src/test/java/org/apache/sling/models/it/testbundle/exporter/ExtendedRequestComponent.java new file mode 100644 index 0000000..c2c34c4 --- /dev/null +++ b/src/test/java/org/apache/sling/models/it/testbundle/exporter/ExtendedRequestComponent.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.models.it.testbundle.exporter; + +import javax.inject.Inject; + +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; + +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.models.annotations.Exporter; +import org.apache.sling.models.annotations.ExporterOption; +import org.apache.sling.models.annotations.Model; +import org.apache.sling.models.annotations.Via; + +@Model( + adaptables = {SlingHttpServletRequest.class}, + resourceType = "sling/exp-request/extended") +@Exporter( + name = "jackson", + extensions = "json", + options = {@ExporterOption(name = "SerializationFeature.WRITE_DATES_AS_TIMESTAMPS", value = "false")}) +public class ExtendedRequestComponent extends BaseRequestComponent { + + @Inject + @Via("resource") + private Date date; + + public ExtendedRequestComponent(SlingHttpServletRequest request) { + super(request); + } + + public Calendar getDateByCalendar() { + Calendar cal = new GregorianCalendar(); + cal.setTime(date); + return cal; + } + + public Date getDate() { + return date; + } +} diff --git a/src/test/java/org/apache/sling/models/it/testbundle/exporter/RequestComponentImpl.java b/src/test/java/org/apache/sling/models/it/testbundle/exporter/RequestComponentImpl.java new file mode 100644 index 0000000..796b2f6 --- /dev/null +++ b/src/test/java/org/apache/sling/models/it/testbundle/exporter/RequestComponentImpl.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.models.it.testbundle.exporter; + +import javax.inject.Inject; + +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.models.annotations.Exporter; +import org.apache.sling.models.annotations.Model; +import org.apache.sling.models.annotations.Via; +import org.apache.sling.models.annotations.injectorspecific.SlingObject; + +@Model( + adaptables = {SlingHttpServletRequest.class}, + adapters = Component.class, + resourceType = "sling/exp-request/interface") +@Exporter(name = "jackson", extensions = "json") +public class RequestComponentImpl implements Component { + + @Inject + @SlingObject + private Resource resource; + + @Inject + @Via("resource") + private String sampleValue; + + @SuppressWarnings("unused") + private final SlingHttpServletRequest request; + + public RequestComponentImpl(SlingHttpServletRequest request) { + this.request = request; + } + + public String getId() { + return this.resource.getPath(); + } + + public String getSampleValue() { + return sampleValue; + } +} diff --git a/src/test/java/org/apache/sling/models/it/testbundle/exporter/package-info.java b/src/test/java/org/apache/sling/models/it/testbundle/exporter/package-info.java new file mode 100644 index 0000000..509ddef --- /dev/null +++ b/src/test/java/org/apache/sling/models/it/testbundle/exporter/package-info.java @@ -0,0 +1,21 @@ +/* + * 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. + */ + +@Version("1.0") +package org.apache.sling.models.it.testbundle.exporter; + +import org.osgi.annotation.versioning.Version; diff --git a/src/test/java/org/apache/sling/models/it/testing/exporter/ExporterIT.java b/src/test/java/org/apache/sling/models/it/testing/exporter/ExporterIT.java new file mode 100644 index 0000000..76eb2b5 --- /dev/null +++ b/src/test/java/org/apache/sling/models/it/testing/exporter/ExporterIT.java @@ -0,0 +1,344 @@ +/* + * 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.models.it.testing.exporter; + +import javax.json.Json; +import javax.json.JsonObject; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.StringReader; +import java.text.Format; +import java.util.Calendar; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.TimeZone; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.FastDateFormat; +import org.apache.sling.api.SlingConstants; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.resource.ResourceResolver; +import org.apache.sling.api.resource.ResourceResolverFactory; +import org.apache.sling.api.resource.ResourceUtil; +import org.apache.sling.engine.SlingRequestProcessor; +import org.apache.sling.junit.rules.TeleporterRule; +import org.apache.sling.models.factory.MissingExporterException; +import org.apache.sling.models.factory.ModelFactory; +import org.apache.sling.models.it.testing.helper.FakeRequest; +import org.apache.sling.models.it.testing.helper.FakeResponse; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +public class ExporterIT { + + @Rule + public final TeleporterRule teleporter = TeleporterRule.forClass(getClass(), "SM_Teleporter"); + + private ResourceResolverFactory rrFactory; + + private ModelFactory modelFactory; + + private SlingRequestProcessor slingRequestProcessor; + + private final String baseComponentPath = "/content/exp/baseComponent"; + private final String doubledComponentPath = "/content/exp/doubledComponent"; + private final String childComponentPath = "/content/exp/childComponent"; + private final String extendedComponentPath = "/content/exp/extendedComponent"; + private final String interfaceComponentPath = "/content/exp/interfaceComponent"; + private final String baseRequestComponentPath = "/content/exp-request/baseComponent"; + private final String extendedRequestComponentPath = "/content/exp-request/extendedComponent"; + private final String interfaceRequestComponentPath = "/content/exp-request/interfaceComponent"; + private Calendar testDate; + + private Format dateFormat = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss.SSSZ", TimeZone.getTimeZone("UTC")); + + @Before + @SuppressWarnings("null") + public void setup() throws Exception { + rrFactory = teleporter.getService(ResourceResolverFactory.class); + modelFactory = teleporter.getService(ModelFactory.class); + slingRequestProcessor = teleporter.getService(SlingRequestProcessor.class); + + try (ResourceResolver adminResolver = rrFactory.getServiceResourceResolver(null); ) { + Map<String, Object> properties = new HashMap<String, Object>(); + properties.put("sampleValue", "baseTESTValue"); + properties.put("sampleBooleanValue", true); + properties.put("sampleLongValue", 1l); + properties.put("sampleDoubleValue", 1d); + properties.put("sampleArray", new String[] {"a", "b", "c"}); + properties.put("sampleEmptyArray", new String[0]); + properties.put("sampleBinary", new ByteArrayInputStream("abc".getBytes("UTF-8"))); + properties.put("sampleBinaryArray", new InputStream[] { + new ByteArrayInputStream("abc".getBytes("UTF-8")), new ByteArrayInputStream("def".getBytes("UTF-8")) + }); + properties.put( + SlingConstants.NAMESPACE_PREFIX + ":" + SlingConstants.PROPERTY_RESOURCE_TYPE, "sling/exp/base"); + ResourceUtil.getOrCreateResource(adminResolver, baseComponentPath, properties, null, false); + + ResourceUtil.getOrCreateResource( + adminResolver, baseComponentPath + "/child", Collections.<String, Object>emptyMap(), null, false); + + properties.put( + SlingConstants.NAMESPACE_PREFIX + ":" + SlingConstants.PROPERTY_RESOURCE_TYPE, + "sling/exp-request/base"); + ResourceUtil.getOrCreateResource(adminResolver, baseRequestComponentPath, properties, null, false); + properties.clear(); + + properties.put("sampleValue", "childTESTValue"); + properties.put( + SlingConstants.NAMESPACE_PREFIX + ":" + SlingConstants.PROPERTY_RESOURCE_TYPE, "sling/exp/child"); + properties.put( + SlingConstants.NAMESPACE_PREFIX + ":" + SlingConstants.PROPERTY_RESOURCE_SUPER_TYPE, + "sling/exp/base"); + ResourceUtil.getOrCreateResource(adminResolver, childComponentPath, properties, null, false); + properties.clear(); + + properties.put("sampleValue", "extendedTESTValue"); + properties.put( + SlingConstants.NAMESPACE_PREFIX + ":" + SlingConstants.PROPERTY_RESOURCE_TYPE, + "sling/exp/extended"); + testDate = Calendar.getInstance(); + testDate.setTimeZone(TimeZone.getTimeZone("UTC")); + testDate.setTimeInMillis(0); + testDate.set(2015, 6, 29); + properties.put("date", testDate); + ResourceUtil.getOrCreateResource(adminResolver, extendedComponentPath, properties, null, false); + + properties.put( + SlingConstants.NAMESPACE_PREFIX + ":" + SlingConstants.PROPERTY_RESOURCE_TYPE, + "sling/exp-request/extended"); + ResourceUtil.getOrCreateResource(adminResolver, extendedRequestComponentPath, properties, null, false); + properties.clear(); + + properties.put("sampleValue", "interfaceTESTValue"); + properties.put( + SlingConstants.NAMESPACE_PREFIX + ":" + SlingConstants.PROPERTY_RESOURCE_TYPE, + "sling/exp/interface"); + ResourceUtil.getOrCreateResource(adminResolver, interfaceComponentPath, properties, null, false); + + properties.put( + SlingConstants.NAMESPACE_PREFIX + ":" + SlingConstants.PROPERTY_RESOURCE_TYPE, + "sling/exp-request/interface"); + ResourceUtil.getOrCreateResource(adminResolver, interfaceRequestComponentPath, properties, null, false); + properties.clear(); + + properties.put( + SlingConstants.NAMESPACE_PREFIX + ":" + SlingConstants.PROPERTY_RESOURCE_TYPE, "sling/exp/doubled"); + ResourceUtil.getOrCreateResource(adminResolver, doubledComponentPath, properties, null, false); + + adminResolver.commit(); + } + } + + @Test + @SuppressWarnings("null") + public void testExportToJSON() throws Exception { + try (ResourceResolver resolver = rrFactory.getServiceResourceResolver(null); ) { + final Resource baseComponentResource = resolver.getResource(baseComponentPath); + Assert.assertNotNull(baseComponentResource); + String jsonData = modelFactory.exportModelForResource( + baseComponentResource, "jackson", String.class, Collections.<String, String>emptyMap()); + Assert.assertTrue( + "JSON Data should contain the property value", StringUtils.contains(jsonData, "baseTESTValue")); + + JsonObject parsed = Json.createReader(new StringReader(jsonData)).readObject(); + JsonObject resource = parsed.getJsonObject("resource"); + Assert.assertEquals(3, resource.getJsonArray("sampleArray").size()); + Assert.assertEquals( + 1.0d, resource.getJsonNumber("sampleDoubleValue").doubleValue(), .1); + Assert.assertEquals(2, resource.getJsonArray(":sampleBinaryArray").size()); + Assert.assertTrue(resource.getBoolean("sampleBooleanValue")); + Assert.assertEquals(1, resource.getInt("sampleLongValue")); + Assert.assertEquals(3, resource.getInt(":sampleBinary")); + Assert.assertEquals(0, resource.getJsonArray("sampleEmptyArray").size()); + + final Resource extendedComponentResource = resolver.getResource(extendedComponentPath); + Assert.assertNotNull(extendedComponentResource); + jsonData = modelFactory.exportModelForResource( + extendedComponentResource, "jackson", String.class, Collections.<String, String>emptyMap()); + Assert.assertTrue( + "JSON Data should contain the property value", StringUtils.contains(jsonData, "extendedTESTValue")); + + final Resource interfaceComponentResource = resolver.getResource(interfaceComponentPath); + Assert.assertNotNull(baseComponentResource); + jsonData = modelFactory.exportModelForResource( + interfaceComponentResource, "jackson", String.class, Collections.<String, String>emptyMap()); + Assert.assertTrue( + "JSON Data should contain the property value", + StringUtils.contains(jsonData, "interfaceTESTValue")); + } + } + + @Test + public void testExportToTidyJSON() throws Exception { + try (ResourceResolver resolver = rrFactory.getServiceResourceResolver(null); ) { + final Resource baseComponentResource = resolver.getResource(baseComponentPath); + Assert.assertNotNull(baseComponentResource); + String jsonData = modelFactory.exportModelForResource( + baseComponentResource, "jackson", String.class, Collections.<String, String>emptyMap()); + Assert.assertFalse(jsonData.contains(System.lineSeparator())); + + jsonData = modelFactory.exportModelForResource( + baseComponentResource, + "jackson", + String.class, + Collections.<String, String>singletonMap("tidy", "true")); + Assert.assertTrue(jsonData.contains(System.lineSeparator())); + } + } + + @SuppressWarnings("unchecked") + @Test + public void testExportToMap() throws Exception { + try (ResourceResolver resolver = rrFactory.getServiceResourceResolver(null); ) { + final Resource baseComponentResource = resolver.getResource(baseComponentPath); + Assert.assertNotNull(baseComponentResource); + Map<String, Object> data = modelFactory.exportModelForResource( + baseComponentResource, "jackson", Map.class, Collections.<String, String>emptyMap()); + Assert.assertEquals("Should have resource value", "baseTESTValue", data.get("sampleValue")); + Assert.assertEquals("Should have resource value", "BASETESTVALUE", data.get("UPPER")); + } + } + + @Test + public void testResourceServlets() throws Exception { + try (ResourceResolver resolver = rrFactory.getServiceResourceResolver(null); ) { + FakeResponse response = new FakeResponse(); + slingRequestProcessor.processRequest( + new FakeRequest(baseComponentPath + ".model.json"), response, resolver); + JsonObject obj = Json.createReader( + new StringReader((response.getStringWriter().toString()))) + .readObject(); + Assert.assertEquals("application/json", response.getContentType()); + Assert.assertEquals("UTF-8", response.getCharacterEncoding()); + Assert.assertEquals("BASETESTVALUE", obj.getString("UPPER")); + Assert.assertEquals(baseComponentPath, obj.getString("id")); + + response = new FakeResponse(); + slingRequestProcessor.processRequest( + new FakeRequest(extendedComponentPath + ".model.json"), response, resolver); + obj = Json.createReader(new StringReader((response.getStringWriter().toString()))) + .readObject(); + Assert.assertEquals("application/json", response.getContentType()); + Assert.assertEquals("UTF-8", response.getCharacterEncoding()); + Assert.assertEquals(extendedComponentPath, obj.getString("id")); + Assert.assertEquals( + testDate.getTimeInMillis(), obj.getJsonNumber("date").longValue()); + + response = new FakeResponse(); + slingRequestProcessor.processRequest( + new FakeRequest(interfaceComponentPath + ".model.json"), response, resolver); + obj = Json.createReader(new StringReader((response.getStringWriter().toString()))) + .readObject(); + Assert.assertEquals("application/json", response.getContentType()); + Assert.assertEquals("UTF-8", response.getCharacterEncoding()); + Assert.assertEquals(interfaceComponentPath, obj.getString("id")); + Assert.assertEquals("interfaceTESTValue", obj.getString("sampleValue")); + } + } + + @Test + public void testRequestServlets() throws Exception { + try (ResourceResolver resolver = rrFactory.getServiceResourceResolver(null); ) { + FakeResponse response = new FakeResponse(); + slingRequestProcessor.processRequest( + new FakeRequest(baseRequestComponentPath + ".model.json"), response, resolver); + String stringOutput = response.getStringWriter().toString(); + + Assert.assertTrue(stringOutput.startsWith("{\"UPPER\":")); + + JsonObject obj = Json.createReader(new StringReader(stringOutput)).readObject(); + Assert.assertEquals("application/json", response.getContentType()); + Assert.assertEquals("UTF-8", response.getCharacterEncoding()); + Assert.assertEquals("BASETESTVALUE", obj.getString("UPPER")); + Assert.assertTrue(obj.containsKey("testBindingsObject")); + JsonObject testBindingsObject = obj.getJsonObject("testBindingsObject"); + Assert.assertEquals("value", testBindingsObject.getString("name")); + Assert.assertTrue(obj.containsKey("testBindingsObject2")); + JsonObject testBindingsObject2 = obj.getJsonObject("testBindingsObject2"); + Assert.assertEquals("value2", testBindingsObject2.getString("name2")); + Assert.assertEquals(baseRequestComponentPath, obj.getString("id")); + + response = new FakeResponse(); + slingRequestProcessor.processRequest( + new FakeRequest(extendedRequestComponentPath + ".model.json"), response, resolver); + obj = Json.createReader(new StringReader((response.getStringWriter().toString()))) + .readObject(); + Assert.assertEquals("application/json", response.getContentType()); + Assert.assertEquals("UTF-8", response.getCharacterEncoding()); + Assert.assertEquals(extendedRequestComponentPath, obj.getString("id")); + Assert.assertEquals(dateFormat.format(testDate), obj.getString("date")); + + response = new FakeResponse(); + slingRequestProcessor.processRequest( + new FakeRequest(interfaceRequestComponentPath + ".model.json"), response, resolver); + obj = Json.createReader(new StringReader((response.getStringWriter().toString()))) + .readObject(); + Assert.assertEquals("application/json", response.getContentType()); + Assert.assertEquals("UTF-8", response.getCharacterEncoding()); + Assert.assertEquals(interfaceRequestComponentPath, obj.getString("id")); + Assert.assertEquals("interfaceTESTValue", obj.getString("sampleValue")); + } + } + + @Test + public void testDoubledServlets() throws Exception { + try (ResourceResolver resolver = rrFactory.getServiceResourceResolver(null); ) { + FakeResponse response = new FakeResponse(); + slingRequestProcessor.processRequest( + new FakeRequest(doubledComponentPath + ".firstmodel.json"), response, resolver); + + JsonObject obj = Json.createReader( + new StringReader((response.getStringWriter().toString()))) + .readObject(); + Assert.assertEquals("application/json", response.getContentType()); + Assert.assertEquals("first", obj.getString("value")); + + response = new FakeResponse(); + slingRequestProcessor.processRequest( + new FakeRequest(doubledComponentPath + ".secondmodel.json"), response, resolver); + obj = Json.createReader(new StringReader((response.getStringWriter().toString()))) + .readObject(); + Assert.assertEquals("application/json", response.getContentType()); + Assert.assertEquals("second", obj.getString("value")); + } + } + + @Test + public void testFailedExport() throws Exception { + boolean thrown = false; + try { + try (ResourceResolver resolver = rrFactory.getServiceResourceResolver(null); ) { + final Resource baseComponentResource = resolver.getResource(baseComponentPath); + Assert.assertNotNull(baseComponentResource); + modelFactory.exportModelForResource( + baseComponentResource, "jaxb", String.class, Collections.<String, String>emptyMap()); + Assert.fail("Should have thrown missing serializer error."); + } + } catch (MissingExporterException e) { + thrown = true; + Assert.assertEquals("No exporter named jaxb supports java.lang.String.", e.getMessage()); + } + Assert.assertTrue(thrown); + } +}
