Repository: authorjapps/zerocode
Pull request #249 (2019-06-07 11:30:36)

ISS-5 # Add date.after and date.before assertions
PR to add functionality for issue #5. Added 4 test cases to _ZeroCodeJsonTestProcesorImplTest.java_ to test 'after' and 'before' conditions. Added 1 example test case to _http-testing_ module.


Patch:
diff --git a/core/src/main/java/org/jsmart/zerocode/core/engine/assertion/FieldHasDateAfterValueAsserter.java b/core/src/main/java/org/jsmart/zerocode/core/engine/assertion/FieldHasDateAfterValueAsserter.java
new file mode 100644
index 00000000..add71c1a
--- /dev/null
+++ b/core/src/main/java/org/jsmart/zerocode/core/engine/assertion/FieldHasDateAfterValueAsserter.java
@@ -0,0 +1,44 @@
+package org.jsmart.zerocode.core.engine.assertion;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
+
+public class FieldHasDateAfterValueAsserter implements JsonAsserter {
+	private final String path;
+	private final LocalDateTime expected;
+
+	public FieldHasDateAfterValueAsserter(String path, LocalDateTime expected) {
+		this.path = path;
+		this.expected = expected;
+	}
+
+	@Override
+	public String getPath() {
+		return path;
+	}
+
+	@Override
+	public AssertionReport actualEqualsToExpected(Object result) {
+		boolean areEqual;
+
+		if (result == null && expected == null) {
+			areEqual = true;
+		} else if (result == null) {
+			areEqual = false;
+		} else {
+			LocalDateTime resultDT = null;
+			try {
+				resultDT = LocalDateTime.parse((String) result,
+						DateTimeFormatter.ISO_DATE_TIME);
+				areEqual = resultDT.isAfter(expected);
+			} catch (DateTimeParseException ex) {
+				areEqual = false;
+			}
+		}
+
+		return areEqual ? AssertionReport.createFieldMatchesReport()
+				: AssertionReport.createFieldDoesNotMatchReport(path,
+						"Date After:" + expected, result);
+	}
+}
diff --git a/core/src/main/java/org/jsmart/zerocode/core/engine/assertion/FieldHasDateBeforeValueAsserter.java b/core/src/main/java/org/jsmart/zerocode/core/engine/assertion/FieldHasDateBeforeValueAsserter.java
new file mode 100644
index 00000000..a9c642b5
--- /dev/null
+++ b/core/src/main/java/org/jsmart/zerocode/core/engine/assertion/FieldHasDateBeforeValueAsserter.java
@@ -0,0 +1,44 @@
+package org.jsmart.zerocode.core.engine.assertion;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
+
+public class FieldHasDateBeforeValueAsserter implements JsonAsserter {
+	private final String path;
+	private final LocalDateTime expected;
+
+	public FieldHasDateBeforeValueAsserter(String path, LocalDateTime expected) {
+		this.path = path;
+		this.expected = expected;
+	}
+
+	@Override
+	public String getPath() {
+		return path;
+	}
+
+	@Override
+	public AssertionReport actualEqualsToExpected(Object result) {
+		boolean areEqual;
+
+		if (result == null && expected == null) {
+			areEqual = true;
+		} else if (result == null) {
+			areEqual = false;
+		} else {
+			LocalDateTime resultDT = null;
+			try {
+				resultDT = LocalDateTime.parse((String) result,
+						DateTimeFormatter.ISO_DATE_TIME);
+				areEqual = resultDT.isBefore(expected);
+			} catch (DateTimeParseException ex) {
+				areEqual = false;
+			}
+		}
+
+		return areEqual ? AssertionReport.createFieldMatchesReport()
+				: AssertionReport.createFieldDoesNotMatchReport(path, "Date Before:"
+						+ expected, result);
+	}
+}


Test patch:
diff --git a/core/src/main/java/org/jsmart/zerocode/core/engine/preprocessor/ZeroCodeJsonTestProcesorImpl.java b/core/src/main/java/org/jsmart/zerocode/core/engine/preprocessor/ZeroCodeJsonTestProcesorImpl.java
index 21a9b0b7..37630eae 100644
--- a/core/src/main/java/org/jsmart/zerocode/core/engine/preprocessor/ZeroCodeJsonTestProcesorImpl.java
+++ b/core/src/main/java/org/jsmart/zerocode/core/engine/preprocessor/ZeroCodeJsonTestProcesorImpl.java
@@ -22,11 +22,15 @@ import com.fasterxml.jackson.databind.node.JsonNodeType;
 import com.google.inject.Inject;
 import com.google.inject.name.Named;
 import com.jayway.jsonpath.JsonPath;
