From 1acc0c27816789f08d9f66d2679810aad7d1c0ea Mon Sep 17 00:00:00 2001 From: Dimitrije Bulaja Date: Thu, 8 Dec 2022 15:57:20 +0100 Subject: [PATCH 1/5] Support unit tests for IndexName validation --- .../scala/zio/elasticsearch/package.scala | 18 +++---- .../zio/elasticsearch/IndexNameSpec.scala | 54 +++++++++++++++++++ 2 files changed, 63 insertions(+), 9 deletions(-) create mode 100644 modules/library/src/test/scala/zio/elasticsearch/IndexNameSpec.scala diff --git a/modules/library/src/main/scala/zio/elasticsearch/package.scala b/modules/library/src/main/scala/zio/elasticsearch/package.scala index 5687e07a3..4a2f11fca 100644 --- a/modules/library/src/main/scala/zio/elasticsearch/package.scala +++ b/modules/library/src/main/scala/zio/elasticsearch/package.scala @@ -26,15 +26,15 @@ package object elasticsearch { ) Left( failure( - """Index names must meet the following criteria: - | - Must be lower case only - | - Cannot include \\, /, *, ?, ", <, >, |, ` `(space character), `,`(comma), #. - | - Cannot include ":"(since 7.0). - | - Cannot start with -, _, +. - | - Cannot be `.` or `..`. - | - Cannot be longer than 255 bytes (note it is bytes, so multi-byte characters will count towards the 255 limit faster). - | - Names starting with . are deprecated, except for hidden indices and internal indices managed by plugins. - |""".stripMargin + s""" + | - Must be lower case only + | - Cannot include \\, /, *, ?, ", <, >, |, ` `(space character), `,`(comma), #. + | - Cannot include ":"(since 7.0). + | - Cannot start with -, _, +. + | - Cannot be `.` or `..`. + | - Cannot be longer than 255 bytes (note it is bytes, so multi-byte characters will count towards the 255 limit faster). + | - Names starting with . are deprecated, except for hidden indices and internal indices managed by plugins. + |""".stripMargin ) ) else diff --git a/modules/library/src/test/scala/zio/elasticsearch/IndexNameSpec.scala b/modules/library/src/test/scala/zio/elasticsearch/IndexNameSpec.scala new file mode 100644 index 000000000..c0161d3fb --- /dev/null +++ b/modules/library/src/test/scala/zio/elasticsearch/IndexNameSpec.scala @@ -0,0 +1,54 @@ +package zio.elasticsearch + +import zio.prelude.Validation +import zio.test.Assertion.equalTo +import zio.test._ + +object IndexNameSpec extends ZIOSpecDefault { + + override def spec: Spec[TestEnvironment, Any] = + suite("IndexName validation")( + test("succeed for valid string") { + assert(IndexName.make("index-name"))(equalTo(Validation.succeed(IndexName("index-name")))) + }, + test("fail for string containing upper letter") { + val invalidIndexStr = "Index-name" + assert(IndexName.make(invalidIndexStr))(equalTo(Validation.fail(validationFailedStr(invalidIndexStr)))) + }, + test("fail for string containing charachter '*'") { + val invalidIndexStr = "index*name" + assert(IndexName.make(invalidIndexStr))(equalTo(Validation.fail(validationFailedStr(invalidIndexStr)))) + }, + test("fail for string containing charachter ':'") { + val invalidIndexStr = "index:name" + assert(IndexName.make(invalidIndexStr))(equalTo(Validation.fail(validationFailedStr(invalidIndexStr)))) + }, + test("fail for string starting with charachter '-'") { + val invalidIndexStr = "-index.name" + assert(IndexName.make(invalidIndexStr))(equalTo(Validation.fail(validationFailedStr(invalidIndexStr)))) + }, + test("fail for string '.'") { + val invalidIndexStr = "." + assert(IndexName.make(invalidIndexStr))(equalTo(Validation.fail(validationFailedStr(invalidIndexStr)))) + }, + test("fail for string longer than 255 bytes") { + checkN(5)(Gen.stringN(256)(Gen.alphaChar)) { invalidIndexStr => + val lowerCaseStr = invalidIndexStr.toLowerCase() + assert(IndexName.make(lowerCaseStr.toLowerCase))( + equalTo(Validation.fail(validationFailedStr(lowerCaseStr.toLowerCase))) + ) + } + } + ) + + private def validationFailedStr(indexStr: String): String = + s"""$indexStr did not satisfy + | - Must be lower case only + | - Cannot include \\, /, *, ?, ", <, >, |, ` `(space character), `,`(comma), #. + | - Cannot include ":"(since 7.0). + | - Cannot start with -, _, +. + | - Cannot be `.` or `..`. + | - Cannot be longer than 255 bytes (note it is bytes, so multi-byte characters will count towards the 255 limit faster). + | - Names starting with . are deprecated, except for hidden indices and internal indices managed by plugins. + |""".stripMargin +} From 8b0a7a3d9ef75712a5057c93ca9bcdb1007ca3aa Mon Sep 17 00:00:00 2001 From: Dimitrije Bulaja Date: Fri, 9 Dec 2022 10:21:12 +0100 Subject: [PATCH 2/5] Fix tests --- build.sbt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index ff73868fb..28cfb4a9c 100644 --- a/build.sbt +++ b/build.sbt @@ -40,8 +40,8 @@ lazy val library = "dev.zio" %% "zio-schema" % "0.3.1", "dev.zio" %% "zio-schema-json" % "0.3.1", "org.apache.commons" % "commons-lang3" % "3.12.0", - "dev.zio" %% "zio-test" % "2.0.4" % IntegrationTest, - "dev.zio" %% "zio-test-sbt" % "2.0.4" % IntegrationTest + "dev.zio" %% "zio-test" % "2.0.4" % "it,test", + "dev.zio" %% "zio-test-sbt" % "2.0.4" % "it,test" ), testFrameworks := Seq(new TestFramework("zio.test.sbt.ZTestFramework")) ) From 69402f247b1cc115f543ab73ac09d16f303440a4 Mon Sep 17 00:00:00 2001 From: Dimitrije Bulaja Date: Fri, 9 Dec 2022 11:39:56 +0100 Subject: [PATCH 3/5] Fix code remarks --- build.sbt | 3 +- .../zio/elasticsearch/IndexNameSpec.scala | 30 +++++++++---------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/build.sbt b/build.sbt index 28cfb4a9c..81b37e1ed 100644 --- a/build.sbt +++ b/build.sbt @@ -1,4 +1,5 @@ import BuildHelper._ +import sbt.librarymanagement.Configurations.IntegrationTest Global / onChangedBuildSource := ReloadOnSourceChanges @@ -43,7 +44,7 @@ lazy val library = "dev.zio" %% "zio-test" % "2.0.4" % "it,test", "dev.zio" %% "zio-test-sbt" % "2.0.4" % "it,test" ), - testFrameworks := Seq(new TestFramework("zio.test.sbt.ZTestFramework")) + testFrameworks := List(new TestFramework("zio.test.sbt.ZTestFramework")) ) lazy val example = diff --git a/modules/library/src/test/scala/zio/elasticsearch/IndexNameSpec.scala b/modules/library/src/test/scala/zio/elasticsearch/IndexNameSpec.scala index c0161d3fb..e24d34d6a 100644 --- a/modules/library/src/test/scala/zio/elasticsearch/IndexNameSpec.scala +++ b/modules/library/src/test/scala/zio/elasticsearch/IndexNameSpec.scala @@ -12,37 +12,37 @@ object IndexNameSpec extends ZIOSpecDefault { assert(IndexName.make("index-name"))(equalTo(Validation.succeed(IndexName("index-name")))) }, test("fail for string containing upper letter") { - val invalidIndexStr = "Index-name" - assert(IndexName.make(invalidIndexStr))(equalTo(Validation.fail(validationFailedStr(invalidIndexStr)))) + val name = "Index-name" + assert(IndexName.make(name))(equalTo(Validation.fail(indexNameFailureMessage(name)))) }, test("fail for string containing charachter '*'") { - val invalidIndexStr = "index*name" - assert(IndexName.make(invalidIndexStr))(equalTo(Validation.fail(validationFailedStr(invalidIndexStr)))) + val name = "index*name" + assert(IndexName.make(name))(equalTo(Validation.fail(indexNameFailureMessage(name)))) }, test("fail for string containing charachter ':'") { - val invalidIndexStr = "index:name" - assert(IndexName.make(invalidIndexStr))(equalTo(Validation.fail(validationFailedStr(invalidIndexStr)))) + val name = "index:name" + assert(IndexName.make(name))(equalTo(Validation.fail(indexNameFailureMessage(name)))) }, test("fail for string starting with charachter '-'") { - val invalidIndexStr = "-index.name" - assert(IndexName.make(invalidIndexStr))(equalTo(Validation.fail(validationFailedStr(invalidIndexStr)))) + val name = "-index.name" + assert(IndexName.make(name))(equalTo(Validation.fail(indexNameFailureMessage(name)))) }, test("fail for string '.'") { - val invalidIndexStr = "." - assert(IndexName.make(invalidIndexStr))(equalTo(Validation.fail(validationFailedStr(invalidIndexStr)))) + val name = "." + assert(IndexName.make(name))(equalTo(Validation.fail(indexNameFailureMessage(name)))) }, test("fail for string longer than 255 bytes") { - checkN(5)(Gen.stringN(256)(Gen.alphaChar)) { invalidIndexStr => - val lowerCaseStr = invalidIndexStr.toLowerCase() + check(Gen.stringN(256)(Gen.alphaChar)) { name => + val lowerCaseStr = name.toLowerCase() assert(IndexName.make(lowerCaseStr.toLowerCase))( - equalTo(Validation.fail(validationFailedStr(lowerCaseStr.toLowerCase))) + equalTo(Validation.fail(indexNameFailureMessage(lowerCaseStr.toLowerCase))) ) } } ) - private def validationFailedStr(indexStr: String): String = - s"""$indexStr did not satisfy + private def indexNameFailureMessage(name: String): String = + s"""$name did not satisfy | - Must be lower case only | - Cannot include \\, /, *, ?, ", <, >, |, ` `(space character), `,`(comma), #. | - Cannot include ":"(since 7.0). From 3d47a02cc50ba052b754d514b75887119b24baeb Mon Sep 17 00:00:00 2001 From: Dimitrije Bulaja Date: Fri, 9 Dec 2022 15:04:01 +0100 Subject: [PATCH 4/5] Fix code remarks --- .../zio/elasticsearch/IndexNameSpec.scala | 39 ++++++++++++------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/modules/library/src/test/scala/zio/elasticsearch/IndexNameSpec.scala b/modules/library/src/test/scala/zio/elasticsearch/IndexNameSpec.scala index e24d34d6a..94b1f757b 100644 --- a/modules/library/src/test/scala/zio/elasticsearch/IndexNameSpec.scala +++ b/modules/library/src/test/scala/zio/elasticsearch/IndexNameSpec.scala @@ -1,5 +1,6 @@ package zio.elasticsearch +import zio.prelude.Newtype.unsafeWrap import zio.prelude.Validation import zio.test.Assertion.equalTo import zio.test._ @@ -9,33 +10,42 @@ object IndexNameSpec extends ZIOSpecDefault { override def spec: Spec[TestEnvironment, Any] = suite("IndexName validation")( test("succeed for valid string") { - assert(IndexName.make("index-name"))(equalTo(Validation.succeed(IndexName("index-name")))) + check(genString(5, 20)) { name => + assert(IndexName.make(name))(equalTo(Validation.succeed(unsafeWrap(IndexName)(name)))) + } }, test("fail for string containing upper letter") { - val name = "Index-name" - assert(IndexName.make(name))(equalTo(Validation.fail(indexNameFailureMessage(name)))) + check(genString(5, 20)) { name => + val invalidName = s"A$name" + assert(IndexName.make(invalidName))(equalTo(Validation.fail(indexNameFailureMessage(invalidName)))) + } }, test("fail for string containing charachter '*'") { - val name = "index*name" - assert(IndexName.make(name))(equalTo(Validation.fail(indexNameFailureMessage(name)))) + check(genString(5, 20)) { name => + val invalidName = s"*$name" + assert(IndexName.make(invalidName))(equalTo(Validation.fail(indexNameFailureMessage(invalidName)))) + } }, test("fail for string containing charachter ':'") { - val name = "index:name" - assert(IndexName.make(name))(equalTo(Validation.fail(indexNameFailureMessage(name)))) + check(genString(5, 20)) { name => + val invalidName = s":$name" + assert(IndexName.make(invalidName))(equalTo(Validation.fail(indexNameFailureMessage(invalidName)))) + } }, test("fail for string starting with charachter '-'") { - val name = "-index.name" - assert(IndexName.make(name))(equalTo(Validation.fail(indexNameFailureMessage(name)))) + check(genString(5, 20)) { name => + val invalidName = s"-$name" + assert(IndexName.make(invalidName))(equalTo(Validation.fail(indexNameFailureMessage(invalidName)))) + } }, test("fail for string '.'") { val name = "." assert(IndexName.make(name))(equalTo(Validation.fail(indexNameFailureMessage(name)))) }, test("fail for string longer than 255 bytes") { - check(Gen.stringN(256)(Gen.alphaChar)) { name => - val lowerCaseStr = name.toLowerCase() - assert(IndexName.make(lowerCaseStr.toLowerCase))( - equalTo(Validation.fail(indexNameFailureMessage(lowerCaseStr.toLowerCase))) + check(Gen.stringBounded(256, 300)(Gen.alphaChar).map(_.toLowerCase())) { name => + assert(IndexName.make(name))( + equalTo(Validation.fail(indexNameFailureMessage(name))) ) } } @@ -51,4 +61,7 @@ object IndexNameSpec extends ZIOSpecDefault { | - Cannot be longer than 255 bytes (note it is bytes, so multi-byte characters will count towards the 255 limit faster). | - Names starting with . are deprecated, except for hidden indices and internal indices managed by plugins. |""".stripMargin + + private def genString(min: Int, max: Int): Gen[Any, String] = + Gen.stringBounded(min, max)(Gen.alphaChar).map(_.toLowerCase()) } From 43e5c4fadd6407213aa24c38d6ae791ad68ab2c7 Mon Sep 17 00:00:00 2001 From: Dimitrije Bulaja Date: Fri, 9 Dec 2022 17:09:10 +0100 Subject: [PATCH 5/5] Fix code remarks --- .../scala/zio/elasticsearch/package.scala | 1 + .../zio/elasticsearch/IndexNameSpec.scala | 23 +++++++++++-------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/modules/library/src/main/scala/zio/elasticsearch/package.scala b/modules/library/src/main/scala/zio/elasticsearch/package.scala index 4a2f11fca..4b76118c4 100644 --- a/modules/library/src/main/scala/zio/elasticsearch/package.scala +++ b/modules/library/src/main/scala/zio/elasticsearch/package.scala @@ -30,6 +30,7 @@ package object elasticsearch { | - Must be lower case only | - Cannot include \\, /, *, ?, ", <, >, |, ` `(space character), `,`(comma), #. | - Cannot include ":"(since 7.0). + | - Cannot be empty | - Cannot start with -, _, +. | - Cannot be `.` or `..`. | - Cannot be longer than 255 bytes (note it is bytes, so multi-byte characters will count towards the 255 limit faster). diff --git a/modules/library/src/test/scala/zio/elasticsearch/IndexNameSpec.scala b/modules/library/src/test/scala/zio/elasticsearch/IndexNameSpec.scala index 94b1f757b..06f5e6a23 100644 --- a/modules/library/src/test/scala/zio/elasticsearch/IndexNameSpec.scala +++ b/modules/library/src/test/scala/zio/elasticsearch/IndexNameSpec.scala @@ -10,30 +10,34 @@ object IndexNameSpec extends ZIOSpecDefault { override def spec: Spec[TestEnvironment, Any] = suite("IndexName validation")( test("succeed for valid string") { - check(genString(5, 20)) { name => + check(genString(1, 255)) { name => assert(IndexName.make(name))(equalTo(Validation.succeed(unsafeWrap(IndexName)(name)))) } }, test("fail for string containing upper letter") { - check(genString(5, 20)) { name => - val invalidName = s"A$name" + check(genString(0, 127), genString(0, 128)) { (part1, part2) => + val invalidName = s"${part1}A$part2" assert(IndexName.make(invalidName))(equalTo(Validation.fail(indexNameFailureMessage(invalidName)))) } }, test("fail for string containing charachter '*'") { - check(genString(5, 20)) { name => - val invalidName = s"*$name" + check(genString(0, 127), genString(0, 128)) { (part1, part2) => + val invalidName = s"$part1*$part2" assert(IndexName.make(invalidName))(equalTo(Validation.fail(indexNameFailureMessage(invalidName)))) } }, test("fail for string containing charachter ':'") { - check(genString(5, 20)) { name => - val invalidName = s":$name" + check(genString(0, 127), genString(0, 128)) { (part1, part2) => + val invalidName = s"$part1:$part2" assert(IndexName.make(invalidName))(equalTo(Validation.fail(indexNameFailureMessage(invalidName)))) } }, + test("fail for empty string") { + val name = "" + assert(IndexName.make(name))(equalTo(Validation.succeed(unsafeWrap(IndexName)(name)))) + }, test("fail for string starting with charachter '-'") { - check(genString(5, 20)) { name => + check(genString(1, 255)) { name => val invalidName = s"-$name" assert(IndexName.make(invalidName))(equalTo(Validation.fail(indexNameFailureMessage(invalidName)))) } @@ -43,7 +47,7 @@ object IndexNameSpec extends ZIOSpecDefault { assert(IndexName.make(name))(equalTo(Validation.fail(indexNameFailureMessage(name)))) }, test("fail for string longer than 255 bytes") { - check(Gen.stringBounded(256, 300)(Gen.alphaChar).map(_.toLowerCase())) { name => + check(genString(256, 300)) { name => assert(IndexName.make(name))( equalTo(Validation.fail(indexNameFailureMessage(name))) ) @@ -56,6 +60,7 @@ object IndexNameSpec extends ZIOSpecDefault { | - Must be lower case only | - Cannot include \\, /, *, ?, ", <, >, |, ` `(space character), `,`(comma), #. | - Cannot include ":"(since 7.0). + | - Cannot be empty | - Cannot start with -, _, +. | - Cannot be `.` or `..`. | - Cannot be longer than 255 bytes (note it is bytes, so multi-byte characters will count towards the 255 limit faster).