PSC-2 added test implementation for ContentAPI

This commit is contained in:
Mikhail Astafyev 2019-11-04 15:00:42 +05:00
parent 518064cc1b
commit 7a5fd177c8
4 changed files with 89 additions and 2 deletions

View File

@ -1,12 +1,14 @@
package com.insanusmokrassar.postssystem.core.content.api package com.insanusmokrassar.postssystem.core.content.api
import com.insanusmokrassar.postssystem.core.content.* import com.insanusmokrassar.postssystem.core.content.Content
import com.insanusmokrassar.postssystem.core.content.ContentId
import com.insanusmokrassar.postssystem.core.content.RegisteredContent
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
interface WriteContentAPI { interface WriteContentAPI {
val contentCreatedFlow: Flow<RegisteredContent> val contentCreatedFlow: Flow<RegisteredContent>
val contentDeletedFlow: Flow<RegisteredContent> val contentDeletedFlow: Flow<RegisteredContent>
suspend fun createContent(post: Content): RegisteredContent? suspend fun createContent(content: Content): RegisteredContent?
suspend fun deleteContent(id: ContentId): Boolean suspend fun deleteContent(id: ContentId): Boolean
} }

View File

@ -0,0 +1,9 @@
package com.insanusmokrassar.postssystem.core.utils
import org.joda.time.DateTime
fun DateTime?.orMin(): DateTime = this ?: MIN_DATE
fun DateTime?.orMax(): DateTime = this ?: MAX_DATE
private val MIN_DATE = DateTime(Long.MIN_VALUE)
private val MAX_DATE = DateTime(Long.MAX_VALUE)

View File

@ -1,5 +1,7 @@
package com.insanusmokrassar.postssystem.core.utils.pagination package com.insanusmokrassar.postssystem.core.utils.pagination
import kotlin.math.ceil
/** /**
* Base interface of pagination * Base interface of pagination
* *
@ -33,3 +35,10 @@ val Pagination.firstIndex: Int
*/ */
val Pagination.lastIndex: Int val Pagination.lastIndex: Int
get() = firstIndex + size - 1 get() = firstIndex + size - 1
/**
* Calculates pages count for given [datasetSize]
*/
fun Pagination.pagesCount(datasetSize: Int): Int {
return ceil(datasetSize.toDouble() / size).toInt()
}

View File

@ -0,0 +1,67 @@
package com.insanusmokrassar.postssystem.core.api
import com.insanusmokrassar.postssystem.core.content.*
import com.insanusmokrassar.postssystem.core.content.api.ContentAPI
import com.insanusmokrassar.postssystem.core.utils.pagination.Pagination
import com.insanusmokrassar.postssystem.core.utils.pagination.PaginationResult
import com.insanusmokrassar.postssystem.core.utils.pagination.firstIndex
import com.insanusmokrassar.postssystem.core.utils.pagination.pagesCount
import kotlinx.coroutines.channels.BroadcastChannel
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.asFlow
import kotlinx.serialization.ImplicitReflectionSerializer
import java.util.*
@ImplicitReflectionSerializer
private fun generateId(): ContentId = UUID.randomUUID().toString()
@ImplicitReflectionSerializer
class InMemoryContentAPI(
initialContent: List<RegisteredContent> = emptyList()
): ContentAPI {
override val contentCreatedFlow: Flow<RegisteredContent>
get() = contentCreatedBroadcastChannel.asFlow()
override val contentDeletedFlow: Flow<RegisteredContent>
get() = contentDeletedBroadcastChannel.asFlow()
private val contents: MutableMap<ContentId, RegisteredContent> = initialContent
.associateBy(RegisteredContent::id)
.toMutableMap()
private val contentCreatedBroadcastChannel = BroadcastChannel<RegisteredContent>(Channel.BUFFERED)
private val contentDeletedBroadcastChannel = BroadcastChannel<RegisteredContent>(Channel.BUFFERED)
override suspend fun createContent(content: Content): RegisteredContent? {
return content.createRegisteredEntity(generateId())?.also { registeredContent ->
contents[registeredContent.id] = registeredContent
contentCreatedBroadcastChannel.send(registeredContent)
}
}
override suspend fun getContentById(id: ContentId): RegisteredContent? = contents[id]
override suspend fun getContentByPagination(pagination: Pagination): PaginationResult<out RegisteredContent> {
return PaginationResult(
page = pagination.page,
pagesNumber = pagination.pagesCount(contents.size),
results = contents.values.drop(pagination.firstIndex).take(pagination.size)
)
}
override suspend fun deleteContent(id: ContentId): Boolean {
return contents.remove(id)?.also { content ->
contentDeletedBroadcastChannel.send(content)
} != null
}
private fun Content.createRegisteredEntity(id: ContentId): RegisteredContent? {
return when(this) {
is TextContent -> SimpleTextRegisteredContent(id, text)
is SpecialContent -> SimpleTextRegisteredContent(id, internalId)
else -> null
}
}
}