Skip to content

Commit

Permalink
Merge pull request #556 from NDLANO/4233-space-problems
Browse files Browse the repository at this point in the history
search-api: Stop returning 500 on whitespace only queries
  • Loading branch information
gunnarvelle authored Dec 6, 2024
2 parents ab69e82 + 0bb87a4 commit 1bf76f5
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 6 deletions.
18 changes: 12 additions & 6 deletions network/src/main/scala/no/ndla/network/tapir/NonEmptyString.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,26 @@ import io.circe.{Decoder, DecodingFailure, Encoder, FailedCursor, HCursor, Json}
import sttp.tapir.CodecFormat.TextPlain
import sttp.tapir.{Codec, CodecFormat, DecodeResult, Schema}

/** Class that cannot be constructed with an empty string (""), therefore it means that if you have one of these the
* underlying string is not empty
/** Class that cannot be constructed with an empty string ("") or a whitespace only string (" "), therefore it means
* that if you have one of these the underlying string is not empty.
*/
class NonEmptyString private (val underlying: String) {
override def equals(obj: Any): Boolean = obj match {
case other: NonEmptyString => other.underlying == underlying
case other: String => other == underlying
case _ => false
}
}

object NonEmptyString {
def apply(underlying: String): Option[NonEmptyString] = fromString(underlying)
def fromOptString(s: Option[String]): Option[NonEmptyString] = s.filter(_.nonEmpty).map(f => new NonEmptyString(f))
def fromString(s: String): Option[NonEmptyString] = Option.when(s.nonEmpty)(new NonEmptyString(s))
def apply(underlying: String): Option[NonEmptyString] = fromString(underlying)

private def validateString(underlying: String): Boolean = underlying.trim.nonEmpty

def fromOptString(s: Option[String]): Option[NonEmptyString] =
s.filter(validateString).map(f => new NonEmptyString(f))
def fromString(s: String): Option[NonEmptyString] =
Option.when(validateString(s))(new NonEmptyString(s))

implicit val schema: Schema[NonEmptyString] = Schema.string
implicit val schemaOpt: Schema[Option[NonEmptyString]] = Schema.string.asOption
Expand Down Expand Up @@ -60,7 +66,7 @@ object NonEmptyString {

implicit def circeEncoder: Encoder[NonEmptyString] = (a: NonEmptyString) => Json.fromString(a.underlying)

/** Helpers that should make working with a bit `Option[NonEmptyString]` easier */
/** Helpers that should make working with `Option[NonEmptyString]` a bit easier */
implicit class NonEmptyStringImplicit(self: Option[NonEmptyString]) {
def underlying: Option[String] = self.map(_.underlying)
def underlyingOrElse(default: => String): String = self.map(_.underlying).getOrElse(default)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,21 @@ class NonEmptyStringTest extends UnitSuite {
failure.message should be(NonEmptyString.parseErrorMessage)
}

test("That comparisons works as expected") {
val a = NonEmptyString.fromString("hei").get
val b = NonEmptyString.fromString("hei").get
val c = NonEmptyString.fromString("hallo").get

a == b should be(true)
a == c should be(false)
a == "hei" should be(true)
a == "hallo" should be(false)
}

test("That only whitespace strings are not parsed as NonEmptyString") {
NonEmptyString.fromString(" ") should be(None)
NonEmptyString.fromString(" ") should be(None)
NonEmptyString.fromString(" ") should be(None)
}

}

0 comments on commit 1bf76f5

Please sign in to comment.