You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

156 lines
4.8 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. package wow.doge.http4sdemo
  2. import cats.syntax.all._
  3. import monix.bio.IO
  4. import monix.bio.Task
  5. import monix.bio.UIO
  6. import monix.reactive.Observable
  7. import org.http4s.Method
  8. import org.http4s.Request
  9. import org.http4s.Status
  10. import org.http4s.Uri
  11. import org.http4s.implicits._
  12. import wow.doge.http4sdemo.MonixBioSuite
  13. import wow.doge.http4sdemo.dto.Book
  14. import wow.doge.http4sdemo.dto.BookSearchMode
  15. import wow.doge.http4sdemo.dto.BookUpdate
  16. import wow.doge.http4sdemo.routes.LibraryRoutes
  17. import wow.doge.http4sdemo.services.LibraryService
  18. import wow.doge.http4sdemo.services.NoopLibraryService
  19. class LibraryControllerSpec extends MonixBioSuite {
  20. val Root = Uri(path = "")
  21. test("get books success") {
  22. import org.http4s.circe.CirceEntityCodec._
  23. val book = Book(1, "book1", "adsgq342dsdc", 1, date)
  24. val service = new NoopLibraryService {
  25. override def getBooks: Observable[Book] =
  26. Observable.fromIterable(book :: Nil)
  27. override def getBookById(id: Int): Task[Option[Book]] =
  28. Task.some(book)
  29. }
  30. for {
  31. _ <- UIO.unit
  32. routes = new LibraryRoutes(service, noopLogger).routes
  33. res <- routes
  34. .run(Request[Task](Method.GET, uri"/api/books"))
  35. .value
  36. .hideErrors
  37. body <- res.traverse(_.as[List[Book]])
  38. _ <- UIO(assertEquals(body, Some(List(book))))
  39. // _ <- logger2.debug(body.toString).hideErrors
  40. } yield ()
  41. }
  42. test("update book error") {
  43. import org.http4s.circe.CirceEntityCodec._
  44. val service = new NoopLibraryService {
  45. override def updateBook(id: Int, updateData: BookUpdate) =
  46. IO.raiseError(
  47. LibraryService.EntityDoesNotExist(s"Book with id=$id does not exist")
  48. )
  49. }
  50. for {
  51. _ <- UIO.unit
  52. reqBody = BookUpdate(Some("blah"), None)
  53. routes = new LibraryRoutes(service, noopLogger).routes
  54. res <- routes
  55. .run(
  56. Request[Task](Method.PATCH, Root / "api" / "books" / "1")
  57. .withEntity(reqBody)
  58. )
  59. .value
  60. .hideErrors
  61. _ <- UIO(assertEquals(res.map(_.status), Some(Status.NotFound)))
  62. body <- res.traverse(_.as[LibraryService.Error])
  63. _ <- UIO(
  64. assertEquals(
  65. body,
  66. Some(
  67. LibraryService.EntityDoesNotExist("Book with id=1 does not exist")
  68. )
  69. )
  70. )
  71. // _ <- logger.debug(res.toString).hideErrors
  72. // _ <- logger.debug(body.toString).hideErrors
  73. } yield ()
  74. }
  75. test("get books by author name") {
  76. import org.http4s.circe.CirceEntityCodec._
  77. val value = "blah"
  78. val books =
  79. List(Book(1, "book1", value, 1, date), Book(2, "book1", value, 1, date))
  80. val service = new NoopLibraryService {
  81. override def searchBook(mode: BookSearchMode, value: String) =
  82. mode match {
  83. case BookSearchMode.BookTitle =>
  84. Observable.fromIterable(books)
  85. case BookSearchMode.AuthorName =>
  86. Observable.fromIterable(books)
  87. }
  88. }
  89. for {
  90. _ <- UIO.unit
  91. // logger2 = logger.withConstContext(
  92. // Map("Test" -> "get books by author name")
  93. // )
  94. routes = new LibraryRoutes(service, noopLogger).routes
  95. request = Request[Task](
  96. Method.GET,
  97. Root / "api" / "books"
  98. withQueryParams Map(
  99. "mode" -> BookSearchMode.AuthorName.entryName,
  100. "value" -> "blah"
  101. )
  102. )
  103. // _ <- logger2.info(s"Request -> $request")
  104. res <- routes.run(request).value.hideErrors
  105. body <- res.traverse(_.as[List[Book]])
  106. _ <- UIO.pure(body).assertEquals(Some(books))
  107. // _ <- logger2.debug(s"Response body -> $body").hideErrors
  108. } yield ()
  109. }
  110. test("get books by book title") {
  111. import org.http4s.circe.CirceEntityCodec._
  112. val value = "blah"
  113. val books =
  114. List(Book(1, "book1", value, 1, date), Book(2, "book1", value, 1, date))
  115. val service = new NoopLibraryService {
  116. override def searchBook(mode: BookSearchMode, value: String) =
  117. mode match {
  118. case BookSearchMode.BookTitle =>
  119. Observable.fromIterable(books)
  120. case BookSearchMode.AuthorName =>
  121. Observable.fromIterable(books)
  122. }
  123. }
  124. for {
  125. _ <- UIO.unit
  126. // logger2 = logger.withConstContext(
  127. // Map("Test" -> "get books by book title")
  128. // )
  129. routes = new LibraryRoutes(service, noopLogger).routes
  130. request = Request[Task](
  131. Method.GET,
  132. Root / "api" / "books"
  133. withQueryParams Map(
  134. "mode" -> BookSearchMode.BookTitle.entryName,
  135. "value" -> "blah"
  136. )
  137. )
  138. // _ <- logger2.info(s"Request -> $request")
  139. res <- routes.run(request).value.hideErrors
  140. body <- res.traverse(_.as[List[Book]])
  141. _ <- UIO.pure(body).assertEquals(Some(books))
  142. // _ <- logger2.debug(s"Response body -> $body").hideErrors
  143. } yield ()
  144. }
  145. }