+
 import org.apache.commons.lang.text.StrSubstitutor;
+import org.jsmart.zerocode.core.domain.reports.LocalDateTimeDeserializer;
 import org.jsmart.zerocode.core.engine.assertion.*;
 
 import java.io.IOException;
 import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
 import java.util.*;
 
 import static java.lang.String.format;
@@ -55,6 +59,8 @@ public class ZeroCodeJsonTestProcesorImpl implements ZeroCodeJsonTestProcesor {
     public static final String ASSERT_VALUE_NOT_EQUAL_TO_NUMBER = "$NOT.EQ.";
     public static final String ASSERT_VALUE_GREATER_THAN = "$GT.";
     public static final String ASSERT_VALUE_LESSER_THAN = "$LT.";
+    public static final String ASSERT_DATE_AFTER = "$DATE.AFTER:";
+    public static final String ASSERT_DATE_BEFORE = "$DATE.BEFORE:";
     public static final String ASSERT_PATH_VALUE_NODE = "$";
     public static final String RAW_BODY = ".rawBody";
 
@@ -203,7 +209,14 @@ public class ZeroCodeJsonTestProcesorImpl implements ZeroCodeJsonTestProcesor {
                 } else if (value instanceof String && (value.toString()).startsWith(ASSERT_VALUE_LESSER_THAN)) {
                     String expected = ((String) value).substring(ASSERT_VALUE_LESSER_THAN.length());
                     asserter = new FieldHasLesserThanValueAsserter(path, new BigDecimal(expected));
-                } else {
+                } else if (value instanceof String && (value.toString()).startsWith(ASSERT_DATE_AFTER)) {
+                    String expected = ((String) value).substring(ASSERT_DATE_AFTER.length());
+                    asserter = new FieldHasDateAfterValueAsserter(path, parseLocalDateTime(expected));
+                }else if (value instanceof String && (value.toString()).startsWith(ASSERT_DATE_BEFORE)) {
+                    String expected = ((String) value).substring(ASSERT_DATE_BEFORE.length());
+                    asserter = new FieldHasDateBeforeValueAsserter(path, parseLocalDateTime(expected));
+                }
+                else {
                     asserter = new FieldHasExactValueAsserter(path, value);
                 }
 
@@ -332,4 +345,8 @@ public class ZeroCodeJsonTestProcesorImpl implements ZeroCodeJsonTestProcesor {
     private boolean isPropertyKey(String runTimeToken) {
         return propertyKeys.contains(runTimeToken);
     }
+    
+    private LocalDateTime parseLocalDateTime (String value){ 	
+    	return LocalDateTime.parse(value, DateTimeFormatter.ISO_DATE_TIME);
+    }
 }
diff --git a/core/src/test/java/org/jsmart/zerocode/core/engine/preprocessor/ZeroCodeJsonTestProcesorImplTest.java b/core/src/test/java/org/jsmart/zerocode/core/engine/preprocessor/ZeroCodeJsonTestProcesorImplTest.java
index 93749cc3..70d55a72 100644
--- a/core/src/test/java/org/jsmart/zerocode/core/engine/preprocessor/ZeroCodeJsonTestProcesorImplTest.java
+++ b/core/src/test/java/org/jsmart/zerocode/core/engine/preprocessor/ZeroCodeJsonTestProcesorImplTest.java
@@ -710,4 +710,139 @@ public class ZeroCodeJsonTestProcesorImplTest {
         assertThat(failedReports.get(0).toString(),
                 is("Assertion path '$.body.persons' with actual value '2' did not match the expected value 'Array of size $NOT.EQ.2'"));
     }
+    
+    @Test
+    public void testDateAfterBefore_both() throws Exception {
+        ScenarioSpec scenarioSpec = smartUtils.jsonFileToJava(
+                "date_after_before/dateAfterBefore_test_both.json",
+                ScenarioSpec.class);
+
+        final String assertionsSectionAsString = scenarioSpec.getSteps().get(0).getAssertions().toString();
+        String mockScenarioState = "{}";
+
+        final String resolvedAssertions = jsonPreProcessor.resolveStringJson(assertionsSectionAsString, mockScenarioState);
+        assertThat(resolvedAssertions, containsString("\"startDateTime\":\"$DATE.BEFORE:2015-09-14T09:49:34.000Z\","));
+        assertThat(resolvedAssertions, containsString("\"endDateTime\":\"$DATE.AFTER:2015-09-14T09:49:34.000Z\""));
+        
+        List<JsonAsserter> asserters = jsonPreProcessor.createAssertersFrom(resolvedAssertions);
+        assertThat(asserters.size(), is(3));
+
+        String mockTestResponse = "{\n" +
+                "	\"status\": 200,\n" +
+                "	\"body\": {\n" +
+                "	    \"projectDetails\": {\n" +
+                "            \"startDateTime\": \"2014-09-14T09:49:34.000Z\",\n" +
+                "            \"endDateTime\": \"2016-09-14T09:49:34.000Z\"\n" +
+                "        }\n" +
+                "    }\n" +
+                "}";
+    
+        
+        List<AssertionReport> failedReports = jsonPreProcessor.assertAllAndReturnFailed(asserters, mockTestResponse);
+        assertThat(failedReports.size(), is(0));
+    }
+    
+    @Test
+    public void testDateAfterBefore_fail_both() throws Exception {
+        ScenarioSpec scenarioSpec = smartUtils.jsonFileToJava(
+                "date_after_before/dateAfterBefore_test_fail_both.json",
+                ScenarioSpec.class);
+
+        final String assertionsSectionAsString = scenarioSpec.getSteps().get(0).getAssertions().toString();
+        String mockScenarioState = "{}";
+
+        final String resolvedAssertions = jsonPreProcessor.resolveStringJson(assertionsSectionAsString, mockScenarioState);
+        assertThat(resolvedAssertions, containsString("\"startDateTime\":\"$DATE.BEFORE:2016-09-14T09:49:34.000Z\","));
+        assertThat(resolvedAssertions, containsString("\"endDateTime\":\"$DATE.AFTER:2019-09-14T09:49:34.000Z\""));
+        
+        List<JsonAsserter> asserters = jsonPreProcessor.createAssertersFrom(resolvedAssertions);
+        assertThat(asserters.size(), is(3));
+
+        String mockTestResponse = "{\n" +
+                "	\"status\": 200,\n" +
+                "	\"body\": {\n" +
+                "	    \"projectDetails\": {\n" +
+                "	            \"startDateTime\": \"2017-04-14T11:49:56.000Z\",\n" +
+                "	            \"endDateTime\": \"2018-11-12T09:39:34.000Z\"\n" +
+                "        }\n" +
+                "    }\n" +
+                "}";
+    
+        
+        List<AssertionReport> failedReports = jsonPreProcessor.assertAllAndReturnFailed(asserters, mockTestResponse);
+
+        assertThat(failedReports.size(), is(2));
+        assertThat(failedReports.get(0).toString(),
+                is("Assertion path '$.body.projectDetails.startDateTime' with actual value '2017-04-14T11:49:56.000Z' "
+                		+ "did not match the expected value 'Date Before:2016-09-14T09:49:34'"));
+        assertThat(failedReports.get(1).toString(),
+                is("Assertion path '$.body.projectDetails.endDateTime' with actual value '2018-11-12T09:39:34.000Z' "
+                		+ "did not match the expected value 'Date After:2019-09-14T09:49:34'"));
+    }
+    
+    @Test
+    public void testDateAfterBefore_fail_afterSameDate() throws Exception {
+        ScenarioSpec scenarioSpec = smartUtils.jsonFileToJava(
+                "date_after_before/dateAfterBefore_test_fail_afterSameDate.json",
+                ScenarioSpec.class);
+
+        final String assertionsSectionAsString = scenarioSpec.getSteps().get(0).getAssertions().toString();
+        String mockScenarioState = "{}";
+
+        final String resolvedAssertions = jsonPreProcessor.resolveStringJson(assertionsSectionAsString, mockScenarioState);
+        assertThat(resolvedAssertions, containsString("\"startDateTime\":\"$DATE.AFTER:2015-09-14T09:49:34.000Z\""));
+        
+        List<JsonAsserter> asserters = jsonPreProcessor.createAssertersFrom(resolvedAssertions);
+        assertThat(asserters.size(), is(2));
+
+        String mockTestResponse = "{\n" +
+                "	\"status\": 200,\n" +
+                "	\"body\": {\n" +
+                "	    \"projectDetails\": {\n" +
+                "	            \"startDateTime\": \"2015-09-14T09:49:34.000Z\",\n" +
+                "        }\n" +
+                "    }\n" +
+                "}";
+    
+        
+        List<AssertionReport> failedReports = jsonPreProcessor.assertAllAndReturnFailed(asserters, mockTestResponse);
+
+        assertThat(failedReports.size(), is(1));
+        assertThat(failedReports.get(0).toString(),
+                is("Assertion path '$.body.projectDetails.startDateTime' with actual value '2015-09-14T09:49:34.000Z' "
+                		+ "did not match the expected value 'Date After:2015-09-14T09:49:34'"));
+    }
+    
+    @Test
+    public void testDateAfterBefore_fail_beforeSameDate() throws Exception {
+        ScenarioSpec scenarioSpec = smartUtils.jsonFileToJava(
+                "date_after_before/dateAfterBefore_test_fail_beforeSameDate.json",
+                ScenarioSpec.class);
+
+        final String assertionsSectionAsString = scenarioSpec.getSteps().get(0).getAssertions().toString();
+        String mockScenarioState = "{}";
+
+        final String resolvedAssertions = jsonPreProcessor.resolveStringJson(assertionsSectionAsString, mockScenarioState);
+        assertThat(resolvedAssertions, containsString("\"startDateTime\":\"$DATE.BEFORE:2015-09-14T09:49:34.000Z\""));
+        
+        List<JsonAsserter> asserters = jsonPreProcessor.createAssertersFrom(resolvedAssertions);
+        assertThat(asserters.size(), is(2));
+
+        String mockTestResponse = "{\n" +
+                "	\"status\": 200,\n" +
+                "	\"body\": {\n" +
+                " 		\"projectDetails\": {\n" +
+                "			\"startDateTime\": \"2015-09-14T09:49:34.000Z\",\n" +
+                "		}\n" +
+                "	}\n" +
+                "}";
+    
+        
+        List<AssertionReport> failedReports = jsonPreProcessor.assertAllAndReturnFailed(asserters, mockTestResponse);
+
+        assertThat(failedReports.size(), is(1));
+        assertThat(failedReports.get(0).toString(),
+                is("Assertion path '$.body.projectDetails.startDateTime' with actual value '2015-09-14T09:49:34.000Z' "
+                		+ "did not match the expected value 'Date Before:2015-09-14T09:49:34'"));
+    }
 }
