diff --git a/modules/core/src/test/java/org/apache/synapse/mediators/transform/pfutils/RegexTemplateProcessorTest.java b/modules/core/src/test/java/org/apache/synapse/mediators/transform/pfutils/RegexTemplateProcessorTest.java
new file mode 100644
index 0000000000..21009fe981
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/synapse/mediators/transform/pfutils/RegexTemplateProcessorTest.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com) All Rights Reserved.
+ *
+ * WSO2 LLC. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.synapse.mediators.transform.pfutils;
+
+import junit.framework.TestCase;
+import org.apache.synapse.MessageContext;
+import org.apache.synapse.mediators.TestUtils;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.experimental.runners.Enclosed;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * Unit tests for Payload factory Regex Template Processor with inline synapse expressions
+ */
+@RunWith(Enclosed.class)
+public class RegexTemplateProcessorTest extends TestCase {
+
+ @RunWith(Parameterized.class)
+ public static class PayloadRegexTemplateProcessor {
+
+ private final String template;
+ private final String mediaType;
+ private final String expectedOutput;
+ private final MessageContext messageContext;
+
+ public PayloadRegexTemplateProcessor(String template, String mediaType, String payloadContentType, String payload, String expectedOutput) throws Exception {
+
+ this.template = template;
+ this.mediaType = mediaType;
+ this.expectedOutput = expectedOutput;
+ if (payloadContentType.equals("application/json"))
+ this.messageContext = TestUtils.getTestContextJson(payload, null);
+ else
+ this.messageContext = TestUtils.getTestContext(payload, null);
+ }
+
+ @Parameterized.Parameters
+ public static Collection provideConfigsForPrepareReplacementValueWithEscapeXmlCharsTests() throws Exception {
+
+ return Arrays.asList(new Object[][]{
+ // Test Case 1: Strings with escape characters
+ {
+ "{\n" +
+ " \"name\": \"${payload.user.name}\",\n" +
+ " \"message\": \"Welcome, ${payload.user.name}!\",\n" +
+ " \"rawString\": \"${payload.rawData}\"\n" +
+ "}",
+ "json",
+ "application/json",
+ "{\n" +
+ " \"user\": {\n" +
+ " \"name\": \"John \\\"Doe\\\"\"\n" +
+ " },\n" +
+ " \"rawData\": \"This is a raw \\\\n string with \\\"quotes\\\".\"\n" +
+ "}\n",
+ "{\n" +
+ " \"name\": \"John \\\"Doe\\\"\",\n" +
+ " \"message\": \"Welcome, John \\\"Doe\\\"!\",\n" +
+ " \"rawString\": \"This is a raw \\\\n string with \\\"quotes\\\".\"\n" +
+ "}"
+ },
+ // Test Case 2: Numbers and booleans
+ {
+ "{ \"age\": ${payload.user.age}, \"isActive\": ${payload.user.isActive} }",
+ "json",
+ "application/json",
+ "{ \"user\": { \"age\": 30, \"isActive\": true } }",
+ "{ \"age\": 30, \"isActive\": true }"
+ },
+ // Test Case 3: Arrays and nested objects
+ {
+ "{ \"items\": ${payload.items}, \"firstItem\": \"${payload.items[0].name}\" }",
+ "json",
+ "application/json",
+ "{ \"items\": [{ \"name\": \"item1\" }, { \"name\": \"item2\" }] }",
+ "{ \"items\": [{\"name\":\"item1\"},{\"name\":\"item2\"}], \"firstItem\": \"item1\" }"
+ },
+ // Test Case 4: Special characters and escaping
+ {
+ "{ \"description\": \"${payload.details}\" }",
+ "json",
+ "application/json",
+ "{ \"details\": \"Line1\\\\nLine2\" }",
+ "{ \"description\": \"Line1\\\\nLine2\" }"
+ },
+ // Test Case 5: non-existing expression
+ {
+ "{\n" +
+ " \"description\": \"${payload.test1}\",\n" +
+ " \"path\": ${var.path}\n" +
+ "}",
+ "json",
+ "application/json",
+ "{ \"details\": \"Line1\\\\nLine2\" }",
+ "{\n" +
+ " \"description\": \"\",\n" +
+ " \"path\": \n" +
+ "}"
+ },
+ // Test Case 6: XML to JSON
+ {
+ "{\n" +
+ " \"first_name\": \"${xpath('//person/first_name')}\",\n" +
+ " \"last_name\": \"${xpath('//person/last_name')}\",\n" +
+ " \"email\": \"${xpath('//person/contact/email')}\",\n" +
+ " \"is_active\": ${xpath('//person/is_active')},\n" +
+ " \"address\": \"${xpath('//person/address/street')}\",\n" +
+ " \"escapedAddress\": \"${xpath('//person/address/street')}\",\n" +
+ " \"special_characters\": \"${xpath('//person/notes')}\"\n" +
+ "}\n",
+ "json",
+ "application/xml",
+ "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " John\n" +
+ " Doe\n" +
+ " \n" +
+ " john.doe@example.com\n" +
+ " \n" +
+ " false\n" +
+ " \n" +
+ " 1234 Elm Street\n" +
+ " Springfield\n" +
+ " \n" +
+ " Special characters: &*()_+|~=`{}[]:"<>?/'\n" +
+ " \n" +
+ " \n" +
+ "\n\n",
+ "{\n" +
+ " \"first_name\": \"John\",\n" +
+ " \"last_name\": \"Doe\",\n" +
+ " \"email\": \"john.doe@example.com\",\n" +
+ " \"is_active\": false,\n" +
+ " \"address\": \"1234 Elm Street\",\n" +
+ " \"escapedAddress\": \"1234 Elm Street\",\n" +
+ " \"special_characters\": \"Special characters: &*()_+|~=`{}[]:\"<>?/'\"\n" +
+ "}\n"
+ },
+ // Test Case 7: XML to XML
+ {
+ "\n" +
+ " ${xpath('//person/first_name')} ${xpath('//person/last_name')}\n" +
+ " \n" +
+ " ${xpath('//person/contact/email')}\n" +
+ " ${xpath('//person/is_active')}\n" +
+ " \n" +
+ " \n" +
+ " ${xpath('//person/address/street')}\n" +
+ " ${xpath('//person/address/city')}\n" +
+ " \n" +
+ " ${xpath('//person/notes')}\n" +
+ "\n",
+ "xml",
+ "application/xml",
+ "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " John\n" +
+ " Doe\n" +
+ " \n" +
+ " john.doe@example.com\n" +
+ " \n" +
+ " false\n" +
+ " \n" +
+ " 1234 Elm Street\n" +
+ " Springfield\n" +
+ " \n" +
+ " Special characters: &*()_+|~=`{}[]:"<>?/'\n" +
+ " \n" +
+ " \n" +
+ "\n",
+ "\n" +
+ " John Doe\n" +
+ " \n" +
+ " john.doe@example.com\n" +
+ " false\n" +
+ " \n" +
+ " \n" +
+ " 1234 Elm Street\n" +
+ " Springfield\n" +
+ " \n" +
+ " Special characters: &*()_+|~=`{}[]:"<>?/'\n" +
+ "\n"
+ },
+ }
+ );
+ }
+
+ @Test
+ public void testPrepareReplacementValueWithEscapeXmlChars() {
+
+ TemplateProcessor templateProcessor = new RegexTemplateProcessor();
+ String result = templateProcessor.processTemplate(template, mediaType, messageContext);
+ Assert.assertEquals(expectedOutput, result);
+ }
+ }
+}
diff --git a/modules/core/src/test/java/org/apache/synapse/util/InlineExpressionUtilTest.java b/modules/core/src/test/java/org/apache/synapse/util/InlineExpressionUtilTest.java
new file mode 100644
index 0000000000..86ccffce53
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/synapse/util/InlineExpressionUtilTest.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com) All Rights Reserved.
+ *
+ * WSO2 LLC. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.synapse.util;
+
+import com.google.gson.JsonObject;
+import junit.framework.TestCase;
+import org.apache.synapse.MessageContext;
+import org.apache.synapse.mediators.TestUtils;
+import org.junit.Assert;
+
+public class InlineExpressionUtilTest extends TestCase {
+
+ private static String payload = "{\n" +
+ " \"team\": [\n" +
+ " {\n" +
+ " \"name\": \"Alice\",\n" +
+ " \"role\": \"Developer\",\n" +
+ " \"experience\": 3\n" +
+ " },\n" +
+ " {\n" +
+ " \"name\": \"Bob\",\n" +
+ " \"role\": \"Designer\",\n" +
+ " \"experience\": 5\n" +
+ " },\n" +
+ " {\n" +
+ " \"name\": \"Charlie\",\n" +
+ " \"role\": \"Product Manager\",\n" +
+ " \"experience\": 7\n" +
+ " }\n" +
+ " ]\n" +
+ "}\n";
+
+ private static String xmlPayload = "\n" +
+ " \n" +
+ " 101\n" +
+ " The Great Gatsby\n" +
+ " F. Scott Fitzgerald\n" +
+ " Fiction\n" +
+ " 10.99\n" +
+ " 1925-04-10\n" +
+ " \n" +
+ " \n" +
+ " 102\n" +
+ " 1984\n" +
+ " George Orwell\n" +
+ " Dystopian\n" +
+ " 8.99\n" +
+ " 1949-06-08\n" +
+ " \n" +
+ " \n" +
+ " 103\n" +
+ " To Kill a Mockingbird\n" +
+ " Harper Lee\n" +
+ " Classic\n" +
+ " 12.99\n" +
+ " 1960-07-11\n" +
+ " \n" +
+ "\n";
+
+ /**
+ * Test inline synapse expression template processing with a JSON object.
+ */
+ public void testsInLineSynapseExpressionTemplate1() throws Exception {
+
+ String expected = "Processing payload : {\"name\":\"Alice\",\"role\":\"Developer\",\"experience\":3}";
+
+ MessageContext mc = TestUtils.getTestContextJson(payload, null);
+ String inlineExpression = "Processing payload : ${payload.team[0]}";
+
+ boolean isContentAware = InlineExpressionUtil.isInlineSynapseExpressionsContentAware(inlineExpression);
+ Assert.assertTrue("Inline expression content aware should be true", isContentAware);
+
+ String result = InlineExpressionUtil.processInLineSynapseExpressionTemplate(mc, inlineExpression);
+ Assert.assertEquals("Inline expression result mismatch", expected, result);
+ }
+
+ /**
+ * Test inline synapse expression template processing with a JSON primitive.
+ */
+ public void testsInLineSynapseExpressionTemplate2() throws Exception {
+
+ String expected = "Processing user : Alice";
+
+ MessageContext mc = TestUtils.getTestContextJson(payload, null);
+ String inlineExpression = "Processing user : ${payload.team[0].name}";
+
+ boolean isContentAware = InlineExpressionUtil.isInlineSynapseExpressionsContentAware(inlineExpression);
+ Assert.assertTrue("Inline expression content aware should be true", isContentAware);
+
+ String result = InlineExpressionUtil.processInLineSynapseExpressionTemplate(mc, inlineExpression);
+ Assert.assertEquals("Inline expression result mismatch", expected, result);
+ }
+
+ /**
+ * Test inline synapse expression template processing with non-existing expression.
+ */
+ public void testsInLineSynapseExpressionTemplate3() throws Exception {
+
+ String expected = "Processing user : ";
+
+ MessageContext mc = TestUtils.getTestContextJson(payload, null);
+ String inlineExpression = "Processing user : ${payload.team[0].age}";
+
+ boolean isContentAware = InlineExpressionUtil.isInlineSynapseExpressionsContentAware(inlineExpression);
+ Assert.assertTrue("Inline expression content aware should be true", isContentAware);
+
+ String result = InlineExpressionUtil.processInLineSynapseExpressionTemplate(mc, inlineExpression);
+ Assert.assertEquals("Inline expression result mismatch", expected, result);
+ }
+
+ /**
+ * Test inline synapse expression template processing with variables.
+ */
+ public void testsInLineSynapseExpressionTemplate4() throws Exception {
+
+ String expected = "Processing user with age : 3 lives at {\"no\":110,\"street\":\"Palm Grove\",\"city\":\"Colombo\"}";
+
+ MessageContext mc = TestUtils.getTestContextJson(payload, null);
+ mc.setVariable("age", 3);
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("no", 110);
+ jsonObject.addProperty("street", "Palm Grove");
+ jsonObject.addProperty("city", "Colombo");
+ mc.setVariable("address", jsonObject);
+ String inlineExpression = "Processing user with age : ${var.age} lives at ${var.address}";
+
+ boolean isContentAware = InlineExpressionUtil.isInlineSynapseExpressionsContentAware(inlineExpression);
+ Assert.assertFalse("Inline expression content aware should be false", isContentAware);
+
+ String result = InlineExpressionUtil.processInLineSynapseExpressionTemplate(mc, inlineExpression);
+ Assert.assertEquals("Inline expression result mismatch", expected, result);
+ }
+
+ /**
+ * Test inline synapse expression template processing with multiple expressions.
+ */
+ public void testsInLineSynapseExpressionTemplate5() throws Exception {
+
+ String expected = "Processing user : Alice, role : Developer, experience : 3 years";
+
+ MessageContext mc = TestUtils.getTestContextJson(payload, null);
+ mc.setVariable("role", "Developer");
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("level", "3");
+ mc.setVariable("experience", jsonObject);
+ mc.setProperty("duration", "years");
+ String inlineExpression = "Processing user : ${payload.team[0].name}, role : ${var.role}, " +
+ "experience : ${var.experience.level} ${properties.synapse.duration}";
+
+ boolean isContentAware = InlineExpressionUtil.isInlineSynapseExpressionsContentAware(inlineExpression);
+ Assert.assertTrue("Inline expression content aware should be true", isContentAware);
+
+ String result = InlineExpressionUtil.processInLineSynapseExpressionTemplate(mc, inlineExpression);
+ Assert.assertEquals("Inline expression result mismatch", expected, result);
+ }
+
+ /**
+ * Test inline synapse expression template processing with multiple expressions.
+ */
+ public void testsInLineSynapseExpressionTemplate6() throws Exception {
+
+ String expected = "Processing using endpoint : https://test.wso2.com/, method : get, role : Product Manager";
+
+ MessageContext mc = TestUtils.getTestContextJson(payload, null);
+ mc.setVariable("endpoint", "https://test.wso2.com/");
+ mc.setProperty("method", "get");
+ String inlineExpression = "Processing using endpoint : ${var.endpoint}, method : ${properties.synapse.method}, role : ${payload.team[2].role}";
+
+ boolean isContentAware = InlineExpressionUtil.isInlineSynapseExpressionsContentAware(inlineExpression);
+ Assert.assertTrue("Inline expression content aware should be true", isContentAware);
+
+ String result = InlineExpressionUtil.processInLineSynapseExpressionTemplate(mc, inlineExpression);
+ Assert.assertEquals("Inline expression result mismatch", expected, result);
+ }
+
+ /**
+ * Test inline synapse expression template processing with multiple expressions.
+ */
+ public void testsInLineSynapseExpressionTemplate7() throws Exception {
+
+ String expected = "Using endpoint : https://test.wso2.com/ to process book : \n" +
+ " 101\n" +
+ " The Great Gatsby\n" +
+ " F. Scott Fitzgerald\n" +
+ " Fiction\n" +
+ " 10.99\n" +
+ " 1925-04-10\n" +
+ " ";
+
+ MessageContext mc = TestUtils.getTestContext(xmlPayload);
+ mc.setVariable("endpoint", "https://test.wso2.com/");
+ String inlineExpression = "Using endpoint : ${var.endpoint} to process book : ${xpath('//catalog/book[1]')}";
+
+ boolean isContentAware = InlineExpressionUtil.isInlineSynapseExpressionsContentAware(inlineExpression);
+ Assert.assertTrue("Inline expression content aware should be true", isContentAware);
+
+ String result = InlineExpressionUtil.processInLineSynapseExpressionTemplate(mc, inlineExpression);
+ Assert.assertEquals("Inline expression result mismatch", expected, result);
+ }
+}