You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nlpcraft.apache.org by se...@apache.org on 2020/09/07 11:27:19 UTC

[incubator-nlpcraft] branch NLPCRAFT-113 created (now 850d134)

This is an automated email from the ASF dual-hosted git repository.

sergeykamov pushed a change to branch NLPCRAFT-113
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git.


      at 850d134  WIP.

This branch includes the following new commits:

     new 850d134  WIP.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[incubator-nlpcraft] 01/01: WIP.

Posted by se...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

sergeykamov pushed a commit to branch NLPCRAFT-113
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git

commit 850d134fa18eab8c3f8faa154511ac9aae66113a
Author: Sergey Kamov <se...@apache.org>
AuthorDate: Mon Sep 7 14:27:11 2020 +0300

    WIP.
---
 nlpcraft/pom.xml                                   |   5 +
 .../nlpcraft/server/rest/NCRestAskSpec.scala       |  82 ++++++++++
 .../nlpcraft/server/rest/NCRestClearSpec.scala     |  28 ++++
 .../nlpcraft/server/rest/NCRestCompanySpec.scala   |  70 ++++++++
 .../nlpcraft/server/rest/NCRestFeedbackSpec.scala  |  61 +++++++
 .../apache/nlpcraft/server/rest/NCRestSpec.scala   | 177 +++++++++++++++++++++
 .../nlpcraft/server/rest/NCRestUserSpec.scala      |  96 +++++++++++
 pom.xml                                            |   6 +
 8 files changed, 525 insertions(+)

diff --git a/nlpcraft/pom.xml b/nlpcraft/pom.xml
index 2e087bd..69a812a 100644
--- a/nlpcraft/pom.xml
+++ b/nlpcraft/pom.xml
@@ -236,6 +236,11 @@
             <artifactId>scalatest_${scala.base}</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>com.jayway.jsonpath</groupId>
