~jan0sch/smederee

Showing details for patch bde8c66e9be29a24e68757fda552ca1504151a02.
2022-12-28 (Wed), 2:54 PM - Jens Grassel - bde8c66e9be29a24e68757fda552ca1504151a02

Add tests for email middleware module.

- implement scalacheck generators
- some refactoring
- add tests for opaque data types and their helpers
Summary of changes
2 files added
  • modules/email/src/test/scala/de/smederee/email/EmailMiddlewareTest.scala
  • modules/email/src/test/scala/de/smederee/email/Generators.scala
1 files modified with 1 lines added and 34 lines removed
  • modules/email/src/test/scala/de/smederee/email/SimpleJavaMailMiddlewareHelpersTest.scala with 1 added and 34 removed lines
diff -rN -u old-smederee/modules/email/src/test/scala/de/smederee/email/EmailMiddlewareTest.scala new-smederee/modules/email/src/test/scala/de/smederee/email/EmailMiddlewareTest.scala
--- old-smederee/modules/email/src/test/scala/de/smederee/email/EmailMiddlewareTest.scala	1970-01-01 00:00:00.000000000 +0000
+++ new-smederee/modules/email/src/test/scala/de/smederee/email/EmailMiddlewareTest.scala	2025-02-01 09:44:23.090249136 +0000
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2022  Contributors as noted in the AUTHORS.md file
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.smederee.email
+
+import java.nio.charset.StandardCharsets
+
+import cats.data._
+import cats.kernel.Eq
+import cats.syntax.all._
+import de.smederee.email.Generators._
+import jakarta.mail.Message.RecipientType
+
+import munit._
+import org.scalacheck._
+import org.scalacheck.Prop._
+
+import scala.jdk.CollectionConverters._
+
+final class EmailMiddlewareTest extends ScalaCheckSuite {
+  given Arbitrary[FromAddress] = Arbitrary(genValidFromAddress)
+  given Arbitrary[ToAddress]   = Arbitrary(genValidToAddress)
+
+  property("EmailServerPassword.apply and .toArray must be reversible") {
+    forAll { (randomBytes: Array[Byte]) =>
+      val password = EmailServerPassword(randomBytes)
+      assert(java.util.Arrays.equals(password.toArray, randomBytes))
+    }
+  }
+
+  property("EmailServerPassword.from must create correct instances") {
+    forAll { (randomString: String) =>
+      EmailServerPassword.from(randomString) match {
+        case None => fail("Could not create EmailServerPassword!")
+        case Some(password) =>
+          assert(java.util.Arrays.equals(password.toArray, randomString.getBytes(StandardCharsets.UTF_8)))
+      }
+    }
+  }
+
+  property("FromAddress.from must not accept invalid input") {
+    forAll { (randomString: String) =>
+      assert(FromAddress.from(randomString).isEmpty)
+    }
+  }
+
+  property("FromAddress.from must accept valid input") {
+    forAll { (validFrom: FromAddress) =>
+      FromAddress.from(validFrom.toString) match {
+        case None          => fail("Could not create FromAddress!")
+        case Some(address) => assertEquals(address, validFrom)
+      }
+    }
+  }
+
+  property("SubjectLine.from must only accept invalid input") {
+    forAll { (randomString: String) =>
+      if (randomString.length <= SubjectLine.MaxLength)
+        assert(SubjectLine.from(randomString).nonEmpty)
+      else
+        assert(SubjectLine.from(randomString).isEmpty)
+    }
+  }
+
+  test("TextBody.from must not accept empty input") {
+    assert(TextBody.from("").isEmpty)
+  }
+
+  property("ToAddress.from must not accept invalid input") {
+    forAll { (randomString: String) =>
+      assert(ToAddress.from(randomString).isEmpty)
+    }
+  }
+
+  property("ToAddress.from must accept valid input") {
+    forAll { (validTo: ToAddress) =>
+      ToAddress.from(validTo.toString) match {
+        case None          => fail("Could not create ToAddress!")
+        case Some(address) => assertEquals(address, validTo)
+      }
+    }
+  }
+
+}
diff -rN -u old-smederee/modules/email/src/test/scala/de/smederee/email/Generators.scala new-smederee/modules/email/src/test/scala/de/smederee/email/Generators.scala
--- old-smederee/modules/email/src/test/scala/de/smederee/email/Generators.scala	1970-01-01 00:00:00.000000000 +0000
+++ new-smederee/modules/email/src/test/scala/de/smederee/email/Generators.scala	2025-02-01 09:44:23.090249136 +0000
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2022  Contributors as noted in the AUTHORS.md file
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.smederee.email
+
+import cats.data.NonEmptyList
+
+import org.scalacheck._
+
+/** A container for ScalaCheck generators for our data types.
+  */
+object Generators {
+  private val validEmailAddressPrefixChars =
+    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.!#$%&’'*+/=?^_`{|}~-".toList
+  private val validDomainNameChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-".toList
+
+  val genValidFromAddress: Gen[FromAddress] = for {
+    prefix <- Gen.nonEmptyListOf(Gen.oneOf(validEmailAddressPrefixChars)).map(_.take(64).mkString)
+    domain <- Gen.nonEmptyListOf(Gen.oneOf(validDomainNameChars)).map(_.take(32).mkString)
+    topLevelDomain <- Gen
+      .nonEmptyListOf(Gen.oneOf(validDomainNameChars))
+      .suchThat(_.length >= 2)
+      .map(_.take(24).mkString)
+    suffix = s"$domain.$topLevelDomain"
+  } yield FromAddress(s"$prefix@$suffix")
+
+  val genValidSubjectLine: Gen[SubjectLine] =
+    Gen.nonEmptyListOf(Gen.alphaNumChar).map(_.take(78).mkString).map(SubjectLine.apply)
+
+  val genValidTextBody: Gen[TextBody] = Gen.nonEmptyListOf(Gen.alphaNumChar).map(_.mkString).map(TextBody.apply)
+
+  val genValidToAddress: Gen[ToAddress] = for {
+    prefix <- Gen.nonEmptyListOf(Gen.oneOf(validEmailAddressPrefixChars)).map(_.take(64).mkString)
+    domain <- Gen.nonEmptyListOf(Gen.oneOf(validDomainNameChars)).map(_.take(32).mkString)
+    topLevelDomain <- Gen
+      .nonEmptyListOf(Gen.oneOf(validDomainNameChars))
+      .suchThat(_.length >= 2)
+      .map(_.take(24).mkString)
+    suffix = s"$domain.$topLevelDomain"
+  } yield ToAddress(s"$prefix@$suffix")
+
+  val genEmailMessage: Gen[EmailMessage] = for {
+    from     <- genValidFromAddress
+    to       <- genValidToAddress
+    too      <- Gen.listOf(genValidToAddress)
+    cc       <- Gen.listOf(genValidToAddress)
+    bcc      <- Gen.listOf(genValidToAddress)
+    subject  <- genValidSubjectLine
+    textBody <- genValidTextBody
+  } yield EmailMessage(
+    from,
+    NonEmptyList.of(to, too: _*),
+    cc,
+    bcc,
+    subject,
+    textBody
+  )
+}
diff -rN -u old-smederee/modules/email/src/test/scala/de/smederee/email/SimpleJavaMailMiddlewareHelpersTest.scala new-smederee/modules/email/src/test/scala/de/smederee/email/SimpleJavaMailMiddlewareHelpersTest.scala
--- old-smederee/modules/email/src/test/scala/de/smederee/email/SimpleJavaMailMiddlewareHelpersTest.scala	2025-02-01 09:44:23.090249136 +0000
+++ new-smederee/modules/email/src/test/scala/de/smederee/email/SimpleJavaMailMiddlewareHelpersTest.scala	2025-02-01 09:44:23.090249136 +0000
@@ -20,6 +20,7 @@
 import cats.data._
 import cats.kernel.Eq
 import cats.syntax.all._
