Skip to content

Commit

Permalink
feat(server): Implement get company by id (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
kevchuang authored May 19, 2024
1 parent 5603e2b commit 7133481
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,13 @@ object company:
DeriveJsonCodec.gen[CompanyAlreadyExists]
end CompanyAlreadyExists

final case class CompanyNotFound(companyId: CompanyId)
extends CompanyDomainError
object CompanyNotFound:
given JsonCodec[CompanyNotFound] =
DeriveJsonCodec.gen[CompanyNotFound]
end CompanyNotFound

final case class UnableToGenerateCompanyId(message: String)
extends CompanyDomainError
object UnableToGenerateCompanyId:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package io.kevchuang.reviewboard.http.endpoints

import io.kevchuang.reviewboard.domain.company.*
import io.kevchuang.reviewboard.services.company.CompanyService
import io.kevchuang.reviewboard.services.db.DatabaseService
import sttp.model.StatusCode
import sttp.tapir.*
import sttp.tapir.json.zio.*
import sttp.tapir.generic.auto.*
import sttp.tapir.codec.iron.{*, given}
import zio.ZIO

final case class GetCompanyByIdEndpoint()
extends HttpEndpoint[
DatabaseService & CompanyService,
CompanyId,
CompanyNotFound,
Company
]:

override def endpointDescription
: ApiEndpoint[CompanyId, CompanyNotFound, Company] =
endpoint
.tag("companies")
.name("getById")
.description("get company by its id")
.in("companies" / path[CompanyId]("companyId"))
.get
.errorOut(jsonBody[CompanyNotFound])
.out(jsonBody[Company])

override def endpointLogic: CompanyId => ZIO[
DatabaseService & CompanyService,
CompanyNotFound,
Company
] = CompanyService.getCompanyById
end GetCompanyByIdEndpoint
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ trait CompanyService:
def createCompany(
company: CreateCompany
): ZIO[DatabaseService, CompanyDomainError, Company]

def getCompanies: URIO[DatabaseService, List[Company]]
def getCompanyById(
companyId: CompanyId
): ZIO[DatabaseService, CompanyNotFound, Company]
end CompanyService

object CompanyService:
Expand All @@ -21,4 +23,9 @@ object CompanyService:
def getCompanies
: ZIO[DatabaseService & CompanyService, Nothing, List[Company]] =
ZIO.serviceWithZIO[CompanyService](_.getCompanies)

def getCompanyById(
companyId: CompanyId
): ZIO[DatabaseService & CompanyService, CompanyNotFound, Company] =
ZIO.serviceWithZIO[CompanyService](_.getCompanyById(companyId))
end CompanyService
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,13 @@ object CompanyServiceLive:

override def getCompanies: URIO[DatabaseService, List[Company]] =
DatabaseService.getCompanies

override def getCompanyById(
companyId: CompanyId
): ZIO[DatabaseService, CompanyNotFound, Company] =
DatabaseService
.getCompany(companyId)
.flatMap(ZIO.fromOption)
.orElseFail(CompanyNotFound(companyId))
)
end CompanyServiceLive
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ trait DatabaseService:
def countCompanies: UIO[Long]
def existsCompany(companyName: CompanyName): UIO[Boolean]
def getCompanies: UIO[List[Company]]
def getCompany(companyId: CompanyId): UIO[Option[Company]]
def insertCompany(company: Company): UIO[Unit]
end DatabaseService

Expand All @@ -22,6 +23,9 @@ object DatabaseService:
def getCompanies: URIO[DatabaseService, List[Company]] =
ZIO.serviceWithZIO[DatabaseService](_.getCompanies)

def getCompany(companyId: CompanyId): URIO[DatabaseService, Option[Company]] =
ZIO.serviceWithZIO[DatabaseService](_.getCompany(companyId))

def insertCompany(
company: Company
): URIO[DatabaseService, Unit] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ final case class InMemoryDatabase(database: mutable.Map[CompanyId, Company])
override def getCompanies: UIO[List[Company]] =
ZIO.succeed(database.values.toList)

override def getCompany(companyId: CompanyId): UIO[Option[Company]] =
ZIO.succeed(database.get(companyId))

override def insertCompany(
company: Company
): UIO[Unit] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import io.kevchuang.reviewboard.services.db.{DatabaseService, InMemoryDatabase}

object CompanyServiceSpec extends ZIOSpecDefault:
override def spec: Spec[TestEnvironment with Scope, Any] =
createCompanySuite + getCompaniesSuite
(createCompanySuite + getCompaniesSuite + getCompanyByIdSuite)

private lazy val createCompanySuite =
suite("createCompany")(
Expand All @@ -30,7 +30,7 @@ object CompanyServiceSpec extends ZIOSpecDefault:
exists <- DatabaseService.existsCompany(companyName)
yield assertTrue(company == expected, exists)
end for
}.provide(InMemoryDatabase.live, CompanyServiceLive.live)
}.provide(CompanyServiceLive.live, InMemoryDatabase.live)
)

private lazy val getCompaniesSuite =
Expand Down Expand Up @@ -66,6 +66,32 @@ object CompanyServiceSpec extends ZIOSpecDefault:
hasSameElements(List(expectedFirstCompany, expectedSecondCompany))
)
end for
}.provide(InMemoryDatabase.live, CompanyServiceLive.live)
}.provide(CompanyServiceLive.live, InMemoryDatabase.live)
)

private lazy val getCompanyByIdSuite =
suite("getCompanyById")(
test("should return company by giving its id") {
val company = DataGenerator.generateCreateCompany(
CompanyName("RockTheJVM"),
Url("rockthejvm.com")
)
val expectedCompany = DataGenerator.generateCompany(
id = CompanyId(1),
slug = CompanySlug("rockthejvm"),
name = CompanyName("RockTheJVM"),
url = Url("rockthejvm.com")
)
for
_ <- CompanyService.createCompany(company)
result <- CompanyService.getCompanyById(CompanyId(1))
yield assertTrue(result == expectedCompany)
end for
}.provide(CompanyServiceLive.live, InMemoryDatabase.live),
test("should return CompanyNotFound if company id was not found") {
assertZIO(CompanyService.getCompanyById(CompanyId(1)).exit)(
fails(equalTo(CompanyNotFound(CompanyId(1))))
)
}.provide(CompanyServiceLive.live, InMemoryDatabase.live)
)
end CompanyServiceSpec

0 comments on commit 7133481

Please sign in to comment.