From 9b7f7a63e70b173e680fb0496dc356c4495c099c Mon Sep 17 00:00:00 2001
From: rschoene <rene.schoene@tu-dresden.de>
Date: Tue, 25 Jul 2023 17:15:12 +0200
Subject: [PATCH] finished rest-client-server test.

- document constraint for rest-client receiving port to only support tokens right now
---
 pages/docs/handlers.md                        |  6 +-
 .../tests/RestClientServerTest.java           | 74 +++++++++++++++++--
 2 files changed, 71 insertions(+), 9 deletions(-)

diff --git a/pages/docs/handlers.md b/pages/docs/handlers.md
index f7ada19..f126ea1 100644
--- a/pages/docs/handlers.md
+++ b/pages/docs/handlers.md
@@ -14,6 +14,7 @@ Uses Java methods to supply values (receive) and for callbacks (send).
     - First leading slash not included in topic.
     - Currently, the default mappings are applied, which requires a consumer to expect `byte[]` (instead of a more intuitive token or node value). This might change in future versions.
 
+
 ## MQTT
 
 Use an MQTT broker to receive and send messages.
@@ -31,6 +32,7 @@ Use an MQTT broker to receive and send messages.
     - Mqtt is selected by default, so this dependency therefore is required "by default".
     - Might work with other versions of `org.fusesource.mqtt-client.mqtt.client` as well.
 
+
 ## REST Server
 
 Create a new REST server with its own target routes.
@@ -38,13 +40,14 @@ Create a new REST server with its own target routes.
 - Protocol identifier: `rest`
 - URI scheme: `rest://localhost[:port]/<path>`
 - Default port: 4567
-- Type for mapping definitions: `String` --> TODO --> `byte[]`
+- Type for mapping definitions: `byte[]`
 - Required runtime dependencies:
     - `group: 'com.sparkjava', name: 'spark-core', version: '2.9.3'`
 - Receive behaviour: Upon connection, create a new PUT connection and pass the value of every call to this PUT route to the receiving port.
 - Send behaviour: Upon connection, create a new GET connection and serve the latest value at this GET route.
 - Additional remarks:
     - Host is always `localhost`.
+    - Targets to be invoked need to replace `rest` with `http`
     - Might work with newer versions of `com.sparkjava.spark-core` as well.
     - For debugging, it is beneficial to include an implementation for [SLF4J][slf4j].
 
@@ -62,5 +65,6 @@ Invoke REST routes to fetch and send values.
 - Send behaviour: When the value to be sent changes, a PUT request sends this data.
 - Additional remarks:
     - Invoked target replaces `restClient` with `http`
+    - **Important constraint**: Receiving ports are only supported for tokens, since they interrupt the getter method!
 
 [slf4j]: https://www.slf4j.org/manual.html
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/RestClientServerTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/RestClientServerTest.java
index ff22f4f..bcfaea9 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/RestClientServerTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/RestClientServerTest.java
@@ -1,7 +1,9 @@
 package org.jastadd.ragconnect.tests;
 
+import org.jastadd.ragconnect.tests.utils.TestChecker;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 import restClientServer.ast.*;
 
@@ -16,6 +18,10 @@ import static org.assertj.core.api.Assertions.assertThat;
  */
 public class RestClientServerTest extends RagConnectTest {
   private Root root;
+  private TestChecker checker;
+
+  private static final String TOPIC_NT_A_VALUE = "nt/a/value";
+  private static final String TOPIC_NT_A_INNER_VALUE = "nt/a/inner/value";
 
   @Test
   public void testSimpleSenderRest() throws IOException {
@@ -43,20 +49,72 @@ public class RestClientServerTest extends RagConnectTest {
     assertThat(root.getReceiverRoot().getReceivedValue()).isEqualTo(2);
   }
 
-//  @Test
-//  public void testA() throws IOException {
-//    A a2 = new A().setName("a2");
-//    model.addMultiple(a2);
-//    a2.setId(11);
-//    assertThat(a2.connectId("restClient://localhost:5000/write-single-a", true)).isTrue();
-//    a2.setId(23);
-//  }
+  @Test
+  public void testNonterminalSenderRest() throws IOException {
+    A a = new A().setValue("a1");
+    a.setInner(new Inner().setInnerValue("1"));
+    root.getSenderRoot().setSingleA(a);
+
+    checker.put(TOPIC_NT_A_VALUE, "a1")
+            .put(TOPIC_NT_A_INNER_VALUE, "1");
+
+    assertThat(root.getReceiverRoot().connectSomeA("rest://localhost:4567/put-nt")).isTrue();
+    assertThat(root.getSenderRoot().connectSingleA("restClient://localhost:4567/put-nt", true)).isTrue();
+
+    communicateNonterminal();
+  }
+
+  @Test
+  @Disabled("Receiving nonterminals using restClient is not supported yet")
+  public void testNonterminalSenderRestClient() throws IOException {
+    A a = new A().setValue("a1");
+    a.setInner(new Inner().setInnerValue("1"));
+    root.getSenderRoot().setSingleA(a);
+
+    assertThat(root.getReceiverRoot().connectSomeA("restClient://localhost:4567/serve-nt")).isTrue();
+    assertThat(root.getSenderRoot().connectSingleA("rest://localhost:4567/serve-nt", true)).isTrue();
+
+    communicateNonterminal();
+  }
+
+  private void communicateNonterminal() {
+    A a = root.getSenderRoot().getSingleA();
+
+    checker.check();
+
+    a.setValue("a23");
+    checker.put(TOPIC_NT_A_VALUE, "a23").check();
+
+    a.getInner().setInnerValue("abc");
+    checker.put(TOPIC_NT_A_INNER_VALUE, "abc").check();
+  }
 
   @BeforeEach
   public void createModel() {
     root = new Root();
     root.setReceiverRoot(new ReceiverRoot());
     root.setSenderRoot(new SenderRoot());
+
+    checker = new TestChecker().setActualNumberOfValues(() -> 0);
+    checker.setCheckForString(TOPIC_NT_A_VALUE, (name, expected) ->
+                    assertThat(someAValue()).describedAs(name).isEqualTo(expected))
+            .setCheckForString(TOPIC_NT_A_INNER_VALUE, (name, expected) ->
+                    assertThat(someAInnerValueOrNull()).describedAs(name).isEqualTo(expected))
+    ;
+  }
+
+  private String someAValue() {
+    if (root.getReceiverRoot().getSomeA() == null) {
+      return null;
+    }
+    return root.getReceiverRoot().getSomeA().getValue();
+  }
+
+  private String someAInnerValueOrNull() {
+    if (root.getReceiverRoot().getSomeA() == null || root.getReceiverRoot().getSomeA().getInner() == null) {
+      return null;
+    }
+    return root.getReceiverRoot().getSomeA().getInner().getInnerValue();
   }
 
   @AfterEach
-- 
GitLab