GithubHelp home page GithubHelp logo

icfnext / prosper Goto Github PK

View Code? Open in Web Editor NEW
28.0 53.0 19.0 1.66 MB

A Spock-based integration testing library for prosperous AEM development.

License: Other

Groovy 100.00%
aem sling spock groovy jcr mock

prosper's Introduction

Prosper

ICF Next

Overview

Prosper is an integration testing library for Adobe Experience Manager projects using Spock, a Groovy-based testing framework notable for it's expressive specification language. The library contains a base Spock specification that provides an in-memory JCR, Sling framework support, and a mock OSGi context for registering and testing services.

Features

  • Test AEM projects outside of an OSGi container in the standard Maven build lifecycle.
  • Write test specifications in Groovy using Spock, a JUnit-based testing framework with an elegant syntax for writing tests quickly and efficiently.
  • Sling ResourceResolver instance backed by an in-memory Jackrabbit Oak JCR instance supporting the complete set of repository operations.
  • Supplies mock OSGi bundle and Sling contexts for registering services, adapters, and Sling models.
  • Utilizes Groovy builders from the AEM Groovy Extension to provide a simple DSL for creating test content.
  • Provides additional builders for mock Sling requests and responses to simplify setup of test cases.

Requirements

  • Maven 3.x
  • Familiarity with Groovy language and the Spock specification syntax (or see included tests for examples).

Compatibility

Prosper Version(s) AEM Version(s)
14.x.x 6.3, 6.4, 6.5
13.x.x, 12.x.x 6.4
11.x.x 6.3
10.x.x, 9.x.x, 8.x.x 6.2
7.x.x, 6.x.x, 5.x.x, 4.x.x 6.1
3.x.x, 2.x.x, 1.x.x 6.0
<= 0.10.x 5.6 (CQ)

Getting Started

Add Maven dependency to project pom.xml.

<dependency>
    <groupId>com.icfolson.aem.prosper</groupId>
    <artifactId>prosper</artifactId>
    <version>15.0.0</version>
    <scope>test</scope>
</dependency>

Create a src/test/groovy directory in your project structure and add a Spock specification extending the base ProsperSpec.

import com.icfolson.aem.prosper.specs.ProsperSpec

class ExampleSpec extends ProsperSpec {

    def setupSpec() {
        // use PageBuilder from base spec to create test content
        pageBuilder.content {
            home("Home") {
                "jcr:content"("sling:resourceType": "foundation/components/page")
            }
        }
    }

    // basic content assertions provided
    def "home page exists"() {
        expect:
        assertPageExists("/content/home")
    }

    // Node metaclass provided by AEM Groovy Extension simplifies JCR operations
    def "home page has expected resource type"() {
        setup:
        def contentNode = session.getNode("/content/home/jcr:content")

        expect:
        contentNode.get("sling:resourceType") == "foundation/components/page"
    }
}

Configure Groovy compiler and Surefire plugin in Maven pom.xml. Additional configurations details for projects with mixed Java/Groovy sources can be found here.

<build>
    <sourceDirectory>src/main/groovy</sourceDirectory>
    <testSourceDirectory>src/test/groovy</testSourceDirectory>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.0</version>
            <configuration>
                <compilerId>groovy-eclipse-compiler</compilerId>
                <source>1.8</source>
                <target>1.8</target>
                <encoding>utf-8</encoding>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>org.codehaus.groovy</groupId>
                    <artifactId>groovy-eclipse-compiler</artifactId>
                    <version>2.9.2-01</version>
                </dependency>
                <dependency>
                    <groupId>org.codehaus.groovy</groupId>
                    <artifactId>groovy-eclipse-batch</artifactId>
                    <version>2.4.3-01</version>
                </dependency>
            </dependencies>
        </plugin>
        <plugin>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.19.1</version>
            <configuration>
                <includes>
                    <!-- Spock naming convention.  Change as needed if your test classes have a different naming strategy. -->
                    <include>**/*Spec*</include>
                </includes>
            </configuration>
        </plugin>
    </plugins>
</build>

<dependencies>
    <dependency>
        <groupId>org.codehaus.groovy</groupId>
        <artifactId>groovy-all</artifactId>
        <version>2.4.15</version>
    </dependency>
</dependencies>

Finally, run mvn test from the command line to verify that specifications are found and execute successfully.

User Guide

Specification Anatomy

The Spock documentation outlines the features and methods that define a Spock specification (and their JUnit analogues, for those more familiar with Java-based testing), but the setupSpec fixture method is of critical importance when testing AEM classes. This method, executed prior to the first feature method of the specification, is the conventional location for creating test content in the JCR. Likewise, the cleanup and cleanupSpec fixture methods are the appropriate place to remove test content following the execution of a test (or set of tests). However, the cleanupSpec method will be implemented less frequently, as the base ProsperSpec removes all test content from the JCR after every specification is executed to prevent cross-contamination of content between specifications.

class ExampleSpec extends ProsperSpec {

    def setupSpec() {
        // runs before first feature method, create test content and initialize shared resources here
    }

    def setup() {
        // runs before each feature method, less commonly used
    }

    def "a feature method"() {
        setup:
        // create test-specific content, instances and/or mocks

        expect:
        // result
    }

    def "another feature method"() {
        setup:
        // create test content, etc.

        when:
        // stimulus

        then:
        // response
    }

    def cleanup() {
        // optionally call the method below to remove all test content after each feature method
        removeAllNodes()
    }

    def cleanupSpec() {
        // runs after all feature methods, implemented in base spec but less commonly used
    }
}

Available Fields and Methods

The base specification exposes a number of fields and methods for use in tests.

Field Name Type Description
session javax.jcr.Session Administrative JCR session
resourceResolver org.apache.sling.api.resource.ResourceResolver Administrative Sling Resource Resolver
pageManager com.day.cq.wcm.api.PageManager AEM Page Manager
nodeBuilder com.icfolson.aem.groovy.extension.builders.NodeBuilder JCR Node Builder
pageBuilder com.icfolson.aem.groovy.extension.builders.PageBuilder AEM Page Builder
slingContext com.icfolson.aem.prosper.context.SlingContextProvider Prosper extension of Sling/OSGi Context

See the ProsperSpec GroovyDoc for details on available methods.

Content Builders

A test specification will often require content such as pages, components, or supporting node structures to facilitate the interactions of the class under test. Creating a large and/or complex content hierarchy using the JCR and Sling APIs can be tedious and time consuming. The base ProsperSpec simplifies the content creation process by defining two Groovy builder instances, pageBuilder and nodeBuilder, that greatly reduce the amount of code needed to produce a working content structure in the JCR.

Page Builder

PageBuilder creates nodes of type cq:Page by default.

def setupSpec() {
    pageBuilder.content {
        beer { // page with no title
            styles("Styles") { // create page with title "Styles"
                "jcr:content"("jcr:lastModifiedBy": "mdaugherty", "jcr:lastModified": Calendar.instance) {
                    data("sling:Folder")  // descendant of "jcr:content", argument sets node type instead of title
                    navigation("sling:resourceType: "components/navigation", "rootPath": "/content/beer")
                }
                dubbel("Dubbel")
                tripel("Tripel")
                saison("Saison")
            }
            // create a page with title "Breweries" and set properties on it's "jcr:content" node
            breweries("Breweries", "jcr:lastModifiedBy": "mdaugherty", "jcr:lastModified": Calendar.instance)
        }
    }
}

Nodes named jcr:content, however, are treated as unstructured nodes to allow the creation of descendant component/data nodes that are not of type cq:Page. Descendants of jcr:content nodes can specify a node type using a String value as the first argument in the tree syntax (see /content/beer/styles/jcr:content/data in the above example). As with page nodes, additional properties can be passed with a map argument.

Node Builder

This builder should be used when creating non-page content hierarchies, such as descendants of /etc in the JCR. The syntax is similar to PageBuilder, but the first argument is used to specify the node type rather than the jcr:title property.

def setupSpec() {
    nodeBuilder.etc { // unstructured node
        designs("sling:Folder") { // node with type
            site("sling:Folder", "jcr:title": "Site", "inceptionYear": 2014) // node with type and properties
        }
    }
}

The above example will create an nt:unstructured (the default type) node at /etc and sling:Folder nodes at /etc/designs and /etc/designs/site. An additional map argument will set properties on the target node in the same manner as PageBuilder.

Both builders automatically save the underlying JCR session after executing the provided closure.

In addition to the content builders, the session and pageManager instances provided by the base specification can be used directly to create test content in the JCR.

Content Import

Another way to generate supporting content is to import a vault exported/packaged content structure. The content import is completely automatic and will run for all of your specs when it detects content to import. To take advantage of the content import, simply create a SLING-INF/content directory within your project's test resources location (ex. src/test/resources/SLING-INF/content). The content directory must contain a child jcr_root directory and META-INF directory. The jcr_root directory will contain all the vault exported/packaged content. The META-INF directory will contain all the vault configuration XML files typically found within an AEM package.

Specifying a Filter File

You can specify an alternative filter.xml file by using the class level com.icfolson.aem.prosper.annotations.ContentFilters annotation. Simply provide the path to the filter.xml file in the XML element and it will be used instead of the filter.xml file within the META-INF/vault directory. The example below shows how you can provide a path to a non-default filter.xml file.

@ContentFilters(
    xml = "/SLING-INF/content/META-INF/vault/alt-filter.xml"
)
class MySpec extends ProsperSpec {

}

Dynamic Filters

You can also dynamically generate spec-specific filters by using the various content filter annotations. This allows you to isolate the content you need for your individual specs. The example below shows how you can define a dynamic filter.

@ContentFilters(
    filters = [
        @ContentFilter(
            root = "/etc",
            mode = ImportMode.REPLACE,
            rules = [
                @ContentFilterRule(
                    type = ContentFilterRuleType.EXCLUDE,
                    pattern = "/etc/tags"
                )
            ]
        )
    ]
)
class MySpec extends ProsperSpec {

}

It is also possible to extend the provided filter.xml file through dynamic filters. This allows you to provide common filters in the XML file and define specific filters for your spec with the annotations. The example below shows how you can extend an existing filter.xml file.

@ContentFilters(
    xml = "/SLING-INF/content/META-INF/vault/alt-filter.xml",
    filters = [
        @ContentFilter(
            root = "/etc",
            mode = ImportMode.REPLACE,
            rules = [
                @ContentFilterRule(
                    type = ContentFilterRuleType.EXCLUDE,
                    pattern = "/etc/tags"
                )
            ]
        )
    ]
)
class MySpec extends ProsperSpec {

}

Skipping Content Import

In some cases, you may not want to import content for your spec. To skip the content import, annotate your spec class with @SkipContentImport. The example below shows a spec that skips the content import.

@SkipContentImport
class MySpec extends ProsperSpec {

}

Metaclasses

The AEM Groovy Extension decorates the com.day.cq.wcm.api.Page, javax.jcr.Node, and javax.jcr.Binary classes with additional methods to simplify common operations. See the extension library Groovydocs for details of these additions. The metaclasses are registered automatically and available for use in all test methods.

Assertions

Prosper's built-in assertion methods are used within Spock's then and expect blocks to verify the state of content in the transient repository following execution of a test. For example, a test that creates a node with property values (either directly or as a side effect of other operations) will want to confirm that the node was created and that the desired property name and values exist in the JCR.

Since expressions in these blocks are implicitly treated as boolean conditions by Spock, Prosper's assertion methods eliminate the need to logically combine expressions for the complex conditions required to assert JCR state. This is best illustrated with an example.

import com.day.cq.commons.jcr.JcrConstants
import com.day.cq.wcm.api.NameConstants

def "create content"() {
    setup: "create a page with some properties"
    def pageProperties = ["sling:resourceType": "foundation/components/page",
        "jcr:description": "Prosper is an integration testing library for AEM."]

    pageBuilder.content {
        prosper("Prosper") {
            "jcr:content"(pageProperties)
        }
    }

    expect: "page is created and properties match expected values"
    session.nodeExists("/content/prosper")
    && session.getNode("/content/prosper").primaryNodeType.name == NameConstants.NT_PAGE
    && session.getNode("/content/prosper").hasNode(JcrConstants.JCR_CONTENT)
    && pageProperties.every { name, value ->
        session.getNode("/content/prosper").getNode(JcrConstants.JCR_CONTENT).get(name) == value
    }
}

Thankfully, the expect block can be simplified using an assertion method from the base ProsperSpec.

expect: "page is created and properties match expected values"
assertPageExists("/content/prosper", pageProperties)

All available assert... methods are detailed in the Prosper GroovyDocs.

Mocking Requests and Responses

Testing servlets and request-scoped supporting classes require mocking the SlingHttpServletRequest and SlingHttpServletResponse objects. The RequestBuilder and ResponseBuilder instances acquired through the base spec leverage Groovy closures to set the necessary properties and state on these mock objects with a minimal amount of initialization code.

Given a Sling servlet:

import groovy.json.JsonBuilder
import org.apache.sling.api.SlingHttpServletRequest
import org.apache.sling.api.SlingHttpServletResponse
import org.apache.sling.api.servlets.SlingAllMethodsServlet

import javax.jcr.Session
import javax.servlet.ServletException

import static com.google.common.base.Preconditions.checkNotNull

class TestServlet extends SlingAllMethodsServlet {

    @Override
    protected void doPost(SlingHttpServletRequest request,
        SlingHttpServletResponse response) throws ServletException, IOException {
        def path = checkNotNull(request.getParameter("path"))
        def selector = request.requestPathInfo.selectors[1]

        def session = request.resourceResolver.adaptTo(Session)

        def node = session.getNode(path)

        node.setProperty("testProperty", selector)

        session.save()

        new JsonBuilder([path: path, value: selector]).writeTo(response.writer)
    }
}

A Prosper specification for this servlet will use the request and response builders to create the necessary method arguments to simulate a POST request to the servlet and verify both the JCR content updates and the JSON output resulting from the servlet execution.

class ServletSpec extends ProsperSpec {

    def setupSpec() {
        nodeBuilder.content {
            prosper()
        }
    }

    def "missing request parameter throws exception"() {
        setup:
        def servlet = new TestServlet()

        // requestBuilder and responseBuilder are inherited from the base spec
        def request = requestBuilder.build()
        def response = responseBuilder.build()

        when:
        servlet.doPost(request, response)

        then:
        thrown(NullPointerException)
    }

    def "valid request parameter sets node property and returns JSON response"() {
        setup:
        def servlet = new TestServlet()

        def request = requestBuilder.build {
            parameterMap = [path: "/content/prosper"]
            selectors = ["one", "two"]
            contentType = "application/json"
        }

        def response = responseBuilder.build()

        when:
        servlet.doPost(request, response)

        then:
        assertNodeExists("/content/prosper", [testProperty: "two"])

        and:
        response.outputAsString == '{"path":"/content/prosper","value":"two"}'
    }
}

The mock request and response objects delegate to the MockSlingHttpServletRequest and MockSlingHttpServletResponse objects from the Sling Mocks framework. The setter methods exposed by these classes are thus made available in the build closures for the request and response builders to assist in setting appropriate mock values for the class under test.

Sling Context

See the Groovydoc for complete details of the available service registration and additional context methods; specific Sling adaptable examples are provided below.

AEM Context Builder

Override the getAemContext() method in a test specification to supply a custom Resource Resolver configuration or add context callbacks using the wcm.io AemContextBuilder.

class CustomContextSpec extends ProsperSpec {

    @Override
    AemContext getAemContext() {
        new AemContextBuilder(ResourceResolverType.JCR_OAK)
            .beforeSetUp(new AemContextCallback() {
                @Override
                void execute(AemContext context) throws Exception {
                    context.registerService(new CustomService())
                }
            })
            .resourceResolverFactoryActivatorProps(["resource.resolver.mapping": ["/content/:/", "/-/"] as String[]])
            .build()
    }

    def "test"() {
        
    }
}

OSGi Services

OSGi services can be mocked (fully or partially) using Spock's mocking API. Real service objects can also be used if all required dependency services are registered in the Sling context.

import com.day.cq.replication.ReplicationActionType
import com.day.cq.replication.ReplicationException
import com.day.cq.replication.Replicator
import groovy.util.logging.Slf4j
import org.apache.felix.scr.annotations.Reference
import org.apache.felix.scr.annotations.sling.SlingServlet
import org.apache.sling.api.SlingHttpServletRequest
import org.apache.sling.api.SlingHttpServletResponse

import javax.jcr.Session
import javax.servlet.ServletException

@SlingServlet(paths = "/bin/replicate/custom")
@Slf4j("LOG")
class CustomReplicationServlet extends SlingAllMethodsServlet {

    @Reference
    Replicator replicator

    @Override
    protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws
        ServletException, IOException {
        def path = request.getParameter("path")
        def session = request.resourceResolver.adaptTo(Session)

        try {
            replicator.replicate(session, ReplicationActionType.ACTIVATE, path)
        } catch (ReplicationException e) {
            LOG.error("replication error", e)
        }
    }
}

The Prosper specification for this servlet can then set a mocked Replicator instance and verify the expected interactions using the Spock syntax. Alternatively, services can inject other service references using the slingContext.registerInjectActivateService methods.

def "servlet with mock service"() {
    setup:
    def servlet = new CustomReplicationServlet()
    def replicator = Mock(Replicator)

    slingContext.registerService(Replicator, replicator)
    slingContext.registerInjectActivateService(servlet)

    def request = requestBuilder.build {
        parameters = [path: "/content"]
    }

    def response = responseBuilder.build()

    when:
    servlet.doPost(request, response)

    then:
    1 * replicator.replicate(_, _, "/content")
}

Registering Adapters

Specs can register adapters in the Sling context by adding AdapterFactory instances or by providing mappings from adapter instances to closures that instantiate these instances from a Resource, ResourceResolver or SlingHttpRequestServlet. Adapters will be registered with the mock BundleContext and their adaptables and adapters properties will be respected when an adapter is chosen. Registered AdapterFactory instances will pull these properties from the XML metadata files located in the classpath at /OSGI-INF, or the adaptable/adapter properites can be explicitly specified in the method arguments. Registered adapter closures will use the Resource, ResourceResolver or SlingHttpRequestServlet as the adaptables property and the adapter instance class as the adapters property. The methods for registering adapters are illustrated in the examples below.

class ExampleAdapterFactory implements AdapterFactory {

    @Override
    <AdapterType> AdapterType getAdapter(Object adaptable, Class<AdapterType> type) {
        AdapterType result = null

        if (type == String) {
            if (adaptable instanceof ResourceResolver) {
                result = "Hello."
            } else if (adaptable instanceof Resource) {
                result = "Goodbye."
            }
        }

        result
    }
}

class ExampleSpec extends ProsperSpec {

    def setupSpec() {
        // example adapter factory
        slingContext.registerAdapterFactory(new ExampleAdapterFactory(),
            ["org.apache.sling.api.resource.ResourceResolver", "org.apache.sling.api.resource.Resource"] as String[],
            ["java.lang.String"] as String[])

        // resource adapters
        slingContext.registerResourceAdapter(Integer, { Resource resource ->
            resource.name.length()
        })
        slingContext.registerResourceAdapter(Map, { Resource resource ->
            resource.metadata
        })

        // resource resolver adapters
        slingContext.registerResourceResolverAdapter(Integer, { ResourceResolver resourceResolver ->
            resourceResolver.searchPath.length
        })
        slingContext.registerResourceResolverAdapter(Node, { ResourceResolver resourceResolver ->
            resourceResolver.getResource("/").adaptTo(Node)
        })

        // request adapters
        slingContext.registerRequestAdapter(Integer, { SlingHttpServletRequest request ->
            request.pathInfo.length()
        })
    }

    def "resource is adaptable to multiple types"() {
        setup:
        def resource = resourceResolver.getResource("/")

        expect:
        resource.adaptTo(type) == result

        where:
        type    | result
        Integer | 0
        Map     | [:]
    }

    def "resource resolver is adaptable to multiple types"() {
        expect:
        resourceResolver.adaptTo(String) == "Hello."
        resourceResolver.adaptTo(Integer) == 0
        resourceResolver.adaptTo(Node).path == "/"
    }

    def "request is adaptable"() {
        expect:
        requestBuilder.build {
            path = "/request/path.html"
        }.adaptTo(Integer) == 18
    }
}

Sling Models

Sling Model classes and injectors can also be registered in the Sling context for use in tests. The addModelsForPackage method from the SlingContextProvider scans the given package for classes annotated with @org.apache.sling.models.annotations.Model and registers them in the mock bundle context, while the registerInjector allows for registration of custom Sling injectors. A model instance can then be acquired by adapting from a Sling resource or request as shown below.

package com.icfolson.aem.prosper

import org.apache.sling.models.annotations.Model
import org.apache.sling.models.annotations.injectorspecific.Self

@Model(adaptables = [Resource, SlingHttpServletRequest])
class ProsperModel {

    @Self
    Resource resource

    String getPath() {
        resource.path
    }
}
class ProsperModelSpec extends ProsperSpec {

    def setupSpec() {
        pageBuilder.content {
            prosper()
        }
    }

    def "adapt resource to model"() {
        setup:
        slingContext.addModelsForPackage("com.icfolson.aem.prosper")

        def resource = getResource("/content/prosper")
        def model = resource.adaptTo(ProsperModel)

        expect:
        model.path == "/content/prosper"
    }
}

Adding JCR Namespaces and Node Types

Many of the common AEM, JCR, and Sling namespaces and node types are registered when the Prosper test repository is created. Additional namespaces and node types may be added at runtime by annotating a test spec with the @NodeTypes annotation and supplying an array containing paths to classpath .cnd file resources. For more information on the CND node type notation, see Node Type Notation in the Apache Jackrabbit documentation. An example of the annotation usage is presented below.

import com.icfolson.aem.prosper.annotations.NodeTypes

@NodeTypes("SLING-INF/nodetypes/spock.cnd")
class ExampleSpec extends ProsperSpec {

}

Traits

Traits are a Groovy language feature that can be utilized to "mix in" new functionality to test specs. Custom traits can be defined to support domain-specific features.

import com.icfolson.aem.prosper.builders.RequestBuilder
import org.apache.sling.api.SlingHttpServletRequest

trait MobileRequestTrait {

    abstract RequestBuilder getRequestBuilder()

    SlingHttpServletRequest buildMobileRequest(Map<String, Object> parameters) {
        requestBuilder.setSelectors(["mobile"]).setParameterMap(parameters).build()
    }
}

Specs can then implement the trait to add the new functionality. Note that the getRequestBuilder() abstract method does not have to be implemented by the new spec, since this spec (as seen below) already inherits the required method from ProsperSpec. Traits can thus "borrow" functionality from the base ProsperSpec by defining abstract methods that match the corresponding method signatures in ProsperSpec.

import spock.lang.Shared

class MobileRequestTraitSpec extends ProsperSpec implements MobileRequestTrait {

    def "trait usage"() {
        setup:
        def request = buildMobileRequest([:])

        expect:
        request.requestPathInfo.selectors[0] == "mobile"
    }
}

References

Versioning

Follows Semantic Versioning guidelines.

prosper's People

Contributors

bryanw avatar markdaugherty avatar pmichelotti avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

prosper's Issues

Unable to initialize JCR_OAK resource resolver factory

Hello,

We are looking at integrating Prosper testing into an existing AEM 6.1 project, but are having some trouble with getting the initial basic test to work.

Initially, after adding Prosper as a test-scoped dependency, we were getting errors with other classes that use the Sling API, so I added an exclusion for the transitive Sling API dependency on the Prosper node in our pom.xml. Now the compiler is able to resolve all the dependencies and compile successfully, but when running the test you suggest in the README.md I get an error excerpted here: com.gerardvh.prosper.ExampleSpec: Unable to initialize JCR_OAK resource resolver factory: Unable to invoke method 'activate' for class org.apache.sling.testing.mock.sling.oak.OakMockSlingRepository. (Full error from surefire available here.)

It's possible there is another dependency conflict with our existing setup, or perhaps something else, but I hoped you might be able to offer some advice to try and resolve the issue. We currently use the AEM 6.1 obfuscated API's and I wonder if there is something conflicting there that we cannot see. In case it's useful I also did a dependency tree analysis that you can see here.

Thanks for your time.

Error in 6.3: Unable to initialize JCR_OAK resource resolver factory

After we upgraded to AEM 6.3.3.2 and updated Prosper version to 14.0.0 (as recommended), we are getting following error in our unit test cases which were earlier working fine in AEM 6.2/Prosper 11.0.0

java.lang.RuntimeException: Unable to initialize JCR_OAK resource resolver factory: Unable to invoke method 'activate' for class org.apache.sling.testing.mock.sling.oak.OakMockSlingRepository at org.apache.sling.testing.mock.sling.context.ContextResourceResolverFactory.get(ContextResourceResolverFactory.java:66) at org.apache.sling.testing.mock.sling.context.SlingContextImpl.newResourceResolverFactory(SlingContextImpl.java:125) at org.apache.sling.testing.mock.sling.context.SlingContextImpl.resourceResolverFactory(SlingContextImpl.java:130) at org.apache.sling.testing.mock.sling.context.SlingContextImpl.setUp(SlingContextImpl.java:114) at org.apache.sling.testing.mock.sling.junit.SlingContext.access$100(SlingContext.java:40) at org.apache.sling.testing.mock.sling.junit.SlingContext$1.before(SlingContext.java:127) at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:46) at org.spockframework.runtime.extension.builtin.ClassRuleInterceptor.intercept(ClassRuleInterceptor.java:39) at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:97) at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:365) at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:273) at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238) at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:159) at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:383) at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:344) at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:125) at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:417) Caused by: java.lang.RuntimeException: Unable to invoke method 'activate' for class org.apache.sling.testing.mock.sling.oak.OakMockSlingRepository at org.apache.sling.testing.mock.osgi.OsgiServiceUtil.invokeMethod(OsgiServiceUtil.java:320) at org.apache.sling.testing.mock.osgi.OsgiServiceUtil.invokeLifecycleMethod(OsgiServiceUtil.java:149) at org.apache.sling.testing.mock.osgi.OsgiServiceUtil.activateDeactivate(OsgiServiceUtil.java:84) at org.apache.sling.testing.mock.osgi.MockOsgi.activate(MockOsgi.java:171) at org.apache.sling.testing.mock.sling.ResourceResolverFactoryInitializer.registerServiceIfNotPresent(ResourceResolverFactoryInitializer.java:165) at org.apache.sling.testing.mock.sling.ResourceResolverFactoryInitializer.registerServiceIfNotPresent(ResourceResolverFactoryInitializer.java:150) at org.apache.sling.testing.mock.sling.ResourceResolverFactoryInitializer.setUp(ResourceResolverFactoryInitializer.java:61) at org.apache.sling.testing.mock.sling.MockSling.newResourceResolverFactory(MockSling.java:75) at org.apache.sling.testing.mock.sling.context.ContextResourceResolverFactory.get(ContextResourceResolverFactory.java:45) ... 16 more Caused by: java.lang.NoClassDefFoundError: org/apache/jackrabbit/oak/plugins/document/bundlor/BundlingConfigInitializer at org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent.initialize(InitialContent.java:88) at org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent.createInitialContent(InitialContent.java:61) at org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent.<clinit>(InitialContent.java:57) at org.apache.jackrabbit.oak.jcr.Jcr.<init>(Jcr.java:114) at org.apache.jackrabbit.oak.jcr.Jcr.<init>(Jcr.java:141) at org.apache.sling.testing.mock.sling.oak.OakMockSlingRepository.activate(OakMockSlingRepository.java:73) at org.apache.sling.testing.mock.osgi.OsgiServiceUtil.invokeMethod(OsgiServiceUtil.java:311) ... 24 more Caused by: java.lang.ClassNotFoundException: org.apache.jackrabbit.oak.plugins.document.bundlor.BundlingConfigInitializer at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ... 31 more

Sling Only Version

Is there a way one go about using this on Apache Sling (9+) without AEM?

Issue configuring Prosper

I have modified to include dependencies mentioned in the README.. When running tests, I am getting following error:
ExampleSpec Time elapsed: 1.395 sec <<< ERROR!
java.lang.NoClassDefFoundError: org/slf4j/helpers/NOPLoggerFactory
Caused by: java.lang.ClassNotFoundException: org.slf4j.helpers.NOPLoggerFactory

ExampleSpec Time elapsed: 1.396 sec <<< ERROR!
java.lang.NoClassDefFoundError: Could not initialize class com.icfolson.aem.groovy.extension.metaclass.GroovyExtensionMetaClassRegistry

Propser Example described is not working and throwing maven exceptions

After downloading the existing code and followed the confluence to run the code .I ran into the issue listed below , tried to sort the issues but not able to get any solution.Please help.

`Running com.icfolson.aem.prosper.annotations.ModelSpecAnnotationSpec
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 1.497 sec <<< FAILURE! - in com.icfolson.aem.prosper.annotations.ModelSpecAnnotationSpec
com.icfolson.aem.prosper.annotations.ModelSpecAnnotationSpec Time elapsed: 1.496 sec <<< ERROR!
java.lang.NoClassDefFoundError: org/apache/sling/models/impl/ModelAdapterFactory
Caused by: java.lang.ClassNotFoundException: org.apache.sling.models.impl.ModelAdapterFactory

Running com.icfolson.aem.prosper.builders.RequestBuilderSpec
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.327 sec <<< FAILURE! - in com.icfolson.aem.prosper.builders.RequestBuilderSpec
com.icfolson.aem.prosper.builders.RequestBuilderSpec Time elapsed: 0.327 sec <<< ERROR!
java.lang.NoClassDefFoundError: org/apache/sling/models/impl/ModelAdapterFactory

Running com.icfolson.aem.prosper.builders.ResponseBuilderSpec
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.265 sec <<< FAILURE! - in com.icfolson.aem.prosper.builders.ResponseBuilderSpec
com.icfolson.aem.prosper.builders.ResponseBuilderSpec Time elapsed: 0.264 sec <<< ERROR!
java.lang.NoClassDefFoundError: org/apache/sling/models/impl/ModelAdapterFactory`

Building Content with Binary Data

I am testing an OSGI Service, which returns an image path given a page resource.

Here is the setup

//Case 4 Image from pages parsys
    def "Path for Image from inside page content"() {
        setup:
        def imageFile = new File("src/test/resources", "thumbnail.jpg")
pageBuilder.content {
    'subpage-upload' {
        'jcr:content' { par {
            'image' ("sling:resourceType": "wcm/foundation/components/image")
                    { 'file' { 'jcr:content'("jcr:data": imageFile.bytes ) } }
        }
        }
    }
    'subpage-file-reference' {
        'jcr:content' { par {
            'image' ("fileReference": "/content/dam/um-lsa.jpg",
                    "sling:resourceType": "wcm/foundation/components/image")
        }
        }
    }

    'dam' { 'um-lsa.jpg' {} }
}

It gives an error when setting { 'file' { 'jcr:content'("jcr:data": imageFile.bytes ) } }

groovy.lang.MissingMethodException: No signature of method:services.osgi.services.ImageServiceSpec.jcr:content() is applicable for argument types: (java.util.LinkedHashMap) values: [[jcr:data:[-119, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, ...]]]

at services.osgi.services.ImageServiceSpec$__spock_feature_1_7_closure8$_closure58$_closure61$_closure62.closure63$_closure64(ImageServiceSpec.groovy:218)
at services.osgi.services.ImageServiceSpec$__spock_feature_1_7_closure8$_closure58$_closure61$_closure62.closure63$_closure64(ImageServiceSpec.groovy)
at groovy.lang.Closure.call(Closure.java:414)
at groovy.lang.Closure.call(Closure.java:408)
at groovy.util.BuilderSupport.doInvokeMethod(BuilderSupport.java:147)
at groovy.util.BuilderSupport.invokeMethod(BuilderSupport.java:67)
at services.osgi.services.ImageServiceSpec$__spock_feature_1_7_closure8$_closure58$_closure61.closure62$_closure63(ImageServiceSpec.groovy:218)
at services.osgi.services.ImageServiceSpec$__spock_feature_1_7_closure8$_closure58$_closure61.closure62$_closure63(ImageServiceSpec.groovy)
at groovy.lang.Closure.call(Closure.java:414)
at groovy.lang.Closure.call(Closure.java:408)
at groovy.util.BuilderSupport.doInvokeMethod(BuilderSupport.java:147)
at groovy.util.BuilderSupport.invokeMethod(BuilderSupport.java:67)
at services.osgi.services.ImageServiceSpec$__spock_feature_1_7_closure8$_closure58.closure61$_closure62(ImageServiceSpec.groovy:217)
at services.osgi.services.ImageServiceSpec$__spock_feature_1_7_closure8$_closure58.closure61$_closure62(ImageServiceSpec.groovy)
at groovy.lang.Closure.call(Closure.java:414)
at groovy.lang.Closure.call(Closure.java:408)
at groovy.util.BuilderSupport.doInvokeMethod(BuilderSupport.java:147)
at groovy.util.BuilderSupport.invokeMethod(BuilderSupport.java:67)
at services.osgi.services.ImageServiceSpec$__spock_feature_1_7_closure8.closure58$_closure61(ImageServiceSpec.groovy:216)
at services.osgi.services.ImageServiceSpec$__spock_feature_1_7_closure8.closure58$_closure61(ImageServiceSpec.groovy)
at groovy.lang.Closure.call(Closure.java:414)
at groovy.lang.Closure.call(Closure.java:408)
at groovy.util.BuilderSupport.doInvokeMethod(BuilderSupport.java:147)
at groovy.util.BuilderSupport.invokeMethod(BuilderSupport.java:67)
at services.osgi.services.ImageServiceSpec.$spock_feature_1_7_closure8$_closure58(ImageServiceSpec.groovy:216)
at services.osgi.services.ImageServiceSpec.$spock_feature_1_7_closure8$_closure58(ImageServiceSpec.groovy)
at groovy.lang.Closure.call(Closure.java:414)
at groovy.lang.Closure.call(Closure.java:408)
at groovy.util.BuilderSupport.doInvokeMethod(BuilderSupport.java:147)
at groovy.util.BuilderSupport.invokeMethod(BuilderSupport.java:67)
at services.osgi.services.ImageServiceSpec.Path for Image from inside page content_closure8(ImageServiceSpec.groovy:215)
at services.osgi.services.ImageServiceSpec.Path for Image from inside page content_closure8(ImageServiceSpec.groovy)
at groovy.lang.Closure.call(Closure.java:414)
at groovy.lang.Closure.call(Closure.java:408)
at groovy.util.BuilderSupport.doInvokeMethod(BuilderSupport.java:147)
at groovy.util.BuilderSupport.invokeMethod(BuilderSupport.java:67)
at services.osgi.services.ImageServiceSpec.Path for Image from inside page content(ImageServiceSpec.groovy:214)

Do you have any advice for building Spock test JCR data that would simulate an image resource with binary data under the page or fileReference from the DAM?
Screen Shot 2019-09-23 at 11 27 30 AM

Unable to create page with PageManager

I need to test programmatic page creation, but unfortunately this line is causing problems with Prosper:

pageManager.create("/content/path/to/parent", "pagename", "/apps/example/templates/page", "title");

It triggers a VerifyError:
java.lang.VerifyError: (class: com/day/text/Text, method: <init> signature: ()V) Constructor must call super() or this()

I'm using the AEM6.2 obfuscated Uberjar and Prosper 8.1.1. I've tried moving this line directly from my class into the test case, and still get this error.

Is this fixable in Propser or is it a fault in my project? Information online about this Error is scant, and mostly points to tests where real objects and mocks are interchanged, and as the test now only contains this line I'm not sure if there's anything left for me to remove! Any help would be appreciated.

Prosper Tests in AEM6.4

Hello

I am studying an upgrade from AEM 6.3 to AEM 6.4. We have some Prosper specs set up for testing various parts of our project. Previously we used Prosper version 7.0.1 which I have updated to 12.1.0. Unfortunately the tests have errors. I have gone thru our specs and updated the package name, but still getting errors. Could you please look at the error below? Any suggestions would be most appreciated.

-------------------------------------------------------------------------------
Test set: edu.umich.lsa.services.osgi.common.ResourceCategorySpec
-------------------------------------------------------------------------------
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 2.924 sec <<< FAILURE!
edu.umich.lsa.services.osgi.common.ResourceCategorySpec  Time elapsed: 2.918 sec  <<< ERROR!
java.lang.RuntimeException: Unable to invoke method 'bindImplementationPicker' for class org.apache.sling.models.impl.ModelAdapterFactory
	at org.apache.sling.testing.mock.osgi.OsgiServiceUtil.invokeMethod(OsgiServiceUtil.java:320)
	at org.apache.sling.testing.mock.osgi.OsgiServiceUtil.invokeBindUnbindMethod(OsgiServiceUtil.java:458)
	at org.apache.sling.testing.mock.osgi.OsgiServiceUtil.invokeBindMethod(OsgiServiceUtil.java:583)
	at org.apache.sling.testing.mock.osgi.MockBundleContext.handleRefsUpdateOnRegister(MockBundleContext.java:153)
	at org.apache.sling.testing.mock.osgi.MockBundleContext.registerService(MockBundleContext.java:123)
	at org.apache.sling.testing.mock.osgi.MockBundleContext.registerService(MockBundleContext.java:108)
	at org.apache.sling.testing.mock.osgi.context.OsgiContextImpl.registerService(OsgiContextImpl.java:117)
	at org.apache.sling.testing.mock.osgi.context.OsgiContextImpl.registerInjectActivateService(OsgiContextImpl.java:155)
	at org.apache.sling.testing.mock.osgi.context.OsgiContextImpl.registerInjectActivateService(OsgiContextImpl.java:141)
	at org.apache.sling.testing.mock.sling.context.SlingContextImpl.registerInjectActivateServiceByClassName(SlingContextImpl.java:175)
	at org.apache.sling.testing.mock.sling.context.SlingContextImpl.registerDefaultServices(SlingContextImpl.java:146)
	at org.apache.sling.testing.mock.sling.context.SlingContextImpl.setUp(SlingContextImpl.java:117)
	at org.apache.sling.testing.mock.sling.junit.SlingContext.access$100(SlingContext.java:40)
	at org.apache.sling.testing.mock.sling.junit.SlingContext$1.before(SlingContext.java:127)
	at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:46)
	at org.spockframework.runtime.extension.builtin.ClassRuleInterceptor.intercept(ClassRuleInterceptor.java:38)
	at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:87)
	at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:236)
	at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:134)
	at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:113)
	at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
	at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
	at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
	at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:103)
	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:74)
Caused by: java.lang.NoSuchMethodError: org.apache.sling.commons.osgi.ServiceUtil.getComparableForServiceRanking(Ljava/util/Map;Lorg/apache/sling/commons/osgi/Order;)Ljava/lang/Comparable;
	at org.apache.sling.commons.osgi.RankedServices.bind(RankedServices.java:126)
	at org.apache.sling.models.impl.ModelAdapterFactory.bindImplementationPicker(ModelAdapterFactory.java:973)
	at org.apache.sling.testing.mock.osgi.OsgiServiceUtil.invokeMethod(OsgiServiceUtil.java:311)
	... 24 more

groovy.lang.GroovyRuntimeException: Could not find matching constructor for: org.apache.sling.jcr.resource.internal.helper.jcr.JcrResourceProvider(org.apache.jackrabbit.core.XASessionImpl, null, null)

I'm having an issue running a basic ProsperSpec with version 0.12.0. Here's my spec:

package my.prosper.test.package
import com.citytechinc.aem.prosper.specs.ProsperSpec
class ProsperTest extends ProsperSpec {
    def "test"() {
        expect:
        1 == 1
    }
}

and here's the output (including the error) that I get:

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/Users/162423/.m2/repository/org/slf4j/slf4j-simple/1.5.2/slf4j-simple-1.5.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/Users/162423/.m2/repository/org/slf4j/slf4j-nop/1.6.4/slf4j-nop-1.6.4.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
544 [main] INFO org.apache.jackrabbit.core.RepositoryImpl - Starting repository...
552 [main] INFO org.apache.jackrabbit.core.fs.local.LocalFileSystem - LocalFileSystem initialized at path C:\ws\wcm-platform-camd-digital-on-air\bundle\target\repository\repository
1070 [main] INFO org.apache.jackrabbit.core.fs.local.LocalFileSystem - LocalFileSystem initialized at path C:\ws\wcm-platform-camd-digital-on-air\bundle\target\repository\version
3750 [main] INFO org.apache.jackrabbit.core.RepositoryImpl - initializing workspace 'default'...
3751 [main] INFO org.apache.jackrabbit.core.fs.local.LocalFileSystem - LocalFileSystem initialized at path C:\ws\wcm-platform-camd-digital-on-air\bundle\target\repository\workspaces\default
5859 [main] INFO org.apache.jackrabbit.core.query.lucene.SearchIndex - Index initialized: C:\ws\wcm-platform-camd-digital-on-air\bundle\target\repository/repository/index Version: 3
5930 [main] INFO org.apache.jackrabbit.core.query.lucene.SearchIndex - Index initialized: C:\ws\wcm-platform-camd-digital-on-air\bundle\target\repository\workspaces\default/index Version: 3
5932 [main] INFO org.apache.jackrabbit.core.RepositoryImpl - workspace 'default' initialized
5955 [main] INFO org.apache.jackrabbit.core.RepositoryImpl - SecurityManager = class org.apache.jackrabbit.core.DefaultSecurityManager
5956 [main] INFO org.apache.jackrabbit.core.RepositoryImpl - initializing workspace 'security'...
5958 [main] INFO org.apache.jackrabbit.core.fs.local.LocalFileSystem - LocalFileSystem initialized at path C:\ws\wcm-platform-camd-digital-on-air\bundle\target\repository\workspaces\security
6235 [main] INFO org.apache.jackrabbit.core.query.lucene.SearchIndex - Index initialized: C:\ws\wcm-platform-camd-digital-on-air\bundle\target\repository\workspaces\security/index Version: 3
6236 [main] INFO org.apache.jackrabbit.core.RepositoryImpl - workspace 'security' initialized
6238 [main] INFO org.apache.jackrabbit.core.DefaultSecurityManager - init: use Repository Login-Configuration for Jackrabbit
6353 [main] INFO org.apache.jackrabbit.core.RepositoryImpl - Repository started (5809ms)
6354 [main] INFO org.apache.jackrabbit.core.TransientRepository - Transient repository initialized
6541 [main] INFO org.apache.jackrabbit.core.TransientRepository - Session opened
6684 [main] INFO org.apache.jackrabbit.core.TransientRepository - Session opened
7698 [main] INFO org.apache.jackrabbit.core.TransientRepository - Session closed
7712 [main] INFO org.apache.jackrabbit.core.TransientRepository - Session opened
7729 [main] INFO org.apache.jackrabbit.core.TransientRepository - Session opened
7778 [main] INFO org.apache.jackrabbit.core.TransientRepository - Session closed

groovy.lang.GroovyRuntimeException: Could not find matching constructor for: org.apache.sling.jcr.resource.internal.helper.jcr.JcrResourceProvider(org.apache.jackrabbit.core.XASessionImpl, null, null)
    at com.citytechinc.aem.prosper.mocks.resource.MockResourceResolver.<init>(MockResourceResolver.groovy:32)
    at com.citytechinc.aem.prosper.specs.ProsperSpec.setupSpec(ProsperSpec.groovy:68)

8272 [main] INFO org.apache.jackrabbit.core.TransientRepository - Session closed
8280 [Thread-4] INFO org.apache.jackrabbit.core.TransientRepository - Session closed
8280 [Thread-4] INFO org.apache.jackrabbit.core.RepositoryImpl - Shutting down repository...
8287 [Thread-4] INFO org.apache.jackrabbit.core.query.lucene.SearchIndex - Index closed: C:\ws\wcm-platform-camd-digital-on-air\bundle\target\repository/repository/index
8287 [Thread-4] INFO org.apache.jackrabbit.core.RepositoryImpl - shutting down workspace 'default'...
8288 [Thread-4] INFO org.apache.jackrabbit.core.observation.ObservationDispatcher - Notification of EventListeners stopped.
8291 [Thread-4] INFO org.apache.jackrabbit.core.query.lucene.SearchIndex - Index closed: C:\ws\wcm-platform-camd-digital-on-air\bundle\target\repository\workspaces\default/index
8353 [Thread-4] INFO org.apache.jackrabbit.core.util.db.DerbyConnectionHelper - Database 'C:\ws\wcm-platform-camd-digital-on-air\bundle\target\repository\workspaces\default/db' shutdown.
8361 [Thread-4] INFO org.apache.jackrabbit.core.RepositoryImpl - workspace 'default' has been shutdown
8361 [Thread-4] INFO org.apache.jackrabbit.core.RepositoryImpl - shutting down workspace 'security'...
8361 [Thread-4] INFO org.apache.jackrabbit.core.observation.ObservationDispatcher - Notification of EventListeners stopped.
8364 [Thread-4] INFO org.apache.jackrabbit.core.query.lucene.SearchIndex - Index closed: C:\ws\wcm-platform-camd-digital-on-air\bundle\target\repository\workspaces\security/index
8407 [Thread-4] INFO org.apache.jackrabbit.core.util.db.DerbyConnectionHelper - Database 'C:\ws\wcm-platform-camd-digital-on-air\bundle\target\repository\workspaces\security/db' shutdown.
8408 [Thread-4] INFO org.apache.jackrabbit.core.RepositoryImpl - workspace 'security' has been shutdown
8449 [Thread-4] INFO org.apache.jackrabbit.core.util.db.DerbyConnectionHelper - Database 'C:\ws\wcm-platform-camd-digital-on-air\bundle\target\repository/version/db' shutdown.
8489 [Thread-4] INFO org.apache.jackrabbit.core.RepositoryImpl - Repository has been shutdown
8490 [Thread-4] INFO org.apache.jackrabbit.core.TransientRepository - Transient repository shut down

Code Coverage Report

Team,
I am able to successfully create groovy test cases using prosper but i am not able to run any code coverage tool on it to find the coverage depth.Can anyone throw some light on it,please. Corbutra or clover or sonarqube is not able to detect groovy test cases extending Prosper.

Tags mocking isssue | AEM 6.5 | JAVA 11

We have upgraded from AEM 6.3(JAVA 8) to AEM 6.5(JAVA 11). After upgrade, unit test cases related to tags stopped working.

Can you please let us know how to mock tags with AEM 6.5(JAVA11)?

nodeBuilder.content {
cq:tags("sling:Folder") {
fruit("cq:Tag") {
apple() {
"red"("cq:Tag", "jcr:title": "Red")
"green"("cq:Tag", "jcr:title": "Green")
}
}
}
}

nodeBuilder.etc{
tags("sling:Folder") {
fruit("cq:Tag") {
apple() {
"red"("cq:Tag", "jcr:title": "Red")
"green"("cq:Tag", "jcr:title": "Green")
}
}
}
}

pageDecorator.getAbsoluteParent() throwing null pointer

When i'm trying to test a method that uses pageDecorator.getAbsoluteParent(), the test fails throwing a null pointer exception. When i checked the AEM library code's test classes for page decorator, they've used page.getAbsoluteParent() which works perfectly fine. (Not sure how the tests were passed)

Here is the content:-

def setupSpec() {
		pageBuilder.content {
			xyz{blueprint{en{abc{}}}}}}

Error_-

page.getAbsoluteParent(2) != null
|    |
|    java.lang.NullPointerException: Cannot invoke method getPage() on null object
DefaultPageDecorator{path=/content/xyz/blueprint/en/abc, title=}


	at com.company.aem.utils.UtiliySpec.check page decorator(UtiliySpec.groovy:189)
Caused by: java.lang.NullPointerException: Cannot invoke method getPage() on null object
	at com.icfolson.aem.library.core.page.impl.DefaultPageDecorator.getAbsoluteParent(DefaultPageDecorator.groovy:487)
	... 1 more

Unable to use older versions

Hi,

I want to test my application based that is currently on 5.6(pheww). The version 0.10.0 is not available on central repo anymore. Is there a way I can still use this to test my application?

addModelsForPackage Issue

Hi,

I'm currently experimenting with Prosper, and I have the following issue.
Adapting a resource to a Sling Model is not working, eventhough the following call has been made.

slingContext.addModelsForPackage("be.tutak.jcr.example.entity")

example code

Any ideas ?
Thanks!

Facing issue with Build 11.1.0- ExampleSpec » Runtime Unable to initialize JCR_...

When i try to write test case by using latest propser 11.1.0 , i am getting ExampleSpec » Runtime Unable to initialize JCR_... exception
<<< ERROR!
java.lang.RuntimeException: Unable to initialize JCR_OAK resource resolver factory: Unable to invoke method 'activate' for class org.apache.sling.testing.mock.sling.oak.OakMockSlingRepository
at org.apache.sling.testing.mock.sling.context.ContextResourceResolverFactory.get(ContextResourceResolverFactory.java:66)
at org.apache.sling.testing.mock.sling.context.SlingContextImpl.newResourceResolverFactory(SlingContextImpl.java:125)
at org.apache.sling.testing.mock.sling.context.SlingContextImpl.resourceResolverFactory(SlingContextImpl.java:130)
at org.apache.sling.testing.mock.sling.context.SlingContextImpl.setUp(SlingContextImpl.java:114)
at org.apache.sling.testing.mock.sling.junit.SlingContext.access$100(SlingContext.java:40)
at org.apache.sling.testing.mock.sling.junit.SlingContext$1.before(SlingContext.java:127).

Below are the pom file inclusion i have done as part of my project.Please shed some light on it .
<dependency> <groupId>cglib</groupId> <artifactId>cglib-nodep</artifactId> <version>3.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.testing.sling-mock-oak</artifactId> <version>1.0.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.objenesis</groupId> <artifactId>objenesis</artifactId> <version>2.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.codehaus.groovy</groupId> <artifactId>groovy-all</artifactId> <version>2.4.1</version> </dependency> <dependency> <groupId>org.spockframework</groupId> <artifactId>spock-core</artifactId> <version>1.0-groovy-2.4</version> </dependency> <dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.core</artifactId> </dependency> <dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.compendium</artifactId> </dependency> <dependency> <groupId>com.icfolson.aem.prosper</groupId> <artifactId>prosper</artifactId> <version>11.1.0</version> <scope>test</scope> </dependency>

The Complete Dependency list is given below
<dependencies> <dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.core</artifactId> </dependency> <dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.compendium</artifactId> </dependency> <dependency> <groupId>org.apache.felix</groupId> <artifactId>org.apache.felix.scr.annotations</artifactId> </dependency> <dependency> <groupId>biz.aQute.bnd</groupId> <artifactId>annotation</artifactId> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/commons-collections/commons-collections --> <dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.4.2</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.4.2</version> </dependency> <dependency> <groupId>javax.jcr</groupId> <artifactId>jcr</artifactId> </dependency> <!-- test dependencies --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> <dependency> <groupId>junit-addons</groupId> <artifactId>junit-addons</artifactId> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib-nodep</artifactId> <version>3.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.testing.sling-mock-oak</artifactId> <version>1.0.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.objenesis</groupId> <artifactId>objenesis</artifactId> <version>2.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.codehaus.groovy</groupId> <artifactId>groovy-all</artifactId> <version>2.4.1</version> </dependency> <dependency> <groupId>org.spockframework</groupId> <artifactId>spock-core</artifactId> <version>1.0-groovy-2.4</version> </dependency> <dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.core</artifactId> </dependency> <dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.compendium</artifactId> </dependency> <dependency> <groupId>com.icfolson.aem.prosper</groupId> <artifactId>prosper</artifactId> <version>11.1.0</version> <scope>test</scope> </dependency> <dependency> <groupId>com.adobe.aem</groupId> <artifactId>uber-jar</artifactId> <version>6.2.0</version> <classifier>obfuscated-apis</classifier> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> </dependency> <dependency> <groupId>com.google.code.findbugs</groupId> <artifactId>jsr305</artifactId> </dependency> <dependency> <groupId>com.adobe.acs</groupId> <artifactId>acs-aem-commons-bundle</artifactId> </dependency> <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20160810</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-email</artifactId> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> <version>4.3.2</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.3.4</version> </dependency> <dependency> <groupId>com.google.http-client</groupId> <artifactId>google-http-client</artifactId> <version>1.21.0</version> </dependency> </dependencies>

Sample Empty Class -- import com.icfolson.aem.prosper.specs.ProsperSpec
class ExampleSpec extends ProsperSpec {
def setupSpec() {
// runs before first feature method, create test content and initialize shared resources here
}
}

Prosper fails when we integrate with Jenkins with null pointer

Hi Team,
I am working to integrate Prosper test framework in my company and i already posted few issues i faced as part of it and how i solved it.Here is one more issue,when i run my project in my local using maven, all my test cases run successfully and able to create report as well.But when i run the same branch in Jenkins it fails with the error listed below
***ServiceImplSpec Time elapsed: 3.033 sec <<< ERROR!
java.lang.NullPointerException: null
at org.apache.jackrabbit.vault.fs.io.FileArchive.open(FileArchive.java:62)
at com.icfolson.aem.prosper.importer.ContentImporter.importVaultContent(ContentImporter.groovy:32)
at com.icfolson.aem.prosper.specs.ProsperSpec.importVaultContent(ProsperSpec.groovy:308)
at com.icfolson.aem.prosper.specs.ProsperSpec.setupSpec(ProsperSpec.groovy:70)
Results :
Tests in error:
**ServiceImplSpec>ProsperSpec.setupSpec:70->ProsperSpec.importVaultContent:308 » NullPointer

Any idea why i am getting ProsperSpec.importVaultContent:Nullpointer ?

tagManger.resolve on a pageDecorator page is returning null always

Please see the code below. The tagManager.resolve() is returning null even though the tag data is created.

setup:
		PageDecorator page = new DefaultPageDecorator(pageManager.getPage('/content/company/blueprint/xy/somePage'))
		TagManager tagManager = page.contentResource.resourceResolver.adaptTo(TagManager)
		tagManager.resolve(page.properties.someStringProperty)
		
		expect:
		tagManager.resolve(page.properties.someStringProperty) != null

Content

def setupSpec() {
		pageBuilder.content {
			company {
				blueprint {
					xy {
						somePage ('someStringProperty': 'ehtulhaq:CODE') {
						}
					}
				}
			}
		}
		nodeBuilder.etc {
			tags {
				'ehtulhaq'('sling:resourceType': 'cq/tagging/components/tag') {
					'CODE'('sling:resourceType': 'cq/tagging/components/tag')
				}
			}
		}
	}

Error

tagManager.resolve(page.properties.someStringProperty) != null
|          |       |    |          |                   |
|          null    |    |          ehtulhaq:CODE       false
|                  |    [someStringProperty:ehtulhaq:CODE, jcr:created:java.util.GregorianCalendar[time=1568828252023,areFieldsSet=true,areAllFieldsSet=true,lenient=false,zone=sun.util.calendar.ZoneInfo[id="GMT-04:00",offset=-14400000,dstSavings=0,useDaylight=false,transitions=0,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2019,MONTH=8,WEEK_OF_YEAR=38,WEEK_OF_MONTH=3,DAY_OF_MONTH=18,DAY_OF_YEAR=261,DAY_OF_WEEK=4,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=1,HOUR_OF_DAY=13,MINUTE=37,SECOND=32,MILLISECOND=23,ZONE_OFFSET=-14400000,DST_OFFSET=0], jcr:createdBy:admin, jcr:primaryType:cq:PageContent]
|                  DefaultPageDecorator{path=/content/company/blueprint/xy/somePage, title=}
<io.wcm.testing.mock.aem.MockTagManager@72e295cc resourceResolver=org.apache.sling.resourceresolver.impl.ResourceResolverImpl@37468787 log=org.slf4j.helpers.NOPLogger(NOP)>

Unable to apply mixins using NodeBuilder

I've tried to put mixins on a node using the NodeBuilder, but

javax.jcr.nodetype.ConstraintViolationException: No matching property definition: jcr:primaryType = sling:Folder

I've tried

"jcr:mixinTypes": ["mix:language"]
"jcr:mixinTypes": "[mix:language]"
"jcr:mixinTypes": "mix:language"

None of which work. I should be able to apply a mixin to a Sling Folder node, but it's just won't permit this. Is there a special way to apply mixins, or is this a shortcoming of Prosper?

7.0.0 build is not success

[ERROR] Failed to execute goal on project prosper: Could not resolve dependencies for project com.citytechinc.aem.prosper:prosper:jar:6.1.0: Failed to collect dependencies at com.day.cq:cq-commons:jar:5.8.32: Failed to read artifact descriptor for com.day.cq:cq-commons:jar:5.8.32: Could not transfer artifact com.day.cq:parent:pom:42 from/to adobe (http://repo.adobe.com/nexus/content/groups/public/): hostname in certificate didn't match: <repo.adobe.com> != <devedge.day.com> OR <devedge.day.com> -> [Help 1]
[ERROR]

tried to find parent 42 but not fine in any repo. any help pleae

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.