You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2021/02/09 04:29:47 UTC

[james-project] 19/33: JAMES-3491 WebSocketPushEnable integration test

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

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit f0d38eedf38f013177a13de1a510db672fe824ef
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Feb 5 10:11:12 2021 +0700

    JAMES-3491 WebSocketPushEnable integration test
---
 .../jmap/rfc8621/contract/WebSocketContract.scala  | 207 ++++++++++++++++++++-
 1 file changed, 206 insertions(+), 1 deletion(-)

diff --git a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/WebSocketContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/WebSocketContract.scala
index 9bd810c..f47f734 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/WebSocketContract.scala
+++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/WebSocketContract.scala
@@ -22,10 +22,13 @@ import java.net.{ProtocolException, URI}
 
 import net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson
 import org.apache.james.GuiceJamesServer
+import org.apache.james.jmap.api.model.AccountId
 import org.apache.james.jmap.draft.JmapGuiceProbe
 import org.apache.james.jmap.rfc8621.contract.Fixture._
+import org.apache.james.mailbox.model.MailboxPath
+import org.apache.james.modules.MailboxProbeImpl
 import org.apache.james.utils.DataProbeImpl
-import org.assertj.core.api.Assertions.assertThatThrownBy
+import org.assertj.core.api.Assertions.{assertThat, assertThatThrownBy}
 import org.junit.jupiter.api.{BeforeEach, Test}
 import sttp.capabilities.WebSockets
 import sttp.client3.monad.IdMonad
@@ -37,6 +40,8 @@ import sttp.monad.syntax.MonadErrorOps
 import sttp.ws.WebSocketFrame
 import sttp.ws.WebSocketFrame.Text
 
