From c9f45d1bf4334189233c04f75fec916352474d55 Mon Sep 17 00:00:00 2001 From: Override-6 Date: Thu, 2 Feb 2023 00:19:03 +0100 Subject: [PATCH] adding tests to register page handler --- Core/src/org/tbasket/auth/Authenticator.scala | 19 ++++--- Core/src/org/tbasket/endpoint/Endpoint.scala | 5 +- .../test/pages/LoginPageHandlerTests.scala | 22 ++------ .../test/pages/RegisterPageHandlerTests.scala | 50 +++++++++++++++++++ .../tbasket/test/pages/TBasketPageSpec.scala | 33 ++++++++++++ 5 files changed, 100 insertions(+), 29 deletions(-) create mode 100644 tests/src/org/tbasket/test/pages/RegisterPageHandlerTests.scala create mode 100644 tests/src/org/tbasket/test/pages/TBasketPageSpec.scala diff --git a/Core/src/org/tbasket/auth/Authenticator.scala b/Core/src/org/tbasket/auth/Authenticator.scala index 0a6a0df..69461b8 100644 --- a/Core/src/org/tbasket/auth/Authenticator.scala +++ b/Core/src/org/tbasket/auth/Authenticator.scala @@ -77,15 +77,6 @@ class Authenticator(url: URL, key: PublicKey, algorithm: JwtAsymmetricAlgorithm) .filterOrElse(_.passwordHash == hashPassword(password))(Clock.sleep(1.seconds) *> ZIO.fail(InvalidPassword("invalid password"))) } - private def insert(user: User) = quote { - query[User].insert( - _.id -> user.id, - _.name -> user.name, - _.forename -> user.forename, - _.passwordHash -> user.passwordHash, - _.mailAddress -> user.mailAddress, - ) - } def registerUser(name: String, forename: String, mail: String, password: String) = ZIO.serviceWithZIO[DatabaseContext] { ctx => import ctx.* @@ -100,7 +91,15 @@ class Authenticator(url: URL, key: PublicKey, algorithm: JwtAsymmetricAlgorithm) ZIO.fail(InvalidPassword(s"password did not satisfy regex pattern $ValidPasswordPattern")) else for _ <- findByMail(mail).none.orElse(ZIO.fail(UserAlreadyRegistered(s"an email address already exists for '$mail'"))) - _ <- run(insert(user)).fork + _ <- run(quote { + query[User].insert( + _.id -> lift(user).id, + _.name -> lift(user).name, + _.forename -> lift(user).forename, + _.passwordHash -> lift(user).passwordHash, + _.mailAddress -> lift(user).mailAddress, + ) + }).fork yield user } diff --git a/Core/src/org/tbasket/endpoint/Endpoint.scala b/Core/src/org/tbasket/endpoint/Endpoint.scala index 3a4fe07..d270b95 100644 --- a/Core/src/org/tbasket/endpoint/Endpoint.scala +++ b/Core/src/org/tbasket/endpoint/Endpoint.scala @@ -10,7 +10,7 @@ import org.tbasket.data.DatabaseContext import org.tbasket.endpoint.Endpoint.{Log, app} import org.tbasket.error.* import org.tbasket.handler.HandlerUtils.errorBody -import org.tbasket.handler.{HandlerUtils, LoginPageHandler} +import org.tbasket.handler.{HandlerUtils, LoginPageHandler, RegisterPageHandler} import zio.* import zio.http.* import zio.http.ServerConfig.LeakDetectionLevel @@ -50,6 +50,9 @@ object Endpoint: private def tryHandle(r: Request) = r match case r@POST -> _ / "login" => LoginPageHandler.post(r) + + case r@POST -> _ / "register" => + RegisterPageHandler.post(r) case r@method -> path => val ipInsights = r.remoteAddress diff --git a/tests/src/org/tbasket/test/pages/LoginPageHandlerTests.scala b/tests/src/org/tbasket/test/pages/LoginPageHandlerTests.scala index ed5f912..e53be97 100644 --- a/tests/src/org/tbasket/test/pages/LoginPageHandlerTests.scala +++ b/tests/src/org/tbasket/test/pages/LoginPageHandlerTests.scala @@ -21,16 +21,9 @@ import zio.json.ast.{Json, JsonCursor} import zio.test.* import zio.test.Assertion.* -object LoginPageHandlerTests extends ZIOSpecDefault { - - import LoginPageHandler.post - import TestLayers.* - - private final val url = URL.fromString("http://localhost/login") match - case Left(value) => throw value - case Right(url) => url - +object LoginPageHandlerTests extends TBasketPageSpec("/login") { + private def requestsSpec = suite("bad request tests")( ZIO.attempt(Map( "empty packet" -> Body.empty, @@ -88,15 +81,8 @@ object LoginPageHandlerTests extends ZIOSpecDefault { ) } - override def spec = suite("/login page handler")( + override def tspec = suite("/login page handler")( requestsSpec, loginSpec - ).provide( - db.datasourceLayer, - db.contextLayer, - auth, - ConnectionPool.fixed(1), - Scope.default, - ClientConfig.default, - Client.live) + ) } diff --git a/tests/src/org/tbasket/test/pages/RegisterPageHandlerTests.scala b/tests/src/org/tbasket/test/pages/RegisterPageHandlerTests.scala new file mode 100644 index 0000000..6a074f4 --- /dev/null +++ b/tests/src/org/tbasket/test/pages/RegisterPageHandlerTests.scala @@ -0,0 +1,50 @@ +package org.tbasket.test.pages + +import zio.test.ZIOSpecDefault +import org.tbasket.endpoint.Endpoint.handle +import org.tbasket.handler.HandlerUtils.parseAttribute +import org.tbasket.test.TestUtils +import org.tbasket.test.TestUtils.getJsonBody +import org.tbasket.test.pages.RegisterPageHandlerTests.test +import zio.http.* +import zio.http.model.{HeaderNames, Headers, Status} +import zio.json.ast.JsonCursor +import zio.test.Assertion.* +import zio.test.* + +object RegisterPageHandlerTests extends TBasketPageSpec("/register") { + + + private def requestsSpec = suite("bad request tests")( + + ) + + private def registerSpec = suite("register tests")( + test("normal register") { + for + resp <- handle(Request.post(Body.fromString(s"""{"name":"tuaillon","forename":"leo","email":"leo.tuaillon@etu.uca.fr","password":"bouhours"}"""), url)) + + yield + assert(resp)(hasField("status", _.status, equalTo(Status.Found))) + && assert(resp)(hasField("body", _.body, equalTo(Body.empty))) //TODO assert that the cookie name is JWT + && assert(resp)(hasField("headers", _.headers, exists(hasField("key", _.key, equalTo(HeaderNames.setCookie))))) + && assert(resp)(hasField("headers", _.headers, contains(Headers.location("/")))) + }, + test("register again with same credentials") { + for + resp <- handle(Request.post(Body.fromString(s"""{"name":"tuaillon","forename":"leo","email":"leo.tuaillon@etu.uca.fr","password":"bouhours"}"""), url)) + json <- getJsonBody(resp) + errorType <- parseAttribute(json, "error", JsonCursor.field("error").isString) + + yield + assert(resp)(hasField("status", _.status, equalTo(Status.NotAcceptable))) + && assert(errorType)(equalTo("already registered")) + && assert(resp)(hasField("headers", _.headers, contains(Headers.location("/login")))) + } + ) + + override def tspec = suite("/login page handler")( + requestsSpec, + registerSpec + ) +} diff --git a/tests/src/org/tbasket/test/pages/TBasketPageSpec.scala b/tests/src/org/tbasket/test/pages/TBasketPageSpec.scala new file mode 100644 index 0000000..b86e4cd --- /dev/null +++ b/tests/src/org/tbasket/test/pages/TBasketPageSpec.scala @@ -0,0 +1,33 @@ +package org.tbasket.test.pages + +import io.getquill.NamingStrategy +import io.getquill.context.qzio.ZioJdbcContext +import io.getquill.context.sql.idiom.SqlIdiom +import org.tbasket.auth.Authenticator +import org.tbasket.data.DatabaseContext +import zio.test.{Spec, TestEnvironment, ZIOSpecDefault} +import org.tbasket.handler.LoginPageHandler.post +import zio.* +import org.tbasket.test.TestLayers.* +import zio.http.{Client, ClientConfig, URL} +import zio.http.netty.client.ConnectionPool + +import javax.sql.DataSource + +abstract class TBasketPageSpec(location: String) extends ZIOSpecDefault { + + protected val url = URL.fromString(s"http://localhost$location") match + case Left(value) => throw value + case Right(url) => url + + protected def tspec: Spec[DataSource & ClientConfig & Authenticator & ConnectionPool & Scope & DatabaseContext & Client, Any] + + final override def spec = tspec.provide( + db.datasourceLayer, + db.contextLayer, + auth, + ConnectionPool.fixed(1), + Scope.default, + ClientConfig.default, + Client.live) +}