+            <artifactId>json-path</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/NCRestAskSpec.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/NCRestAskSpec.scala
new file mode 100644
index 0000000..b1d35e3
--- /dev/null
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/NCRestAskSpec.scala
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.nlpcraft.server.rest
+
+import org.junit.jupiter.api.Assertions._
+import org.junit.jupiter.api.Test
+
+import scala.collection.JavaConverters._
+
+class NCRestAskSpec extends NCRestSpec {
+    private def askAsync(): String = {
+        var id: String = null
+
+        post("ask", "txt" → "LA weather", "mdlId" → "nlpcraft.weather.ex")(
+            ("$.srvReqId", (srvReqId: String) ⇒ id = srvReqId)
+        )
+
+        assertNotNull(id)
+
+        id
+    }
+
+    @Test
+    def testSync(): Unit = {
+        post(
+            "ask/sync",
+            "txt" → "LA weather",
+            "mdlId" → "nlpcraft.weather.ex"
+        )(("$.state.status", (status: String) ⇒ assertEquals("QRY_READY", status)))
+    }
+
+    @Test
+    def testAsync(): Unit = {
+        // Asks.
+        askAsync()
+        askAsync()
+
+        // Checks non empty states.
+        post("check")(("$.states", (states: DataMap) ⇒ assertFalse(states.isEmpty)))
+
+        // Cancels all.
+        post("cancel")()
+
+        // Checks empty states.
+        post("check")(("$.states", (states: DataMap) ⇒ assertTrue(states.isEmpty)))
+
+        // Asks.
+        val id1 = askAsync()
+        val id2 = askAsync()
+        val id3 = askAsync()
+
+        // Cancels two.
+        post("cancel", "srvReqIds" → Set(id1, id2).asJava)()
+
+        // Checks states.
+        post("check")(("$.states", (states: DataMap) ⇒ {
+            assertEquals(1, states.size())
+            assertEquals(id3, states.get(0).get("srvReqId").asInstanceOf[String])
+        }))
+
+        // Cancels last one.
+        post("cancel", "srvReqIds" → Set(id3).asJava)()
+
+        // Checks empty states.
+        post("check")(("$.states", (states: DataMap) ⇒ assertTrue(states.isEmpty)))
+    }
+}
diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/NCRestClearSpec.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/NCRestClearSpec.scala
new file mode 100644
index 0000000..8782c82
--- /dev/null
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/NCRestClearSpec.scala
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.nlpcraft.server.rest
+
+import org.junit.jupiter.api.Test
+
+class NCRestClearSpec extends NCRestSpec {
+    @Test
+    def test(): Unit = {
+        post("clear/conversation", "mdlId" → "nlpcraft.weather.ex")()
+        post("clear/dialog", "mdlId" → "nlpcraft.weather.ex")()
+    }
+}
diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/NCRestCompanySpec.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/NCRestCompanySpec.scala
new file mode 100644
index 0000000..213016c
--- /dev/null
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/NCRestCompanySpec.scala
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.nlpcraft.server.rest
+
+import org.junit.jupiter.api.Assertions._
+import org.junit.jupiter.api.Test
+
+class NCRestCompanySpec extends NCRestSpec {
+    @Test
+    def testCurrentCompany(): Unit = {
+        var name: String = null
+
+        post("company/get")(("$.name", (n: String) ⇒ {
+            assertNotNull(n)
+
+            name = n
+        }))
+
+        post("company/update", "name" → "newName")()
+        post("company/get")(("$.name", (n: String) ⇒ assertEquals("newName", n)))
+        post("company/update", "name" → name)()
+        post("company/get")(("$.name", (n: String) ⇒ assertEquals(name, n)))
+    }
+
+    @Test
+    def testNewCompany(): Unit = {
+        val adminEmail = s"${rnd()}@test.com"
+        val adminPswd = "test"
+
+        // Adds company.
+        post(
+            "company/add",
+            "name" → rnd(),
+            "adminEmail" → adminEmail,
+            "adminPasswd" → adminPswd,
+            "adminFirstName" → "test",
+            "adminLastName" → "test"
+        )(
+            ("$.token", (tkn: String) ⇒ assertNotNull(tkn)),
+            ("$.adminId", (id: Number) ⇒ assertNotNull(id))
+        )
+
+        // Connects as new company admin.
+        var adminTkn = signin(adminEmail, adminPswd)
+
+        // Disconnects.
+        signout(adminTkn)
+
+        // Connects again.
+        adminTkn = signin(adminEmail, adminPswd)
+
+        post("company/token/reset", adminTkn)()
+        post("company/delete", adminTkn)()
+    }
+}
diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/NCRestFeedbackSpec.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/NCRestFeedbackSpec.scala
new file mode 100644
index 0000000..59e0b9f
--- /dev/null
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/NCRestFeedbackSpec.scala
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.nlpcraft.server.rest
+
+import org.junit.jupiter.api.Assertions._
+import org.junit.jupiter.api.Test
+
+class NCRestFeedbackSpec extends NCRestSpec {
+    /**
+      *
+      */
+    private def addFeedback(): Long = {
+        var fId: Long = 0
+
+        post("feedback/add", "srvReqId" → rnd(), "score" → 0.5)(("$.id", (id: Number) ⇒ fId = id.longValue()))
+
+        assertTrue(fId != 0)
+
+        fId
+    }
+
+    @Test
+    def test(): Unit = {
+        // Gets.
+        post("feedback/all")()
+
+        // Adds.
+        val id = addFeedback()
+
+        // Gets and checks.
+        post("feedback/all")(("$.feedback", (fs: DataMap) ⇒ assertTrue(containsLong(fs, "id", id))))
+
+        // Deletes by id.
+        post("feedback/delete", "id" → id)()
+
+        // Adds few.
+        addFeedback()
+        addFeedback()
+
+        // Deletes all.
+        post("feedback/delete")()
+
+        // Gets and checks.
+        post("feedback/all")(("$.feedback", (feedbacks: DataMap) ⇒ assertTrue(feedbacks.isEmpty)))
+    }
+}
diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/NCRestSpec.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/NCRestSpec.scala
new file mode 100644
index 0000000..dcf3355
--- /dev/null
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/NCRestSpec.scala
@@ -0,0 +1,177 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.nlpcraft.server.rest
+
+import java.util
+import java.util.UUID
+
+import com.google.gson.GsonBuilder
+import com.google.gson.reflect.TypeToken
+import com.jayway.jsonpath.JsonPath
+import org.apache.http.HttpResponse
+import org.apache.http.client.ResponseHandler
+import org.apache.http.client.methods.HttpPost
+import org.apache.http.entity.StringEntity
+import org.apache.http.impl.client.HttpClients
+import org.apache.http.util.EntityUtils
+import org.junit.jupiter.api.Assertions._
+import org.junit.jupiter.api.{AfterEach, BeforeEach}
+
+import scala.collection.JavaConverters._
+
+object NCRestSpec {
+    private final val DFLT_BASEURL = "http://localhost:8081/api/v1/"
+    private final val TYPE_RESP = new TypeToken[util.Map[String, Object]]() {}.getType
+    private final val GSON = new GsonBuilder().setPrettyPrinting().create()
+    private final val CLI = HttpClients.createDefault
+    private final val HANDLER: ResponseHandler[java.util.Map[String, Object]] =
+        (resp: HttpResponse) ⇒ {
+            val code = resp.getStatusLine.getStatusCode
+            val e = resp.getEntity
+
+            val js = if (e != null) EntityUtils.toString(e) else null
+
+            if (js == null)
+                throw new RuntimeException(s"Unexpected empty response [code=$code]")
+
+            code match {
+                case 200 ⇒ GSON.fromJson(js, TYPE_RESP)
+
+                case 400 ⇒ throw new RuntimeException(js)
+                case _ ⇒ throw new RuntimeException(s"Unexpected response [code=$code, response=$js]")
+            }
+        }
+
+    /**
+      *
+      * @param url
+      * @param ps
+      */
+    private def post0(url: String, ps: (String, Any)*): Map[String, Object] = {
+        val post = new HttpPost(DFLT_BASEURL + url)
+
+        post.setHeader("Content-Type", "application/json")
+        post.setEntity(new StringEntity(GSON.toJson(ps.filter(_._2 != null).toMap.asJava), "UTF-8"))
+
+        try
+            CLI.execute(post, HANDLER).asScala.toMap
+        finally
+            post.releaseConnection()
+    }
+}
+
+import org.apache.nlpcraft.server.rest.NCRestSpec._
+
+class NCRestSpec {
+    final val TYPE_MAP = new TypeToken[util.Map[String, Object]]() {}.getType
+    final val TYPE_LIST_MAP = new TypeToken[util.List[util.Map[String, Object]]]() {}.getType
+
+    private var acsTok: String = _
+
+    type DataMap = java.util.List[java.util.Map[String, Object]]
+    type JList[T] = java.util.List[T]
+
+    private def checkStatus(resp: Map[String, Object]): Unit = {
+        assertTrue(resp.contains("status"))
+        assertEquals("API_OK", resp("status"))
+    }
+
+    @BeforeEach
+    def signin(): Unit = acsTok = signin("admin@admin.com", "admin")
+
+    @AfterEach
+    def signout(): Unit =
+        if (acsTok != null) {
+            signout(acsTok)
+
+            acsTok = null
+        }
+
+    protected def signout(tkn: String): Unit = {
+        val resp = post0("signout", "acsTok" → tkn)
+
+        checkStatus(resp)
+    }
+
+    protected def signin(email: String, passwd: String): String = {
+        val resp = post0("signin", "email" → email, "passwd" → passwd)
+
+        val tkn = resp("acsTok").asInstanceOf[String]
+
+        assertNotNull(tkn)
+
+        tkn
+    }
+
+    protected def post[T](url: String, tkn: String, ps: (String, Any)*)(validations: (String, T ⇒ Unit)*): Unit = {
+        val resp = post0(url, Seq("acsTok" → tkn) ++ ps:_*)
+
+        checkStatus(resp)
+
+        val js = GSON.toJson(resp.asJava)
+
+        println(s"Request [url=$url, parameters=[${ps.map { case (k, v) ⇒ s"$k=$v" }.mkString(", ")}]")
+        println("Response:")
+        println(js)
+
+        val ctx = JsonPath.parse(js)
+
+        validations.foreach { case (name, check) ⇒
+            val v: Object = ctx.read(name)
+
+            println(s"Checked value [$name=$v]")
+
+            check(v match {
+                case arr: net.minidev.json.JSONArray ⇒ (0 until arr.size()).map(i ⇒ arr.get(i)).asJava.asInstanceOf[T]
+                case _ ⇒ v.asInstanceOf[T]
+            })
+        }
+    }
+
+
+    protected def post[T](url: String, ps: (String, Any)*)(validations: (String, T ⇒ Unit)*): Unit = {
+        assertNotNull(acsTok)
+
+        post(url, acsTok, ps:_*)(validations:_*)
+    }
+
+    /**
+      *
+      * @param data
+      * @param field
+      * @param extract
+      * @param expected
+      */
+    protected def contains[T](data: DataMap, field: String, extract: Object ⇒ T, expected: T): Boolean =
+        data.asScala.exists(p ⇒ extract(p.get(field)) == expected)
+
+    /**
+      *
+      * @param data
+      * @param field
+      * @param expected
+      */
+    protected def containsLong(data: DataMap, field: String, expected: Long): Boolean =
+        contains(data, field, (o: Object) ⇒ o.asInstanceOf[Number].longValue(), expected)
+
+    /**
+      *
+      * @return
+      */
+    protected def rnd(): String = UUID.randomUUID().toString
+}
diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/NCRestUserSpec.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/NCRestUserSpec.scala
new file mode 100644
index 0000000..97c20b3
--- /dev/null
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/NCRestUserSpec.scala
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.nlpcraft.server.rest
+
+import org.junit.jupiter.api.Assertions._
+import org.junit.jupiter.api.Test
+
+class NCRestUserSpec extends NCRestSpec {
+    private def addUser(): Long = {
+        var usrId: Long = 0
+
+        post(
+            "user/add",
+            "email" → s"${rnd()}@test.com",
+            "passwd" → "test",
+            "firstName" → "test",
+            "lastName" → "test",
+            "isAdmin" → false
+        )(
+            ("$.id", (id: Number) ⇒ usrId = id.longValue())
+        )
+
+        assertTrue(usrId != 0)
+
+        usrId
+    }
+
+    @Test
+    def test(): Unit = {
+        // Checks own ID.
+        post("user/get")(("$.id", (id: Number) ⇒ assertNotNull(id)))
+
+        // Adds user.
+        val id1 = addUser()
+
+        // Checks.
+        post("user/get", "id" → id1)(("$.id", (id: Number) ⇒ assertEquals(id1, id.longValue())))
+
+        // Updates.
+        post("user/update", "firstName" → "firstName", "lastName" → "lastName")()
+
+        // Checks updated.
+        post("user/get")(
+            ("$.firstName", (firstName: String) ⇒ assertEquals(firstName, "firstName")),
+            ("$.lastName", (lastName: String) ⇒ assertEquals(lastName, "lastName"))
+        )
+
+        // Updates (special cases).
+        post("user/admin", "id" → id1, "admin" → true)()
+        post("user/admin", "id" → id1, "admin" → false)()
+        post("user/passwd/reset", "id" → id1, "newPasswd" → "test1")()
+
+        // Checks existed.
+        post("user/all")(("$.users", (users: DataMap) ⇒ assertTrue(containsLong(users, "id", id1))))
+
+        // Deletes.
+        post("user/delete", "id" → id1)()
+
+        // Checks not existed.
+        post("user/all")(("$.users", (users: DataMap) ⇒ assertFalse(containsLong(users, "id", id1))))
+
+        // Adds.
+        val id2 = addUser()
+        val id3 = addUser()
+
+        // Checks existed.
+        post("user/all")(("$.users", (users: DataMap) ⇒ {
+            assertTrue(containsLong(users, "id", id2))
+            assertTrue(containsLong(users, "id", id3))
+        }))
+
+        // Deletes.
+        post("user/delete")()
+
+        // Checks not existed.
+        post("user/all")(("$.users", (users: DataMap) ⇒ {
+            assertFalse(containsLong(users, "id", id2))
+            assertFalse(containsLong(users, "id", id3))
+        }))
+    }
+}
diff --git a/pom.xml b/pom.xml
index 0541d45..9ae607c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -145,6 +145,7 @@
         <lightstep.ver>0.0.3</lightstep.ver>
         <lightstep.grpc.ver>0.15.8</lightstep.grpc.ver>
         <junit.ver>5.5.1</junit.ver>
+        <jsonpath.ver>2.4.0</jsonpath.ver>
 
         <!-- Force specific encoding on text resources. -->
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -477,6 +478,11 @@
                 <artifactId>junit-jupiter-engine</artifactId>
                 <version>${junit.ver}</version>
             </dependency>
+            <dependency>
+                <groupId>com.jayway.jsonpath</groupId>
+                <artifactId>json-path</artifactId>
+                <version>${jsonpath.ver}</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>