+import scala.jdk.CollectionConverters._
+
 trait WebSocketContract {
   private lazy val backend: SttpBackend[Identity, WebSockets] = OkHttpSyncBackend()
   private lazy implicit val monadError: MonadError[Identity] = IdMonad
@@ -95,6 +100,66 @@ trait WebSocketContract {
   }
 
   @Test
+  def executingSeveralAPICallsShouldBePossible(server: GuiceJamesServer): Unit = {
+    val response: Either[String, List[String]] =
+      authenticatedRequest(server)
+        .response(asWebSocket[Identity, List[String]] {
+          ws =>
+            List({
+              ws.send(WebSocketFrame.text(
+                """{
+                  |  "@type": "Request",
+                  |  "requestId": "req-36",
+                  |  "using": [ "urn:ietf:params:jmap:core"],
+                  |  "methodCalls": [
+                  |    [
+                  |      "Core/echo",
+                  |      {
+                  |        "arg1": "1",
+                  |        "arg2": "arg2data"
+                  |      },
+                  |      "c1"
+                  |    ]
+                  |  ]
+                  |}""".stripMargin))
+              ws.receive()
+                .map {
+                  case t: Text => t.payload
+                }
+            }, {
+              Thread.sleep(200)
+
+              ws.send(WebSocketFrame.text(
+                """{
+                  |  "@type": "Request",
+                  |  "requestId": "req-36",
+                  |  "using": [ "urn:ietf:params:jmap:core"],
+                  |  "methodCalls": [
+                  |    [
+                  |      "Core/echo",
+                  |      {
+                  |        "arg1": "2",
+                  |        "arg2": "arg2data"
+                  |      },
+                  |      "c1"
+                  |    ]
+                  |  ]
+                  |}""".stripMargin))
+
+              ws.receive()
+                .map {
+                  case t: Text => t.payload
+                }
+            })
+        })
+        .send(backend)
+        .body
+
+    assertThat(response.toOption.get.asJava)
+      .hasSize(2)
+  }
+
+  @Test
   def apiRequestsShouldBeProcessedWhenNoRequestId(server: GuiceJamesServer): Unit = {
     val response: Either[String, String] =
       authenticatedRequest(server)
@@ -362,6 +427,146 @@ trait WebSocketContract {
                    |}""".stripMargin)
   }
 
+  @Test
+  def pushEnableRequestsShouldBeProcessed(server: GuiceJamesServer): Unit = {
+    val bobPath = MailboxPath.inbox(BOB)
+    val accountId: AccountId = AccountId.fromUsername(BOB)
+    val mailboxId = server.getProbe(classOf[MailboxProbeImpl]).createMailbox(bobPath)
+
+    Thread.sleep(100)
+
+    val response: Either[String, List[String]] =
+      authenticatedRequest(server)
+        .response(asWebSocket[Identity, List[String]] {
+          ws =>
+            ws.send(WebSocketFrame.text(
+              """{
+                |  "@type": "WebSocketPushEnable",
+                |  "dataTypes": ["Mailbox", "Email"]
+                |}""".stripMargin))
+
+            Thread.sleep(100)
+
+            ws.send(WebSocketFrame.text(
+              s"""{
+                 |  "@type": "Request",
+                 |  "requestId": "req-36",
+                 |  "using": ["urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail"],
+                 |  "methodCalls": [
+                 |    ["Email/set", {
+                 |      "accountId": "$ACCOUNT_ID",
+                 |      "create": {
+                 |        "aaaaaa":{
+                 |          "mailboxIds": {
+                 |             "${mailboxId.serialize}": true
+                 |          }
+                 |        }
+                 |      }
+                 |    }, "c1"]]
+                 |}""".stripMargin))
+
+            List(
+            ws.receive()
+              .map { case t: Text =>
+                t.payload
+              },
+            ws.receive()
+              .map { case t: Text =>
+                t.payload
+              },
+            ws.receive()
+              .map { case t: Text =>
+                t.payload
+              })
+        })
+        .send(backend)
+        .body
+
+    Thread.sleep(100)
+
+    val jmapGuiceProbe: JmapGuiceProbe = server.getProbe(classOf[JmapGuiceProbe])
+    val emailState: String = jmapGuiceProbe.getLatestEmailState(accountId).getValue.toString
+    val mailboxState: String = jmapGuiceProbe.getLatestMailboxState(accountId).getValue.toString
+
+    val mailboxStateChange: String = s"""{"@type":"StateChange","changed":{"$ACCOUNT_ID":{"Mailbox":"$mailboxState"}}}"""
+    val emailStateChange: String = s"""{"@type":"StateChange","changed":{"$ACCOUNT_ID":{"Email":"$emailState"}}}"""
+
+    assertThat(response.toOption.get.asJava)
+      .hasSize(3) // email notification + mailbox notification + API response
+      .contains(mailboxStateChange, emailStateChange)
+  }
+
+  @Test
+  def pushEnableShouldUpdatePreviousSubscriptions(server: GuiceJamesServer): Unit = {
+    val bobPath = MailboxPath.inbox(BOB)
+    val mailboxId = server.getProbe(classOf[MailboxProbeImpl]).createMailbox(bobPath)
+    val accountId: AccountId = AccountId.fromUsername(BOB)
+    Thread.sleep(100)
+
+    val response: Either[String, List[String]] =
+      authenticatedRequest(server)
+        .response(asWebSocket[Identity, List[String]] {
+          ws =>
+            ws.send(WebSocketFrame.text(
+              """{
+                |  "@type": "WebSocketPushEnable",
+                |  "dataTypes": ["Mailbox", "Email"]
+                |}""".stripMargin))
+
+            Thread.sleep(100)
+
+            ws.send(WebSocketFrame.text(
+              """{
+                |  "@type": "WebSocketPushEnable",
+                |  "dataTypes": ["Mailbox"]
+                |}""".stripMargin))
+
+            Thread.sleep(100)
+
+            ws.send(WebSocketFrame.text(
+              s"""{
+                 |  "@type": "Request",
+                 |  "requestId": "req-36",
+                 |  "using": ["urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail"],
+                 |  "methodCalls": [
+                 |    ["Email/set", {
+                 |      "accountId": "$ACCOUNT_ID",
+                 |      "create": {
+                 |        "aaaaaa":{
+                 |          "mailboxIds": {
+                 |             "${mailboxId.serialize}": true
+                 |          }
+                 |        }
+                 |      }
+                 |    }, "c1"]]
+                 |}""".stripMargin))
+
+            List(ws.receive()
+              .map { case t: Text =>
+                t.payload
+            },
+            ws.receive()
+              .map { case t: Text =>
+                t.payload
+              })
+        })
+        .send(backend)
+        .body
+
+    Thread.sleep(100)
+    val jmapGuiceProbe: JmapGuiceProbe = server.getProbe(classOf[JmapGuiceProbe])
+    val emailState: String = jmapGuiceProbe.getLatestEmailState(accountId).getValue.toString
+    val mailboxState: String = jmapGuiceProbe.getLatestMailboxState(accountId).getValue.toString
+
+    val mailboxStateChange: String = s"""{"@type":"StateChange","changed":{"$ACCOUNT_ID":{"Mailbox":"$mailboxState"}}}"""
+    val emailStateChange: String = s"""{"@type":"StateChange","changed":{"$ACCOUNT_ID":{"Email":"$emailState"}}}"""
+
+    assertThat(response.toOption.get.asJava)
+      .hasSize(2) // No Email notification
+      .contains(mailboxStateChange)
+      .doesNotContain(emailStateChange)
+  }
+
   private def authenticatedRequest(server: GuiceJamesServer): RequestT[Identity, Either[String, String], Any] = {
     val port = server.getProbe(classOf[JmapGuiceProbe])
       .getJmapPort


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org