Fix tests
This commit is contained in:
parent
efdc50eb1d
commit
87bd780f9f
34 changed files with 230 additions and 303 deletions
|
|
@ -1,23 +1,18 @@
|
|||
package lu.foyer
|
||||
|
||||
import zio.*
|
||||
import zio.http.*
|
||||
import zio.http.Header.AccessControlAllowOrigin
|
||||
import zio.http.Middleware.CorsConfig
|
||||
import zio.http.Middleware.cors
|
||||
import zio.http.codec.*
|
||||
import zio.http.codec.PathCodec.path
|
||||
import zio.http.endpoint.openapi.OpenAPIGen
|
||||
import zio.http.endpoint.openapi.SwaggerUI
|
||||
|
||||
import lu.foyer.clients.*
|
||||
import lu.foyer.contracts.*
|
||||
import zio.*
|
||||
import zio.Console.*
|
||||
import zio.http.*
|
||||
import zio.http.codec.*
|
||||
import zio.http.codec.PathCodec.path
|
||||
import zio.http.endpoint.*
|
||||
import zio.http.endpoint.openapi.OpenAPIGen
|
||||
import zio.http.endpoint.openapi.SwaggerUI
|
||||
import zio.schema.*
|
||||
import zio.http.Middleware.cors
|
||||
import zio.http.Middleware.CorsConfig
|
||||
import zio.http.Header.AccessControlAllowOrigin
|
||||
|
||||
import java.net.URI
|
||||
import java.time.LocalDate
|
||||
import java.util.UUID
|
||||
import zio.schema.codec.JsonCodec.ExplicitConfig
|
||||
|
||||
object HttpServer:
|
||||
|
||||
|
|
@ -33,6 +28,11 @@ object HttpServer:
|
|||
++ SwaggerUI.routes("docs" / "openapi", openAPI)
|
||||
|
||||
object App extends ZIOAppDefault:
|
||||
|
||||
override val bootstrap = CodecConfig.configLayer(
|
||||
CodecConfig(explicitNulls = ExplicitConfig(encoding = false, decoding = false))
|
||||
)
|
||||
|
||||
val app =
|
||||
for
|
||||
routes <- HttpServer.routes
|
||||
|
|
|
|||
|
|
@ -1,39 +1,32 @@
|
|||
package lu.foyer
|
||||
|
||||
import lu.foyer.JsonApiResponse.One
|
||||
import zio.*
|
||||
import zio.Console.*
|
||||
import zio.http.*
|
||||
import zio.http.codec.*
|
||||
import zio.http.codec.PathCodec.path
|
||||
import zio.http.endpoint.*
|
||||
import zio.schema.*
|
||||
|
||||
import java.net.URI
|
||||
import java.time.LocalDate
|
||||
import java.util.UUID
|
||||
|
||||
trait CommandEngineController[Command: Schema, Event: Schema, State: Schema]
|
||||
extends JsonApiController:
|
||||
trait CommandEngineController[Command, Event: Schema, State: Schema] extends JsonApiController:
|
||||
|
||||
def commandEngine: CommandEngine[Command, Event, State]
|
||||
|
||||
private lazy val fetchMany =
|
||||
Endpoint(Method.GET / entityName)
|
||||
// .query(HttpCodec.query[Page])
|
||||
.query(HttpCodec.query[Page])
|
||||
.jsonApiMany[State]
|
||||
|
||||
private lazy val fetchOne =
|
||||
Endpoint(Method.GET / entityName / uuid("entityId"))
|
||||
Endpoint(Method.GET / entityName / string("entityId"))
|
||||
.jsonApiOne[State]
|
||||
|
||||
private lazy val fetchEventsMany =
|
||||
Endpoint(Method.GET / entityName / uuid("entityId") / "events")
|
||||
// .query(HttpCodec.query[Page])
|
||||
Endpoint(Method.GET / entityName / string("entityId") / "events")
|
||||
.query(HttpCodec.query[Page])
|
||||
.jsonApiMany[Event]
|
||||
|
||||
private lazy val fetchEventsOne =
|
||||
Endpoint(Method.GET / entityName / uuid("entityId") / "events" / uuid("eventId"))
|
||||
Endpoint(Method.GET / entityName / string("entityId") / "events" / string("eventId"))
|
||||
.jsonApiOne[Event]
|
||||
|
||||
private def generateCommands = commandEngine.handlers.map(handler =>
|
||||
|
|
@ -49,15 +42,17 @@ trait CommandEngineController[Command: Schema, Event: Schema, State: Schema]
|
|||
val route = endpoint.implementJsonApiOneEvent(command =>
|
||||
for
|
||||
entityId <- Random.nextUUID
|
||||
(event, state) <- commandEngine
|
||||
.handleCommand(command, handler.name, entityId)
|
||||
(event, _) <- commandEngine
|
||||
.handleCommand(command, handler.name, entityId.toString)
|
||||
yield Some(event)
|
||||
)
|
||||
(endpoint, route)
|
||||
|
||||
private def generateUpdateCommand(handler: CommandHandler[Command, Event, State]) =
|
||||
given Schema[Command] = handler.commandSchema.asInstanceOf[Schema[Command]]
|
||||
val endpoint = Endpoint(Method.PUT / entityName / uuid("entityId") / "commands" / handler.name)
|
||||
val endpoint = Endpoint(
|
||||
Method.PUT / entityName / string("entityId") / "commands" / handler.name
|
||||
)
|
||||
.in[Command]
|
||||
.jsonApiOne[Event]
|
||||
val route = endpoint.implementJsonApiOneEvent((entityId, command) =>
|
||||
|
|
@ -70,17 +65,13 @@ trait CommandEngineController[Command: Schema, Event: Schema, State: Schema]
|
|||
private lazy val (commands, commandsRoutes) = generateCommands.unzip
|
||||
|
||||
private lazy val fetchManyRoute =
|
||||
fetchMany.implementJsonApiManyEntity(_ =>
|
||||
commandEngine.stateRepo.fetchMany(Page(None, None, totals = Some(true)))
|
||||
)
|
||||
fetchMany.implementJsonApiManyEntity(commandEngine.stateRepo.fetchMany)
|
||||
|
||||
private lazy val fetchOneRoute =
|
||||
fetchOne.implementJsonApiOneEntity(commandEngine.stateRepo.fetchOne)
|
||||
|
||||
private lazy val fetchEventsManyRoute =
|
||||
fetchEventsMany.implementJsonApiManyEvent(entityId =>
|
||||
commandEngine.eventRepo.fetchMany(entityId, Page(None, None, totals = Some(true)))
|
||||
)
|
||||
fetchEventsMany.implementJsonApiManyEvent(commandEngine.eventRepo.fetchMany(_, _))
|
||||
|
||||
private lazy val fetchEventsOneRoute =
|
||||
fetchEventsOne.implementJsonApiOneEvent(commandEngine.eventRepo.fetchOne(_, _))
|
||||
|
|
|
|||
|
|
@ -1,19 +1,14 @@
|
|||
package lu.foyer
|
||||
|
||||
import lu.foyer.JsonApiResponse.Many
|
||||
import lu.foyer.JsonApiResponse.One
|
||||
import zio.*
|
||||
import zio.http.*
|
||||
import zio.http.Header.Forwarded
|
||||
import zio.http.codec.*
|
||||
import zio.http.codec.PathCodec.path
|
||||
import zio.http.endpoint.*
|
||||
import zio.schema.*
|
||||
import zio.schema.annotation.discriminatorName
|
||||
import zio.schema.annotation.fieldName
|
||||
|
||||
import java.util.UUID
|
||||
import scala.annotation.targetName
|
||||
import lu.foyer.JsonApiResponse.Many
|
||||
import lu.foyer.JsonApiResponse.One
|
||||
|
||||
object JsonApiResponse:
|
||||
|
||||
|
|
@ -26,7 +21,7 @@ object JsonApiResponse:
|
|||
|
||||
case class Entity[T](
|
||||
`type`: String,
|
||||
id: UUID,
|
||||
id: String,
|
||||
attributes: T,
|
||||
relationships: Option[Relationships] = None,
|
||||
links: Map[String, String])
|
||||
|
|
@ -34,17 +29,17 @@ object JsonApiResponse:
|
|||
|
||||
case class Relationships(_entity: RelationshipsEntity) derives Schema
|
||||
object Relationships:
|
||||
def apply(id: UUID, `type`: String, entityUrl: String): Relationships = Relationships(
|
||||
def apply(id: String, `type`: String, entityUrl: String): Relationships = Relationships(
|
||||
RelationshipsEntity(RelationshipsData(id, `type`), RelationshipsLinks(entityUrl))
|
||||
)
|
||||
case class RelationshipsEntity(data: RelationshipsData, links: RelationshipsLinks) derives Schema
|
||||
case class RelationshipsData(id: UUID, `type`: String) derives Schema
|
||||
case class RelationshipsData(id: String, `type`: String) derives Schema
|
||||
case class RelationshipsLinks(related: String) derives Schema
|
||||
|
||||
@discriminatorName("errorType")
|
||||
enum Error(title: String) derives Schema:
|
||||
case NotFound(id: String) extends Error(s"Entity $id not found")
|
||||
case InternalServerError(title: String) extends Error(title)
|
||||
enum Error derives Schema:
|
||||
case NotFound(id: String)
|
||||
case InternalServerError(title: String)
|
||||
object Error:
|
||||
given Schema[Error.NotFound] = DeriveSchema.gen
|
||||
given Schema[Error.InternalServerError] = DeriveSchema.gen
|
||||
|
|
@ -105,7 +100,7 @@ trait JsonApiController:
|
|||
)
|
||||
def implementJsonApiOne[Env, A](
|
||||
f: Input => RIO[Env, Option[A]],
|
||||
getId: A => UUID,
|
||||
getId: A => String,
|
||||
getEntity: A => Output,
|
||||
onthology: String = this.onthology,
|
||||
links: (A, ProxyHeaders) => Map[String, String] = (_: A, _: ProxyHeaders) => Map.empty,
|
||||
|
|
@ -177,7 +172,7 @@ trait JsonApiController:
|
|||
)
|
||||
def implementJsonApiMany[Env, A](
|
||||
f: Input => RIO[Env, Paged[A]],
|
||||
getId: A => UUID,
|
||||
getId: A => String,
|
||||
getEntity: A => Output,
|
||||
links: (A, ProxyHeaders) => Map[String, String] = (_: A, _: ProxyHeaders) => Map.empty
|
||||
)(implicit trace: Trace
|
||||
|
|
|
|||
|
|
@ -2,16 +2,6 @@ package lu.foyer
|
|||
package clients
|
||||
|
||||
import zio.*
|
||||
import zio.Console.*
|
||||
import zio.http.*
|
||||
import zio.http.codec.*
|
||||
import zio.http.codec.PathCodec.path
|
||||
import zio.http.endpoint.*
|
||||
import zio.schema.*
|
||||
|
||||
import java.net.URI
|
||||
import java.time.LocalDate
|
||||
import java.util.UUID
|
||||
|
||||
class ClientController(val commandEngine: CommandEngine[ClientCommand, ClientEvent, ClientState])
|
||||
extends CommandEngineController[ClientCommand, ClientEvent, ClientState]:
|
||||
|
|
|
|||
|
|
@ -1,22 +1,21 @@
|
|||
package lu.foyer
|
||||
package clients
|
||||
|
||||
import java.util.UUID
|
||||
import zio.*
|
||||
|
||||
class ClientEventRepositoryInMemory(events: Ref[Map[UUID, Event[ClientEvent]]])
|
||||
class ClientEventRepositoryInMemory(events: Ref[Map[String, Event[ClientEvent]]])
|
||||
extends EventRepository[ClientEvent]
|
||||
with InMemoryRepository[Event[ClientEvent]](events):
|
||||
def fetchOne(entityId: UUID, eventId: UUID): Task[Option[Event[ClientEvent]]] =
|
||||
def fetchOne(entityId: String, eventId: String): Task[Option[Event[ClientEvent]]] =
|
||||
events.get.map(_.get(eventId))
|
||||
def fetchMany(entityId: UUID, page: Page): Task[Paged[Event[ClientEvent]]] =
|
||||
def fetchMany(entityId: String, page: Page): Task[Paged[Event[ClientEvent]]] =
|
||||
events.get
|
||||
.map(entities =>
|
||||
val items = entities.values
|
||||
.filter(_.entityId == entityId)
|
||||
.drop(page.number.getOrElse(0) * page.size.getOrElse(50))
|
||||
.take(page.size.getOrElse(50))
|
||||
Paged(items.toList, if page.totals.getOrElse(false) then Some(entities.size) else None)
|
||||
Paged(items.toList, if page.totals.getOrElse(true) then Some(entities.size) else None)
|
||||
)
|
||||
|
||||
object ClientEventRepositoryInMemory:
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
package lu.foyer
|
||||
package clients
|
||||
|
||||
import java.util.UUID
|
||||
import zio.*
|
||||
|
||||
class ClientStateRepositoryInMemory(clients: Ref[Map[UUID, Entity[ClientState]]])
|
||||
class ClientStateRepositoryInMemory(clients: Ref[Map[String, Entity[ClientState]]])
|
||||
extends StateRepository[ClientState]
|
||||
with InMemoryRepository[Entity[ClientState]](clients)
|
||||
|
||||
|
|
|
|||
|
|
@ -2,16 +2,6 @@ package lu.foyer
|
|||
package contracts
|
||||
|
||||
import zio.*
|
||||
import zio.Console.*
|
||||
import zio.http.*
|
||||
import zio.http.codec.*
|
||||
import zio.http.codec.PathCodec.path
|
||||
import zio.http.endpoint.*
|
||||
import zio.schema.*
|
||||
|
||||
import java.net.URI
|
||||
import java.time.LocalDate
|
||||
import java.util.UUID
|
||||
|
||||
class ContractController(
|
||||
val commandEngine: CommandEngine[ContractCommand, ContractEvent, ContractState])
|
||||
|
|
|
|||
|
|
@ -1,22 +1,21 @@
|
|||
package lu.foyer
|
||||
package contracts
|
||||
|
||||
import java.util.UUID
|
||||
import zio.*
|
||||
|
||||
class ContractEventRepositoryInMemory(events: Ref[Map[UUID, Event[ContractEvent]]])
|
||||
class ContractEventRepositoryInMemory(events: Ref[Map[String, Event[ContractEvent]]])
|
||||
extends EventRepository[ContractEvent]
|
||||
with InMemoryRepository[Event[ContractEvent]](events):
|
||||
def fetchOne(entityId: UUID, eventId: UUID): Task[Option[Event[ContractEvent]]] =
|
||||
def fetchOne(entityId: String, eventId: String): Task[Option[Event[ContractEvent]]] =
|
||||
events.get.map(_.get(eventId))
|
||||
def fetchMany(entityId: UUID, page: Page): Task[Paged[Event[ContractEvent]]] =
|
||||
def fetchMany(entityId: String, page: Page): Task[Paged[Event[ContractEvent]]] =
|
||||
events.get
|
||||
.map(entities =>
|
||||
val items = entities.values
|
||||
.filter(_.entityId == entityId)
|
||||
.drop(page.number.getOrElse(0) * page.size.getOrElse(50))
|
||||
.take(page.size.getOrElse(50))
|
||||
Paged(items.toList, if page.totals.getOrElse(false) then Some(entities.size) else None)
|
||||
Paged(items.toList, if page.totals.getOrElse(true) then Some(entities.size) else None)
|
||||
)
|
||||
|
||||
object ContractEventRepositoryInMemory:
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
package lu.foyer
|
||||
package contracts
|
||||
|
||||
import java.util.UUID
|
||||
import zio.*
|
||||
|
||||
class ContractStateRepositoryInMemory(clients: Ref[Map[UUID, Entity[ContractState]]])
|
||||
class ContractStateRepositoryInMemory(clients: Ref[Map[String, Entity[ContractState]]])
|
||||
extends StateRepository[ContractState]
|
||||
with InMemoryRepository[Entity[ContractState]](clients)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,7 @@
|
|||
package lu.foyer
|
||||
package contracts
|
||||
|
||||
import java.util.UUID
|
||||
import zio.*
|
||||
import lu.foyer.clients.Address
|
||||
import scala.math.BigDecimal.RoundingMode
|
||||
import java.util.Currency
|
||||
import lu.foyer.clients.Country
|
||||
|
||||
object EmployeeServiceImpl extends EmployeeService:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
package lu.foyer
|
||||
package contracts
|
||||
|
||||
import java.util.UUID
|
||||
import zio.*
|
||||
import lu.foyer.clients.Address
|
||||
import scala.math.BigDecimal.RoundingMode
|
||||
import java.util.Currency
|
||||
import scala.math.BigDecimal.RoundingMode
|
||||
|
||||
import zio.*
|
||||
|
||||
import lu.foyer.clients.Address
|
||||
import lu.foyer.clients.Country
|
||||
|
||||
object PremiumServiceImpl extends PremiumService:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue