From 4dd9d7b6c8d6bf1d878b5958c740a3ea87de80e9 Mon Sep 17 00:00:00 2001 From: Jim Moore Date: Thu, 10 Sep 2015 11:51:53 -0600 Subject: [PATCH 1/2] Refactoring Extracted AbstractJcrSpec Added ClientServiceSpec integration test --- README.md | 4 +- build.gradle | 2 + .../server/services/ClientServiceSpec.groovy | 64 +++++++++++++ .../client/batch/ClientBatchJob.groovy | 37 ++++---- .../services/impl/DefaultClientService.groovy | 29 +++--- .../grabbit/servlets/GrabbitServlet.groovy | 8 +- .../client/batch/ClientBatchJobSpec.groovy | 45 ++++----- .../grabbit/jcr/AbstractJcrSpec.groovy | 86 +++++++++++++++++ .../jcrnodes/JcrNodesProcessorSpec.groovy | 95 ++++++------------- gradle.properties | 2 +- 10 files changed, 238 insertions(+), 134 deletions(-) create mode 100644 grabbit/src/integrationTest/groovy/com/twcable/grabbit/server/services/ClientServiceSpec.groovy create mode 100644 grabbit/src/test/groovy/com/twcable/grabbit/jcr/AbstractJcrSpec.groovy diff --git a/README.md b/README.md index 86c67de..e54a3fa 100644 --- a/README.md +++ b/README.md @@ -241,8 +241,8 @@ For the Grabbit developers, [instructions for releasing a new version of Grabbit * [Groovy v2.3.6](http://groovy.codehaus.org/Download) * [Google Protocol Buffers v2.4.1](https://code.google.com/p/protobuf/downloads/list) - The compiler and runtime library is used for Serialization and De-serialization of Data * [Spring Batch v2.2.7.RELEASE](http://docs.spring.io/spring-batch/2.2.x/downloads.html) - It is used on the server and client to read/write, marshal/unmarshall and send/receive the data to client in a controlled manner. -* [Jackalope v2.0.0](https://bintray.com/twcable/aem/jackalope/2.0.0/view) - Jackalope is used for testing -* [CQ Gradle Plugins v2.0.1](https://bintray.com/twcable/aem/cq-gradle-plugins/2.0.1/view) : They provide Gradle build support. +* [Jackalope](https://bintray.com/twcable/aem/jackalope/) - Jackalope is used for testing +* [CQ Gradle Plugins](https://bintray.com/twcable/aem/cq-gradle-plugins/) : They provide Gradle build support. * [Gradle Protocol Buffers Plugin v0.9.1](http://search.maven.org/#artifactdetails%7Cws.antonov.gradle.plugins%7Cgradle-plugin-protobuf%7C0.9.1%7Cjar) - It provides easy integration of the ProtoBuf compiler with Gradle. # LICENSE diff --git a/build.gradle b/build.gradle index e19067c..a4c7d96 100644 --- a/build.gradle +++ b/build.gradle @@ -41,6 +41,8 @@ allprojects { // hack to allow getting to a working version of AEM 6.1 workflow-console jar // without running afoul of licensing restrictions flatDir { dirs rootProject.projectDir } + + mavenLocal() } } diff --git a/grabbit/src/integrationTest/groovy/com/twcable/grabbit/server/services/ClientServiceSpec.groovy b/grabbit/src/integrationTest/groovy/com/twcable/grabbit/server/services/ClientServiceSpec.groovy new file mode 100644 index 0000000..ae8f803 --- /dev/null +++ b/grabbit/src/integrationTest/groovy/com/twcable/grabbit/server/services/ClientServiceSpec.groovy @@ -0,0 +1,64 @@ +/* + * Copyright 2015 Time Warner Cable, Inc. + * + * Licensed 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 com.twcable.grabbit.server.services + +import com.twcable.grabbit.GrabbitConfiguration +import com.twcable.grabbit.client.services.ClientService +import com.twcable.grabbit.client.services.impl.DefaultClientService +import com.twcable.grabbit.jcr.AbstractJcrSpec +import com.twcable.jackalope.impl.sling.SimpleResourceResolverFactory +import com.twcable.jackalope.impl.sling.SlingRepositoryImpl +import org.apache.sling.jcr.api.SlingRepository +import org.springframework.context.ApplicationContext +import org.springframework.context.ConfigurableApplicationContext +import org.springframework.context.support.ClassPathXmlApplicationContext +import org.springframework.context.support.StaticApplicationContext +import spock.lang.Subject + +@Subject(ServerService) +class ClientServiceSpec extends AbstractJcrSpec { + + SlingRepository slingRepository + + ConfigurableApplicationContext appCtx + + ClientService syncClientService + + + def setup() { + slingRepository = new SlingRepositoryImpl() + + ApplicationContext parentAppCtx = new StaticApplicationContext() + parentAppCtx.beanFactory.registerSingleton("slingRepository", slingRepository) + parentAppCtx.beanFactory.registerSingleton("resourceResolverFactory", new SimpleResourceResolverFactory(slingRepository)) + parentAppCtx.refresh() + appCtx = new ClassPathXmlApplicationContext(["META-INF/spring/client-batch-job.xml", "META-INF/spring/client-workflow-on-step.xml", "META-INF/spring/client-workflow-off-step.xml"] as String[], parentAppCtx) + + syncClientService = new DefaultClientService(slingRepository: slingRepository, + applicationContext: appCtx) + } + + + def "Service initiate a grab and return jobs"() { + when: + def jobIds = syncClientService.initiateGrab(new GrabbitConfiguration("admin", "adminPass", "testbox", "4502", false, [new GrabbitConfiguration.PathConfiguration("/content/test", [], [], false)]), "admin") + + then: + jobIds.size() == 1 + } + +} diff --git a/grabbit/src/main/groovy/com/twcable/grabbit/client/batch/ClientBatchJob.groovy b/grabbit/src/main/groovy/com/twcable/grabbit/client/batch/ClientBatchJob.groovy index 1b998fd..d13551c 100644 --- a/grabbit/src/main/groovy/com/twcable/grabbit/client/batch/ClientBatchJob.groovy +++ b/grabbit/src/main/groovy/com/twcable/grabbit/client/batch/ClientBatchJob.groovy @@ -22,7 +22,7 @@ import groovy.util.logging.Slf4j import org.springframework.batch.core.BatchStatus import org.springframework.batch.core.JobExecution import org.springframework.batch.core.launch.JobOperator -import org.springframework.context.ConfigurableApplicationContext +import org.springframework.context.ApplicationContext import javax.annotation.Nonnull @@ -48,7 +48,9 @@ class ClientBatchJob { public static final String CONTENT_AFTER_DATE = "contentAfterDate" public static final String DELETE_BEFORE_WRITE = "deleteBeforeWrite" + @SuppressWarnings("GrFinalVariableAccess") private final Map jobParameters + @SuppressWarnings("GrFinalVariableAccess") private final JobOperator jobOperator @@ -80,12 +82,12 @@ class ClientBatchJob { @CompileStatic static class ServerBuilder { - final ConfigurableApplicationContext configAppContext + final ApplicationContext configAppContext String host String port - ServerBuilder(ConfigurableApplicationContext configurableApplicationContext) { + ServerBuilder(ApplicationContext configurableApplicationContext) { this.configAppContext = configurableApplicationContext } @@ -193,16 +195,16 @@ class ClientBatchJob { ClientBatchJob build() { final jobParameters = [ - "timestamp" : System.currentTimeMillis() as String, - "${PATH}" : pathConfiguration.path, - "${HOST}" : serverBuilder.host, - "${PORT}" : serverBuilder.port, - "${CLIENT_USERNAME}" : credentialsBuilder.clientUsername, - "${SERVER_USERNAME}" : credentialsBuilder.serverUsername, - "${SERVER_PASSWORD}" : credentialsBuilder.serverPassword, - "${EXCLUDE_PATHS}" : pathConfiguration.excludePaths.join("*"), - "${WORKFLOW_CONFIGS}" : pathConfiguration.workflowConfigIds.join("|"), - "${DELETE_BEFORE_WRITE}" : "${pathConfiguration.deleteBeforeWrite}" + timestamp : System.currentTimeMillis() as String, + (PATH) : pathConfiguration.path, + (HOST) : serverBuilder.host, + (PORT) : serverBuilder.port, + (CLIENT_USERNAME) : credentialsBuilder.clientUsername, + (SERVER_USERNAME) : credentialsBuilder.serverUsername, + (SERVER_PASSWORD) : credentialsBuilder.serverPassword, + (EXCLUDE_PATHS) : pathConfiguration.excludePaths.join("*"), + (WORKFLOW_CONFIGS) : pathConfiguration.workflowConfigIds.join("|"), + (DELETE_BEFORE_WRITE): "${pathConfiguration.deleteBeforeWrite}" ] as Map if (deltaContentBuilder.doDeltaContent) { @@ -212,18 +214,15 @@ class ClientBatchJob { if (lastSuccessFulJobExecution) { final contentAfterDate = DateUtil.getISOStringFromDate(lastSuccessFulJobExecution.endTime) log.info "Last Successful run for ${pathConfiguration.path} was on $contentAfterDate" - return new ClientBatchJob( - jobParameters + (["${CONTENT_AFTER_DATE}": contentAfterDate] as Map), - serverBuilder.configAppContext.getBean("clientJobOperator", JobOperator) - ) + jobParameters.put(CONTENT_AFTER_DATE, contentAfterDate) } else { log.warn "There was no successful job run for $pathConfiguration.path. Defaulting to normal content grab" } } return new ClientBatchJob( - jobParameters, - serverBuilder.configAppContext.getBean("clientJobOperator", JobOperator) + jobParameters, + serverBuilder.configAppContext.getBean("clientJobOperator", JobOperator) ) } } diff --git a/grabbit/src/main/groovy/com/twcable/grabbit/client/services/impl/DefaultClientService.groovy b/grabbit/src/main/groovy/com/twcable/grabbit/client/services/impl/DefaultClientService.groovy index 7be2bd6..fee09d3 100644 --- a/grabbit/src/main/groovy/com/twcable/grabbit/client/services/impl/DefaultClientService.groovy +++ b/grabbit/src/main/groovy/com/twcable/grabbit/client/services/impl/DefaultClientService.groovy @@ -22,7 +22,6 @@ import com.twcable.grabbit.client.batch.ClientBatchJob import com.twcable.grabbit.client.services.ClientService import groovy.transform.CompileStatic import groovy.util.logging.Slf4j -import org.apache.felix.scr.annotations.Activate import org.apache.felix.scr.annotations.Component import org.apache.felix.scr.annotations.Reference import org.apache.felix.scr.annotations.Service @@ -30,7 +29,7 @@ import org.apache.sling.jcr.api.SlingRepository import org.springframework.batch.core.JobExecution import org.springframework.batch.core.JobInstance import org.springframework.batch.core.explore.JobExplorer -import org.springframework.context.ConfigurableApplicationContext +import org.springframework.context.ApplicationContext @Slf4j @CompileStatic @@ -44,14 +43,8 @@ class DefaultClientService implements ClientService { @Reference(bind = 'setSlingRepository') SlingRepository slingRepository - @Reference(bind = 'setConfigurableApplicationContext') - ConfigurableApplicationContext configurableApplicationContext - - - @Activate - void activate() { - log.info "Activate\n\n" - } + @Reference(bind = 'setApplicationContext') + ApplicationContext applicationContext @Override @@ -67,13 +60,13 @@ class DefaultClientService implements ClientService { for (PathConfiguration pathConfig : configuration.pathConfigurations) { try { - final clientBatchJob = new ClientBatchJob.ServerBuilder(configurableApplicationContext) - .andServer(configuration.serverHost, configuration.serverPort) - .andCredentials(clientUsername, configuration.serverUsername, configuration.serverPassword) - .andDoDeltaContent(doDeltaContent) - .andClientJobExecutions(clientJobExecutions) - .andConfiguration(pathConfig) - .build() + final clientBatchJob = new ClientBatchJob.ServerBuilder(applicationContext) + .andServer(configuration.serverHost, configuration.serverPort) + .andCredentials(clientUsername, configuration.serverUsername, configuration.serverPassword) + .andDoDeltaContent(doDeltaContent) + .andClientJobExecutions(clientJobExecutions) + .andConfiguration(pathConfig) + .build() final Long currentJobExecutionId = clientBatchJob.start() jobExecutionIds << currentJobExecutionId } @@ -88,7 +81,7 @@ class DefaultClientService implements ClientService { private List fetchAllClientJobExecutions() { - final explorer = configurableApplicationContext.getBean("clientJobExplorer", JobExplorer) + final explorer = applicationContext.getBean("clientJobExplorer", JobExplorer) final instances = explorer.getJobInstances("clientJob", 0, Integer.MAX_VALUE - 1) ?: [] as List final executions = instances.collect { explorer.getJobExecutions(it) }.flatten() as List executions diff --git a/grabbit/src/main/groovy/com/twcable/grabbit/servlets/GrabbitServlet.groovy b/grabbit/src/main/groovy/com/twcable/grabbit/servlets/GrabbitServlet.groovy index fbcf35a..d41fad3 100644 --- a/grabbit/src/main/groovy/com/twcable/grabbit/servlets/GrabbitServlet.groovy +++ b/grabbit/src/main/groovy/com/twcable/grabbit/servlets/GrabbitServlet.groovy @@ -31,7 +31,7 @@ import org.apache.sling.api.SlingHttpServletRequest import org.apache.sling.api.SlingHttpServletResponse import org.apache.sling.api.servlets.SlingAllMethodsServlet import org.springframework.batch.core.explore.JobExplorer -import org.springframework.context.ConfigurableApplicationContext +import org.springframework.context.ApplicationContext import javax.servlet.http.HttpServletResponse @@ -40,8 +40,8 @@ import javax.servlet.http.HttpServletResponse @SlingServlet(methods = ['GET', 'PUT'], resourceTypes = ['twcable:grabbit/job']) class GrabbitServlet extends SlingAllMethodsServlet { - @Reference(bind = 'setConfigurableApplicationContext') - ConfigurableApplicationContext configurableApplicationContext + @Reference(bind = 'setApplicationContext') + ApplicationContext applicationContext @Reference(bind = 'setClientService') ClientService clientService @@ -114,7 +114,7 @@ class GrabbitServlet extends SlingAllMethodsServlet { private String getJsonString(String jobId) { - final JobExplorer jobExplorer = configurableApplicationContext.getBean("clientJobExplorer", JobExplorer) + final JobExplorer jobExplorer = applicationContext.getBean("clientJobExplorer", JobExplorer) if (jobId.isNumber()) { //Returns Status for A Job final ClientJobStatus status = ClientJobStatus.get(jobExplorer, Long.valueOf(jobId)) diff --git a/grabbit/src/test/groovy/com/twcable/grabbit/client/batch/ClientBatchJobSpec.groovy b/grabbit/src/test/groovy/com/twcable/grabbit/client/batch/ClientBatchJobSpec.groovy index e38d10b..787b9dc 100644 --- a/grabbit/src/test/groovy/com/twcable/grabbit/client/batch/ClientBatchJobSpec.groovy +++ b/grabbit/src/test/groovy/com/twcable/grabbit/client/batch/ClientBatchJobSpec.groovy @@ -22,51 +22,46 @@ import org.springframework.batch.core.BatchStatus import org.springframework.batch.core.JobExecution import org.springframework.batch.core.JobParametersBuilder import org.springframework.batch.core.launch.JobOperator -import org.springframework.context.ConfigurableApplicationContext +import org.springframework.context.ApplicationContext import spock.lang.Shared import spock.lang.Specification import spock.lang.Subject import spock.lang.Unroll @Subject(ClientBatchJob) +@SuppressWarnings("GroovyAccessibility") class ClientBatchJobSpec extends Specification { @Shared - def dateNow - - - def setupSpec() { - dateNow = new Date() - } + Date dateNow = new Date() @Unroll - def "Make sure ClientBatch job gets configured correctly"() { + def "Job Params: #path #doDeltaContent #contentAfterDate #deleteBeforeWrite"() { when: - final appContext = Mock(ConfigurableApplicationContext) + final appContext = Mock(ApplicationContext) appContext.getBean(_ as String, JobOperator) >> Mock(JobOperator) final job = new ClientBatchJob.ServerBuilder(appContext) - .andServer("host", "port") - .andCredentials("clientUser", "serverUser", "serverPass") - .andDoDeltaContent(doDeltaContent) - .andClientJobExecutions(jobExecutions) - .andConfiguration(new GrabbitConfiguration.PathConfiguration(path, [], [], deleteBeforeWrite)) - .build() + .andServer("host", "port") + .andCredentials("clientUser", "serverUser", "serverPass") + .andDoDeltaContent(doDeltaContent) + .andClientJobExecutions(jobExecutions) + .andConfiguration(new GrabbitConfiguration.PathConfiguration(path, [], [], deleteBeforeWrite)) + .build() then: job != null job.jobParameters != null - job.jobParameters.get("${ClientBatchJob.PATH}") == path - job.jobParameters.get("${ClientBatchJob.CONTENT_AFTER_DATE}") == contentAfterDate - job.jobParameters.get("${ClientBatchJob.DELETE_BEFORE_WRITE}").toBoolean() == deleteBeforeWrite + job.jobParameters.get(ClientBatchJob.PATH) == path + job.jobParameters.get(ClientBatchJob.CONTENT_AFTER_DATE) == contentAfterDate + job.jobParameters.get(ClientBatchJob.DELETE_BEFORE_WRITE).toBoolean() == deleteBeforeWrite where: - doDeltaContent | path | contentAfterDate | deleteBeforeWrite - true | "/path1" | DateUtil.getISOStringFromDate(dateNow) | true - false | "/path1" | null | false - true | "/path2" | null | true - false | "/path2" | null | false - + path | doDeltaContent | contentAfterDate | deleteBeforeWrite + "/path1" | true | DateUtil.getISOStringFromDate(dateNow) | true + "/path1" | false | null | false + "/path2" | true | null | true + "/path2" | false | null | false } @@ -74,10 +69,12 @@ class ClientBatchJobSpec extends Specification { def ex1 = new JobExecution(1, new JobParametersBuilder().addString("path", "/path1").toJobParameters()) ex1.endTime = dateNow ex1.status = BatchStatus.COMPLETED + def ex2 = new JobExecution(2, new JobParametersBuilder().addString("path", "/path2").toJobParameters()) ex2.endTime = dateNow ex2.status = BatchStatus.FAILED [ex1, ex2] } + } diff --git a/grabbit/src/test/groovy/com/twcable/grabbit/jcr/AbstractJcrSpec.groovy b/grabbit/src/test/groovy/com/twcable/grabbit/jcr/AbstractJcrSpec.groovy new file mode 100644 index 0000000..810c3a8 --- /dev/null +++ b/grabbit/src/test/groovy/com/twcable/grabbit/jcr/AbstractJcrSpec.groovy @@ -0,0 +1,86 @@ +/* + * Copyright 2015 Time Warner Cable, Inc. + * + * Licensed 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 com.twcable.grabbit.jcr + +import com.twcable.jackalope.impl.jcr.ValueImpl +import org.apache.jackrabbit.JcrConstants +import org.apache.jackrabbit.commons.iterator.NodeIteratorAdapter +import org.apache.jackrabbit.commons.iterator.PropertyIteratorAdapter +import spock.lang.Specification + +import javax.jcr.Node +import javax.jcr.Property +import javax.jcr.PropertyIterator +import javax.jcr.nodetype.NodeDefinition +import javax.jcr.nodetype.NodeType + +import static javax.jcr.PropertyType.STRING + +abstract class AbstractJcrSpec extends Specification { + + Node createNode(String path, boolean isMandatory, String primaryType) { + createNode(path, isMandatory, primaryType, []) + } + + + Node createNode(String path, boolean isMandatory, String primaryType, Collection children) { + def nodeDefinition = isMandatory ? mandatoryNodeDefinition() : nonMandatoryNodeDefinition() + + def childDefinitions = children.collect { it.getDefinition() } as List + + def node = Mock(Node) { + getPath() >> path + getDefinition() >> nodeDefinition + getProperties() >> propertyIterator(primaryTypeProperty(primaryType)) + getPrimaryNodeType() >> Mock(NodeType) { + getChildNodeDefinitions() >> childDefinitions.toArray() + } + } + + children.each { Node child -> + child.getParent() >> node + } + node.getNodes() >> new NodeIteratorAdapter(children.iterator()) + + return node + } + + protected NodeDefinition mandatoryNodeDefinition() { + return Mock(NodeDefinition) { + isMandatory() >> true + } + } + + protected NodeDefinition nonMandatoryNodeDefinition() { + return Mock(NodeDefinition) { + isMandatory() >> false + } + } + + protected Property primaryTypeProperty(String propertyValue) { + return Mock(Property) { + getType() >> STRING + getName() >> JcrConstants.JCR_PRIMARYTYPE + getValue() >> new ValueImpl(propertyValue) + } + } + + protected static PropertyIterator propertyIterator(Property... properties) { + new PropertyIteratorAdapter(properties.iterator()) + } + +} diff --git a/grabbit/src/test/groovy/com/twcable/grabbit/server/batch/steps/jcrnodes/JcrNodesProcessorSpec.groovy b/grabbit/src/test/groovy/com/twcable/grabbit/server/batch/steps/jcrnodes/JcrNodesProcessorSpec.groovy index d5afb74..7bad4bf 100644 --- a/grabbit/src/test/groovy/com/twcable/grabbit/server/batch/steps/jcrnodes/JcrNodesProcessorSpec.groovy +++ b/grabbit/src/test/groovy/com/twcable/grabbit/server/batch/steps/jcrnodes/JcrNodesProcessorSpec.groovy @@ -16,17 +16,19 @@ package com.twcable.grabbit.server.batch.steps.jcrnodes +import com.twcable.grabbit.jcr.AbstractJcrSpec import com.twcable.grabbit.proto.NodeProtos import com.twcable.jackalope.NodeBuilder as FakeNodeBuilder -import com.twcable.jackalope.impl.jcr.ValueImpl import org.apache.jackrabbit.JcrConstants -import org.apache.jackrabbit.commons.iterator.NodeIteratorAdapter -import org.apache.jackrabbit.commons.iterator.PropertyIteratorAdapter -import spock.lang.Specification +import org.joda.time.DateTime +import spock.lang.Shared import spock.lang.Subject +import spock.lang.Unroll + import javax.jcr.Node as JcrNode +import javax.jcr.NodeIterator +import javax.jcr.Property import javax.jcr.Property as JcrProperty -import javax.jcr.PropertyIterator import javax.jcr.nodetype.NodeDefinition import javax.jcr.nodetype.NodeType @@ -34,13 +36,17 @@ import static com.twcable.jackalope.JCRBuilder.node import static com.twcable.jackalope.JCRBuilder.property import static javax.jcr.PropertyType.LONG import static javax.jcr.PropertyType.STRING -import org.joda.time.DateTime -import javax.jcr.NodeIterator -import spock.lang.Shared -import spock.lang.Unroll @Subject(JcrNodesProcessor) -class JcrNodesProcessorSpec extends Specification { +@SuppressWarnings("GrEqualsBetweenInconvertibleTypes") +class JcrNodesProcessorSpec extends AbstractJcrSpec { + + @Shared + DateTime oldDate = new DateTime(2015, 8, 4, 15, 24, 34, 961) + + @Shared + DateTime currentDate = new DateTime() + def "Can marshall a JCR Node to a Protobuf Message"() { given: @@ -127,12 +133,13 @@ class JcrNodesProcessorSpec extends Specification { nodeProto == null } + def "Example not found and extreme case where grand child node is also required"() { given: def thumbnailFile = "/content/dam/geometrixx-outdoors/activities/jcr:content/folderThumbnail" def parentNode = createNode(thumbnailFile, false, JcrConstants.NT_FILE, [createNode("${thumbnailFile}/jcr:content", true, JcrConstants.NT_RESOURCE, - [createNode("${thumbnailFile}/jcr:content/metadata", true, JcrConstants.NT_UNSTRUCTURED)])]) + [createNode("${thumbnailFile}/jcr:content/metadata", true, JcrConstants.NT_UNSTRUCTURED)])]) when: NodeProtos.Node nodeProto = new JcrNodesProcessor().process(parentNode) @@ -150,52 +157,6 @@ class JcrNodesProcessorSpec extends Specification { nodeProto.mandatoryChildNodeList.first().mandatoryChildNodeList.first().properties.propertyList.first().value.stringValue == JcrConstants.NT_UNSTRUCTURED } - private JcrNode createNode(String path, boolean isMandatory, String primaryType, Collection children = []) { - def nodeDefinition = isMandatory ? mandatoryNodeDefinition() : nonMandatoryNodeDefinition() - - def childDefinitions = children.collect {it.getDefinition()} as List - - def node = Mock(JcrNode) { - getPath() >> path - getDefinition() >> nodeDefinition - getProperties() >> propertyIterator(primaryTypeProperty(primaryType)) - getPrimaryNodeType() >> Mock(NodeType) { - getChildNodeDefinitions() >> childDefinitions.toArray() - } - } - - children.each { JcrNode child -> - child.getParent() >> node - } - node.getNodes() >> new NodeIteratorAdapter(children.iterator()) - - return node - } - - private NodeDefinition mandatoryNodeDefinition() { - return Mock(NodeDefinition) { - isMandatory() >> true - } - } - - private NodeDefinition nonMandatoryNodeDefinition() { - return Mock(NodeDefinition) { - isMandatory() >> false - } - } - - private JcrProperty primaryTypeProperty(String propertyValue) { - return Mock(JcrProperty) { - getType() >> STRING - getName() >> JcrConstants.JCR_PRIMARYTYPE - getValue() >> new ValueImpl(propertyValue) - } - } - - private static PropertyIterator propertyIterator(JcrProperty... properties) { - new PropertyIteratorAdapter(properties.iterator()) - } - /* Node Processing & DeltaContent testing */ def "Process a mandatory child node with no date properties but modified parent"() { @@ -208,7 +169,7 @@ class JcrNodesProcessorSpec extends Specification { getPath() >> "testParent" getProperties() >> propertyIterator(primaryTypeProperty(JcrConstants.NT_FILE)) hasProperty(JcrConstants.JCR_LASTMODIFIED) >> true - getProperty(JcrConstants.JCR_LASTMODIFIED) >> Mock(JcrProperty){ + getProperty(JcrConstants.JCR_LASTMODIFIED) >> Mock(JcrProperty) { getDate() >> currentDate.toCalendar(Locale.default) } getDefinition() >> Mock(NodeDefinition) { @@ -253,9 +214,6 @@ class JcrNodesProcessorSpec extends Specification { } - @Shared - DateTime oldDate = new DateTime(2015, 8, 4, 15, 24, 34, 961) - @Unroll def "Process a node with old date properties: #propList"() { //tests for all situations with non-deltaContent nodes (not updated since last sync) @@ -263,7 +221,6 @@ class JcrNodesProcessorSpec extends Specification { JcrNodesProcessor jcrNodesProcessor = new JcrNodesProcessor() jcrNodesProcessor.setContentAfterDate(oldDate.plusDays(1).toString()) NodeProtos.Node nodeProto = jcrNodesProcessor.process(aJcrNode) - aJcrNode.properties.toList() then: nodeProto == null //not copying old data @@ -293,11 +250,9 @@ class JcrNodesProcessorSpec extends Specification { property("cq:lastModified", oldDate.toCalendar(Locale.default)) ).build(), ] - propList = aJcrNode.properties.toList().findAll {it.name != JcrConstants.JCR_PRIMARYTYPE}.collectEntries { [(it.name): new DateTime(it.value.date.time.time)]} + propList = nodeProperties(aJcrNode) } - @Shared - DateTime currentDate = new DateTime() @Unroll def "Process a node with updated content and date properties: #propList"() { @@ -340,6 +295,14 @@ class JcrNodesProcessorSpec extends Specification { property("cq:lastModified", currentDate.toCalendar(Locale.default)) ).build(), ] - propList = aJcrNode.properties.toList().findAll {it.name != JcrConstants.JCR_PRIMARYTYPE}.collectEntries { [(it.name): new DateTime(it.value.date.time.time)]} + propList = nodeProperties(aJcrNode) + } + + static Map nodeProperties(JcrNode aJcrNode) { + return ((List)aJcrNode.properties.toList()).findAll { + it.name != JcrConstants.JCR_PRIMARYTYPE + }.collectEntries { + [(it.name): new DateTime(it.value.date.time.time)] + } } } diff --git a/gradle.properties b/gradle.properties index 0d5e1c1..2a16c11 100644 --- a/gradle.properties +++ b/gradle.properties @@ -22,7 +22,7 @@ guava_version = 15.0 httpcomponents_version = 4.3.4 httpcomponents_client_version = 4.3.6 httpcomponents_core_version = 4.3.2 -jackalope_version = 2.0.0 +jackalope_version = 3.0.1 jackrabbit_ocm_version = 1.5.3 jackrabbit_version = 2.10.0 jcr_version = 2.0 From 67c1b2064bc44ae93f8332cd3fed08838e4035b8 Mon Sep 17 00:00:00 2001 From: Jim Moore Date: Wed, 30 Sep 2015 14:38:40 -0600 Subject: [PATCH 2/2] Update Spock --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 2a16c11..27cc98a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -42,7 +42,7 @@ sling_jcr_api_version = 2.5.0 sling_jcr_resource_version = 2.5.0 sling_resourceresolver_version = 1.0.6 sling_rewriter_version = 1.0.4 -spock_version = 0.7-groovy-2.0 +spock_version = 1.0-groovy-2.0 spring_batch_version = 2.2.7.RELEASE spring_osgi_version = 2.0.0.M1 woodstox_version = 4.2.0