Skip to content

Commit

Permalink
M4l2 mappers
Browse files Browse the repository at this point in the history
  • Loading branch information
evgnep committed Jul 27, 2024
1 parent 078c4d9 commit 6ec66ec
Show file tree
Hide file tree
Showing 33 changed files with 1,099 additions and 0 deletions.
14 changes: 14 additions & 0 deletions ok-marketplace-be/ok-marketplace-api-v1-mappers/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
plugins {
id("build-jvm")
}

group = rootProject.group
version = rootProject.version

dependencies {
implementation(kotlin("stdlib"))
implementation(project(":ok-marketplace-api-v1-jackson"))
implementation(project(":ok-marketplace-common"))

testImplementation(kotlin("test-junit"))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package ru.otus.otuskotlin.marketplace.mappers.v1

import ru.otus.otuskotlin.marketplace.api.v1.models.*
import ru.otus.otuskotlin.marketplace.common.MkplContext
import ru.otus.otuskotlin.marketplace.common.models.*
import ru.otus.otuskotlin.marketplace.common.models.MkplWorkMode
import ru.otus.otuskotlin.marketplace.common.stubs.MkplStubs
import ru.otus.otuskotlin.marketplace.mappers.v1.exceptions.UnknownRequestClass

fun MkplContext.fromTransport(request: IRequest) = when (request) {
is AdCreateRequest -> fromTransport(request)
is AdReadRequest -> fromTransport(request)
is AdUpdateRequest -> fromTransport(request)
is AdDeleteRequest -> fromTransport(request)
is AdSearchRequest -> fromTransport(request)
is AdOffersRequest -> fromTransport(request)
else -> throw UnknownRequestClass(request.javaClass)
}

private fun String?.toAdId() = this?.let { MkplAdId(it) } ?: MkplAdId.NONE
private fun String?.toAdWithId() = MkplAd(id = this.toAdId())
private fun String?.toAdLock() = this?.let { MkplAdLock(it) } ?: MkplAdLock.NONE

private fun AdDebug?.transportToWorkMode(): MkplWorkMode = when (this?.mode) {
AdRequestDebugMode.PROD -> MkplWorkMode.PROD
AdRequestDebugMode.TEST -> MkplWorkMode.TEST
AdRequestDebugMode.STUB -> MkplWorkMode.STUB
null -> MkplWorkMode.PROD
}

private fun AdDebug?.transportToStubCase(): MkplStubs = when (this?.stub) {
AdRequestDebugStubs.SUCCESS -> MkplStubs.SUCCESS
AdRequestDebugStubs.NOT_FOUND -> MkplStubs.NOT_FOUND
AdRequestDebugStubs.BAD_ID -> MkplStubs.BAD_ID
AdRequestDebugStubs.BAD_TITLE -> MkplStubs.BAD_TITLE
AdRequestDebugStubs.BAD_DESCRIPTION -> MkplStubs.BAD_DESCRIPTION
AdRequestDebugStubs.BAD_VISIBILITY -> MkplStubs.BAD_VISIBILITY
AdRequestDebugStubs.CANNOT_DELETE -> MkplStubs.CANNOT_DELETE
AdRequestDebugStubs.BAD_SEARCH_STRING -> MkplStubs.BAD_SEARCH_STRING
null -> MkplStubs.NONE
}

fun MkplContext.fromTransport(request: AdCreateRequest) {
command = MkplCommand.CREATE
adRequest = request.ad?.toInternal() ?: MkplAd()
workMode = request.debug.transportToWorkMode()
stubCase = request.debug.transportToStubCase()
}

fun MkplContext.fromTransport(request: AdReadRequest) {
command = MkplCommand.READ
adRequest = request.ad.toInternal()
workMode = request.debug.transportToWorkMode()
stubCase = request.debug.transportToStubCase()
}

private fun AdReadObject?.toInternal(): MkplAd = if (this != null) {
MkplAd(id = id.toAdId())
} else {
MkplAd()
}


fun MkplContext.fromTransport(request: AdUpdateRequest) {
command = MkplCommand.UPDATE
adRequest = request.ad?.toInternal() ?: MkplAd()
workMode = request.debug.transportToWorkMode()
stubCase = request.debug.transportToStubCase()
}

fun MkplContext.fromTransport(request: AdDeleteRequest) {
command = MkplCommand.DELETE
adRequest = request.ad.toInternal()
workMode = request.debug.transportToWorkMode()
stubCase = request.debug.transportToStubCase()
}

private fun AdDeleteObject?.toInternal(): MkplAd = if (this != null) {
MkplAd(
id = id.toAdId(),
lock = lock.toAdLock(),
)
} else {
MkplAd()
}

fun MkplContext.fromTransport(request: AdSearchRequest) {
command = MkplCommand.SEARCH
adFilterRequest = request.adFilter.toInternal()
workMode = request.debug.transportToWorkMode()
stubCase = request.debug.transportToStubCase()
}

fun MkplContext.fromTransport(request: AdOffersRequest) {
command = MkplCommand.OFFERS
adRequest = request.ad?.id.toAdWithId()
workMode = request.debug.transportToWorkMode()
stubCase = request.debug.transportToStubCase()
}

private fun AdSearchFilter?.toInternal(): MkplAdFilter = MkplAdFilter(
searchString = this?.searchString ?: ""
)

private fun AdCreateObject.toInternal(): MkplAd = MkplAd(
title = this.title ?: "",
description = this.description ?: "",
adType = this.adType.fromTransport(),
visibility = this.visibility.fromTransport(),
)

private fun AdUpdateObject.toInternal(): MkplAd = MkplAd(
id = this.id.toAdId(),
title = this.title ?: "",
description = this.description ?: "",
adType = this.adType.fromTransport(),
visibility = this.visibility.fromTransport(),
lock = lock.toAdLock(),
)

private fun AdVisibility?.fromTransport(): MkplVisibility = when (this) {
AdVisibility.PUBLIC -> MkplVisibility.VISIBLE_PUBLIC
AdVisibility.OWNER_ONLY -> MkplVisibility.VISIBLE_TO_OWNER
AdVisibility.REGISTERED_ONLY -> MkplVisibility.VISIBLE_TO_GROUP
null -> MkplVisibility.NONE
}

private fun DealSide?.fromTransport(): MkplDealSide = when (this) {
DealSide.DEMAND -> MkplDealSide.DEMAND
DealSide.SUPPLY -> MkplDealSide.SUPPLY
null -> MkplDealSide.NONE
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package ru.otus.otuskotlin.marketplace.mappers.v1

import ru.otus.otuskotlin.marketplace.api.v1.models.*
import ru.otus.otuskotlin.marketplace.common.MkplContext
import ru.otus.otuskotlin.marketplace.common.exceptions.UnknownMkplCommand
import ru.otus.otuskotlin.marketplace.common.models.*

fun MkplContext.toTransportAd(): IResponse = when (val cmd = command) {
MkplCommand.CREATE -> toTransportCreate()
MkplCommand.READ -> toTransportRead()
MkplCommand.UPDATE -> toTransportUpdate()
MkplCommand.DELETE -> toTransportDelete()
MkplCommand.SEARCH -> toTransportSearch()
MkplCommand.OFFERS -> toTransportOffers()
MkplCommand.NONE -> throw UnknownMkplCommand(cmd)
}

fun MkplContext.toTransportCreate() = AdCreateResponse(
result = state.toResult(),
errors = errors.toTransportErrors(),
ad = adResponse.toTransportAd()
)

fun MkplContext.toTransportRead() = AdReadResponse(
result = state.toResult(),
errors = errors.toTransportErrors(),
ad = adResponse.toTransportAd()
)

fun MkplContext.toTransportUpdate() = AdUpdateResponse(
result = state.toResult(),
errors = errors.toTransportErrors(),
ad = adResponse.toTransportAd()
)

fun MkplContext.toTransportDelete() = AdDeleteResponse(
result = state.toResult(),
errors = errors.toTransportErrors(),
ad = adResponse.toTransportAd()
)

fun MkplContext.toTransportSearch() = AdSearchResponse(
result = state.toResult(),
errors = errors.toTransportErrors(),
ads = adsResponse.toTransportAd()
)

fun MkplContext.toTransportOffers() = AdOffersResponse(
result = state.toResult(),
errors = errors.toTransportErrors(),
ads = adsResponse.toTransportAd()
)

fun List<MkplAd>.toTransportAd(): List<AdResponseObject>? = this
.map { it.toTransportAd() }
.toList()
.takeIf { it.isNotEmpty() }

private fun MkplAd.toTransportAd(): AdResponseObject = AdResponseObject(
id = id.takeIf { it != MkplAdId.NONE }?.asString(),
title = title.takeIf { it.isNotBlank() },
description = description.takeIf { it.isNotBlank() },
ownerId = ownerId.takeIf { it != MkplUserId.NONE }?.asString(),
adType = adType.toTransportAd(),
visibility = visibility.toTransportAd(),
permissions = permissionsClient.toTransportAd(),
)

private fun Set<MkplAdPermissionClient>.toTransportAd(): Set<AdPermissions>? = this
.map { it.toTransportAd() }
.toSet()
.takeIf { it.isNotEmpty() }

private fun MkplAdPermissionClient.toTransportAd() = when (this) {
MkplAdPermissionClient.READ -> AdPermissions.READ
MkplAdPermissionClient.UPDATE -> AdPermissions.UPDATE
MkplAdPermissionClient.MAKE_VISIBLE_OWNER -> AdPermissions.MAKE_VISIBLE_OWN
MkplAdPermissionClient.MAKE_VISIBLE_GROUP -> AdPermissions.MAKE_VISIBLE_GROUP
MkplAdPermissionClient.MAKE_VISIBLE_PUBLIC -> AdPermissions.MAKE_VISIBLE_PUBLIC
MkplAdPermissionClient.DELETE -> AdPermissions.DELETE
}

private fun MkplVisibility.toTransportAd(): AdVisibility? = when (this) {
MkplVisibility.VISIBLE_PUBLIC -> AdVisibility.PUBLIC
MkplVisibility.VISIBLE_TO_GROUP -> AdVisibility.REGISTERED_ONLY
MkplVisibility.VISIBLE_TO_OWNER -> AdVisibility.OWNER_ONLY
MkplVisibility.NONE -> null
}

private fun MkplDealSide.toTransportAd(): DealSide? = when (this) {
MkplDealSide.DEMAND -> DealSide.DEMAND
MkplDealSide.SUPPLY -> DealSide.SUPPLY
MkplDealSide.NONE -> null
}

private fun List<MkplError>.toTransportErrors(): List<Error>? = this
.map { it.toTransportAd() }
.toList()
.takeIf { it.isNotEmpty() }

private fun MkplError.toTransportAd() = Error(
code = code.takeIf { it.isNotBlank() },
group = group.takeIf { it.isNotBlank() },
field = field.takeIf { it.isNotBlank() },
message = message.takeIf { it.isNotBlank() },
)

private fun MkplState.toResult(): ResponseResult? = when (this) {
MkplState.RUNNING -> ResponseResult.SUCCESS
MkplState.FAILING -> ResponseResult.ERROR
MkplState.FINISHING -> ResponseResult.SUCCESS
MkplState.NONE -> null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package ru.otus.otuskotlin.marketplace.mappers.v1.exceptions

class UnknownRequestClass(clazz: Class<*>) : RuntimeException("Class $clazz cannot be mapped to MkplContext")
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package ru.otus.otuskotlin.marketplace.mappers.v1

import org.junit.Test
import ru.otus.otuskotlin.marketplace.api.v1.models.*
import ru.otus.otuskotlin.marketplace.common.MkplContext
import ru.otus.otuskotlin.marketplace.common.models.*
import ru.otus.otuskotlin.marketplace.common.stubs.MkplStubs
import kotlin.test.assertEquals

class MapperTest {
@Test
fun fromTransport() {
val req = AdCreateRequest(
debug = AdDebug(
mode = AdRequestDebugMode.STUB,
stub = AdRequestDebugStubs.SUCCESS,
),
ad = AdCreateObject(
title = "title",
description = "desc",
adType = DealSide.DEMAND,
visibility = AdVisibility.PUBLIC,
),
)

val context = MkplContext()
context.fromTransport(req)

assertEquals(MkplStubs.SUCCESS, context.stubCase)
assertEquals(MkplWorkMode.STUB, context.workMode)
assertEquals("title", context.adRequest.title)
assertEquals(MkplVisibility.VISIBLE_PUBLIC, context.adRequest.visibility)
assertEquals(MkplDealSide.DEMAND, context.adRequest.adType)
}

@Test
fun toTransport() {
val context = MkplContext(
requestId = MkplRequestId("1234"),
command = MkplCommand.CREATE,
adResponse = MkplAd(
title = "title",
description = "desc",
adType = MkplDealSide.DEMAND,
visibility = MkplVisibility.VISIBLE_PUBLIC,
),
errors = mutableListOf(
MkplError(
code = "err",
group = "request",
field = "title",
message = "wrong title",
)
),
state = MkplState.RUNNING,
)

val req = context.toTransportAd() as AdCreateResponse

assertEquals("title", req.ad?.title)
assertEquals("desc", req.ad?.description)
assertEquals(AdVisibility.PUBLIC, req.ad?.visibility)
assertEquals(DealSide.DEMAND, req.ad?.adType)
assertEquals(1, req.errors?.size)
assertEquals("err", req.errors?.firstOrNull()?.code)
assertEquals("request", req.errors?.firstOrNull()?.group)
assertEquals("title", req.errors?.firstOrNull()?.field)
assertEquals("wrong title", req.errors?.firstOrNull()?.message)
}
}
2 changes: 2 additions & 0 deletions ok-marketplace-be/ok-marketplace-api-v2-kmp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ kotlin {

implementation(libs.kotlinx.serialization.core)
implementation(libs.kotlinx.serialization.json)

implementation(project(":ok-marketplace-common"))
}
}
val commonTest by getting {
Expand Down
Loading

0 comments on commit 6ec66ec

Please sign in to comment.