diff --git a/marketplace-service/src/main/java/com/axonivy/market/util/ProductContentUtils.java b/marketplace-service/src/main/java/com/axonivy/market/util/ProductContentUtils.java index 9a9e0b8c..a90e3be0 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/util/ProductContentUtils.java +++ b/marketplace-service/src/main/java/com/axonivy/market/util/ProductContentUtils.java @@ -22,12 +22,16 @@ import static com.axonivy.market.constants.ProductJsonConstants.DEFAULT_PRODUCT_TYPE; public class ProductContentUtils { - public static final String DEMO_SETUP_TITLE = "(?i)## Demo|## Setup"; + /* + * Accept any combination of #, can be ## or ###, and whitespaces before Demo/Setup word + * Match exactly Demo or Setup + */ + public static final String DEMO_SETUP_TITLE = "(?m)^[#\\s]*##?\\s*(Demo|Setup)\\s*$"; private static final String HASH = "#"; public static final String DESCRIPTION = "description"; public static final String DEMO = "demo"; public static final String SETUP = "setup"; - public static final String README_IMAGE_FORMAT = "\\(([^)]*?/)?%s\\)"; + public static final String README_IMAGE_FORMAT = "\\(([^)]*?/)?%s(\\s+\"[^\"]+\")?\\)"; public static final String IMAGE_DOWNLOAD_URL_FORMAT = "(%s)"; private ProductContentUtils() { @@ -141,6 +145,11 @@ public static void updateProductModuleTabContents(ProductModuleContent productMo productModuleContent.setSetup(replaceEmptyContentsWithEnContent(moduleContents.get(SETUP))); } + /** + * Cover some inconsistent cases: + * Products contain image names in round brackets (employee-onboarding, demo-projects, etc.) + * Image with name contains in other images' (mattermost) + */ public static String replaceImageDirWithImageCustomId(Map imageUrls, String readmeContents) { for (Map.Entry entry : imageUrls.entrySet()) { String imagePattern = String.format(README_IMAGE_FORMAT, Pattern.quote(entry.getKey())); diff --git a/marketplace-service/src/test/java/com/axonivy/market/BaseSetup.java b/marketplace-service/src/test/java/com/axonivy/market/BaseSetup.java index 971097a6..9800ebc7 100644 --- a/marketplace-service/src/test/java/com/axonivy/market/BaseSetup.java +++ b/marketplace-service/src/test/java/com/axonivy/market/BaseSetup.java @@ -54,6 +54,7 @@ public class BaseSetup { protected static final String MOCK_PRODUCT_REPOSITORY_NAME = "axonivy-market/bpmn-statistic"; protected static final String MOCK_IMAGE_ID_FORMAT_1 = "imageId-66e2b14868f2f95b2f95549a"; protected static final String MOCK_IMAGE_ID_FORMAT_2 = "imageId-66e2b14868f2f95b2f95550a"; + protected static final String MOCK_IMAGE_ID_FORMAT_3 = "imageId-66e2b14868f2f95b2f95551a"; protected static final String MOCK_PRODUCT_JSON_FILE_PATH = "src/test/resources/product.json"; protected static final String MOCK_PRODUCT_JSON_FILE_PATH_NO_URL = "src/test/resources/productMissingURL.json"; protected static final String MOCK_PRODUCT_JSON_WITH_DROPINS_FILE_PATH = "src/test/resources/product-dropins.json"; diff --git a/marketplace-service/src/test/java/com/axonivy/market/util/ProductContentUtilsTest.java b/marketplace-service/src/test/java/com/axonivy/market/util/ProductContentUtilsTest.java index c302c66e..b1199ede 100644 --- a/marketplace-service/src/test/java/com/axonivy/market/util/ProductContentUtilsTest.java +++ b/marketplace-service/src/test/java/com/axonivy/market/util/ProductContentUtilsTest.java @@ -50,10 +50,11 @@ void testReplaceImageDirWithImageCustomId() { Map imageUrls = new HashMap<>(); imageUrls.put("slash-command.png", MOCK_IMAGE_ID_FORMAT_1); imageUrls.put("create-slash-command.png", MOCK_IMAGE_ID_FORMAT_2); + imageUrls.put("screen2.png", MOCK_IMAGE_ID_FORMAT_3); String expectedResult = readmeContents.replace("images/slash-command.png", MOCK_IMAGE_ID_FORMAT_1).replace("images/create-slash-command.png", - MOCK_IMAGE_ID_FORMAT_2); + MOCK_IMAGE_ID_FORMAT_2).replace("screen2.png \"Restful Person Manager\"", MOCK_IMAGE_ID_FORMAT_3); String updatedContents = ProductContentUtils.replaceImageDirWithImageCustomId(imageUrls, readmeContents); assertEquals(expectedResult, updatedContents); @@ -114,6 +115,40 @@ void testGetExtractedPartsOfEmptyReadme() { assertTrue(StringUtils.isBlank(readmeContentsModel.getSetup())); } + @Test + void testGetExtractedPartsOfReadmeAtCorrectHeadings() { + String readmeContents = getMockReadmeContent(); + ReadmeContentsModel readmeContentsModel = ProductContentUtils.getExtractedPartsOfReadme(readmeContents); + assertTrue(readmeContentsModel.getDescription().startsWith("Axon Ivy’s mattermost connector")); + assertTrue(readmeContentsModel.getDemo().startsWith("### Demo sample")); + assertTrue(readmeContentsModel.getSetup().startsWith("### Setup guideline")); + } + + @Test + void testGetExtractedPartsOfReadmeWithInconsistentFormats() { + String readmeContentsWithHeading3 = """ + #Product-name + Test README + ### Setup + Setup content (./image.png)"""; + ReadmeContentsModel readmeContentsModel = ProductContentUtils.getExtractedPartsOfReadme(readmeContentsWithHeading3); + assertTrue(readmeContentsModel.getDescription().startsWith("Test README")); + assertTrue(readmeContentsModel.getSetup().startsWith("Setup content (./image.png)")); + + String readmeContentsWithSpaceHeading = """ + #Product-name + Test README + ##Demo + ### Demo project + Demo content + ## Setup + Setup content (./image.png)"""; + ReadmeContentsModel readmeContentsModel1 = + ProductContentUtils.getExtractedPartsOfReadme(readmeContentsWithSpaceHeading); + assertTrue(readmeContentsModel1.getDemo().startsWith("### Demo project")); + assertTrue(readmeContentsModel1.getSetup().startsWith("Setup content (./image.png)")); + } + @Test void testHasImageDirectives() { String readmeContents = getMockReadmeContent(); diff --git a/marketplace-service/src/test/resources/README.md b/marketplace-service/src/test/resources/README.md index c86eea4e..d7ef143e 100644 --- a/marketplace-service/src/test/resources/README.md +++ b/marketplace-service/src/test/resources/README.md @@ -9,9 +9,11 @@ This connector: - allow you to start the Axon Ivy process by hitting the slash command key from the mattermost's channel. - allow you to send a message to the mattermost's channel from the Axon Ivy workplace. - notifies users on the channel for new Axon Ivy workflow Tasks. + ![Restful Person Manager](screen2.png "Restful Person Manager") ## Demo +### Demo sample 1. Hit the slash command key on the channel's chat. The Axon Ivy process will be triggered and create a new task. The task's information will be sent to the channel by a message. @@ -20,6 +22,7 @@ This connector: ## Setup +### Setup guideline Mattermost Instance 1. Ref to [Deploy Mattermost](https://docs.mattermost.com/guides/deployment.html).