From c36c25a05c9af3d91ea90e2fa88e0e8ed167bae9 Mon Sep 17 00:00:00 2001 From: tsurdilo Date: Mon, 5 Nov 2018 13:51:19 -0800 Subject: [PATCH] pastebin workitem --- pastebin-workitem/.gitignore | 11 ++ pastebin-workitem/assembly/assembly.xml | 40 ++++ pastebin-workitem/pom.xml | 171 ++++++++++++++++++ pastebin-workitem/readme.md | 9 + .../CreatePastebinWorkitemHandler.java | 153 ++++++++++++++++ .../GetExistingPastebinWorkitemHandler.java | 97 ++++++++++ pastebin-workitem/src/main/resources/icon.png | Bin 0 -> 41405 bytes .../pastebin/PastebinWorkitemHandlerTest.java | 161 +++++++++++++++++ .../PastebinWorkitemIntegrationTest.java | 45 +++++ pom.xml | 33 ++++ repository/pom.xml | 5 + .../java/HostedRepositoryIntegrationTest.java | 2 +- 12 files changed, 726 insertions(+), 1 deletion(-) create mode 100644 pastebin-workitem/.gitignore create mode 100644 pastebin-workitem/assembly/assembly.xml create mode 100644 pastebin-workitem/pom.xml create mode 100644 pastebin-workitem/readme.md create mode 100644 pastebin-workitem/src/main/java/org/jbpm/process/workitem/pastebin/CreatePastebinWorkitemHandler.java create mode 100644 pastebin-workitem/src/main/java/org/jbpm/process/workitem/pastebin/GetExistingPastebinWorkitemHandler.java create mode 100644 pastebin-workitem/src/main/resources/icon.png create mode 100644 pastebin-workitem/src/test/java/org/jbpm/process/workitem/pastebin/PastebinWorkitemHandlerTest.java create mode 100644 pastebin-workitem/src/test/java/org/jbpm/process/workitem/pastebin/PastebinWorkitemIntegrationTest.java diff --git a/pastebin-workitem/.gitignore b/pastebin-workitem/.gitignore new file mode 100644 index 000000000..8dd71d331 --- /dev/null +++ b/pastebin-workitem/.gitignore @@ -0,0 +1,11 @@ +/target +/local +/bin + +# Eclipse, Netbeans and IntelliJ files +/.* +!.gitignore +/nbproject +/*.ipr +/*.iws +/*.iml diff --git a/pastebin-workitem/assembly/assembly.xml b/pastebin-workitem/assembly/assembly.xml new file mode 100644 index 000000000..d75c51043 --- /dev/null +++ b/pastebin-workitem/assembly/assembly.xml @@ -0,0 +1,40 @@ + + + bin + + dir + zip + + false + + + + target + + + *.jar + + + + target/generated-sources/annotations + + + *.wid + index.html + *.json + *.xml + + + + target/classes + + + repoconf.part + repoindex.html + icon.png + + + + diff --git a/pastebin-workitem/pom.xml b/pastebin-workitem/pom.xml new file mode 100644 index 000000000..276f84950 --- /dev/null +++ b/pastebin-workitem/pom.xml @@ -0,0 +1,171 @@ + + + 4.0.0 + + org.jbpm.contrib + workitems + 7.14.0-SNAPSHOT + + + pastebin-workitem + Pastebin + Create new or get existing pastes from Pastebin + + jBPM dev team + + + + + + org + jpastebin + + + + commons-io + commons-io + + + + org.kie + kie-api + provided + + + org.jbpm + jbpm-workitems-core + provided + + + org.jbpm + jbpm-document + provided + + + org.jbpm + jbpm-workitems-core + test-jar + test + + + junit + junit + test + + + org.powermock + powermock-api-mockito + test + + + org.powermock + powermock-module-junit4 + test + + + org.jbpm + jbpm-test + test + + + org.jbpm + jbpm-test-util + test + + + org.slf4j + slf4j-api + + + + ${project.groupId} + template-resources + provided + + + + + ${project.build.directory}/generated-sources/java + + + src/main/resources + false + + *.png + + + + ${project.build.directory}/maven-shared-archive-resources + true + + *.part + + + + + + org.codehaus.mojo + templating-maven-plugin + 1.0.0 + + + filter-src + + filter-sources + + + ${basedir}/src/main/java + ${project.build.directory}/generated-sources/java + + + + + + org.apache.maven.plugins + maven-remote-resources-plugin + 1.5 + + + ${project.groupId}:template-resources:${project.version} + + + + + + process + + + + + + org.apache.maven.plugins + maven-resources-plugin + + + copy-repository-resources + prepare-package + + copy-resources + + + UTF-8 + + + target/generated-sources/annotations + + repoindex.html + + true + + + target/classes + + + + + + + + \ No newline at end of file diff --git a/pastebin-workitem/readme.md b/pastebin-workitem/readme.md new file mode 100644 index 000000000..eff9533c8 --- /dev/null +++ b/pastebin-workitem/readme.md @@ -0,0 +1,9 @@ +# Pastebin Workitems - prerequisite + +* To use these workitems first create an account on https://pastebin.com/. +Once you create an account go to +https://pastebin.com/api to get your developer API key. This key +needs to be passed to the handlers in your deployment descriptor configuration. + +* To use the GetExistingPastebin workitem handler it's necessary to have +your IP white-listed. See more info on this on https://pastebin.com/api_scraping_faq. diff --git a/pastebin-workitem/src/main/java/org/jbpm/process/workitem/pastebin/CreatePastebinWorkitemHandler.java b/pastebin-workitem/src/main/java/org/jbpm/process/workitem/pastebin/CreatePastebinWorkitemHandler.java new file mode 100644 index 000000000..49cf1fd0b --- /dev/null +++ b/pastebin-workitem/src/main/java/org/jbpm/process/workitem/pastebin/CreatePastebinWorkitemHandler.java @@ -0,0 +1,153 @@ +/* + * Copyright 2018 Red Hat, Inc. and/or its affiliates. + * + * 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 org.jbpm.process.workitem.pastebin; + +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; + +import org.jbpm.document.Document; +import org.jbpm.process.workitem.core.AbstractLogOrThrowWorkItemHandler; +import org.jbpm.process.workitem.core.util.RequiredParameterValidator; +import org.jbpm.process.workitem.core.util.Wid; +import org.jbpm.process.workitem.core.util.WidMavenDepends; +import org.jbpm.process.workitem.core.util.WidParameter; +import org.jbpm.process.workitem.core.util.WidResult; +import org.jbpm.process.workitem.core.util.service.WidAction; +import org.jbpm.process.workitem.core.util.service.WidService; +import org.jpastebin.pastebin.PastebinLink; +import org.jpastebin.pastebin.PastebinPaste; +import org.kie.api.runtime.process.WorkItem; +import org.kie.api.runtime.process.WorkItemManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Wid(widfile = "CreatePastebin.wid", name = "CreatePastebin", + displayName = "CreatePastebin", + defaultHandler = "mvel: new org.jbpm.process.workitem.pastebin.CreatePastebinWorkitemHandler()", + documentation = "${artifactId}/index.html", + parameters = { + @WidParameter(name = "Title"), + @WidParameter(name = "Content", required = true), + @WidParameter(name = "Format"), + @WidParameter(name = "Visibility"), + @WidParameter(name = "Author") + }, + results = { + @WidResult(name = "PasteURL") + }, + mavenDepends = { + @WidMavenDepends(group = "${groupId}", artifact = "${artifactId}", version = "${version}") + }, + serviceInfo = @WidService(category = "${name}", description = "${description}", + keywords = "paste,pastebin,create", + action = @WidAction(title = "Create a paste on Pastebin") + )) +public class CreatePastebinWorkitemHandler extends AbstractLogOrThrowWorkItemHandler { + + private String develKey; + + private static final Logger logger = LoggerFactory + .getLogger(CreatePastebinWorkitemHandler.class); + private static final String RESULTS_VALUE = "PasteURL"; + + public CreatePastebinWorkitemHandler(String develKey) { + this.develKey = develKey; + } + + public void executeWorkItem(WorkItem workItem, + WorkItemManager workItemManager) { + try { + RequiredParameterValidator.validate(this.getClass(), + workItem); + + String title = (String) workItem.getParameter("Title"); + Object content = workItem.getParameter("Content"); + String format = (String) workItem.getParameter("Format"); + String visibility = (String) workItem.getParameter("Visibility"); + String author = (String) workItem.getParameter("Author"); + + // for testing + PastebinPaste testPastebin = (PastebinPaste) workItem.getParameter("TestPastebin"); + + Map results = new HashMap(); + + PastebinPaste pastebin; + + if (testPastebin != null) { + pastebin = testPastebin; + } else { + pastebin = new PastebinPaste(); + } + + pastebin.setDeveloperKey(develKey); + + if (content instanceof Document) { + pastebin.setContents(new String(((Document) content).getContent(), + StandardCharsets.UTF_8)); + } else if (content instanceof String) { + pastebin.setContents((String) content); + } else { + throw new IllegalArgumentException("Invalid type for " + content + ". Should be Document or String type"); + } + + if (title != null && title.trim().length() > 0) { + pastebin.setPasteTitle(title); + } + + if (format != null && format.trim().length() > 0) { + pastebin.setPasteFormat(format); + } + + if (visibility != null && visibility.trim().length() > 0 && visibility.matches("-?\\d+")) { + int visibilityInt = Integer.parseInt(visibility); + + switch (visibilityInt) { + case 0: + pastebin.setVisibility(PastebinPaste.VISIBILITY_PUBLIC); + break; + case 1: + pastebin.setVisibility(PastebinPaste.VISIBILITY_UNLISTED); + break; + case 2: + pastebin.setVisibility(PastebinPaste.VISIBILITY_PRIVATE); + break; + default: + pastebin.setVisibility(PastebinPaste.VISIBILITY_PUBLIC); + break; + } + } else { + pastebin.setVisibility(PastebinPaste.VISIBILITY_PUBLIC); + } + + if (author != null) { + pastebin.setPasteAuthor(author); + } + + PastebinLink pastebinLink = pastebin.paste(); + results.put(RESULTS_VALUE, + pastebinLink.getLink()); + workItemManager.completeWorkItem(workItem.getId(), + results); + } catch (Exception e) { + handleException(e); + } + } + + public void abortWorkItem(WorkItem wi, + WorkItemManager wim) { + } +} diff --git a/pastebin-workitem/src/main/java/org/jbpm/process/workitem/pastebin/GetExistingPastebinWorkitemHandler.java b/pastebin-workitem/src/main/java/org/jbpm/process/workitem/pastebin/GetExistingPastebinWorkitemHandler.java new file mode 100644 index 000000000..4065a0d6c --- /dev/null +++ b/pastebin-workitem/src/main/java/org/jbpm/process/workitem/pastebin/GetExistingPastebinWorkitemHandler.java @@ -0,0 +1,97 @@ +/* + * Copyright 2018 Red Hat, Inc. and/or its affiliates. + * + * 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 org.jbpm.process.workitem.pastebin; + +import java.util.HashMap; +import java.util.Map; + +import org.jbpm.process.workitem.core.AbstractLogOrThrowWorkItemHandler; +import org.jbpm.process.workitem.core.util.RequiredParameterValidator; +import org.jbpm.process.workitem.core.util.Wid; +import org.jbpm.process.workitem.core.util.WidMavenDepends; +import org.jbpm.process.workitem.core.util.WidParameter; +import org.jbpm.process.workitem.core.util.WidResult; +import org.jbpm.process.workitem.core.util.service.WidAction; +import org.jbpm.process.workitem.core.util.service.WidService; +import org.jpastebin.pastebin.Pastebin; +import org.jpastebin.pastebin.PastebinLink; +import org.kie.api.runtime.process.WorkItem; +import org.kie.api.runtime.process.WorkItemManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Wid(widfile = "GetPastebin.wid", name = "GetPastebin", + displayName = "GetPastebin", + defaultHandler = "mvel: new org.jbpm.process.workitem.pastebin.GetExistingPastebinWorkitemHandler()", + documentation = "${artifactId}/index.html", + parameters = { + @WidParameter(name = "PastebinKey", required = true) + }, + results = { + @WidResult(name = "PasteContent") + }, + mavenDepends = { + @WidMavenDepends(group = "${groupId}", artifact = "${artifactId}", version = "${version}") + }, + serviceInfo = @WidService(category = "${name}", description = "${description}", + keywords = "paste,pastebin,get,existing", + action = @WidAction(title = "Get an existing Pastebin") + )) +public class GetExistingPastebinWorkitemHandler extends AbstractLogOrThrowWorkItemHandler { + + private String develKey; + + private static final Logger logger = LoggerFactory + .getLogger(CreatePastebinWorkitemHandler.class); + private static final String RESULTS_VALUE = "PasteContent"; + + public GetExistingPastebinWorkitemHandler(String develKey) { + this.develKey = develKey; + } + + public void executeWorkItem(WorkItem workItem, + WorkItemManager workItemManager) { + try { + RequiredParameterValidator.validate(this.getClass(), + workItem); + + String pastebinKey = (String) workItem.getParameter("PastebinKey"); + // for testing + PastebinLink testPastebinLink = (PastebinLink) workItem.getParameter("TestPastebinLink"); + + Map results = new HashMap(); + + PastebinLink pastebinLink; + if (testPastebinLink != null) { + pastebinLink = testPastebinLink; + } else { + pastebinLink = Pastebin.getPaste(pastebinKey); + } + + pastebinLink.fetchContent(); + results.put(RESULTS_VALUE, + pastebinLink.getPaste().getContents()); + workItemManager.completeWorkItem(workItem.getId(), + results); + } catch (Exception e) { + handleException(e); + } + } + + public void abortWorkItem(WorkItem wi, + WorkItemManager wim) { + } +} diff --git a/pastebin-workitem/src/main/resources/icon.png b/pastebin-workitem/src/main/resources/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a519e45c2e0c90b93224ae453b34d6abe2809d36 GIT binary patch literal 41405 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 literal 0 HcmV?d00001 diff --git a/pastebin-workitem/src/test/java/org/jbpm/process/workitem/pastebin/PastebinWorkitemHandlerTest.java b/pastebin-workitem/src/test/java/org/jbpm/process/workitem/pastebin/PastebinWorkitemHandlerTest.java new file mode 100644 index 000000000..e418e360b --- /dev/null +++ b/pastebin-workitem/src/test/java/org/jbpm/process/workitem/pastebin/PastebinWorkitemHandlerTest.java @@ -0,0 +1,161 @@ +/* + * Copyright 2018 Red Hat, Inc. and/or its affiliates. + * + * 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 org.jbpm.process.workitem.pastebin; + +import java.net.URL; + +import org.drools.core.process.instance.impl.WorkItemImpl; +import org.jbpm.document.service.impl.DocumentImpl; +import org.jbpm.process.workitem.core.TestWorkItemManager; +import org.jbpm.test.AbstractBaseTest; +import org.jpastebin.pastebin.PastebinLink; +import org.jpastebin.pastebin.PastebinPaste; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +@RunWith(MockitoJUnitRunner.class) +public class PastebinWorkitemHandlerTest extends AbstractBaseTest { + + @Mock + PastebinPaste pastebin; + + @Mock + PastebinLink pastebinLink; + + @Before + public void setUp() throws Exception { + when(pastebin.paste()).thenReturn(pastebinLink); + when(pastebinLink.getPaste()).thenReturn(pastebin); + } + + @Test + public void testCreateNewPasteDocContent() throws Exception { + URL testURL = new URL("http://testpasteurl"); + when(pastebinLink.getLink()).thenReturn(testURL); + + TestWorkItemManager manager = new TestWorkItemManager(); + WorkItemImpl workItem = new WorkItemImpl(); + workItem.setParameter("Title", + "test Title"); + workItem.setParameter("Format", + "text"); + workItem.setParameter("Visibility", + "0"); + workItem.setParameter("Author", + "testAuthor"); + workItem.setParameter("TestPastebin", + pastebin); + + DocumentImpl testPasteDoc = new DocumentImpl(); + testPasteDoc.setContent(new String("Test paste to send").getBytes()); + testPasteDoc.setName("testPaste.txt"); + + workItem.setParameter("Content", + testPasteDoc); + + CreatePastebinWorkitemHandler handler = new CreatePastebinWorkitemHandler("testDevKey"); + + handler.executeWorkItem(workItem, + manager); + assertNotNull(manager.getResults()); + assertEquals(1, + manager.getResults().size()); + assertTrue(manager.getResults().containsKey(workItem.getId())); + + assertTrue((manager.getResults().get(workItem.getId())).get("PasteURL") instanceof URL); + + URL testPasteURL = (URL) manager.getResults().get(workItem.getId()).get("PasteURL"); + assertNotNull(testPasteURL); + assertEquals("http://testpasteurl", + testPasteURL.toString()); + } + + @Test + public void testCreateNewPasteStringContent() throws Exception { + URL testURL = new URL("http://testpasteurl"); + when(pastebinLink.getLink()).thenReturn(testURL); + + TestWorkItemManager manager = new TestWorkItemManager(); + WorkItemImpl workItem = new WorkItemImpl(); + workItem.setParameter("Title", + "test Title"); + workItem.setParameter("Format", + "text"); + workItem.setParameter("Visibility", + "0"); + workItem.setParameter("Author", + "testAuthor"); + workItem.setParameter("TestPastebin", + pastebin); + + workItem.setParameter("Content", + "Test paste to send"); + + CreatePastebinWorkitemHandler handler = new CreatePastebinWorkitemHandler("testDevKey"); + + handler.executeWorkItem(workItem, + manager); + assertNotNull(manager.getResults()); + assertEquals(1, + manager.getResults().size()); + assertTrue(manager.getResults().containsKey(workItem.getId())); + + assertTrue((manager.getResults().get(workItem.getId())).get("PasteURL") instanceof URL); + + URL testPasteURL = (URL) manager.getResults().get(workItem.getId()).get("PasteURL"); + assertNotNull(testPasteURL); + assertEquals("http://testpasteurl", + testPasteURL.toString()); + } + + @Test + public void testGetExistingPasteContent() throws Exception { + doNothing().when(pastebinLink).fetchContent(); + when(pastebin.getContents()).thenReturn("test paste content"); + + TestWorkItemManager manager = new TestWorkItemManager(); + WorkItemImpl workItem = new WorkItemImpl(); + workItem.setParameter("PastebinKey", + "testKey"); + workItem.setParameter("TestPastebinLink", + pastebinLink); + + workItem.setParameter("Content", + "Test paste to send"); + + GetExistingPastebinWorkitemHandler handler = new GetExistingPastebinWorkitemHandler("testDevKey"); + + handler.executeWorkItem(workItem, + manager); + assertNotNull(manager.getResults()); + assertEquals(1, + manager.getResults().size()); + assertTrue(manager.getResults().containsKey(workItem.getId())); + + assertTrue((manager.getResults().get(workItem.getId())).get("PasteContent") instanceof String); + + String testPasteContent = (String) manager.getResults().get(workItem.getId()).get("PasteContent"); + assertNotNull(testPasteContent); + assertEquals("test paste content", + testPasteContent); + } +} diff --git a/pastebin-workitem/src/test/java/org/jbpm/process/workitem/pastebin/PastebinWorkitemIntegrationTest.java b/pastebin-workitem/src/test/java/org/jbpm/process/workitem/pastebin/PastebinWorkitemIntegrationTest.java new file mode 100644 index 000000000..5c40cab80 --- /dev/null +++ b/pastebin-workitem/src/test/java/org/jbpm/process/workitem/pastebin/PastebinWorkitemIntegrationTest.java @@ -0,0 +1,45 @@ +/* + * Copyright 2018 Red Hat, Inc. and/or its affiliates. + * + * 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 org.jbpm.process.workitem.pastebin; + +import java.util.Map; + +import org.jbpm.process.workitem.WorkDefinitionImpl; +import org.jbpm.process.workitem.WorkItemRepository; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class PastebinWorkitemIntegrationTest { + + @Test + public void testWorkitemValidity() { + + String repoPath = "file://" + System.getProperty("builddir") + + "/" + System.getProperty("artifactId") + "-" + + System.getProperty("version") + "/"; + + Map repoResults = new WorkItemRepository().getWorkDefinitions(repoPath, + null, + System.getProperty("artifactId")); + assertNotNull(repoResults); + assertEquals(2, + repoResults.size()); + + assertTrue(repoResults.containsKey("CreatePastebin")); + assertTrue(repoResults.containsKey("GetPastebin")); + } +} diff --git a/pom.xml b/pom.xml index be01bc050..802af2ab5 100644 --- a/pom.xml +++ b/pom.xml @@ -67,6 +67,7 @@ 1.5.1 14.0.1 4.1.0 + 1.0.1 4.2.0 @@ -327,6 +328,12 @@ ${version.xmlsec} + + org + jpastebin + ${version.jpastebin} + + org.jbpm @@ -604,6 +611,11 @@ riot-workitem ${project.version} + + org.jbpm.contrib + pastebin-workitem + ${project.version} + org.jbpm.contrib repository @@ -791,6 +803,12 @@ ${project.version} zip + + org.jbpm.contrib + pastebin-workitem + ${project.version} + zip + @@ -918,6 +936,20 @@ + + jboss-thirdparty-uploads + JBoss Thirdparty Uploads + https://repository.jboss.org/nexus/service/local/repositories/thirdparty-uploads/content/ + + true + never + + + true + daily + + + atlassian-public-repository Atlassian Public Repository @@ -997,6 +1029,7 @@ pdf-workitem execute-sql-workitem riot-workitem + pastebin-workitem repository repository-springboot repository-wildfly diff --git a/repository/pom.xml b/repository/pom.xml index 49d48a5cb..fcee0ebaf 100644 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -316,6 +316,11 @@ riot-workitem zip + + org.jbpm.contrib + pastebin-workitem + zip + ${project.groupId} template-resources diff --git a/repository/src/test/java/HostedRepositoryIntegrationTest.java b/repository/src/test/java/HostedRepositoryIntegrationTest.java index 050ce0fd2..2e829e616 100644 --- a/repository/src/test/java/HostedRepositoryIntegrationTest.java +++ b/repository/src/test/java/HostedRepositoryIntegrationTest.java @@ -100,7 +100,7 @@ public void testRepositoryValidity() throws Exception { Map repoResults = WorkItemRepository.getWorkDefinitions(uri.toString()); assertNotNull(repoResults); // update this when new workitems are added - assertEquals(62, + assertEquals(64, repoResults.size()); }