\ No newline at end of file
diff --git a/core/src/test/resources/date_after_before/dateAfterBefore_test_both.json b/core/src/test/resources/date_after_before/dateAfterBefore_test_both.json
new file mode 100644
index 00000000..988ce03a
--- /dev/null
+++ b/core/src/test/resources/date_after_before/dateAfterBefore_test_both.json
@@ -0,0 +1,21 @@
+{
+    "scenarioName": "Assert that 'startDateTime' is before expected & 'endDateTime' is after expected",
+    "steps": [
+        {
+            "name": "get_project_details",
+            "url": "",
+            "operation": "",
+            "request": {
+            },
+            "assertions": {
+                "status": 200,
+                "body": {
+                "projectDetails": {
+	                    "startDateTime" : "$DATE.BEFORE:2015-09-14T09:49:34.000Z",
+	                    "endDateTime" : "$DATE.AFTER:2015-09-14T09:49:34.000Z"
+                    }
+                }
+            }
+        }
+    ]
+}
\ No newline at end of file
diff --git a/core/src/test/resources/date_after_before/dateAfterBefore_test_fail_afterSameDate.json b/core/src/test/resources/date_after_before/dateAfterBefore_test_fail_afterSameDate.json
new file mode 100644
index 00000000..b422f9af
--- /dev/null
+++ b/core/src/test/resources/date_after_before/dateAfterBefore_test_fail_afterSameDate.json
@@ -0,0 +1,20 @@
+{
+    "scenarioName": "Assert that 'startDateTime' is before expected & 'endDateTime' is after expected",
+    "steps": [
+        {
+            "name": "get_project_details",
+            "url": "",
+            "operation": "",
+            "request": {
+            },
+            "assertions": {
+                "status": 200,
+                "body": {
+                "projectDetails": {
+	                    "startDateTime" : "$DATE.AFTER:2015-09-14T09:49:34.000Z"
+                    }
+                }
+            }
+        }
+    ]
+}
\ No newline at end of file
diff --git a/core/src/test/resources/date_after_before/dateAfterBefore_test_fail_beforeSameDate.json b/core/src/test/resources/date_after_before/dateAfterBefore_test_fail_beforeSameDate.json
new file mode 100644
index 00000000..1110c8c5
--- /dev/null
+++ b/core/src/test/resources/date_after_before/dateAfterBefore_test_fail_beforeSameDate.json
@@ -0,0 +1,20 @@
+{
+    "scenarioName": "Assert that 'startDateTime' is before expected & 'endDateTime' is after expected",
+    "steps": [
+        {
+            "name": "get_project_details",
+            "url": "",
+            "operation": "",
+            "request": {
+            },
+            "assertions": {
+                "status": 200,
+                "body": {
+                "projectDetails": {
+	                    "startDateTime" : "$DATE.BEFORE:2015-09-14T09:49:34.000Z"
+                    }
+                }
+            }
+        }
+    ]
+}
\ No newline at end of file
diff --git a/core/src/test/resources/date_after_before/dateAfterBefore_test_fail_both.json b/core/src/test/resources/date_after_before/dateAfterBefore_test_fail_both.json
new file mode 100644
index 00000000..12240e22
--- /dev/null
+++ b/core/src/test/resources/date_after_before/dateAfterBefore_test_fail_both.json
@@ -0,0 +1,21 @@
+{
+    "scenarioName": "Assert that 'startDateTime' is before expected & 'endDateTime' is after expected",
+    "steps": [
+        {
+            "name": "get_project_details",
+            "url": "",
+            "operation": "",
+            "request": {
+            },
+            "assertions": {
+                "status": 200,
+                "body": {
+                "projectDetails": {
+	                    "startDateTime" : "$DATE.BEFORE:2016-09-14T09:49:34.000Z",
+	                    "endDateTime" : "$DATE.AFTER:2019-09-14T09:49:34.000Z"
+                    }
+                }
+            }
+        }
+    ]
+}
\ No newline at end of file
diff --git a/http-testing/src/test/java/org/jsmart/zerocode/testhelp/tests/helloworlddateafterbefore/HelloWorldDateAfterBeforeTest.java b/http-testing/src/test/java/org/jsmart/zerocode/testhelp/tests/helloworlddateafterbefore/HelloWorldDateAfterBeforeTest.java
new file mode 100644
index 00000000..7924fca7
--- /dev/null
+++ b/http-testing/src/test/java/org/jsmart/zerocode/testhelp/tests/helloworlddateafterbefore/HelloWorldDateAfterBeforeTest.java
@@ -0,0 +1,18 @@
+package org.jsmart.zerocode.testhelp.tests.helloworlddateafterbefore;
+
+import org.jsmart.zerocode.core.domain.JsonTestCase;
+import org.jsmart.zerocode.core.domain.TargetEnv;
+import org.jsmart.zerocode.core.runner.ZeroCodeUnitRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@TargetEnv("github_host.properties")
+@RunWith(ZeroCodeUnitRunner.class)
+public class HelloWorldDateAfterBeforeTest {
+
+    @Test
+    @JsonTestCase("helloworld_date/hello_world_date_after_before_test.json")
+    public void testCreatedDateAfterBefore() throws Exception {
+
+    }
+}
diff --git a/http-testing/src/test/resources/helloworld_date/hello_world_date_after_before_test.json b/http-testing/src/test/resources/helloworld_date/hello_world_date_after_before_test.json
new file mode 100644
index 00000000..eba65c76
--- /dev/null
+++ b/http-testing/src/test/resources/helloworld_date/hello_world_date_after_before_test.json
@@ -0,0 +1,19 @@
+{
+    "scenarioName": "Assert that 'created_at' is before expected & 'updated_at' is after expected",
+    "steps": [
+        {
+            "name": "get_user_details",
+            "url": "/users/octocat",
+            "operation": "GET",
+            "request": {
+            },
+            "assertions": {
+                "status": 200,
+                "body": {
+                    "created_at" : "$DATE.BEFORE:2015-09-14T09:49:34.000Z",
+                    "updated_at" : "$DATE.AFTER:2015-09-14T09:49:34.000Z"
+                }
+            }
+        }
+    ]
+}
\ No newline at end of file