PSC-2 added test implementation for ContentAPI
This commit is contained in:
parent
518064cc1b
commit
7a5fd177c8
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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)
|
@ -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()
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user