+import de.smederee.email.Generators._
 import jakarta.mail.Message.RecipientType
 
 import munit._
@@ -33,40 +34,6 @@
 
   given Eq[RecipientType] = Eq.fromUniversalEquals
 
-  val genFromAddress: Gen[FromAddress] =
-    for {
-      length <- Gen.choose(4, 64)
-      chars  <- Gen.nonEmptyListOf(Gen.alphaNumChar)
-      email = chars.take(length).mkString
-    } yield FromAddress(email + "@example.com")
-
-  val genSubjectLine: Gen[SubjectLine] =
-    Gen.nonEmptyListOf(Gen.alphaNumChar).map(_.take(SubjectLine.MaxLength).mkString).map(SubjectLine.apply)
-  val genTextBody: Gen[TextBody] = Gen.nonEmptyListOf(Gen.alphaNumChar).map(_.mkString).map(TextBody.apply)
-  val genToAddress: Gen[ToAddress] =
-    for {
-      length <- Gen.choose(4, 64)
-      chars  <- Gen.nonEmptyListOf(Gen.alphaNumChar)
-      email = chars.take(length).mkString
-    } yield ToAddress(email + "@example.com")
-
-  val genEmailMessage: Gen[EmailMessage] = for {
-    from     <- genFromAddress
-    to       <- genToAddress
-    too      <- Gen.listOf(genToAddress)
-    cc       <- Gen.listOf(genToAddress)
-    bcc      <- Gen.listOf(genToAddress)
-    subject  <- genSubjectLine
-    textBody <- genTextBody
-  } yield EmailMessage(
-    from,
-    NonEmptyList.of(to, too: _*),
-    cc,
-    bcc,
-    subject,
-    textBody
-  )
-
   given Arbitrary[EmailMessage] = Arbitrary(genEmailMessage)
 
   property("EmailMessage.toEmail must create correct Email instances") {