From d32a0956d135f70dcbbca7a4017f975ae2bffe5a Mon Sep 17 00:00:00 2001 From: dev7odaa Date: Mon, 5 May 2025 18:44:12 +0300 Subject: [PATCH 01/17] create MongoDBDataSource class --- build.gradle.kts | 1 - .../mongodb_data_source/MongoDBDataSource.kt | 34 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/data/mongodb_data_source/MongoDBDataSource.kt diff --git a/build.gradle.kts b/build.gradle.kts index e230fa1..9d1d4d6 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -20,7 +20,6 @@ dependencies { testImplementation("com.google.truth:truth:1.4.4") testImplementation("org.jetbrains.kotlin:kotlin-test") testImplementation("org.junit.jupiter:junit-jupiter-params:5.10.0") - implementation ("com.github.doyaaaaaken:kotlin-csv-jvm:1.9.0") } kover { diff --git a/src/main/kotlin/data/mongodb_data_source/MongoDBDataSource.kt b/src/main/kotlin/data/mongodb_data_source/MongoDBDataSource.kt new file mode 100644 index 0000000..2e193b0 --- /dev/null +++ b/src/main/kotlin/data/mongodb_data_source/MongoDBDataSource.kt @@ -0,0 +1,34 @@ +package com.berlin.data.mongodb_data_source + +import com.berlin.data.BaseDataSource +import com.berlin.data.BaseSchema + +open class MongoDBDataSource( + private val connectionString: String, + private val databaseName: String, + private val schema: BaseSchema, +) : BaseDataSource { + override fun getAll(): List { + TODO("Not yet implemented") + } + + override fun getById(id: String): T? { + TODO("Not yet implemented") + } + + override fun update(id: String, entity: T): Boolean { + TODO("Not yet implemented") + } + + override fun delete(id: String): Boolean { + TODO("Not yet implemented") + } + + override fun write(entity: T): Boolean { + TODO("Not yet implemented") + } + + override fun writeAll(entities: List): Boolean { + TODO("Not yet implemented") + } +} \ No newline at end of file From 607dab90f1b4d284cab5f50240e1e8da738f1f00 Mon Sep 17 00:00:00 2001 From: dev7odaa Date: Mon, 5 May 2025 19:17:00 +0300 Subject: [PATCH 02/17] use coroutines by make suspend functions --- src/main/kotlin/data/BaseDataSource.kt | 12 ++++----- .../mongodb_data_source/MongoDBDataSource.kt | 27 ++++++++++++++----- .../data/project/ProjectRepositoryImpl.kt | 10 +++---- .../kotlin/data/state/StateRepositoryImpl.kt | 14 +++++----- .../kotlin/data/task/TaskRepositoryImpl.kt | 12 ++++----- .../domain/repository/ProjectRepository.kt | 10 +++---- .../domain/repository/StateRepository.kt | 14 +++++----- .../domain/repository/TaskRepository.kt | 12 ++++----- 8 files changed, 63 insertions(+), 48 deletions(-) diff --git a/src/main/kotlin/data/BaseDataSource.kt b/src/main/kotlin/data/BaseDataSource.kt index 8ec4838..c274efd 100644 --- a/src/main/kotlin/data/BaseDataSource.kt +++ b/src/main/kotlin/data/BaseDataSource.kt @@ -2,16 +2,16 @@ package com.berlin.data interface BaseDataSource { - fun getAll(): List + suspend fun getAll(): List - fun getById(id: String): T? + suspend fun getById(id: String): T? - fun update(id: String, entity: T): Boolean + suspend fun update(id: String, entity: T): Boolean - fun delete(id: String): Boolean + suspend fun delete(id: String): Boolean - fun write(entity: T): Boolean + suspend fun write(entity: T): Boolean - fun writeAll(entities: List): Boolean + suspend fun writeAll(entities: List): Boolean } \ No newline at end of file diff --git a/src/main/kotlin/data/mongodb_data_source/MongoDBDataSource.kt b/src/main/kotlin/data/mongodb_data_source/MongoDBDataSource.kt index 2e193b0..7f1f726 100644 --- a/src/main/kotlin/data/mongodb_data_source/MongoDBDataSource.kt +++ b/src/main/kotlin/data/mongodb_data_source/MongoDBDataSource.kt @@ -2,33 +2,48 @@ package com.berlin.data.mongodb_data_source import com.berlin.data.BaseDataSource import com.berlin.data.BaseSchema +import com.mongodb.ConnectionString +import com.mongodb.MongoClientSettings +import com.mongodb.client.MongoClient +import com.mongodb.client.MongoClients +import com.mongodb.client.MongoCollection +import com.mongodb.client.model.Filters +import com.mongodb.client.model.ReplaceOptions +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.bson.Document +import org.bson.types.ObjectId +import java.util.logging.Level +import java.util.logging.Logger open class MongoDBDataSource( private val connectionString: String, private val databaseName: String, private val schema: BaseSchema, ) : BaseDataSource { - override fun getAll(): List { + override suspend fun getAll(): List { TODO("Not yet implemented") } - override fun getById(id: String): T? { + override suspend fun getById(id: String): T? { TODO("Not yet implemented") } - override fun update(id: String, entity: T): Boolean { + override suspend fun update(id: String, entity: T): Boolean { TODO("Not yet implemented") } - override fun delete(id: String): Boolean { + override suspend fun delete(id: String): Boolean { TODO("Not yet implemented") } - override fun write(entity: T): Boolean { + override suspend fun write(entity: T): Boolean { TODO("Not yet implemented") } - override fun writeAll(entities: List): Boolean { + override suspend fun writeAll(entities: List): Boolean { TODO("Not yet implemented") } + + } \ No newline at end of file diff --git a/src/main/kotlin/data/project/ProjectRepositoryImpl.kt b/src/main/kotlin/data/project/ProjectRepositoryImpl.kt index 697204e..b564af5 100644 --- a/src/main/kotlin/data/project/ProjectRepositoryImpl.kt +++ b/src/main/kotlin/data/project/ProjectRepositoryImpl.kt @@ -7,29 +7,29 @@ import com.berlin.domain.repository.ProjectRepository class ProjectRepositoryImpl(private val projectDataSource: BaseDataSource) : ProjectRepository { - override fun createProject(project: Project): Result { + override suspend fun createProject(project: Project): Result { return if (projectDataSource.write(project)) Result.success(project.id) else Result.failure(InvalidProjectException("can not create project")) } - override fun getProjectById(projectId: String): Project? { + override suspend fun getProjectById(projectId: String): Project? { return projectDataSource.getById(projectId) } - override fun getAllProjects(): List? { + override suspend fun getAllProjects(): List? { return projectDataSource.getAll().ifEmpty { null } } - override fun updateProject(project: Project): Result { + override suspend fun updateProject(project: Project): Result { return if (projectDataSource.update(project.id, project)) Result.success(project.id) else Result.failure(InvalidProjectException("can not update project")) } - override fun deleteProject(projectId: String): Result { + override suspend fun deleteProject(projectId: String): Result { return if (projectDataSource.delete(projectId)) Result.success(projectId) else diff --git a/src/main/kotlin/data/state/StateRepositoryImpl.kt b/src/main/kotlin/data/state/StateRepositoryImpl.kt index c7c1885..41ca7ad 100644 --- a/src/main/kotlin/data/state/StateRepositoryImpl.kt +++ b/src/main/kotlin/data/state/StateRepositoryImpl.kt @@ -10,46 +10,46 @@ class StateRepositoryImpl( private val stateDataSource: BaseDataSource, private val taskDataSource: BaseDataSource ):StateRepository { - override fun addState(state: State): Result { + override suspend fun addState(state: State): Result { return if (stateDataSource.write(state)) Result.success(state.id) else Result.failure(InvalidStateException("can not add state")) } - override fun getStatesByProjectId(projectId: String): List? { + override suspend fun getStatesByProjectId(projectId: String): List? { return stateDataSource.getAll() .filter { it.projectId == projectId } .takeIf { it.isNotEmpty() } } - override fun getTasksByStateId(stateId: String): List? { + override suspend fun getTasksByStateId(stateId: String): List? { return taskDataSource.getAll() .filter { it.stateId == stateId } .takeIf { it.isNotEmpty() } } - override fun deleteState(stateId: String): Result { + override suspend fun deleteState(stateId: String): Result { return if (stateDataSource.delete(stateId)) Result.success(stateId) else Result.failure(InvalidStateException("can not delete state")) } - override fun updateState(state: State): Result { + override suspend fun updateState(state: State): Result { return if (stateDataSource.update(state.id,state)) Result.success(state.id) else Result.failure(InvalidStateException("can not update state")) } - override fun getStateByTaskId(taskId: String): State? { + override suspend fun getStateByTaskId(taskId: String): State? { return taskDataSource .getById(taskId) ?.let { stateDataSource.getById(it.stateId) } } - override fun getStateById(stateId: String): State? { + override suspend fun getStateById(stateId: String): State? { return stateDataSource.getById(stateId) } } \ No newline at end of file diff --git a/src/main/kotlin/data/task/TaskRepositoryImpl.kt b/src/main/kotlin/data/task/TaskRepositoryImpl.kt index 54d3835..6230f7a 100644 --- a/src/main/kotlin/data/task/TaskRepositoryImpl.kt +++ b/src/main/kotlin/data/task/TaskRepositoryImpl.kt @@ -12,31 +12,31 @@ class TaskRepositoryImpl( val baseDataSource: BaseDataSource, ) : TaskRepository { - override fun create(task: Task): Result = runCatching { + override suspend fun create(task: Task): Result = runCatching { if (baseDataSource.write(task)) task else throw InvalidTaskException("some thing went error") } - override fun update(task: Task): Result = runCatching { + override suspend fun update(task: Task): Result = runCatching { if (!baseDataSource.update(task.id, task)) throw InvalidTaskException("some thing went error") task } - override fun findById(id: String): Result = + override suspend fun findById(id: String): Result = baseDataSource.getById(id) ?.let { success(it) } ?: failure(TaskNotFoundException(id)) - override fun findTasksByProjectId(projectId: String): Result> = + override suspend fun findTasksByProjectId(projectId: String): Result> = success(baseDataSource.getAll().filter { it.projectId == projectId }) - override fun delete(id: String): Result = runCatching { + override suspend fun delete(id: String): Result = runCatching { if (!baseDataSource.delete(id)) throw TaskNotFoundException(id) } - override fun getAllTasks(): List { + override suspend fun getAllTasks(): List { return baseDataSource.getAll() } } diff --git a/src/main/kotlin/domain/repository/ProjectRepository.kt b/src/main/kotlin/domain/repository/ProjectRepository.kt index ccaa2ff..07cb0ca 100644 --- a/src/main/kotlin/domain/repository/ProjectRepository.kt +++ b/src/main/kotlin/domain/repository/ProjectRepository.kt @@ -3,9 +3,9 @@ package com.berlin.domain.repository import com.berlin.domain.model.Project interface ProjectRepository { - fun createProject(project:Project): Result - fun getProjectById(projectId:String): Project? - fun getAllProjects(): List? - fun updateProject(project: Project): Result - fun deleteProject(projectId: String): Result + suspend fun createProject(project:Project): Result + suspend fun getProjectById(projectId:String): Project? + suspend fun getAllProjects(): List? + suspend fun updateProject(project: Project): Result + suspend fun deleteProject(projectId: String): Result } \ No newline at end of file diff --git a/src/main/kotlin/domain/repository/StateRepository.kt b/src/main/kotlin/domain/repository/StateRepository.kt index a5eef70..7ac761e 100644 --- a/src/main/kotlin/domain/repository/StateRepository.kt +++ b/src/main/kotlin/domain/repository/StateRepository.kt @@ -4,11 +4,11 @@ import com.berlin.domain.model.State import com.berlin.domain.model.Task interface StateRepository { - fun addState(state: State): Result - fun getStatesByProjectId(projectId: String):List? - fun getTasksByStateId(stateId: String):List? - fun deleteState(stateId: String): Result - fun updateState(state: State): Result - fun getStateByTaskId(taskId: String): State? - fun getStateById(stateId: String): State? + suspend fun addState(state: State): Result + suspend fun getStatesByProjectId(projectId: String):List? + suspend fun getTasksByStateId(stateId: String):List? + suspend fun deleteState(stateId: String): Result + suspend fun updateState(state: State): Result + suspend fun getStateByTaskId(taskId: String): State? + suspend fun getStateById(stateId: String): State? } \ No newline at end of file diff --git a/src/main/kotlin/domain/repository/TaskRepository.kt b/src/main/kotlin/domain/repository/TaskRepository.kt index 0f36d9f..8ba5510 100644 --- a/src/main/kotlin/domain/repository/TaskRepository.kt +++ b/src/main/kotlin/domain/repository/TaskRepository.kt @@ -3,10 +3,10 @@ package com.berlin.domain.repository import com.berlin.domain.model.Task interface TaskRepository { - fun create(task: Task): Result - fun update(task: Task): Result - fun findById(id: String): Result - fun findTasksByProjectId(projectId: String): Result> - fun delete(id: String): Result - fun getAllTasks(): List + suspend fun create(task: Task): Result + suspend fun update(task: Task): Result + suspend fun findById(id: String): Result + suspend fun findTasksByProjectId(projectId: String): Result> + suspend fun delete(id: String): Result + suspend fun getAllTasks(): List } From c27e432378e94a0b5f5a8f73c09b03d0872e3ab2 Mon Sep 17 00:00:00 2001 From: dev7odaa Date: Mon, 5 May 2025 19:38:39 +0300 Subject: [PATCH 03/17] add mongodb dependency --- build.gradle.kts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index 9d1d4d6..4385bd9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -20,6 +20,10 @@ dependencies { testImplementation("com.google.truth:truth:1.4.4") testImplementation("org.jetbrains.kotlin:kotlin-test") testImplementation("org.junit.jupiter:junit-jupiter-params:5.10.0") + + implementation("org.mongodb:mongodb-driver-sync:4.10.1") + implementation("org.mongodb:mongodb-driver-kotlin-coroutine:4.10.1") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3") } kover { From ea9aa412db008c5428811aeb2a709a2718d770bf Mon Sep 17 00:00:00 2001 From: Diyar Date: Tue, 6 May 2025 20:25:53 +0300 Subject: [PATCH 04/17] add test and implementation of mongoDBConfig --- build.gradle.kts | 5 +- src/main/kotlin/data/BaseDataSource.kt | 12 +-- .../kotlin/data/mongodb/config/MongoConfig.kt | 47 +++++++++++ .../mongodb_data_source/MongoDBDataSource.kt | 49 ------------ .../data/project/ProjectRepositoryImpl.kt | 10 +-- .../kotlin/data/state/StateRepositoryImpl.kt | 14 ++-- .../kotlin/data/task/TaskRepositoryImpl.kt | 16 ++-- src/main/kotlin/di/dataModule.kt | 5 +- .../domain/repository/ProjectRepository.kt | 10 +-- .../domain/repository/StateRepository.kt | 14 ++-- .../domain/repository/TaskRepository.kt | 12 +-- .../data/mongodb/config/MongoConfigTest.kt | 79 +++++++++++++++++++ .../data/task/TaskRepositoryImplTest.kt | 1 + 13 files changed, 178 insertions(+), 96 deletions(-) create mode 100644 src/main/kotlin/data/mongodb/config/MongoConfig.kt delete mode 100644 src/main/kotlin/data/mongodb_data_source/MongoDBDataSource.kt create mode 100644 src/test/kotlin/data/mongodb/config/MongoConfigTest.kt diff --git a/build.gradle.kts b/build.gradle.kts index 4385bd9..ab5cdca 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,6 +13,7 @@ repositories { dependencies { implementation("io.insert-koin:koin-core:4.0.4") implementation ("org.jetbrains.kotlinx:kotlinx-datetime:0.6.2") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3") implementation("com.opencsv:opencsv:5.7.1") testImplementation(kotlin("test")) testImplementation("org.junit.jupiter:junit-jupiter:5.8.1") @@ -21,9 +22,9 @@ dependencies { testImplementation("org.jetbrains.kotlin:kotlin-test") testImplementation("org.junit.jupiter:junit-jupiter-params:5.10.0") - implementation("org.mongodb:mongodb-driver-sync:4.10.1") implementation("org.mongodb:mongodb-driver-kotlin-coroutine:4.10.1") - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3") + implementation("org.mongodb:bson-kotlin:4.10.1") + } kover { diff --git a/src/main/kotlin/data/BaseDataSource.kt b/src/main/kotlin/data/BaseDataSource.kt index c274efd..22a9105 100644 --- a/src/main/kotlin/data/BaseDataSource.kt +++ b/src/main/kotlin/data/BaseDataSource.kt @@ -2,16 +2,16 @@ package com.berlin.data interface BaseDataSource { - suspend fun getAll(): List + fun getAll(): List - suspend fun getById(id: String): T? + fun getById(id: String): T? - suspend fun update(id: String, entity: T): Boolean + fun update(id: String, entity: T): Boolean - suspend fun delete(id: String): Boolean + fun delete(id: String): Boolean - suspend fun write(entity: T): Boolean + fun write(entity: T): Boolean - suspend fun writeAll(entities: List): Boolean + fun writeAll(entities: List): Boolean } \ No newline at end of file diff --git a/src/main/kotlin/data/mongodb/config/MongoConfig.kt b/src/main/kotlin/data/mongodb/config/MongoConfig.kt new file mode 100644 index 0000000..33c777b --- /dev/null +++ b/src/main/kotlin/data/mongodb/config/MongoConfig.kt @@ -0,0 +1,47 @@ +package com.berlin.data.mongodb.config + +import com.mongodb.ConnectionString +import com.mongodb.MongoClientSettings +import com.mongodb.kotlin.client.coroutine.MongoClient +import com.mongodb.kotlin.client.coroutine.MongoDatabase +import org.bson.codecs.configuration.CodecRegistries +import org.bson.codecs.pojo.PojoCodecProvider +import com.mongodb.kotlin.client.coroutine.MongoCollection + +class MongoConfig( + private val connectionString: String = "mongodb+srv://diyarHussein:BoB0S2i5tDLXr4Xw@planmate.gzyncow.mongodb.net/?retryWrites=true&w=majority&appName=PlanMate", + private val databaseName: String = "PlanMate" +) { + + fun createMongoClient(): MongoClient { + val pojoCodecProvider = PojoCodecProvider.builder() + .automatic(true) + .build() + + val codecRegistry = CodecRegistries.fromRegistries( + MongoClientSettings.getDefaultCodecRegistry(), + CodecRegistries.fromProviders(pojoCodecProvider) + ) + + val clientSettings = MongoClientSettings.builder() + .applyConnectionString(ConnectionString(connectionString)) + .codecRegistry(codecRegistry) + .build() + + return MongoClient.create(clientSettings) + } + + fun getDatabase(client: MongoClient): MongoDatabase { + return client.getDatabase(databaseName) + } + + inline fun getCollection(database: MongoDatabase, collectionName: String): MongoCollection { + return database.getCollection(collectionName) + } + + inline fun getTypedCollection(collectionName: String): MongoCollection { + val client = createMongoClient() + val database = getDatabase(client) + return getCollection(database, collectionName) + } +} \ No newline at end of file diff --git a/src/main/kotlin/data/mongodb_data_source/MongoDBDataSource.kt b/src/main/kotlin/data/mongodb_data_source/MongoDBDataSource.kt deleted file mode 100644 index 7f1f726..0000000 --- a/src/main/kotlin/data/mongodb_data_source/MongoDBDataSource.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.berlin.data.mongodb_data_source - -import com.berlin.data.BaseDataSource -import com.berlin.data.BaseSchema -import com.mongodb.ConnectionString -import com.mongodb.MongoClientSettings -import com.mongodb.client.MongoClient -import com.mongodb.client.MongoClients -import com.mongodb.client.MongoCollection -import com.mongodb.client.model.Filters -import com.mongodb.client.model.ReplaceOptions -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import org.bson.Document -import org.bson.types.ObjectId -import java.util.logging.Level -import java.util.logging.Logger - -open class MongoDBDataSource( - private val connectionString: String, - private val databaseName: String, - private val schema: BaseSchema, -) : BaseDataSource { - override suspend fun getAll(): List { - TODO("Not yet implemented") - } - - override suspend fun getById(id: String): T? { - TODO("Not yet implemented") - } - - override suspend fun update(id: String, entity: T): Boolean { - TODO("Not yet implemented") - } - - override suspend fun delete(id: String): Boolean { - TODO("Not yet implemented") - } - - override suspend fun write(entity: T): Boolean { - TODO("Not yet implemented") - } - - override suspend fun writeAll(entities: List): Boolean { - TODO("Not yet implemented") - } - - -} \ No newline at end of file diff --git a/src/main/kotlin/data/project/ProjectRepositoryImpl.kt b/src/main/kotlin/data/project/ProjectRepositoryImpl.kt index b564af5..697204e 100644 --- a/src/main/kotlin/data/project/ProjectRepositoryImpl.kt +++ b/src/main/kotlin/data/project/ProjectRepositoryImpl.kt @@ -7,29 +7,29 @@ import com.berlin.domain.repository.ProjectRepository class ProjectRepositoryImpl(private val projectDataSource: BaseDataSource) : ProjectRepository { - override suspend fun createProject(project: Project): Result { + override fun createProject(project: Project): Result { return if (projectDataSource.write(project)) Result.success(project.id) else Result.failure(InvalidProjectException("can not create project")) } - override suspend fun getProjectById(projectId: String): Project? { + override fun getProjectById(projectId: String): Project? { return projectDataSource.getById(projectId) } - override suspend fun getAllProjects(): List? { + override fun getAllProjects(): List? { return projectDataSource.getAll().ifEmpty { null } } - override suspend fun updateProject(project: Project): Result { + override fun updateProject(project: Project): Result { return if (projectDataSource.update(project.id, project)) Result.success(project.id) else Result.failure(InvalidProjectException("can not update project")) } - override suspend fun deleteProject(projectId: String): Result { + override fun deleteProject(projectId: String): Result { return if (projectDataSource.delete(projectId)) Result.success(projectId) else diff --git a/src/main/kotlin/data/state/StateRepositoryImpl.kt b/src/main/kotlin/data/state/StateRepositoryImpl.kt index 41ca7ad..c7c1885 100644 --- a/src/main/kotlin/data/state/StateRepositoryImpl.kt +++ b/src/main/kotlin/data/state/StateRepositoryImpl.kt @@ -10,46 +10,46 @@ class StateRepositoryImpl( private val stateDataSource: BaseDataSource, private val taskDataSource: BaseDataSource ):StateRepository { - override suspend fun addState(state: State): Result { + override fun addState(state: State): Result { return if (stateDataSource.write(state)) Result.success(state.id) else Result.failure(InvalidStateException("can not add state")) } - override suspend fun getStatesByProjectId(projectId: String): List? { + override fun getStatesByProjectId(projectId: String): List? { return stateDataSource.getAll() .filter { it.projectId == projectId } .takeIf { it.isNotEmpty() } } - override suspend fun getTasksByStateId(stateId: String): List? { + override fun getTasksByStateId(stateId: String): List? { return taskDataSource.getAll() .filter { it.stateId == stateId } .takeIf { it.isNotEmpty() } } - override suspend fun deleteState(stateId: String): Result { + override fun deleteState(stateId: String): Result { return if (stateDataSource.delete(stateId)) Result.success(stateId) else Result.failure(InvalidStateException("can not delete state")) } - override suspend fun updateState(state: State): Result { + override fun updateState(state: State): Result { return if (stateDataSource.update(state.id,state)) Result.success(state.id) else Result.failure(InvalidStateException("can not update state")) } - override suspend fun getStateByTaskId(taskId: String): State? { + override fun getStateByTaskId(taskId: String): State? { return taskDataSource .getById(taskId) ?.let { stateDataSource.getById(it.stateId) } } - override suspend fun getStateById(stateId: String): State? { + override fun getStateById(stateId: String): State? { return stateDataSource.getById(stateId) } } \ No newline at end of file diff --git a/src/main/kotlin/data/task/TaskRepositoryImpl.kt b/src/main/kotlin/data/task/TaskRepositoryImpl.kt index 6230f7a..f25b98a 100644 --- a/src/main/kotlin/data/task/TaskRepositoryImpl.kt +++ b/src/main/kotlin/data/task/TaskRepositoryImpl.kt @@ -1,4 +1,4 @@ -package com.berlin.data.memory +package com.berlin.data.task import com.berlin.data.BaseDataSource import com.berlin.domain.exception.InvalidTaskException @@ -9,34 +9,34 @@ import kotlin.Result.Companion.failure import kotlin.Result.Companion.success class TaskRepositoryImpl( - val baseDataSource: BaseDataSource, + private val baseDataSource: BaseDataSource, ) : TaskRepository { - override suspend fun create(task: Task): Result = runCatching { + override fun create(task: Task): Result = runCatching { if (baseDataSource.write(task)) task else throw InvalidTaskException("some thing went error") } - override suspend fun update(task: Task): Result = runCatching { + override fun update(task: Task): Result = runCatching { if (!baseDataSource.update(task.id, task)) throw InvalidTaskException("some thing went error") task } - override suspend fun findById(id: String): Result = + override fun findById(id: String): Result = baseDataSource.getById(id) ?.let { success(it) } ?: failure(TaskNotFoundException(id)) - override suspend fun findTasksByProjectId(projectId: String): Result> = + override fun findTasksByProjectId(projectId: String): Result> = success(baseDataSource.getAll().filter { it.projectId == projectId }) - override suspend fun delete(id: String): Result = runCatching { + override fun delete(id: String): Result = runCatching { if (!baseDataSource.delete(id)) throw TaskNotFoundException(id) } - override suspend fun getAllTasks(): List { + override fun getAllTasks(): List { return baseDataSource.getAll() } } diff --git a/src/main/kotlin/di/dataModule.kt b/src/main/kotlin/di/dataModule.kt index baccacb..9996204 100644 --- a/src/main/kotlin/di/dataModule.kt +++ b/src/main/kotlin/di/dataModule.kt @@ -4,7 +4,8 @@ import com.berlin.data.BaseDataSource import com.berlin.data.BaseSchema import com.berlin.data.authentication.AuthenticationRepositoryImpl import com.berlin.data.csv_data_source.CsvDataSource -import com.berlin.data.memory.TaskRepositoryImpl +import com.berlin.data.mongodb.config.MongoConfig +import com.berlin.data.task.TaskRepositoryImpl import com.berlin.data.project.ProjectRepositoryImpl import com.berlin.data.schema.* import com.berlin.data.state.StateRepositoryImpl @@ -79,4 +80,6 @@ val dataModule = module { single { AuthenticationRepositoryImpl(get(named("UserDataSource"))) } single { AuthenticationRepositoryImpl(get(named("UserDataSource"))) } + + single { MongoConfig() } } \ No newline at end of file diff --git a/src/main/kotlin/domain/repository/ProjectRepository.kt b/src/main/kotlin/domain/repository/ProjectRepository.kt index 07cb0ca..e4954de 100644 --- a/src/main/kotlin/domain/repository/ProjectRepository.kt +++ b/src/main/kotlin/domain/repository/ProjectRepository.kt @@ -3,9 +3,9 @@ package com.berlin.domain.repository import com.berlin.domain.model.Project interface ProjectRepository { - suspend fun createProject(project:Project): Result - suspend fun getProjectById(projectId:String): Project? - suspend fun getAllProjects(): List? - suspend fun updateProject(project: Project): Result - suspend fun deleteProject(projectId: String): Result + fun createProject(project:Project): Result + fun getProjectById(projectId:String): Project? + fun getAllProjects(): List? + fun updateProject(project: Project): Result + fun deleteProject(projectId: String): Result } \ No newline at end of file diff --git a/src/main/kotlin/domain/repository/StateRepository.kt b/src/main/kotlin/domain/repository/StateRepository.kt index 7ac761e..58adea1 100644 --- a/src/main/kotlin/domain/repository/StateRepository.kt +++ b/src/main/kotlin/domain/repository/StateRepository.kt @@ -4,11 +4,11 @@ import com.berlin.domain.model.State import com.berlin.domain.model.Task interface StateRepository { - suspend fun addState(state: State): Result - suspend fun getStatesByProjectId(projectId: String):List? - suspend fun getTasksByStateId(stateId: String):List? - suspend fun deleteState(stateId: String): Result - suspend fun updateState(state: State): Result - suspend fun getStateByTaskId(taskId: String): State? - suspend fun getStateById(stateId: String): State? + fun addState(state: State): Result + fun getStatesByProjectId(projectId: String):List? + fun getTasksByStateId(stateId: String):List? + fun deleteState(stateId: String): Result + fun updateState(state: State): Result + fun getStateByTaskId(taskId: String): State? + fun getStateById(stateId: String): State? } \ No newline at end of file diff --git a/src/main/kotlin/domain/repository/TaskRepository.kt b/src/main/kotlin/domain/repository/TaskRepository.kt index 8ba5510..6e59dcd 100644 --- a/src/main/kotlin/domain/repository/TaskRepository.kt +++ b/src/main/kotlin/domain/repository/TaskRepository.kt @@ -3,10 +3,10 @@ package com.berlin.domain.repository import com.berlin.domain.model.Task interface TaskRepository { - suspend fun create(task: Task): Result - suspend fun update(task: Task): Result - suspend fun findById(id: String): Result - suspend fun findTasksByProjectId(projectId: String): Result> - suspend fun delete(id: String): Result - suspend fun getAllTasks(): List + fun create(task: Task): Result + fun update(task: Task): Result + fun findById(id: String): Result + fun findTasksByProjectId(projectId: String): Result> + fun delete(id: String): Result + fun getAllTasks(): List } diff --git a/src/test/kotlin/data/mongodb/config/MongoConfigTest.kt b/src/test/kotlin/data/mongodb/config/MongoConfigTest.kt new file mode 100644 index 0000000..c0f02f0 --- /dev/null +++ b/src/test/kotlin/data/mongodb/config/MongoConfigTest.kt @@ -0,0 +1,79 @@ +package com.berlin.data.mongodb.config + +import com.mongodb.kotlin.client.coroutine.MongoClient +import com.mongodb.kotlin.client.coroutine.MongoDatabase +import com.mongodb.kotlin.client.coroutine.MongoCollection +import io.mockk.every +import io.mockk.mockk + +import io.mockk.verify +import io.mockk.unmockkAll +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNotNull +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test + +class MongoConfigTest { + + private lateinit var mongoConfig: MongoConfig + private lateinit var mockMongoClient: MongoClient + private lateinit var mockMongoDatabase: MongoDatabase + private lateinit var mockCollection: MongoCollection + + @BeforeEach + fun setUp() { + // Create mocks + mockMongoClient = mockk(relaxed = true) + mockMongoDatabase = mockk(relaxed = true) + mockCollection = mockk(relaxed = true) + + mongoConfig = MongoConfig( + connectionString = "mongodb://localhost:27017", + databaseName = "testDatabase" + ) + } + + @AfterEach + fun tearDown() { + unmockkAll() + } + + @Test + fun `getDatabase should return database with correct name`() { + // Given + every { mockMongoClient.getDatabase(any()) } returns mockMongoDatabase + + // When + val database = mongoConfig.getDatabase(mockMongoClient) + + // Then + verify { mockMongoClient.getDatabase("testDatabase") } + assertEquals(mockMongoDatabase, database) + } + + @Test + fun `getCollection should return typed collection with correct name`() { + // Given + every { mockMongoDatabase.getCollection(any()) } returns mockCollection + + // When + val collection = mongoConfig.getCollection(mockMongoDatabase, "testCollection") + + // Then + verify { mockMongoDatabase.getCollection("testCollection") } + assertEquals(mockCollection, collection) + } + + @Test + fun `test MongoConfig constructor sets values correctly`() { + // When + val config = MongoConfig("test-connection-string", "test-db") + + // Then + assertNotNull(config) + } + + // Data class for testing + data class TestDocument(val id: String, val name: String) +} \ No newline at end of file diff --git a/src/test/kotlin/data/task/TaskRepositoryImplTest.kt b/src/test/kotlin/data/task/TaskRepositoryImplTest.kt index eb422ed..1332928 100644 --- a/src/test/kotlin/data/task/TaskRepositoryImplTest.kt +++ b/src/test/kotlin/data/task/TaskRepositoryImplTest.kt @@ -8,6 +8,7 @@ import com.berlin.domain.model.User import com.berlin.domain.model.UserRole import com.google.common.truth.Truth.assertThat import com.berlin.data.DummyData +import com.berlin.data.task.TaskRepositoryImpl import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test From 82c0b21c791ce2a85713f438fee270a679a34b7c Mon Sep 17 00:00:00 2001 From: Diyar Date: Wed, 7 May 2025 19:31:58 +0300 Subject: [PATCH 05/17] fix audit package naming --- csv_files/task.csv | 1 - .../{Audit => audit}/AuditRepositoryImpl.kt | 2 +- .../kotlin/data/mongodb/config/MongoConfig.kt | 6 -- src/main/kotlin/di/dataModule.kt | 4 +- .../AuditRepositoryImplTest.kt | 4 +- .../data/mongodb/config/MongoConfigTest.kt | 87 ++++++++++++++++--- 6 files changed, 78 insertions(+), 26 deletions(-) rename src/main/kotlin/data/{Audit => audit}/AuditRepositoryImpl.kt (97%) rename src/test/kotlin/data/{Audit => audit}/AuditRepositoryImplTest.kt (98%) diff --git a/csv_files/task.csv b/csv_files/task.csv index 7082b73..7cadf91 100644 --- a/csv_files/task.csv +++ b/csv_files/task.csv @@ -1,2 +1 @@ "Task Id","Project Id","Title","Description","State Id","Assigned To User Id","Create By User Id" -"dfgsdgfdd_66055","P1","dfgsdgfd","gasdfgfdaf","S1","U1","U1" diff --git a/src/main/kotlin/data/Audit/AuditRepositoryImpl.kt b/src/main/kotlin/data/audit/AuditRepositoryImpl.kt similarity index 97% rename from src/main/kotlin/data/Audit/AuditRepositoryImpl.kt rename to src/main/kotlin/data/audit/AuditRepositoryImpl.kt index 574b940..48c2aca 100644 --- a/src/main/kotlin/data/Audit/AuditRepositoryImpl.kt +++ b/src/main/kotlin/data/audit/AuditRepositoryImpl.kt @@ -1,4 +1,4 @@ -package com.berlin.data.Audit +package com.berlin.data.audit import com.berlin.data.BaseDataSource import com.berlin.domain.exception.InvalidAuditLogException diff --git a/src/main/kotlin/data/mongodb/config/MongoConfig.kt b/src/main/kotlin/data/mongodb/config/MongoConfig.kt index 33c777b..8bd2004 100644 --- a/src/main/kotlin/data/mongodb/config/MongoConfig.kt +++ b/src/main/kotlin/data/mongodb/config/MongoConfig.kt @@ -38,10 +38,4 @@ class MongoConfig( inline fun getCollection(database: MongoDatabase, collectionName: String): MongoCollection { return database.getCollection(collectionName) } - - inline fun getTypedCollection(collectionName: String): MongoCollection { - val client = createMongoClient() - val database = getDatabase(client) - return getCollection(database, collectionName) - } } \ No newline at end of file diff --git a/src/main/kotlin/di/dataModule.kt b/src/main/kotlin/di/dataModule.kt index 9996204..32e1b4f 100644 --- a/src/main/kotlin/di/dataModule.kt +++ b/src/main/kotlin/di/dataModule.kt @@ -1,5 +1,4 @@ package com.berlin.di -import com.berlin.data.Audit.AuditRepositoryImpl import com.berlin.data.BaseDataSource import com.berlin.data.BaseSchema import com.berlin.data.authentication.AuthenticationRepositoryImpl @@ -10,7 +9,6 @@ import com.berlin.data.project.ProjectRepositoryImpl import com.berlin.data.schema.* import com.berlin.data.state.StateRepositoryImpl import com.berlin.domain.model.* -import com.berlin.domain.repository.AuditRepository import com.berlin.domain.repository.AuthenticationRepository import com.berlin.domain.repository.ProjectRepository import com.berlin.domain.repository.StateRepository @@ -75,7 +73,7 @@ val dataModule = module { single { ProjectRepositoryImpl(get(named("ProjectDataSource"))) } single { TaskRepositoryImpl(get(named("TaskDataSource"))) } - single { AuditRepositoryImpl(get(named("AuditDataSource"))) } +// single { AuditRepositoryImpl(get(named("AuditDataSource"))) } single { StateRepositoryImpl(get(named("StateDataSource")),get(named("TaskDataSource"))) } single { AuthenticationRepositoryImpl(get(named("UserDataSource"))) } diff --git a/src/test/kotlin/data/Audit/AuditRepositoryImplTest.kt b/src/test/kotlin/data/audit/AuditRepositoryImplTest.kt similarity index 98% rename from src/test/kotlin/data/Audit/AuditRepositoryImplTest.kt rename to src/test/kotlin/data/audit/AuditRepositoryImplTest.kt index 6a190d7..d5253a3 100644 --- a/src/test/kotlin/data/Audit/AuditRepositoryImplTest.kt +++ b/src/test/kotlin/data/audit/AuditRepositoryImplTest.kt @@ -1,6 +1,6 @@ -package data.Audit +package data.audit -import com.berlin.data.Audit.AuditRepositoryImpl +import com.berlin.data.audit.AuditRepositoryImpl import com.berlin.data.csv_data_source.CsvDataSource import com.berlin.domain.exception.InvalidAuditLogException import com.berlin.domain.model.AuditAction diff --git a/src/test/kotlin/data/mongodb/config/MongoConfigTest.kt b/src/test/kotlin/data/mongodb/config/MongoConfigTest.kt index c0f02f0..e89ed4d 100644 --- a/src/test/kotlin/data/mongodb/config/MongoConfigTest.kt +++ b/src/test/kotlin/data/mongodb/config/MongoConfigTest.kt @@ -1,18 +1,17 @@ package com.berlin.data.mongodb.config +import com.mongodb.MongoClientSettings import com.mongodb.kotlin.client.coroutine.MongoClient import com.mongodb.kotlin.client.coroutine.MongoDatabase import com.mongodb.kotlin.client.coroutine.MongoCollection -import io.mockk.every -import io.mockk.mockk - -import io.mockk.verify -import io.mockk.unmockkAll +import io.mockk.* +import org.bson.codecs.configuration.CodecRegistry +import org.bson.codecs.pojo.PojoCodecProvider import org.junit.jupiter.api.AfterEach -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Assertions.assertNotNull +import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test +import org.junit.jupiter.api.DisplayName class MongoConfigTest { @@ -28,6 +27,7 @@ class MongoConfigTest { mockMongoDatabase = mockk(relaxed = true) mockCollection = mockk(relaxed = true) + // Create instance with test values mongoConfig = MongoConfig( connectionString = "mongodb://localhost:27017", databaseName = "testDatabase" @@ -40,7 +40,8 @@ class MongoConfigTest { } @Test - fun `getDatabase should return database with correct name`() { + @DisplayName("getDatabase should return database with correct name") + fun `getDatabase returns database with correct name`() { // Given every { mockMongoClient.getDatabase(any()) } returns mockMongoDatabase @@ -53,7 +54,8 @@ class MongoConfigTest { } @Test - fun `getCollection should return typed collection with correct name`() { + @DisplayName("getCollection should return typed collection with correct name") + fun `getCollection returns typed collection with correct name`() { // Given every { mockMongoDatabase.getCollection(any()) } returns mockCollection @@ -66,14 +68,73 @@ class MongoConfigTest { } @Test - fun `test MongoConfig constructor sets values correctly`() { + @DisplayName("test constructor sets correct values") + fun `constructor sets correct values`() { // When - val config = MongoConfig("test-connection-string", "test-db") + val customConfig = MongoConfig("custom-connection-string", "custom-db-name") // Then - assertNotNull(config) + assertNotNull(customConfig) } - // Data class for testing + @Test + fun `createMongoClient creates client with correct configuration`() { + // Mock the static methods we need to control + mockkStatic(MongoClient::class) + mockkStatic(MongoClientSettings::class) + mockkStatic(CodecRegistry::class) + mockkStatic(PojoCodecProvider::class) + + // Mock CodecProvider + val mockProvider = mockk() + val mockBuilder = mockk() + every { PojoCodecProvider.builder() } returns mockBuilder + every { mockBuilder.automatic(true) } returns mockBuilder + every { mockBuilder.build() } returns mockProvider + + // Mock CodecRegistry + val mockRegistry = mockk() + val defaultRegistry = mockk() + every { MongoClientSettings.getDefaultCodecRegistry() } returns defaultRegistry + mockkStatic("org.bson.codecs.configuration.CodecRegistries") + every { + org.bson.codecs.configuration.CodecRegistries.fromProviders(mockProvider) + } returns mockRegistry + every { + org.bson.codecs.configuration.CodecRegistries.fromRegistries(defaultRegistry, mockRegistry) + } returns mockRegistry + + // Mock ClientSettings + val mockSettings = mockk() + val mockSettingsBuilder = mockk() + every { MongoClientSettings.builder() } returns mockSettingsBuilder + every { mockSettingsBuilder.applyConnectionString(any()) } returns mockSettingsBuilder + every { mockSettingsBuilder.codecRegistry(mockRegistry) } returns mockSettingsBuilder + every { mockSettingsBuilder.build() } returns mockSettings + + // Mock MongoClient creation + every { MongoClient.create(mockSettings) } returns mockMongoClient + + // Execute the method + val result = mongoConfig.createMongoClient() + + // Verify + assertNotNull(result) + verify { + PojoCodecProvider.builder() + mockBuilder.automatic(true) + mockBuilder.build() + MongoClientSettings.getDefaultCodecRegistry() + org.bson.codecs.configuration.CodecRegistries.fromProviders(mockProvider) + org.bson.codecs.configuration.CodecRegistries.fromRegistries(defaultRegistry, mockRegistry) + MongoClientSettings.builder() + mockSettingsBuilder.applyConnectionString(match { + it.connectionString == "mongodb://localhost:27017" + }) + mockSettingsBuilder.codecRegistry(mockRegistry) + mockSettingsBuilder.build() + MongoClient.create(mockSettings) + } + } data class TestDocument(val id: String, val name: String) } \ No newline at end of file From 1ec016619cc426d8b257773f5d5e4510d1263be1 Mon Sep 17 00:00:00 2001 From: dev7odaa Date: Thu, 8 May 2025 01:24:31 +0300 Subject: [PATCH 06/17] change models to work with MongoDB --- src/main/kotlin/domain/model/AuditLog.kt | 15 +++++++----- src/main/kotlin/domain/model/Permission.kt | 28 ++++++++++++---------- src/main/kotlin/domain/model/Project.kt | 13 ++++++---- src/main/kotlin/domain/model/State.kt | 9 ++++--- src/main/kotlin/domain/model/Task.kt | 15 +++++++----- src/main/kotlin/domain/model/User.kt | 10 ++++---- 6 files changed, 53 insertions(+), 37 deletions(-) diff --git a/src/main/kotlin/domain/model/AuditLog.kt b/src/main/kotlin/domain/model/AuditLog.kt index b2fcac4..685885b 100644 --- a/src/main/kotlin/domain/model/AuditLog.kt +++ b/src/main/kotlin/domain/model/AuditLog.kt @@ -1,11 +1,14 @@ package com.berlin.domain.model +import org.bson.codecs.pojo.annotations.BsonId +import org.bson.codecs.pojo.annotations.BsonProperty + data class AuditLog( - val id:String, + @BsonId val id: String, val timestamp: Long, - val createdByUserId: String, - val auditAction: AuditAction, - val changesDescription:String?, - val entityType: EntityType, - val entityId:String + @BsonProperty("created_by_user_id") val createdByUserId: String, + @BsonProperty("audit_action") val auditAction: AuditAction, + @BsonProperty("changes_description") val changesDescription: String?, + @BsonProperty("entity_type") val entityType: EntityType, + @BsonProperty("entity_id") val entityId: String ) \ No newline at end of file diff --git a/src/main/kotlin/domain/model/Permission.kt b/src/main/kotlin/domain/model/Permission.kt index 3e0397f..e234c52 100644 --- a/src/main/kotlin/domain/model/Permission.kt +++ b/src/main/kotlin/domain/model/Permission.kt @@ -1,17 +1,19 @@ package com.berlin.domain.model +import org.bson.codecs.pojo.annotations.BsonProperty + data class Permission( - val createProject: Boolean = false, - val editProject: Boolean = false, - val deleteProject: Boolean = false, - val createState: Boolean = false, - val editState: Boolean = false, - val deleteState: Boolean = false, - val viewTaskById: Boolean = false, - val viewTasksByProject: Boolean =false, - val createTask: Boolean = false, - val editTask: Boolean = false, - val deleteTask: Boolean = false, - val assignTask:Boolean = false, - val viewAuditLogs: Boolean= false + @BsonProperty("create_project") val createProject: Boolean = false, + @BsonProperty("edit_project") val editProject: Boolean = false, + @BsonProperty("delete_project") val deleteProject: Boolean = false, + @BsonProperty("create_state") val createState: Boolean = false, + @BsonProperty("edit_state") val editState: Boolean = false, + @BsonProperty("delete_state") val deleteState: Boolean = false, + @BsonProperty("view_task_by_id") val viewTaskById: Boolean = false, + @BsonProperty("view_tasks_by_project") val viewTasksByProject: Boolean = false, + @BsonProperty("create_task") val createTask: Boolean = false, + @BsonProperty("edit_task") val editTask: Boolean = false, + @BsonProperty("delete_task") val deleteTask: Boolean = false, + @BsonProperty("assign_task") val assignTask: Boolean = false, + @BsonProperty("view_audit_logs") val viewAuditLogs: Boolean = false ) \ No newline at end of file diff --git a/src/main/kotlin/domain/model/Project.kt b/src/main/kotlin/domain/model/Project.kt index c96490b..0b61caa 100644 --- a/src/main/kotlin/domain/model/Project.kt +++ b/src/main/kotlin/domain/model/Project.kt @@ -1,9 +1,12 @@ package com.berlin.domain.model +import org.bson.codecs.pojo.annotations.BsonId +import org.bson.codecs.pojo.annotations.BsonProperty + data class Project( - val id:String, - val name:String, - val description:String?, - val statesId:List?, - val tasksId:List? + @BsonId val id: String, + val name: String, + val description: String?, + @BsonProperty("states_id") val statesId: List?, + @BsonProperty("tasks_id") val tasksId: List? ) \ No newline at end of file diff --git a/src/main/kotlin/domain/model/State.kt b/src/main/kotlin/domain/model/State.kt index 0054330..b93d71c 100644 --- a/src/main/kotlin/domain/model/State.kt +++ b/src/main/kotlin/domain/model/State.kt @@ -1,7 +1,10 @@ package com.berlin.domain.model +import org.bson.codecs.pojo.annotations.BsonId +import org.bson.codecs.pojo.annotations.BsonProperty + data class State( - val id: String, + @BsonId val id: String, val name: String, - val projectId: String, -) + @BsonProperty("project_id") val projectId: String, +) \ No newline at end of file diff --git a/src/main/kotlin/domain/model/Task.kt b/src/main/kotlin/domain/model/Task.kt index 1d6671e..2d71cf0 100644 --- a/src/main/kotlin/domain/model/Task.kt +++ b/src/main/kotlin/domain/model/Task.kt @@ -1,11 +1,14 @@ package com.berlin.domain.model +import org.bson.codecs.pojo.annotations.BsonId +import org.bson.codecs.pojo.annotations.BsonProperty + data class Task( - val id: String, - val projectId: String, + @BsonId val id: String, + @BsonProperty("project_id") val projectId: String, val title: String, val description: String?, - val stateId: String, - val assignedToUserId: String, - val createByUserId: String, -) + @BsonProperty("state_id") val stateId: String, + @BsonProperty("assigned_to_user_id") val assignedToUserId: String, + @BsonProperty("create_by_user_id") val createByUserId: String, +) \ No newline at end of file diff --git a/src/main/kotlin/domain/model/User.kt b/src/main/kotlin/domain/model/User.kt index 9a7e320..b8c81d2 100644 --- a/src/main/kotlin/domain/model/User.kt +++ b/src/main/kotlin/domain/model/User.kt @@ -1,9 +1,11 @@ package com.berlin.domain.model +import org.bson.codecs.pojo.annotations.BsonId +import org.bson.codecs.pojo.annotations.BsonProperty data class User( - val id:String, - val userName:String, - val password:String, + @BsonId val id: String, + @BsonProperty("user_name") val userName: String, + val password: String, val role: UserRole -) +) \ No newline at end of file From 2b1155bcf893e5b9be299064a4c9e53538990e59 Mon Sep 17 00:00:00 2001 From: dev7odaa Date: Thu, 8 May 2025 01:27:55 +0300 Subject: [PATCH 07/17] change dataSource for MongoDB --- .../datasource/MongoDBProjectDataSource.kt | 57 +++++++++++++++++++ .../datasource/MongoDBStateDataSource.kt | 57 +++++++++++++++++++ .../datasource/MongoDBTaskDataSource.kt | 57 +++++++++++++++++++ .../datasource/MongoDBUserDataSource.kt | 57 +++++++++++++++++++ .../datasource/MongoDBauditLogDataSource.kt | 57 +++++++++++++++++++ 5 files changed, 285 insertions(+) create mode 100644 src/main/kotlin/data/mongodb/datasource/MongoDBProjectDataSource.kt create mode 100644 src/main/kotlin/data/mongodb/datasource/MongoDBStateDataSource.kt create mode 100644 src/main/kotlin/data/mongodb/datasource/MongoDBTaskDataSource.kt create mode 100644 src/main/kotlin/data/mongodb/datasource/MongoDBUserDataSource.kt create mode 100644 src/main/kotlin/data/mongodb/datasource/MongoDBauditLogDataSource.kt diff --git a/src/main/kotlin/data/mongodb/datasource/MongoDBProjectDataSource.kt b/src/main/kotlin/data/mongodb/datasource/MongoDBProjectDataSource.kt new file mode 100644 index 0000000..4322804 --- /dev/null +++ b/src/main/kotlin/data/mongodb/datasource/MongoDBProjectDataSource.kt @@ -0,0 +1,57 @@ +package com.berlin.data.mongodb.datasource + +import com.berlin.data.BaseDataSource +import com.berlin.data.mongodb.config.MongoConfig +import com.berlin.domain.model.Project +import com.mongodb.client.model.Filters +import kotlinx.coroutines.flow.firstOrNull +import kotlinx.coroutines.flow.toList +import kotlinx.coroutines.runBlocking + +class MongoDBProjectDataSource( + private val mongoConfig: MongoConfig +) : BaseDataSource { + + private val client = mongoConfig.createMongoClient() + private val database = mongoConfig.getDatabase(client) + private val collection = mongoConfig.getCollection(database, "projects") + + override fun getAll(): List { + return runBlocking { + collection.find().toList() + } + } + + override fun getById(id: String): Project? { + return runBlocking { + collection.find(Filters.eq("_id", id)).firstOrNull() + } + } + + override fun update(id: String, entity: Project): Boolean { + return runBlocking { + collection.replaceOne(Filters.eq("_id", id), entity).wasAcknowledged() + } + } + + override fun delete(id: String): Boolean { + return runBlocking { + collection.deleteOne(Filters.eq("_id", id)).wasAcknowledged() + } + } + + override fun write(entity: Project): Boolean { + return runBlocking { + collection.insertOne(entity).wasAcknowledged() + } + } + + override fun writeAll(entities: List): Boolean { + if (entities.isEmpty()) { + return false + } + return runBlocking { + collection.insertMany(entities).wasAcknowledged() + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/data/mongodb/datasource/MongoDBStateDataSource.kt b/src/main/kotlin/data/mongodb/datasource/MongoDBStateDataSource.kt new file mode 100644 index 0000000..98c8acc --- /dev/null +++ b/src/main/kotlin/data/mongodb/datasource/MongoDBStateDataSource.kt @@ -0,0 +1,57 @@ +package com.berlin.data.mongodb.datasource + +import com.berlin.data.BaseDataSource +import com.berlin.data.mongodb.config.MongoConfig +import com.berlin.domain.model.State +import com.mongodb.client.model.Filters +import kotlinx.coroutines.flow.firstOrNull +import kotlinx.coroutines.flow.toList +import kotlinx.coroutines.runBlocking + +class MongoDBStateDataSource( + private val mongoConfig: MongoConfig +) : BaseDataSource { + + private val client = mongoConfig.createMongoClient() + private val database = mongoConfig.getDatabase(client) + private val collection = mongoConfig.getCollection(database, "states") + + override fun getAll(): List { + return runBlocking { + collection.find().toList() + } + } + + override fun getById(id: String): State? { + return runBlocking { + collection.find(Filters.eq("_id", id)).firstOrNull() + } + } + + override fun update(id: String, entity: State): Boolean { + return runBlocking { + collection.replaceOne(Filters.eq("_id", id), entity).wasAcknowledged() + } + } + + override fun delete(id: String): Boolean { + return runBlocking { + collection.deleteOne(Filters.eq("_id", id)).wasAcknowledged() + } + } + + override fun write(entity: State): Boolean { + return runBlocking { + collection.insertOne(entity).wasAcknowledged() + } + } + + override fun writeAll(entities: List): Boolean { + if (entities.isEmpty()) { + return false + } + return runBlocking { + collection.insertMany(entities).wasAcknowledged() + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/data/mongodb/datasource/MongoDBTaskDataSource.kt b/src/main/kotlin/data/mongodb/datasource/MongoDBTaskDataSource.kt new file mode 100644 index 0000000..2322cc7 --- /dev/null +++ b/src/main/kotlin/data/mongodb/datasource/MongoDBTaskDataSource.kt @@ -0,0 +1,57 @@ +package com.berlin.data.mongodb.datasource + +import com.berlin.data.BaseDataSource +import com.berlin.data.mongodb.config.MongoConfig +import com.berlin.domain.model.Task +import com.mongodb.client.model.Filters +import kotlinx.coroutines.flow.firstOrNull +import kotlinx.coroutines.flow.toList +import kotlinx.coroutines.runBlocking + +class MongoDBTaskDataSource( + private val mongoConfig: MongoConfig +) : BaseDataSource { + + private val client = mongoConfig.createMongoClient() + private val database = mongoConfig.getDatabase(client) + private val collection = mongoConfig.getCollection(database, "tasks") + + override fun getAll(): List { + return runBlocking { + collection.find().toList() + } + } + + override fun getById(id: String): Task? { + return runBlocking { + collection.find(Filters.eq("_id", id)).firstOrNull() + } + } + + override fun update(id: String, entity: Task): Boolean { + return runBlocking { + collection.replaceOne(Filters.eq("_id", id), entity).wasAcknowledged() + } + } + + override fun delete(id: String): Boolean { + return runBlocking { + collection.deleteOne(Filters.eq("_id", id)).wasAcknowledged() + } + } + + override fun write(entity: Task): Boolean { + return runBlocking { + collection.insertOne(entity).wasAcknowledged() + } + } + + override fun writeAll(entities: List): Boolean { + if (entities.isEmpty()) { + return false + } + return runBlocking { + collection.insertMany(entities).wasAcknowledged() + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/data/mongodb/datasource/MongoDBUserDataSource.kt b/src/main/kotlin/data/mongodb/datasource/MongoDBUserDataSource.kt new file mode 100644 index 0000000..c5d03b8 --- /dev/null +++ b/src/main/kotlin/data/mongodb/datasource/MongoDBUserDataSource.kt @@ -0,0 +1,57 @@ +package com.berlin.data.mongodb.datasource + +import com.berlin.data.BaseDataSource +import com.berlin.data.mongodb.config.MongoConfig +import com.berlin.domain.model.User +import com.mongodb.client.model.Filters +import kotlinx.coroutines.flow.firstOrNull +import kotlinx.coroutines.flow.toList +import kotlinx.coroutines.runBlocking + +class MongoDBUserDataSource( + private val mongoConfig: MongoConfig +) : BaseDataSource { + + private val client = mongoConfig.createMongoClient() + private val database = mongoConfig.getDatabase(client) + private val collection = mongoConfig.getCollection(database, "users") + + override fun getAll(): List { + return runBlocking { + collection.find().toList() + } + } + + override fun getById(id: String): User? { + return runBlocking { + collection.find(Filters.eq("_id", id)).firstOrNull() + } + } + + override fun update(id: String, entity: User): Boolean { + return runBlocking { + collection.replaceOne(Filters.eq("_id", id), entity).wasAcknowledged() + } + } + + override fun delete(id: String): Boolean { + return runBlocking { + collection.deleteOne(Filters.eq("_id", id)).wasAcknowledged() + } + } + + override fun write(entity: User): Boolean { + return runBlocking { + collection.insertOne(entity).wasAcknowledged() + } + } + + override fun writeAll(entities: List): Boolean { + if (entities.isEmpty()) { + return false + } + return runBlocking { + collection.insertMany(entities).wasAcknowledged() + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/data/mongodb/datasource/MongoDBauditLogDataSource.kt b/src/main/kotlin/data/mongodb/datasource/MongoDBauditLogDataSource.kt new file mode 100644 index 0000000..f290ea8 --- /dev/null +++ b/src/main/kotlin/data/mongodb/datasource/MongoDBauditLogDataSource.kt @@ -0,0 +1,57 @@ +package com.berlin.data.mongodb.datasource + +import com.berlin.data.BaseDataSource +import com.berlin.data.mongodb.config.MongoConfig +import com.berlin.domain.model.AuditLog +import com.mongodb.client.model.Filters +import kotlinx.coroutines.flow.firstOrNull +import kotlinx.coroutines.flow.toList +import kotlinx.coroutines.runBlocking + +class MongoDBauditLogDataSource( + private val mongoConfig: MongoConfig +) : BaseDataSource { + + private val client = mongoConfig.createMongoClient() + private val database = mongoConfig.getDatabase(client) + private val collection = mongoConfig.getCollection(database, "audit_logs") + + override fun getAll(): List { + return runBlocking { + collection.find().toList() + } + } + + override fun getById(id: String): AuditLog? { + return runBlocking { + collection.find(Filters.eq("_id", id)).firstOrNull() + } + } + + override fun update(id: String, entity: AuditLog): Boolean { + return runBlocking { + collection.replaceOne(Filters.eq("_id", id), entity).wasAcknowledged() + } + } + + override fun delete(id: String): Boolean { + return runBlocking { + collection.deleteOne(Filters.eq("_id", id)).wasAcknowledged() + } + } + + override fun write(entity: AuditLog): Boolean { + return runBlocking { + collection.insertOne(entity).wasAcknowledged() + } + } + + override fun writeAll(entities: List): Boolean { + if (entities.isEmpty()) { + return false + } + return runBlocking { + collection.insertMany(entities).wasAcknowledged() + } + } +} \ No newline at end of file From 1a69385f9eecb2dd72650c1c8e6f53ffeb52fe7a Mon Sep 17 00:00:00 2001 From: Diyar Date: Sat, 10 May 2025 12:23:01 +0300 Subject: [PATCH 08/17] fix db connection, connection string was wrong --- src/main/kotlin/data/mongodb/config/MongoConfig.kt | 2 +- src/main/kotlin/di/dataModule.kt | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/data/mongodb/config/MongoConfig.kt b/src/main/kotlin/data/mongodb/config/MongoConfig.kt index 8bd2004..c7d9305 100644 --- a/src/main/kotlin/data/mongodb/config/MongoConfig.kt +++ b/src/main/kotlin/data/mongodb/config/MongoConfig.kt @@ -9,7 +9,7 @@ import org.bson.codecs.pojo.PojoCodecProvider import com.mongodb.kotlin.client.coroutine.MongoCollection class MongoConfig( - private val connectionString: String = "mongodb+srv://diyarHussein:BoB0S2i5tDLXr4Xw@planmate.gzyncow.mongodb.net/?retryWrites=true&w=majority&appName=PlanMate", + private val connectionString: String = "mongodb+srv://diyarHussein:7p53.t@GQ4F#@2c@planmate.gzyncow.mongodb.net/?retryWrites=true&w=majority&appName=PlanMate", private val databaseName: String = "PlanMate" ) { diff --git a/src/main/kotlin/di/dataModule.kt b/src/main/kotlin/di/dataModule.kt index 32e1b4f..8bc181b 100644 --- a/src/main/kotlin/di/dataModule.kt +++ b/src/main/kotlin/di/dataModule.kt @@ -4,6 +4,7 @@ import com.berlin.data.BaseSchema import com.berlin.data.authentication.AuthenticationRepositoryImpl import com.berlin.data.csv_data_source.CsvDataSource import com.berlin.data.mongodb.config.MongoConfig +import com.berlin.data.mongodb.datasource.* import com.berlin.data.task.TaskRepositoryImpl import com.berlin.data.project.ProjectRepositoryImpl import com.berlin.data.schema.* @@ -63,6 +64,16 @@ val dataModule = module { ) } + single { MongoConfig() } + + single>(named("mongoDbTaskDataSource")) { MongoDBTaskDataSource(get()) } + single>(named("mongoDbStateDataSource")) { MongoDBStateDataSource(get()) } + single>(named("mongoDbProjectDataSource")) { MongoDBProjectDataSource(get()) } + single>(named("mongoDbAuditLogDataSource")) { MongoDBauditLogDataSource(get()) } + single>(named("mongoDbUserDataSource")) { MongoDBUserDataSource(get()) } + + single>(named("AuditDataSource")){ CsvDataSource("csv_files", get(named("AuditSchema"))) } + single>(named("UserDataSource")){ CsvDataSource("csv_files", get(named("UserSchema"))) } single>(named("ProjectDataSource")){ CsvDataSource("csv_files", get(named("ProjectSchema"))) } single>(named("TaskDataSource")){ CsvDataSource("csv_files", get(named("TaskSchema"))) } @@ -79,5 +90,4 @@ val dataModule = module { single { AuthenticationRepositoryImpl(get(named("UserDataSource"))) } - single { MongoConfig() } } \ No newline at end of file From c5ad59aad806508b586054149b4166cc29e7a126 Mon Sep 17 00:00:00 2001 From: Diyar Date: Sat, 10 May 2025 12:55:39 +0300 Subject: [PATCH 09/17] remove deprecated file and update task state name --- csv_files/audit.csv | 1 + csv_files/task.csv | 1 + .../kotlin/data/audit/AuditRepositoryImpl.kt | 0 .../mongodb/datasource/MongoDBStateDataSource.kt | 16 ++++++++-------- src/main/kotlin/di/dataModule.kt | 3 +-- 5 files changed, 11 insertions(+), 10 deletions(-) delete mode 100644 src/main/kotlin/data/audit/AuditRepositoryImpl.kt diff --git a/csv_files/audit.csv b/csv_files/audit.csv index f04ba6d..0c8081b 100644 --- a/csv_files/audit.csv +++ b/csv_files/audit.csv @@ -8,3 +8,4 @@ "AUDITDD_50509","1746815950509","user1234","CREATE","","TASK","tasts_50501" "AUDITDDD_26090","1746816126090","user1234","CREATE","","PROJECT","newprojctrrr_26090" "AUDITDDDD_91726","1746817691726","matetttt_16791","CREATE","","TASK","tasctitlett_91718" +"AUDITDD_38672","1746870738672","user1234","CREATE","","TASK","testtaskanddbaftermergedddddd_38667" diff --git a/csv_files/task.csv b/csv_files/task.csv index f4f83f4..f51b6a4 100644 --- a/csv_files/task.csv +++ b/csv_files/task.csv @@ -3,3 +3,4 @@ "titlett_29143","P1","title","description","S1","U2","user1234" "tasts_50501","taskmangermmmm_97132","tast","desc","taskmangermmmm_97132","matetttt_16791","user1234" "tasctitlett_91718","taskmangermmmm_97132","tasc title","desc","taskmangermmmm_97132","ahmadmmmm_70365","matetttt_16791" +"testtaskanddbaftermergedddddd_38667","newprojctrrr_26090","test task and db after merge","this a description for the test task after merge","tododdd_32001","ahmadmmmm_70365","user1234" diff --git a/src/main/kotlin/data/audit/AuditRepositoryImpl.kt b/src/main/kotlin/data/audit/AuditRepositoryImpl.kt deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/kotlin/data/mongodb/datasource/MongoDBStateDataSource.kt b/src/main/kotlin/data/mongodb/datasource/MongoDBStateDataSource.kt index 98c8acc..b173c1f 100644 --- a/src/main/kotlin/data/mongodb/datasource/MongoDBStateDataSource.kt +++ b/src/main/kotlin/data/mongodb/datasource/MongoDBStateDataSource.kt @@ -2,7 +2,7 @@ package com.berlin.data.mongodb.datasource import com.berlin.data.BaseDataSource import com.berlin.data.mongodb.config.MongoConfig -import com.berlin.domain.model.State +import com.berlin.domain.model.TaskState import com.mongodb.client.model.Filters import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.toList @@ -10,25 +10,25 @@ import kotlinx.coroutines.runBlocking class MongoDBStateDataSource( private val mongoConfig: MongoConfig -) : BaseDataSource { +) : BaseDataSource { private val client = mongoConfig.createMongoClient() private val database = mongoConfig.getDatabase(client) - private val collection = mongoConfig.getCollection(database, "states") + private val collection = mongoConfig.getCollection(database, "states") - override fun getAll(): List { + override fun getAll(): List { return runBlocking { collection.find().toList() } } - override fun getById(id: String): State? { + override fun getById(id: String): TaskState? { return runBlocking { collection.find(Filters.eq("_id", id)).firstOrNull() } } - override fun update(id: String, entity: State): Boolean { + override fun update(id: String, entity: TaskState): Boolean { return runBlocking { collection.replaceOne(Filters.eq("_id", id), entity).wasAcknowledged() } @@ -40,13 +40,13 @@ class MongoDBStateDataSource( } } - override fun write(entity: State): Boolean { + override fun write(entity: TaskState): Boolean { return runBlocking { collection.insertOne(entity).wasAcknowledged() } } - override fun writeAll(entities: List): Boolean { + override fun writeAll(entities: List): Boolean { if (entities.isEmpty()) { return false } diff --git a/src/main/kotlin/di/dataModule.kt b/src/main/kotlin/di/dataModule.kt index 50f83f0..de65ec8 100644 --- a/src/main/kotlin/di/dataModule.kt +++ b/src/main/kotlin/di/dataModule.kt @@ -1,9 +1,8 @@ package com.berlin.di -import AuditRepositoryImpl -import TaskRepositoryImpl import com.berlin.data.BaseDataSource import com.berlin.data.BaseSchema +import com.berlin.data.audit.AuditRepositoryImpl import com.berlin.data.csv_data_source.CsvDataSource import com.berlin.data.schema.* import com.berlin.data.mongodb.config.MongoConfig From 331d8fe7de590f056b704130562f4de51968d87d Mon Sep 17 00:00:00 2001 From: dev7odaa Date: Sat, 10 May 2025 18:45:14 +0300 Subject: [PATCH 10/17] delete config test --- .../data/mongodb/config/MongoConfigTest.kt | 140 ------------------ 1 file changed, 140 deletions(-) delete mode 100644 src/test/kotlin/data/mongodb/config/MongoConfigTest.kt diff --git a/src/test/kotlin/data/mongodb/config/MongoConfigTest.kt b/src/test/kotlin/data/mongodb/config/MongoConfigTest.kt deleted file mode 100644 index e89ed4d..0000000 --- a/src/test/kotlin/data/mongodb/config/MongoConfigTest.kt +++ /dev/null @@ -1,140 +0,0 @@ -package com.berlin.data.mongodb.config - -import com.mongodb.MongoClientSettings -import com.mongodb.kotlin.client.coroutine.MongoClient -import com.mongodb.kotlin.client.coroutine.MongoDatabase -import com.mongodb.kotlin.client.coroutine.MongoCollection -import io.mockk.* -import org.bson.codecs.configuration.CodecRegistry -import org.bson.codecs.pojo.PojoCodecProvider -import org.junit.jupiter.api.AfterEach -import org.junit.jupiter.api.Assertions.* -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.DisplayName - -class MongoConfigTest { - - private lateinit var mongoConfig: MongoConfig - private lateinit var mockMongoClient: MongoClient - private lateinit var mockMongoDatabase: MongoDatabase - private lateinit var mockCollection: MongoCollection - - @BeforeEach - fun setUp() { - // Create mocks - mockMongoClient = mockk(relaxed = true) - mockMongoDatabase = mockk(relaxed = true) - mockCollection = mockk(relaxed = true) - - // Create instance with test values - mongoConfig = MongoConfig( - connectionString = "mongodb://localhost:27017", - databaseName = "testDatabase" - ) - } - - @AfterEach - fun tearDown() { - unmockkAll() - } - - @Test - @DisplayName("getDatabase should return database with correct name") - fun `getDatabase returns database with correct name`() { - // Given - every { mockMongoClient.getDatabase(any()) } returns mockMongoDatabase - - // When - val database = mongoConfig.getDatabase(mockMongoClient) - - // Then - verify { mockMongoClient.getDatabase("testDatabase") } - assertEquals(mockMongoDatabase, database) - } - - @Test - @DisplayName("getCollection should return typed collection with correct name") - fun `getCollection returns typed collection with correct name`() { - // Given - every { mockMongoDatabase.getCollection(any()) } returns mockCollection - - // When - val collection = mongoConfig.getCollection(mockMongoDatabase, "testCollection") - - // Then - verify { mockMongoDatabase.getCollection("testCollection") } - assertEquals(mockCollection, collection) - } - - @Test - @DisplayName("test constructor sets correct values") - fun `constructor sets correct values`() { - // When - val customConfig = MongoConfig("custom-connection-string", "custom-db-name") - - // Then - assertNotNull(customConfig) - } - - @Test - fun `createMongoClient creates client with correct configuration`() { - // Mock the static methods we need to control - mockkStatic(MongoClient::class) - mockkStatic(MongoClientSettings::class) - mockkStatic(CodecRegistry::class) - mockkStatic(PojoCodecProvider::class) - - // Mock CodecProvider - val mockProvider = mockk() - val mockBuilder = mockk() - every { PojoCodecProvider.builder() } returns mockBuilder - every { mockBuilder.automatic(true) } returns mockBuilder - every { mockBuilder.build() } returns mockProvider - - // Mock CodecRegistry - val mockRegistry = mockk() - val defaultRegistry = mockk() - every { MongoClientSettings.getDefaultCodecRegistry() } returns defaultRegistry - mockkStatic("org.bson.codecs.configuration.CodecRegistries") - every { - org.bson.codecs.configuration.CodecRegistries.fromProviders(mockProvider) - } returns mockRegistry - every { - org.bson.codecs.configuration.CodecRegistries.fromRegistries(defaultRegistry, mockRegistry) - } returns mockRegistry - - // Mock ClientSettings - val mockSettings = mockk() - val mockSettingsBuilder = mockk() - every { MongoClientSettings.builder() } returns mockSettingsBuilder - every { mockSettingsBuilder.applyConnectionString(any()) } returns mockSettingsBuilder - every { mockSettingsBuilder.codecRegistry(mockRegistry) } returns mockSettingsBuilder - every { mockSettingsBuilder.build() } returns mockSettings - - // Mock MongoClient creation - every { MongoClient.create(mockSettings) } returns mockMongoClient - - // Execute the method - val result = mongoConfig.createMongoClient() - - // Verify - assertNotNull(result) - verify { - PojoCodecProvider.builder() - mockBuilder.automatic(true) - mockBuilder.build() - MongoClientSettings.getDefaultCodecRegistry() - org.bson.codecs.configuration.CodecRegistries.fromProviders(mockProvider) - org.bson.codecs.configuration.CodecRegistries.fromRegistries(defaultRegistry, mockRegistry) - MongoClientSettings.builder() - mockSettingsBuilder.applyConnectionString(match { - it.connectionString == "mongodb://localhost:27017" - }) - mockSettingsBuilder.codecRegistry(mockRegistry) - mockSettingsBuilder.build() - MongoClient.create(mockSettings) - } - } - data class TestDocument(val id: String, val name: String) -} \ No newline at end of file From 3212f6134a10f43d263d765e90eaf86477802f28 Mon Sep 17 00:00:00 2001 From: dev7odaa Date: Sat, 10 May 2025 20:34:41 +0300 Subject: [PATCH 11/17] create datasource test --- .../MongoDBAuditLogDataSourceTest.kt | 241 +++++++++++++++++ .../MongoDBProjectDataSourceTest.kt | 235 +++++++++++++++++ .../datasource/MongoDBStateDataSourceTest.kt | 231 +++++++++++++++++ .../datasource/MongoDBTaskDataSourceTest.kt | 244 ++++++++++++++++++ .../datasource/MongoDBUserDataSourceTest.kt | 234 +++++++++++++++++ 5 files changed, 1185 insertions(+) create mode 100644 src/test/kotlin/data/mongodb/datasource/MongoDBAuditLogDataSourceTest.kt create mode 100644 src/test/kotlin/data/mongodb/datasource/MongoDBProjectDataSourceTest.kt create mode 100644 src/test/kotlin/data/mongodb/datasource/MongoDBStateDataSourceTest.kt create mode 100644 src/test/kotlin/data/mongodb/datasource/MongoDBTaskDataSourceTest.kt create mode 100644 src/test/kotlin/data/mongodb/datasource/MongoDBUserDataSourceTest.kt diff --git a/src/test/kotlin/data/mongodb/datasource/MongoDBAuditLogDataSourceTest.kt b/src/test/kotlin/data/mongodb/datasource/MongoDBAuditLogDataSourceTest.kt new file mode 100644 index 0000000..4c837fa --- /dev/null +++ b/src/test/kotlin/data/mongodb/datasource/MongoDBAuditLogDataSourceTest.kt @@ -0,0 +1,241 @@ +package com.berlin.data.mongodb.datasource + +import com.berlin.data.mongodb.config.MongoConfig +import com.berlin.domain.model.AuditAction +import com.berlin.domain.model.AuditLog +import com.berlin.domain.model.EntityType +import io.mockk.coEvery +import io.mockk.every +import io.mockk.mockk +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import com.mongodb.client.result.DeleteResult +import com.mongodb.client.result.InsertManyResult +import com.mongodb.client.result.InsertOneResult +import com.mongodb.client.result.UpdateResult +import kotlinx.coroutines.flow.FlowCollector +import org.bson.conversions.Bson +import org.junit.jupiter.api.TestInstance +import org.junit.jupiter.api.TestInstance.Lifecycle + +@TestInstance(Lifecycle.PER_CLASS) +class MongoDBAuditLogDataSourceTest { + + private lateinit var dataSource: MongoDBauditLogDataSource + private val mockMongoConfig = mockk() + private val mockCollection = mockk>() + private val mockMongoClient = mockk() + private val mockMongoDatabase = mockk() + private val mockFindPublisher = mockk>() + + private val mockAuditLog = AuditLog( + id = "log1", + timestamp = 1717027200, + createdByUserId = "user1", + auditAction = AuditAction.CREATE, + changesDescription = "Initial creation", + entityType = EntityType.TASK, + entityId = "task1" + ) + + private val mockAuditLogs = listOf( + mockAuditLog, + AuditLog( + id = "log2", + timestamp = 1717027300, + createdByUserId = "user2", + auditAction = AuditAction.UPDATE, + changesDescription = "Status changed", + entityType = EntityType.TASK, + entityId = "task1" + ) + ) + + @BeforeEach + fun setUp() { + every { mockMongoConfig.createMongoClient() } returns mockMongoClient + every { mockMongoConfig.getDatabase(mockMongoClient) } returns mockMongoDatabase + every { mockMongoConfig.getCollection(mockMongoDatabase, "audit_logs") } returns mockCollection + + coEvery { mockFindPublisher.collect(any()) } coAnswers { + val collector = arg>(0) + collector.emit(mockAuditLog) + } + + dataSource = MongoDBauditLogDataSource(mockMongoConfig) + } + + @Test + fun `getAll should return list of audit logs`() { + // Given + coEvery { mockCollection.find() } returns mockFindPublisher + coEvery { mockFindPublisher.collect(any()) } coAnswers { + val collector = arg>(0) + mockAuditLogs.forEach { collector.emit(it) } + } + + // When + val result = dataSource.getAll() + + // Then + assertEquals(mockAuditLogs, result) + } + + @Test + fun `getById should return audit log when found`() { + // Given + coEvery { mockCollection.find(any()) } returns mockFindPublisher + coEvery { mockFindPublisher.collect(any()) } coAnswers { + val collector = arg>(0) + collector.emit(mockAuditLog) + } + + // When + val result = dataSource.getById("log1") + + // Then + assertEquals(mockAuditLog, result) + } + + @Test + fun `getById should return null when not found`() { + // Given + coEvery { mockCollection.find(any()) } returns mockFindPublisher + coEvery { mockFindPublisher.collect(any()) } coAnswers { } + + // When + val result = dataSource.getById("nonexistent") + + // Then + assertNull(result) + } + + @Test + fun `update should return true when acknowledged`() { + // Given + val mockUpdateResult = mockk() + every { mockUpdateResult.wasAcknowledged() } returns true + + coEvery { + mockCollection.replaceOne( + any(), + any(), + any() + ) + } returns mockUpdateResult + + // When + val result = dataSource.update("log1", mockAuditLog) + + // Then + assertTrue(result) + } + + @Test + fun `update should return false when not acknowledged`() { + // Given + val mockUpdateResult = mockk() + every { mockUpdateResult.wasAcknowledged() } returns false + coEvery { mockCollection.replaceOne(any(), any(), any()) } returns mockUpdateResult + + // When + val result = dataSource.update("log1", mockAuditLog) + + // Then + assertFalse(result) + } + + @Test + fun `delete should return true when acknowledged`() { + // Given + val mockDeleteResult = mockk() + every { mockDeleteResult.wasAcknowledged() } returns true + coEvery { mockCollection.deleteOne(any(), any()) } returns mockDeleteResult + + // When + val result = dataSource.delete("log1") + + // Then + assertTrue(result) + } + + @Test + fun `delete should return false when not acknowledged`() { + // Given + val mockDeleteResult = mockk() + every { mockDeleteResult.wasAcknowledged() } returns false + coEvery { mockCollection.deleteOne(any(), any()) } returns mockDeleteResult + + // When + val result = dataSource.delete("log1") + + // Then + assertFalse(result) + } + + @Test + fun `write should return true when acknowledged`() { + // Given + val mockInsertOneResult = mockk() + every { mockInsertOneResult.wasAcknowledged() } returns true + coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult + + // When + val result = dataSource.write(mockAuditLog) + + // Then + assertTrue(result) + } + + @Test + fun `write should return false when not acknowledged`() { + // Given + val mockInsertOneResult = mockk() + every { mockInsertOneResult.wasAcknowledged() } returns false + coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult + + // When + val result = dataSource.write(mockAuditLog) + + // Then + assertFalse(result) + } + + @Test + fun `writeAll should return true when acknowledged`() { + // Given + val mockInsertManyResult = mockk() + every { mockInsertManyResult.wasAcknowledged() } returns true + coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult + + // When + val result = dataSource.writeAll(mockAuditLogs) + + // Then + assertTrue(result) + } + + @Test + fun `writeAll should return false when not acknowledged`() { + // Given + val mockInsertManyResult = mockk() + every { mockInsertManyResult.wasAcknowledged() } returns false + coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult + + // When + val result = dataSource.writeAll(mockAuditLogs) + + // Then + assertFalse(result) + } + + @Test + fun `writeAll should return false when list is empty`() { + // When + val result = dataSource.writeAll(emptyList()) + + // Then + assertFalse(result) + } +} \ No newline at end of file diff --git a/src/test/kotlin/data/mongodb/datasource/MongoDBProjectDataSourceTest.kt b/src/test/kotlin/data/mongodb/datasource/MongoDBProjectDataSourceTest.kt new file mode 100644 index 0000000..f5c01c8 --- /dev/null +++ b/src/test/kotlin/data/mongodb/datasource/MongoDBProjectDataSourceTest.kt @@ -0,0 +1,235 @@ +package com.berlin.data.mongodb.datasource + +import com.berlin.data.mongodb.config.MongoConfig +import com.berlin.domain.model.Project +import io.mockk.coEvery +import io.mockk.every +import io.mockk.mockk +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import com.mongodb.client.result.DeleteResult +import com.mongodb.client.result.InsertManyResult +import com.mongodb.client.result.InsertOneResult +import com.mongodb.client.result.UpdateResult +import kotlinx.coroutines.flow.FlowCollector +import org.bson.conversions.Bson +import org.junit.jupiter.api.TestInstance +import org.junit.jupiter.api.TestInstance.Lifecycle + +@TestInstance(Lifecycle.PER_CLASS) +class MongoDBProjectDataSourceTest { + + private lateinit var dataSource: MongoDBProjectDataSource + private val mockMongoConfig = mockk() + private val mockCollection = mockk>() + private val mockMongoClient = mockk() + private val mockMongoDatabase = mockk() + private val mockFindPublisher = mockk>() + + private val mockProject = Project( + id = "project1", + name = "Task Manager", + description = "Manage tasks efficiently", + statesId = listOf("state1", "state2"), + tasksId = listOf("task1", "task2") + ) + + private val mockProjects = listOf( + mockProject, + Project( + id = "project2", + name = "Marketing Campaign", + description = null, + statesId = emptyList(), + tasksId = null + ) + ) + + @BeforeEach + fun setUp() { + every { mockMongoConfig.createMongoClient() } returns mockMongoClient + every { mockMongoConfig.getDatabase(mockMongoClient) } returns mockMongoDatabase + every { mockMongoConfig.getCollection(mockMongoDatabase, "projects") } returns mockCollection + + coEvery { mockFindPublisher.collect(any()) } coAnswers { + val collector = arg>(0) + collector.emit(mockProject) + } + + dataSource = MongoDBProjectDataSource(mockMongoConfig) + } + + @Test + fun `getAll should return list of projects`() { + // Given + coEvery { mockCollection.find() } returns mockFindPublisher + coEvery { mockFindPublisher.collect(any()) } coAnswers { + val collector = arg>(0) + mockProjects.forEach { collector.emit(it) } + } + + // When + val result = dataSource.getAll() + + // Then + assertEquals(mockProjects, result) + } + + @Test + fun `getById should return project when found`() { + // Given + coEvery { mockCollection.find(any()) } returns mockFindPublisher + coEvery { mockFindPublisher.collect(any()) } coAnswers { + val collector = arg>(0) + collector.emit(mockProject) + } + + // When + val result = dataSource.getById("project1") + + // Then + assertEquals(mockProject, result) + } + + @Test + fun `getById should return null when not found`() { + // Given + coEvery { mockCollection.find(any()) } returns mockFindPublisher + coEvery { mockFindPublisher.collect(any()) } coAnswers { } + + // When + val result = dataSource.getById("nonexistent") + + // Then + assertNull(result) + } + + @Test + fun `update should return true when acknowledged`() { + // Given + val mockUpdateResult = mockk() + every { mockUpdateResult.wasAcknowledged() } returns true + + coEvery { + mockCollection.replaceOne( + any(), + any(), + any() + ) + } returns mockUpdateResult + + // When + val result = dataSource.update("project1", mockProject) + + // Then + assertTrue(result) + } + + @Test + fun `update should return false when not acknowledged`() { + // Given + val mockUpdateResult = mockk() + every { mockUpdateResult.wasAcknowledged() } returns false + coEvery { mockCollection.replaceOne(any(), any(), any()) } returns mockUpdateResult + + // When + val result = dataSource.update("project1", mockProject) + + // Then + assertFalse(result) + } + + @Test + fun `delete should return true when acknowledged`() { + // Given + val mockDeleteResult = mockk() + every { mockDeleteResult.wasAcknowledged() } returns true + coEvery { mockCollection.deleteOne(any(), any()) } returns mockDeleteResult + + // When + val result = dataSource.delete("project1") + + // Then + assertTrue(result) + } + + @Test + fun `delete should return false when not acknowledged`() { + // Given + val mockDeleteResult = mockk() + every { mockDeleteResult.wasAcknowledged() } returns false + coEvery { mockCollection.deleteOne(any(), any()) } returns mockDeleteResult + + // When + val result = dataSource.delete("project1") + + // Then + assertFalse(result) + } + + @Test + fun `write should return true when acknowledged`() { + // Given + val mockInsertOneResult = mockk() + every { mockInsertOneResult.wasAcknowledged() } returns true + coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult + + // When + val result = dataSource.write(mockProject) + + // Then + assertTrue(result) + } + + @Test + fun `write should return false when not acknowledged`() { + // Given + val mockInsertOneResult = mockk() + every { mockInsertOneResult.wasAcknowledged() } returns false + coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult + + // When + val result = dataSource.write(mockProject) + + // Then + assertFalse(result) + } + + @Test + fun `writeAll should return true when acknowledged`() { + // Given + val mockInsertManyResult = mockk() + every { mockInsertManyResult.wasAcknowledged() } returns true + coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult + + // When + val result = dataSource.writeAll(mockProjects) + + // Then + assertTrue(result) + } + + @Test + fun `writeAll should return false when not acknowledged`() { + // Given + val mockInsertManyResult = mockk() + every { mockInsertManyResult.wasAcknowledged() } returns false + coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult + + // When + val result = dataSource.writeAll(mockProjects) + + // Then + assertFalse(result) + } + + @Test + fun `writeAll should return false when list is empty`() { + // When + val result = dataSource.writeAll(emptyList()) + + // Then + assertFalse(result) + } +} \ No newline at end of file diff --git a/src/test/kotlin/data/mongodb/datasource/MongoDBStateDataSourceTest.kt b/src/test/kotlin/data/mongodb/datasource/MongoDBStateDataSourceTest.kt new file mode 100644 index 0000000..157c2a3 --- /dev/null +++ b/src/test/kotlin/data/mongodb/datasource/MongoDBStateDataSourceTest.kt @@ -0,0 +1,231 @@ +package com.berlin.data.mongodb.datasource + +import com.berlin.data.mongodb.config.MongoConfig +import com.berlin.domain.model.TaskState +import io.mockk.coEvery +import io.mockk.every +import io.mockk.mockk +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import com.mongodb.client.result.DeleteResult +import com.mongodb.client.result.InsertManyResult +import com.mongodb.client.result.InsertOneResult +import com.mongodb.client.result.UpdateResult +import kotlinx.coroutines.flow.FlowCollector +import org.bson.conversions.Bson +import org.junit.jupiter.api.TestInstance +import org.junit.jupiter.api.TestInstance.Lifecycle + +@TestInstance(Lifecycle.PER_CLASS) +class MongoDBStateDataSourceTest { + + private lateinit var dataSource: MongoDBStateDataSource + private val mockMongoConfig = mockk() + private val mockCollection = mockk>() + private val mockMongoClient = mockk() + private val mockMongoDatabase = mockk() + private val mockFindPublisher = mockk>() + + private val mockState = TaskState( + id = "state1", + name = "Todo", + projectId = "project1" + ) + + private val mockStates = listOf( + mockState, + TaskState( + id = "state2", + name = "In Progress", + projectId = "project1" + ) + ) + + @BeforeEach + fun setUp() { + every { mockMongoConfig.createMongoClient() } returns mockMongoClient + every { mockMongoConfig.getDatabase(mockMongoClient) } returns mockMongoDatabase + every { mockMongoConfig.getCollection(mockMongoDatabase, "states") } returns mockCollection + + coEvery { mockFindPublisher.collect(any()) } coAnswers { + val collector = arg>(0) + collector.emit(mockState) + } + + dataSource = MongoDBStateDataSource(mockMongoConfig) + } + + @Test + fun `getAll should return list of states`() { + // Given + coEvery { mockCollection.find() } returns mockFindPublisher + coEvery { mockFindPublisher.collect(any()) } coAnswers { + val collector = arg>(0) + mockStates.forEach { collector.emit(it) } + } + + // When + val result = dataSource.getAll() + + // Then + assertEquals(mockStates, result) + } + + @Test + fun `getById should return state when found`() { + // Given + coEvery { mockCollection.find(any()) } returns mockFindPublisher + coEvery { mockFindPublisher.collect(any()) } coAnswers { + val collector = arg>(0) + collector.emit(mockState) + } + + // When + val result = dataSource.getById("state1") + + // Then + assertEquals(mockState, result) + } + + @Test + fun `getById should return null when not found`() { + // Given + coEvery { mockCollection.find(any()) } returns mockFindPublisher + coEvery { mockFindPublisher.collect(any()) } coAnswers { } + + // When + val result = dataSource.getById("nonexistent") + + // Then + assertNull(result) + } + + @Test + fun `update should return true when acknowledged`() { + // Given + val mockUpdateResult = mockk() + every { mockUpdateResult.wasAcknowledged() } returns true + + coEvery { + mockCollection.replaceOne( + any(), + any(), + any() + ) + } returns mockUpdateResult + + // When + val result = dataSource.update("state1", mockState) + + // Then + assertTrue(result) + } + + @Test + fun `update should return false when not acknowledged`() { + // Given + val mockUpdateResult = mockk() + every { mockUpdateResult.wasAcknowledged() } returns false + coEvery { mockCollection.replaceOne(any(), any(), any()) } returns mockUpdateResult + + // When + val result = dataSource.update("state1", mockState) + + // Then + assertFalse(result) + } + + @Test + fun `delete should return true when acknowledged`() { + // Given + val mockDeleteResult = mockk() + every { mockDeleteResult.wasAcknowledged() } returns true + coEvery { mockCollection.deleteOne(any(), any()) } returns mockDeleteResult + + // When + val result = dataSource.delete("state1") + + // Then + assertTrue(result) + } + + @Test + fun `delete should return false when not acknowledged`() { + // Given + val mockDeleteResult = mockk() + every { mockDeleteResult.wasAcknowledged() } returns false + coEvery { mockCollection.deleteOne(any(), any()) } returns mockDeleteResult + + // When + val result = dataSource.delete("state1") + + // Then + assertFalse(result) + } + + @Test + fun `write should return true when acknowledged`() { + // Given + val mockInsertOneResult = mockk() + every { mockInsertOneResult.wasAcknowledged() } returns true + coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult + + // When + val result = dataSource.write(mockState) + + // Then + assertTrue(result) + } + + @Test + fun `write should return false when not acknowledged`() { + // Given + val mockInsertOneResult = mockk() + every { mockInsertOneResult.wasAcknowledged() } returns false + coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult + + // When + val result = dataSource.write(mockState) + + // Then + assertFalse(result) + } + + @Test + fun `writeAll should return true when acknowledged`() { + // Given + val mockInsertManyResult = mockk() + every { mockInsertManyResult.wasAcknowledged() } returns true + coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult + + // When + val result = dataSource.writeAll(mockStates) + + // Then + assertTrue(result) + } + + @Test + fun `writeAll should return false when not acknowledged`() { + // Given + val mockInsertManyResult = mockk() + every { mockInsertManyResult.wasAcknowledged() } returns false + coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult + + // When + val result = dataSource.writeAll(mockStates) + + // Then + assertFalse(result) + } + + @Test + fun `writeAll should return false when list is empty`() { + // When + val result = dataSource.writeAll(emptyList()) + + // Then + assertFalse(result) + } +} \ No newline at end of file diff --git a/src/test/kotlin/data/mongodb/datasource/MongoDBTaskDataSourceTest.kt b/src/test/kotlin/data/mongodb/datasource/MongoDBTaskDataSourceTest.kt new file mode 100644 index 0000000..6578b4f --- /dev/null +++ b/src/test/kotlin/data/mongodb/datasource/MongoDBTaskDataSourceTest.kt @@ -0,0 +1,244 @@ +package com.berlin.data.mongodb.datasource + +import com.berlin.data.mongodb.config.MongoConfig +import com.berlin.domain.model.Task +import io.mockk.coEvery +import io.mockk.every +import io.mockk.mockk +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import com.mongodb.client.result.DeleteResult +import com.mongodb.client.result.InsertManyResult +import com.mongodb.client.result.InsertOneResult +import com.mongodb.client.result.UpdateResult +import kotlinx.coroutines.flow.FlowCollector +import kotlinx.coroutines.flow.firstOrNull +import kotlinx.coroutines.flow.toList +import org.bson.conversions.Bson +import org.junit.jupiter.api.TestInstance +import org.junit.jupiter.api.TestInstance.Lifecycle + +@TestInstance(Lifecycle.PER_CLASS) +class MongoDBTaskDataSourceTest { + + private lateinit var dataSource: MongoDBTaskDataSource + private val mockMongoConfig = mockk() + private val mockCollection = mockk>() + private val mockMongoClient = mockk() + private val mockMongoDatabase = mockk() + private val mockFindPublisher = mockk>() + + private val mockTask = Task( + id = "task1", + projectId = "project1", + title = "Test Task", + description = "Task description", + stateId = "todo", + assignedToUserId = "user1", + createByUserId = "user2" + ) + + private val mockTasks = listOf( + mockTask, + Task( + id = "task2", + projectId = "project1", + title = "Another Task", + description = null, + stateId = "in_progress", + assignedToUserId = "user3", + createByUserId = "user2" + ) + ) + + @BeforeEach + fun setUp() { + every { mockMongoConfig.createMongoClient() } returns mockMongoClient + every { mockMongoConfig.getDatabase(mockMongoClient) } returns mockMongoDatabase + every { mockMongoConfig.getCollection(mockMongoDatabase, "tasks") } returns mockCollection + + coEvery { mockFindPublisher.collect(any()) } coAnswers { + val collector = arg>(0) + collector.emit(mockTask) + } + + dataSource = MongoDBTaskDataSource(mockMongoConfig) + } + + @Test + fun `getAll should return list of tasks`() { + // Given + coEvery { mockCollection.find() } returns mockFindPublisher + coEvery { mockFindPublisher.collect(any()) } coAnswers { + val collector = arg>(0) + mockTasks.forEach { collector.emit(it) } + } + + // When + val result = dataSource.getAll() + + // Then + assertEquals(mockTasks, result) + } + + @Test + fun `getById should return task when found`() { + // Given + coEvery { mockCollection.find(any()) } returns mockFindPublisher + coEvery { mockFindPublisher.collect(any()) } coAnswers { + val collector = arg>(0) + collector.emit(mockTask) + } + + // When + val result = dataSource.getById("task1") + + // Then + assertEquals(mockTask, result) + } + + @Test + fun `getById should return null when not found`() { + // Given + coEvery { mockCollection.find(any()) } returns mockFindPublisher + coEvery { mockFindPublisher.collect(any()) } coAnswers { } // Emit nothing + + // When + val result = dataSource.getById("nonexistent") + + // Then + assertNull(result) + } + + @Test + fun `update should return true when acknowledged`() { + // Given + val mockUpdateResult = mockk() + every { mockUpdateResult.wasAcknowledged() } returns true + + coEvery { + mockCollection.replaceOne( + any(), + any(), + any() + ) + } returns mockUpdateResult + + // When + val result = dataSource.update("task1", mockTask) + + // Then + assertTrue(result) + } + + @Test + fun `update should return false when not acknowledged`() { + // Given + val mockUpdateResult = mockk() + every { mockUpdateResult.wasAcknowledged() } returns false + coEvery { mockCollection.replaceOne(any(), any(), any()) } returns mockUpdateResult + + // When + val result = dataSource.update("task1", mockTask) + + // Then + assertFalse(result) + } + + @Test + fun `delete should return true when acknowledged`() { + // Given + val mockDeleteResult = mockk() + every { mockDeleteResult.wasAcknowledged() } returns true + coEvery { mockCollection.deleteOne(any(), any()) } returns mockDeleteResult + + // When + val result = dataSource.delete("task1") + + // Then + assertTrue(result) + } + + @Test + fun `delete should return false when not acknowledged`() { + // Given + val mockDeleteResult = mockk() + every { mockDeleteResult.wasAcknowledged() } returns false + coEvery { mockCollection.deleteOne(any(), any()) } returns mockDeleteResult + + // When + val result = dataSource.delete("task1") + + // Then + assertFalse(result) + } + + @Test + fun `write should return true when acknowledged`() { + // Given + val mockInsertOneResult = mockk() + every { mockInsertOneResult.wasAcknowledged() } returns true + coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult + + // When + val result = dataSource.write(mockTask) + + // Then + assertTrue(result) + } + + @Test + fun `write should return false when not acknowledged`() { + // Given + val mockInsertOneResult = mockk() + every { mockInsertOneResult.wasAcknowledged() } returns false + coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult + + // When + val result = dataSource.write(mockTask) + + // Then + assertFalse(result) + } + + @Test + fun `writeAll should return true when acknowledged`() { + // Given + val mockInsertManyResult = mockk() + every { mockInsertManyResult.wasAcknowledged() } returns true + coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult + + // When + val result = dataSource.writeAll(mockTasks) + + // Then + assertTrue(result) + } + + @Test + fun `writeAll should return false when not acknowledged`() { + // Given + val mockInsertManyResult = mockk() + every { mockInsertManyResult.wasAcknowledged() } returns false + coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult + + // When + val result = dataSource.writeAll(mockTasks) + + // Then + assertFalse(result) + } + + @Test + fun `writeAll should return false when list is empty`() { + // When + val result = dataSource.writeAll(emptyList()) + + // Then + assertFalse(result) + } +} \ No newline at end of file diff --git a/src/test/kotlin/data/mongodb/datasource/MongoDBUserDataSourceTest.kt b/src/test/kotlin/data/mongodb/datasource/MongoDBUserDataSourceTest.kt new file mode 100644 index 0000000..cc926de --- /dev/null +++ b/src/test/kotlin/data/mongodb/datasource/MongoDBUserDataSourceTest.kt @@ -0,0 +1,234 @@ +package com.berlin.data.mongodb.datasource + +import com.berlin.data.mongodb.config.MongoConfig +import com.berlin.domain.model.User +import com.berlin.domain.model.UserRole +import io.mockk.coEvery +import io.mockk.every +import io.mockk.mockk +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import com.mongodb.client.result.DeleteResult +import com.mongodb.client.result.InsertManyResult +import com.mongodb.client.result.InsertOneResult +import com.mongodb.client.result.UpdateResult +import kotlinx.coroutines.flow.FlowCollector +import org.bson.conversions.Bson +import org.junit.jupiter.api.TestInstance +import org.junit.jupiter.api.TestInstance.Lifecycle + +@TestInstance(Lifecycle.PER_CLASS) +class MongoDBUserDataSourceTest { + + private lateinit var dataSource: MongoDBUserDataSource + private val mockMongoConfig = mockk() + private val mockCollection = mockk>() + private val mockMongoClient = mockk() + private val mockMongoDatabase = mockk() + private val mockFindPublisher = mockk>() + + private val mockUser = User( + id = "user1", + userName = "admin", + password = "secure123", + role = UserRole.ADMIN + ) + + private val mockUsers = listOf( + mockUser, + User( + id = "user2", + userName = "mate", + password = "pass456", + role = UserRole.MATE + ) + ) + + @BeforeEach + fun setUp() { + every { mockMongoConfig.createMongoClient() } returns mockMongoClient + every { mockMongoConfig.getDatabase(mockMongoClient) } returns mockMongoDatabase + every { mockMongoConfig.getCollection(mockMongoDatabase, "users") } returns mockCollection + + coEvery { mockFindPublisher.collect(any()) } coAnswers { + val collector = arg>(0) + collector.emit(mockUser) + } + + dataSource = MongoDBUserDataSource(mockMongoConfig) + } + + @Test + fun `getAll should return list of users`() { + // Given + coEvery { mockCollection.find() } returns mockFindPublisher + coEvery { mockFindPublisher.collect(any()) } coAnswers { + val collector = arg>(0) + mockUsers.forEach { collector.emit(it) } + } + + // When + val result = dataSource.getAll() + + // Then + assertEquals(mockUsers, result) + } + + @Test + fun `getById should return user when found`() { + // Given + coEvery { mockCollection.find(any()) } returns mockFindPublisher + coEvery { mockFindPublisher.collect(any()) } coAnswers { + val collector = arg>(0) + collector.emit(mockUser) + } + + // When + val result = dataSource.getById("user1") + + // Then + assertEquals(mockUser, result) + } + + @Test + fun `getById should return null when not found`() { + // Given + coEvery { mockCollection.find(any()) } returns mockFindPublisher + coEvery { mockFindPublisher.collect(any()) } coAnswers { } + + // When + val result = dataSource.getById("nonexistent") + + // Then + assertNull(result) + } + + @Test + fun `update should return true when acknowledged`() { + // Given + val mockUpdateResult = mockk() + every { mockUpdateResult.wasAcknowledged() } returns true + + coEvery { + mockCollection.replaceOne( + any(), + any(), + any() + ) + } returns mockUpdateResult + + // When + val result = dataSource.update("user1", mockUser) + + // Then + assertTrue(result) + } + + @Test + fun `update should return false when not acknowledged`() { + // Given + val mockUpdateResult = mockk() + every { mockUpdateResult.wasAcknowledged() } returns false + coEvery { mockCollection.replaceOne(any(), any(), any()) } returns mockUpdateResult + + // When + val result = dataSource.update("user1", mockUser) + + // Then + assertFalse(result) + } + + @Test + fun `delete should return true when acknowledged`() { + // Given + val mockDeleteResult = mockk() + every { mockDeleteResult.wasAcknowledged() } returns true + coEvery { mockCollection.deleteOne(any(), any()) } returns mockDeleteResult + + // When + val result = dataSource.delete("user1") + + // Then + assertTrue(result) + } + + @Test + fun `delete should return false when not acknowledged`() { + // Given + val mockDeleteResult = mockk() + every { mockDeleteResult.wasAcknowledged() } returns false + coEvery { mockCollection.deleteOne(any(), any()) } returns mockDeleteResult + + // When + val result = dataSource.delete("user1") + + // Then + assertFalse(result) + } + + @Test + fun `write should return true when acknowledged`() { + // Given + val mockInsertOneResult = mockk() + every { mockInsertOneResult.wasAcknowledged() } returns true + coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult + + // When + val result = dataSource.write(mockUser) + + // Then + assertTrue(result) + } + + @Test + fun `write should return false when not acknowledged`() { + // Given + val mockInsertOneResult = mockk() + every { mockInsertOneResult.wasAcknowledged() } returns false + coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult + + // When + val result = dataSource.write(mockUser) + + // Then + assertFalse(result) + } + + @Test + fun `writeAll should return true when acknowledged`() { + // Given + val mockInsertManyResult = mockk() + every { mockInsertManyResult.wasAcknowledged() } returns true + coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult + + // When + val result = dataSource.writeAll(mockUsers) + + // Then + assertTrue(result) + } + + @Test + fun `writeAll should return false when not acknowledged`() { + // Given + val mockInsertManyResult = mockk() + every { mockInsertManyResult.wasAcknowledged() } returns false + coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult + + // When + val result = dataSource.writeAll(mockUsers) + + // Then + assertFalse(result) + } + + @Test + fun `writeAll should return false when list is empty`() { + // When + val result = dataSource.writeAll(emptyList()) + + // Then + assertFalse(result) + } +} \ No newline at end of file From a5cd2e9299c221e09ea5b9c8c16c2c6411ae7b0c Mon Sep 17 00:00:00 2001 From: dev7odaa Date: Sun, 11 May 2025 14:20:07 +0300 Subject: [PATCH 12/17] use assertThat --- .../MongoDBAuditLogDataSourceTest.kt | 26 ++++++++-------- .../MongoDBProjectDataSourceTest.kt | 26 ++++++++-------- .../datasource/MongoDBStateDataSourceTest.kt | 26 ++++++++-------- .../datasource/MongoDBTaskDataSourceTest.kt | 31 ++++++++----------- .../datasource/MongoDBUserDataSourceTest.kt | 26 ++++++++-------- 5 files changed, 65 insertions(+), 70 deletions(-) diff --git a/src/test/kotlin/data/mongodb/datasource/MongoDBAuditLogDataSourceTest.kt b/src/test/kotlin/data/mongodb/datasource/MongoDBAuditLogDataSourceTest.kt index 4c837fa..5ce4592 100644 --- a/src/test/kotlin/data/mongodb/datasource/MongoDBAuditLogDataSourceTest.kt +++ b/src/test/kotlin/data/mongodb/datasource/MongoDBAuditLogDataSourceTest.kt @@ -4,10 +4,10 @@ import com.berlin.data.mongodb.config.MongoConfig import com.berlin.domain.model.AuditAction import com.berlin.domain.model.AuditLog import com.berlin.domain.model.EntityType +import com.google.common.truth.Truth.assertThat import io.mockk.coEvery import io.mockk.every import io.mockk.mockk -import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import com.mongodb.client.result.DeleteResult @@ -79,7 +79,7 @@ class MongoDBAuditLogDataSourceTest { val result = dataSource.getAll() // Then - assertEquals(mockAuditLogs, result) + assertThat(result).isEqualTo(mockAuditLogs) } @Test @@ -95,7 +95,7 @@ class MongoDBAuditLogDataSourceTest { val result = dataSource.getById("log1") // Then - assertEquals(mockAuditLog, result) + assertThat(result).isEqualTo(mockAuditLog) } @Test @@ -108,7 +108,7 @@ class MongoDBAuditLogDataSourceTest { val result = dataSource.getById("nonexistent") // Then - assertNull(result) + assertThat(result).isNull() } @Test @@ -129,7 +129,7 @@ class MongoDBAuditLogDataSourceTest { val result = dataSource.update("log1", mockAuditLog) // Then - assertTrue(result) + assertThat(result).isTrue() } @Test @@ -143,7 +143,7 @@ class MongoDBAuditLogDataSourceTest { val result = dataSource.update("log1", mockAuditLog) // Then - assertFalse(result) + assertThat(result).isFalse() } @Test @@ -157,7 +157,7 @@ class MongoDBAuditLogDataSourceTest { val result = dataSource.delete("log1") // Then - assertTrue(result) + assertThat(result).isTrue() } @Test @@ -171,7 +171,7 @@ class MongoDBAuditLogDataSourceTest { val result = dataSource.delete("log1") // Then - assertFalse(result) + assertThat(result).isFalse() } @Test @@ -185,7 +185,7 @@ class MongoDBAuditLogDataSourceTest { val result = dataSource.write(mockAuditLog) // Then - assertTrue(result) + assertThat(result).isTrue() } @Test @@ -199,7 +199,7 @@ class MongoDBAuditLogDataSourceTest { val result = dataSource.write(mockAuditLog) // Then - assertFalse(result) + assertThat(result).isFalse() } @Test @@ -213,7 +213,7 @@ class MongoDBAuditLogDataSourceTest { val result = dataSource.writeAll(mockAuditLogs) // Then - assertTrue(result) + assertThat(result).isTrue() } @Test @@ -227,7 +227,7 @@ class MongoDBAuditLogDataSourceTest { val result = dataSource.writeAll(mockAuditLogs) // Then - assertFalse(result) + assertThat(result).isFalse() } @Test @@ -236,6 +236,6 @@ class MongoDBAuditLogDataSourceTest { val result = dataSource.writeAll(emptyList()) // Then - assertFalse(result) + assertThat(result).isFalse() } } \ No newline at end of file diff --git a/src/test/kotlin/data/mongodb/datasource/MongoDBProjectDataSourceTest.kt b/src/test/kotlin/data/mongodb/datasource/MongoDBProjectDataSourceTest.kt index f5c01c8..87c32bd 100644 --- a/src/test/kotlin/data/mongodb/datasource/MongoDBProjectDataSourceTest.kt +++ b/src/test/kotlin/data/mongodb/datasource/MongoDBProjectDataSourceTest.kt @@ -2,10 +2,10 @@ package com.berlin.data.mongodb.datasource import com.berlin.data.mongodb.config.MongoConfig import com.berlin.domain.model.Project +import com.google.common.truth.Truth.assertThat import io.mockk.coEvery import io.mockk.every import io.mockk.mockk -import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import com.mongodb.client.result.DeleteResult @@ -73,7 +73,7 @@ class MongoDBProjectDataSourceTest { val result = dataSource.getAll() // Then - assertEquals(mockProjects, result) + assertThat(result).isEqualTo(mockProjects) } @Test @@ -89,7 +89,7 @@ class MongoDBProjectDataSourceTest { val result = dataSource.getById("project1") // Then - assertEquals(mockProject, result) + assertThat(result).isEqualTo(mockProject) } @Test @@ -102,7 +102,7 @@ class MongoDBProjectDataSourceTest { val result = dataSource.getById("nonexistent") // Then - assertNull(result) + assertThat(result).isNull() } @Test @@ -123,7 +123,7 @@ class MongoDBProjectDataSourceTest { val result = dataSource.update("project1", mockProject) // Then - assertTrue(result) + assertThat(result).isTrue() } @Test @@ -137,7 +137,7 @@ class MongoDBProjectDataSourceTest { val result = dataSource.update("project1", mockProject) // Then - assertFalse(result) + assertThat(result).isFalse() } @Test @@ -151,7 +151,7 @@ class MongoDBProjectDataSourceTest { val result = dataSource.delete("project1") // Then - assertTrue(result) + assertThat(result).isTrue() } @Test @@ -165,7 +165,7 @@ class MongoDBProjectDataSourceTest { val result = dataSource.delete("project1") // Then - assertFalse(result) + assertThat(result).isFalse() } @Test @@ -179,7 +179,7 @@ class MongoDBProjectDataSourceTest { val result = dataSource.write(mockProject) // Then - assertTrue(result) + assertThat(result).isTrue() } @Test @@ -193,7 +193,7 @@ class MongoDBProjectDataSourceTest { val result = dataSource.write(mockProject) // Then - assertFalse(result) + assertThat(result).isFalse() } @Test @@ -207,7 +207,7 @@ class MongoDBProjectDataSourceTest { val result = dataSource.writeAll(mockProjects) // Then - assertTrue(result) + assertThat(result).isTrue() } @Test @@ -221,7 +221,7 @@ class MongoDBProjectDataSourceTest { val result = dataSource.writeAll(mockProjects) // Then - assertFalse(result) + assertThat(result).isFalse() } @Test @@ -230,6 +230,6 @@ class MongoDBProjectDataSourceTest { val result = dataSource.writeAll(emptyList()) // Then - assertFalse(result) + assertThat(result).isFalse() } } \ No newline at end of file diff --git a/src/test/kotlin/data/mongodb/datasource/MongoDBStateDataSourceTest.kt b/src/test/kotlin/data/mongodb/datasource/MongoDBStateDataSourceTest.kt index 157c2a3..90b1d63 100644 --- a/src/test/kotlin/data/mongodb/datasource/MongoDBStateDataSourceTest.kt +++ b/src/test/kotlin/data/mongodb/datasource/MongoDBStateDataSourceTest.kt @@ -2,10 +2,10 @@ package com.berlin.data.mongodb.datasource import com.berlin.data.mongodb.config.MongoConfig import com.berlin.domain.model.TaskState +import com.google.common.truth.Truth.assertThat import io.mockk.coEvery import io.mockk.every import io.mockk.mockk -import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import com.mongodb.client.result.DeleteResult @@ -69,7 +69,7 @@ class MongoDBStateDataSourceTest { val result = dataSource.getAll() // Then - assertEquals(mockStates, result) + assertThat(result).isEqualTo(mockStates) } @Test @@ -85,7 +85,7 @@ class MongoDBStateDataSourceTest { val result = dataSource.getById("state1") // Then - assertEquals(mockState, result) + assertThat(result).isEqualTo(mockState) } @Test @@ -98,7 +98,7 @@ class MongoDBStateDataSourceTest { val result = dataSource.getById("nonexistent") // Then - assertNull(result) + assertThat(result).isNull() } @Test @@ -119,7 +119,7 @@ class MongoDBStateDataSourceTest { val result = dataSource.update("state1", mockState) // Then - assertTrue(result) + assertThat(result).isTrue() } @Test @@ -133,7 +133,7 @@ class MongoDBStateDataSourceTest { val result = dataSource.update("state1", mockState) // Then - assertFalse(result) + assertThat(result).isFalse() } @Test @@ -147,7 +147,7 @@ class MongoDBStateDataSourceTest { val result = dataSource.delete("state1") // Then - assertTrue(result) + assertThat(result).isTrue() } @Test @@ -161,7 +161,7 @@ class MongoDBStateDataSourceTest { val result = dataSource.delete("state1") // Then - assertFalse(result) + assertThat(result).isFalse() } @Test @@ -175,7 +175,7 @@ class MongoDBStateDataSourceTest { val result = dataSource.write(mockState) // Then - assertTrue(result) + assertThat(result).isTrue() } @Test @@ -189,7 +189,7 @@ class MongoDBStateDataSourceTest { val result = dataSource.write(mockState) // Then - assertFalse(result) + assertThat(result).isFalse() } @Test @@ -203,7 +203,7 @@ class MongoDBStateDataSourceTest { val result = dataSource.writeAll(mockStates) // Then - assertTrue(result) + assertThat(result).isTrue() } @Test @@ -217,7 +217,7 @@ class MongoDBStateDataSourceTest { val result = dataSource.writeAll(mockStates) // Then - assertFalse(result) + assertThat(result).isFalse() } @Test @@ -226,6 +226,6 @@ class MongoDBStateDataSourceTest { val result = dataSource.writeAll(emptyList()) // Then - assertFalse(result) + assertThat(result).isFalse() } } \ No newline at end of file diff --git a/src/test/kotlin/data/mongodb/datasource/MongoDBTaskDataSourceTest.kt b/src/test/kotlin/data/mongodb/datasource/MongoDBTaskDataSourceTest.kt index 6578b4f..d1c660f 100644 --- a/src/test/kotlin/data/mongodb/datasource/MongoDBTaskDataSourceTest.kt +++ b/src/test/kotlin/data/mongodb/datasource/MongoDBTaskDataSourceTest.kt @@ -2,13 +2,10 @@ package com.berlin.data.mongodb.datasource import com.berlin.data.mongodb.config.MongoConfig import com.berlin.domain.model.Task +import com.google.common.truth.Truth.assertThat import io.mockk.coEvery import io.mockk.every import io.mockk.mockk -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Assertions.assertFalse -import org.junit.jupiter.api.Assertions.assertNull -import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import com.mongodb.client.result.DeleteResult @@ -16,8 +13,6 @@ import com.mongodb.client.result.InsertManyResult import com.mongodb.client.result.InsertOneResult import com.mongodb.client.result.UpdateResult import kotlinx.coroutines.flow.FlowCollector -import kotlinx.coroutines.flow.firstOrNull -import kotlinx.coroutines.flow.toList import org.bson.conversions.Bson import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.TestInstance.Lifecycle @@ -82,7 +77,7 @@ class MongoDBTaskDataSourceTest { val result = dataSource.getAll() // Then - assertEquals(mockTasks, result) + assertThat(result).isEqualTo(mockTasks) } @Test @@ -98,7 +93,7 @@ class MongoDBTaskDataSourceTest { val result = dataSource.getById("task1") // Then - assertEquals(mockTask, result) + assertThat(result).isEqualTo(mockTask) } @Test @@ -111,7 +106,7 @@ class MongoDBTaskDataSourceTest { val result = dataSource.getById("nonexistent") // Then - assertNull(result) + assertThat(result).isNull() } @Test @@ -132,7 +127,7 @@ class MongoDBTaskDataSourceTest { val result = dataSource.update("task1", mockTask) // Then - assertTrue(result) + assertThat(result).isTrue() } @Test @@ -146,7 +141,7 @@ class MongoDBTaskDataSourceTest { val result = dataSource.update("task1", mockTask) // Then - assertFalse(result) + assertThat(result).isFalse() } @Test @@ -160,7 +155,7 @@ class MongoDBTaskDataSourceTest { val result = dataSource.delete("task1") // Then - assertTrue(result) + assertThat(result).isTrue() } @Test @@ -174,7 +169,7 @@ class MongoDBTaskDataSourceTest { val result = dataSource.delete("task1") // Then - assertFalse(result) + assertThat(result).isFalse() } @Test @@ -188,7 +183,7 @@ class MongoDBTaskDataSourceTest { val result = dataSource.write(mockTask) // Then - assertTrue(result) + assertThat(result).isTrue() } @Test @@ -202,7 +197,7 @@ class MongoDBTaskDataSourceTest { val result = dataSource.write(mockTask) // Then - assertFalse(result) + assertThat(result).isFalse() } @Test @@ -216,7 +211,7 @@ class MongoDBTaskDataSourceTest { val result = dataSource.writeAll(mockTasks) // Then - assertTrue(result) + assertThat(result).isTrue() } @Test @@ -230,7 +225,7 @@ class MongoDBTaskDataSourceTest { val result = dataSource.writeAll(mockTasks) // Then - assertFalse(result) + assertThat(result).isFalse() } @Test @@ -239,6 +234,6 @@ class MongoDBTaskDataSourceTest { val result = dataSource.writeAll(emptyList()) // Then - assertFalse(result) + assertThat(result).isFalse() } } \ No newline at end of file diff --git a/src/test/kotlin/data/mongodb/datasource/MongoDBUserDataSourceTest.kt b/src/test/kotlin/data/mongodb/datasource/MongoDBUserDataSourceTest.kt index cc926de..af13c00 100644 --- a/src/test/kotlin/data/mongodb/datasource/MongoDBUserDataSourceTest.kt +++ b/src/test/kotlin/data/mongodb/datasource/MongoDBUserDataSourceTest.kt @@ -3,10 +3,10 @@ package com.berlin.data.mongodb.datasource import com.berlin.data.mongodb.config.MongoConfig import com.berlin.domain.model.User import com.berlin.domain.model.UserRole +import com.google.common.truth.Truth.assertThat import io.mockk.coEvery import io.mockk.every import io.mockk.mockk -import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import com.mongodb.client.result.DeleteResult @@ -72,7 +72,7 @@ class MongoDBUserDataSourceTest { val result = dataSource.getAll() // Then - assertEquals(mockUsers, result) + assertThat(result).isEqualTo(mockUsers) } @Test @@ -88,7 +88,7 @@ class MongoDBUserDataSourceTest { val result = dataSource.getById("user1") // Then - assertEquals(mockUser, result) + assertThat(result).isEqualTo(mockUser) } @Test @@ -101,7 +101,7 @@ class MongoDBUserDataSourceTest { val result = dataSource.getById("nonexistent") // Then - assertNull(result) + assertThat(result).isNull() } @Test @@ -122,7 +122,7 @@ class MongoDBUserDataSourceTest { val result = dataSource.update("user1", mockUser) // Then - assertTrue(result) + assertThat(result).isTrue() } @Test @@ -136,7 +136,7 @@ class MongoDBUserDataSourceTest { val result = dataSource.update("user1", mockUser) // Then - assertFalse(result) + assertThat(result).isFalse() } @Test @@ -150,7 +150,7 @@ class MongoDBUserDataSourceTest { val result = dataSource.delete("user1") // Then - assertTrue(result) + assertThat(result).isTrue() } @Test @@ -164,7 +164,7 @@ class MongoDBUserDataSourceTest { val result = dataSource.delete("user1") // Then - assertFalse(result) + assertThat(result).isFalse() } @Test @@ -178,7 +178,7 @@ class MongoDBUserDataSourceTest { val result = dataSource.write(mockUser) // Then - assertTrue(result) + assertThat(result).isTrue() } @Test @@ -192,7 +192,7 @@ class MongoDBUserDataSourceTest { val result = dataSource.write(mockUser) // Then - assertFalse(result) + assertThat(result).isFalse() } @Test @@ -206,7 +206,7 @@ class MongoDBUserDataSourceTest { val result = dataSource.writeAll(mockUsers) // Then - assertTrue(result) + assertThat(result).isTrue() } @Test @@ -220,7 +220,7 @@ class MongoDBUserDataSourceTest { val result = dataSource.writeAll(mockUsers) // Then - assertFalse(result) + assertThat(result).isFalse() } @Test @@ -229,6 +229,6 @@ class MongoDBUserDataSourceTest { val result = dataSource.writeAll(emptyList()) // Then - assertFalse(result) + assertThat(result).isFalse() } } \ No newline at end of file From 147abe53596ef0af1fda19562e6b830099346df1 Mon Sep 17 00:00:00 2001 From: Diyar Date: Thu, 15 May 2025 15:38:03 +0300 Subject: [PATCH 13/17] change the name of parameter in mapper functions --- src/main/kotlin/data/mapper/AuditLogMapper.kt | 32 +++++++++---------- src/main/kotlin/data/mapper/ProjectMapper.kt | 24 +++++++------- src/main/kotlin/data/mapper/TaskMapper.kt | 32 +++++++++---------- .../kotlin/data/mapper/TaskStateMapper.kt | 16 +++++----- src/main/kotlin/data/mapper/UserMapper.kt | 18 +++++------ 5 files changed, 61 insertions(+), 61 deletions(-) diff --git a/src/main/kotlin/data/mapper/AuditLogMapper.kt b/src/main/kotlin/data/mapper/AuditLogMapper.kt index a80f266..a047552 100644 --- a/src/main/kotlin/data/mapper/AuditLogMapper.kt +++ b/src/main/kotlin/data/mapper/AuditLogMapper.kt @@ -4,27 +4,27 @@ import com.berlin.data.dto.AuditLogDto import com.berlin.domain.model.AuditLog class AuditLogMapper : EntityMapper { - override fun mapToDomainModel(auditLogDto: AuditLogDto): AuditLog { + override fun mapToDomainModel(from: AuditLogDto): AuditLog { return AuditLog( - id = auditLogDto.id, - timestamp = auditLogDto.timestamp, - createdByUserId = auditLogDto.createdByUserId, - auditAction = auditLogDto.auditAction, - changesDescription = auditLogDto.changesDescription, - entityType = auditLogDto.entityType, - entityId = auditLogDto.entityId + id = from.id, + timestamp = from.timestamp, + createdByUserId = from.createdByUserId, + auditAction = from.auditAction, + changesDescription = from.changesDescription, + entityType = from.entityType, + entityId = from.entityId ) } - override fun mapToDataModel(auditLog: AuditLog): AuditLogDto { + override fun mapToDataModel(from: AuditLog): AuditLogDto { return AuditLogDto( - id = auditLog.id, - timestamp = auditLog.timestamp, - createdByUserId = auditLog.createdByUserId, - auditAction = auditLog.auditAction, - changesDescription = auditLog.changesDescription, - entityType = auditLog.entityType, - entityId = auditLog.entityId + id = from.id, + timestamp = from.timestamp, + createdByUserId = from.createdByUserId, + auditAction = from.auditAction, + changesDescription = from.changesDescription, + entityType = from.entityType, + entityId = from.entityId ) } } \ No newline at end of file diff --git a/src/main/kotlin/data/mapper/ProjectMapper.kt b/src/main/kotlin/data/mapper/ProjectMapper.kt index b38a35c..223fc4e 100644 --- a/src/main/kotlin/data/mapper/ProjectMapper.kt +++ b/src/main/kotlin/data/mapper/ProjectMapper.kt @@ -4,23 +4,23 @@ import com.berlin.data.dto.ProjectDto import com.berlin.domain.model.Project class ProjectMapper : EntityMapper { - override fun mapToDomainModel(projectDto: ProjectDto): Project { + override fun mapToDomainModel(from: ProjectDto): Project { return Project( - id = projectDto.id, - title = projectDto.title, - statesId = projectDto.statesId, - description = projectDto.description, - tasksId = projectDto.tasksId + id = from.id, + title = from.title, + statesId = from.statesId, + description = from.description, + tasksId = from.tasksId ) } - override fun mapToDataModel(project: Project): ProjectDto { + override fun mapToDataModel(from: Project): ProjectDto { return ProjectDto( - id = project.id, - title = project.title, - statesId = project.statesId, - description = project.description, - tasksId = project.tasksId + id = from.id, + title = from.title, + statesId = from.statesId, + description = from.description, + tasksId = from.tasksId ) } } \ No newline at end of file diff --git a/src/main/kotlin/data/mapper/TaskMapper.kt b/src/main/kotlin/data/mapper/TaskMapper.kt index 9cf8723..22646cc 100644 --- a/src/main/kotlin/data/mapper/TaskMapper.kt +++ b/src/main/kotlin/data/mapper/TaskMapper.kt @@ -4,27 +4,27 @@ import com.berlin.data.dto.TaskDto import com.berlin.domain.model.Task class TaskMapper : EntityMapper { - override fun mapToDomainModel(taskDto: TaskDto): Task { + override fun mapToDomainModel(from: TaskDto): Task { return Task( - id = taskDto.id, - title = taskDto.title, - projectId = taskDto.projectId, - description = taskDto.description, - stateId = taskDto.stateId, - assignedToUserId = taskDto.assignedToUserId, - createByUserId = taskDto.createByUserId + id = from.id, + title = from.title, + projectId = from.projectId, + description = from.description, + stateId = from.stateId, + assignedToUserId = from.assignedToUserId, + createByUserId = from.createByUserId ) } - override fun mapToDataModel(task: Task): TaskDto { + override fun mapToDataModel(from: Task): TaskDto { return TaskDto( - id = task.id, - title = task.title, - projectId = task.projectId, - description = task.description, - stateId = task.stateId, - assignedToUserId = task.assignedToUserId, - createByUserId = task.createByUserId + id = from.id, + title = from.title, + projectId = from.projectId, + description = from.description, + stateId = from.stateId, + assignedToUserId = from.assignedToUserId, + createByUserId = from.createByUserId ) } } \ No newline at end of file diff --git a/src/main/kotlin/data/mapper/TaskStateMapper.kt b/src/main/kotlin/data/mapper/TaskStateMapper.kt index 1634b6c..513ffe1 100644 --- a/src/main/kotlin/data/mapper/TaskStateMapper.kt +++ b/src/main/kotlin/data/mapper/TaskStateMapper.kt @@ -4,19 +4,19 @@ import com.berlin.data.dto.TaskStateDto import com.berlin.domain.model.TaskState class TaskStateMapper : EntityMapper { - override fun mapToDomainModel(taskStateDto: TaskStateDto): TaskState { + override fun mapToDomainModel(from: TaskStateDto): TaskState { return TaskState( - id = taskStateDto.id, - name = taskStateDto.name, - projectId = taskStateDto.projectId + id = from.id, + name = from.name, + projectId = from.projectId ) } - override fun mapToDataModel(taskState: TaskState): TaskStateDto { + override fun mapToDataModel(from: TaskState): TaskStateDto { return TaskStateDto( - id = taskState.id, - name = taskState.name, - projectId = taskState.projectId + id = from.id, + name = from.name, + projectId = from.projectId ) } } \ No newline at end of file diff --git a/src/main/kotlin/data/mapper/UserMapper.kt b/src/main/kotlin/data/mapper/UserMapper.kt index eb931d9..95b075f 100644 --- a/src/main/kotlin/data/mapper/UserMapper.kt +++ b/src/main/kotlin/data/mapper/UserMapper.kt @@ -9,21 +9,21 @@ class UserMapper( private val userDataSource: BaseDataSource, ) : EntityMapper { - override fun mapToDomainModel(userDto: UserDto): User { + override fun mapToDomainModel(from: UserDto): User { return User( - id = userDto.id, - userName = userDto.userName, - role = userDto.role + id = from.id, + userName = from.userName, + role = from.role ) } - override fun mapToDataModel(user: User): UserDto { - val userDto = userDataSource.getById(user.id) + override fun mapToDataModel(from: User): UserDto { + val userDto = userDataSource.getById(from.id) ?: throw UserNotFoundException("user not found") return UserDto( - id = user.id, - userName = user.userName, - role = user.role, + id = from.id, + userName = from.userName, + role = from.role, password = userDto.password ) } From 967cde78f8c29d6eccda52ce8edc9feffc4b80e3 Mon Sep 17 00:00:00 2001 From: Diyar Date: Thu, 15 May 2025 15:44:42 +0300 Subject: [PATCH 14/17] changes after merge --- src/main/kotlin/data/mapper/AuditLogMapper.kt | 32 +++++++++---------- src/main/kotlin/data/mapper/ProjectMapper.kt | 24 +++++++------- src/main/kotlin/data/mapper/TaskMapper.kt | 32 +++++++++---------- .../kotlin/data/mapper/TaskStateMapper.kt | 16 +++++----- src/main/kotlin/data/mapper/UserMapper.kt | 18 +++++------ src/main/kotlin/domain/model/AuditLog.kt | 15 ++++----- src/main/kotlin/domain/model/Project.kt | 9 ++---- src/main/kotlin/domain/model/Task.kt | 13 +++----- src/main/kotlin/domain/model/TaskState.kt | 7 ++-- src/main/kotlin/domain/model/User.kt | 0 10 files changed, 77 insertions(+), 89 deletions(-) delete mode 100644 src/main/kotlin/domain/model/User.kt diff --git a/src/main/kotlin/data/mapper/AuditLogMapper.kt b/src/main/kotlin/data/mapper/AuditLogMapper.kt index a80f266..a047552 100644 --- a/src/main/kotlin/data/mapper/AuditLogMapper.kt +++ b/src/main/kotlin/data/mapper/AuditLogMapper.kt @@ -4,27 +4,27 @@ import com.berlin.data.dto.AuditLogDto import com.berlin.domain.model.AuditLog class AuditLogMapper : EntityMapper { - override fun mapToDomainModel(auditLogDto: AuditLogDto): AuditLog { + override fun mapToDomainModel(from: AuditLogDto): AuditLog { return AuditLog( - id = auditLogDto.id, - timestamp = auditLogDto.timestamp, - createdByUserId = auditLogDto.createdByUserId, - auditAction = auditLogDto.auditAction, - changesDescription = auditLogDto.changesDescription, - entityType = auditLogDto.entityType, - entityId = auditLogDto.entityId + id = from.id, + timestamp = from.timestamp, + createdByUserId = from.createdByUserId, + auditAction = from.auditAction, + changesDescription = from.changesDescription, + entityType = from.entityType, + entityId = from.entityId ) } - override fun mapToDataModel(auditLog: AuditLog): AuditLogDto { + override fun mapToDataModel(from: AuditLog): AuditLogDto { return AuditLogDto( - id = auditLog.id, - timestamp = auditLog.timestamp, - createdByUserId = auditLog.createdByUserId, - auditAction = auditLog.auditAction, - changesDescription = auditLog.changesDescription, - entityType = auditLog.entityType, - entityId = auditLog.entityId + id = from.id, + timestamp = from.timestamp, + createdByUserId = from.createdByUserId, + auditAction = from.auditAction, + changesDescription = from.changesDescription, + entityType = from.entityType, + entityId = from.entityId ) } } \ No newline at end of file diff --git a/src/main/kotlin/data/mapper/ProjectMapper.kt b/src/main/kotlin/data/mapper/ProjectMapper.kt index b38a35c..223fc4e 100644 --- a/src/main/kotlin/data/mapper/ProjectMapper.kt +++ b/src/main/kotlin/data/mapper/ProjectMapper.kt @@ -4,23 +4,23 @@ import com.berlin.data.dto.ProjectDto import com.berlin.domain.model.Project class ProjectMapper : EntityMapper { - override fun mapToDomainModel(projectDto: ProjectDto): Project { + override fun mapToDomainModel(from: ProjectDto): Project { return Project( - id = projectDto.id, - title = projectDto.title, - statesId = projectDto.statesId, - description = projectDto.description, - tasksId = projectDto.tasksId + id = from.id, + title = from.title, + statesId = from.statesId, + description = from.description, + tasksId = from.tasksId ) } - override fun mapToDataModel(project: Project): ProjectDto { + override fun mapToDataModel(from: Project): ProjectDto { return ProjectDto( - id = project.id, - title = project.title, - statesId = project.statesId, - description = project.description, - tasksId = project.tasksId + id = from.id, + title = from.title, + statesId = from.statesId, + description = from.description, + tasksId = from.tasksId ) } } \ No newline at end of file diff --git a/src/main/kotlin/data/mapper/TaskMapper.kt b/src/main/kotlin/data/mapper/TaskMapper.kt index 9cf8723..22646cc 100644 --- a/src/main/kotlin/data/mapper/TaskMapper.kt +++ b/src/main/kotlin/data/mapper/TaskMapper.kt @@ -4,27 +4,27 @@ import com.berlin.data.dto.TaskDto import com.berlin.domain.model.Task class TaskMapper : EntityMapper { - override fun mapToDomainModel(taskDto: TaskDto): Task { + override fun mapToDomainModel(from: TaskDto): Task { return Task( - id = taskDto.id, - title = taskDto.title, - projectId = taskDto.projectId, - description = taskDto.description, - stateId = taskDto.stateId, - assignedToUserId = taskDto.assignedToUserId, - createByUserId = taskDto.createByUserId + id = from.id, + title = from.title, + projectId = from.projectId, + description = from.description, + stateId = from.stateId, + assignedToUserId = from.assignedToUserId, + createByUserId = from.createByUserId ) } - override fun mapToDataModel(task: Task): TaskDto { + override fun mapToDataModel(from: Task): TaskDto { return TaskDto( - id = task.id, - title = task.title, - projectId = task.projectId, - description = task.description, - stateId = task.stateId, - assignedToUserId = task.assignedToUserId, - createByUserId = task.createByUserId + id = from.id, + title = from.title, + projectId = from.projectId, + description = from.description, + stateId = from.stateId, + assignedToUserId = from.assignedToUserId, + createByUserId = from.createByUserId ) } } \ No newline at end of file diff --git a/src/main/kotlin/data/mapper/TaskStateMapper.kt b/src/main/kotlin/data/mapper/TaskStateMapper.kt index 1634b6c..513ffe1 100644 --- a/src/main/kotlin/data/mapper/TaskStateMapper.kt +++ b/src/main/kotlin/data/mapper/TaskStateMapper.kt @@ -4,19 +4,19 @@ import com.berlin.data.dto.TaskStateDto import com.berlin.domain.model.TaskState class TaskStateMapper : EntityMapper { - override fun mapToDomainModel(taskStateDto: TaskStateDto): TaskState { + override fun mapToDomainModel(from: TaskStateDto): TaskState { return TaskState( - id = taskStateDto.id, - name = taskStateDto.name, - projectId = taskStateDto.projectId + id = from.id, + name = from.name, + projectId = from.projectId ) } - override fun mapToDataModel(taskState: TaskState): TaskStateDto { + override fun mapToDataModel(from: TaskState): TaskStateDto { return TaskStateDto( - id = taskState.id, - name = taskState.name, - projectId = taskState.projectId + id = from.id, + name = from.name, + projectId = from.projectId ) } } \ No newline at end of file diff --git a/src/main/kotlin/data/mapper/UserMapper.kt b/src/main/kotlin/data/mapper/UserMapper.kt index eb931d9..95b075f 100644 --- a/src/main/kotlin/data/mapper/UserMapper.kt +++ b/src/main/kotlin/data/mapper/UserMapper.kt @@ -9,21 +9,21 @@ class UserMapper( private val userDataSource: BaseDataSource, ) : EntityMapper { - override fun mapToDomainModel(userDto: UserDto): User { + override fun mapToDomainModel(from: UserDto): User { return User( - id = userDto.id, - userName = userDto.userName, - role = userDto.role + id = from.id, + userName = from.userName, + role = from.role ) } - override fun mapToDataModel(user: User): UserDto { - val userDto = userDataSource.getById(user.id) + override fun mapToDataModel(from: User): UserDto { + val userDto = userDataSource.getById(from.id) ?: throw UserNotFoundException("user not found") return UserDto( - id = user.id, - userName = user.userName, - role = user.role, + id = from.id, + userName = from.userName, + role = from.role, password = userDto.password ) } diff --git a/src/main/kotlin/domain/model/AuditLog.kt b/src/main/kotlin/domain/model/AuditLog.kt index 1f979bb..0ec7c48 100644 --- a/src/main/kotlin/domain/model/AuditLog.kt +++ b/src/main/kotlin/domain/model/AuditLog.kt @@ -1,16 +1,13 @@ package com.berlin.domain.model -import org.bson.codecs.pojo.annotations.BsonId -import org.bson.codecs.pojo.annotations.BsonProperty - data class AuditLog( - @BsonId val id: String, + val id: String, val timestamp: Long, - @BsonProperty("created_by_user_id") val createdByUserId: String, - @BsonProperty("audit_action") val auditAction: AuditAction, - @BsonProperty("changes_description") val changesDescription: String?, - @BsonProperty("entity_type") val entityType: EntityType, - @BsonProperty("entity_id") val entityId: String + val createdByUserId: String, + val auditAction: AuditAction, + val changesDescription: String?, + val entityType: EntityType, + val entityId: String ) { enum class AuditAction { CREATE, UPDATE, DELETE diff --git a/src/main/kotlin/domain/model/Project.kt b/src/main/kotlin/domain/model/Project.kt index 778a7a8..f6a0976 100644 --- a/src/main/kotlin/domain/model/Project.kt +++ b/src/main/kotlin/domain/model/Project.kt @@ -1,12 +1,9 @@ package com.berlin.domain.model -import org.bson.codecs.pojo.annotations.BsonId -import org.bson.codecs.pojo.annotations.BsonProperty - data class Project( - @BsonId val id: String, + val id: String, val title: String, val description: String?, - @BsonProperty("states_id") val statesId: List?, - @BsonProperty("tasks_id") val tasksId: List? + val statesId: List?, + val tasksId: List? ) \ No newline at end of file diff --git a/src/main/kotlin/domain/model/Task.kt b/src/main/kotlin/domain/model/Task.kt index 2d71cf0..cd6813b 100644 --- a/src/main/kotlin/domain/model/Task.kt +++ b/src/main/kotlin/domain/model/Task.kt @@ -1,14 +1,11 @@ package com.berlin.domain.model -import org.bson.codecs.pojo.annotations.BsonId -import org.bson.codecs.pojo.annotations.BsonProperty - data class Task( - @BsonId val id: String, - @BsonProperty("project_id") val projectId: String, + val id: String, + val projectId: String, val title: String, val description: String?, - @BsonProperty("state_id") val stateId: String, - @BsonProperty("assigned_to_user_id") val assignedToUserId: String, - @BsonProperty("create_by_user_id") val createByUserId: String, + val stateId: String, + val assignedToUserId: String, + val createByUserId: String, ) \ No newline at end of file diff --git a/src/main/kotlin/domain/model/TaskState.kt b/src/main/kotlin/domain/model/TaskState.kt index 5fb2393..44c252f 100644 --- a/src/main/kotlin/domain/model/TaskState.kt +++ b/src/main/kotlin/domain/model/TaskState.kt @@ -1,10 +1,7 @@ package com.berlin.domain.model -import org.bson.codecs.pojo.annotations.BsonId -import org.bson.codecs.pojo.annotations.BsonProperty - data class TaskState( - @BsonId val id: String, + val id: String, val name: String, - @BsonProperty("project_id") val projectId: String, + val projectId: String, ) \ No newline at end of file diff --git a/src/main/kotlin/domain/model/User.kt b/src/main/kotlin/domain/model/User.kt deleted file mode 100644 index e69de29..0000000 From 32ba928218e00701c70651f42628f5839acf0fa2 Mon Sep 17 00:00:00 2001 From: Diyar Date: Thu, 15 May 2025 20:41:10 +0300 Subject: [PATCH 15/17] fix monogdb connection issue --- .../kotlin/data/mongodb/config/MongoConfig.kt | 6 ++- ...Source.kt => MongoDBAuditLogDataSource.kt} | 18 +++---- .../datasource/MongoDBUserDataSource.kt | 15 +++--- src/main/kotlin/di/dataModule.kt | 53 ++++++++----------- .../MongoDBAuditLogDataSourceTest.kt | 43 ++++++++------- .../MongoDBProjectDataSourceTest.kt | 4 +- .../datasource/MongoDBUserDataSourceTest.kt | 36 ++++++------- 7 files changed, 85 insertions(+), 90 deletions(-) rename src/main/kotlin/data/mongodb/datasource/{MongoDBauditLogDataSource.kt => MongoDBAuditLogDataSource.kt} (71%) diff --git a/src/main/kotlin/data/mongodb/config/MongoConfig.kt b/src/main/kotlin/data/mongodb/config/MongoConfig.kt index c7d9305..b169a22 100644 --- a/src/main/kotlin/data/mongodb/config/MongoConfig.kt +++ b/src/main/kotlin/data/mongodb/config/MongoConfig.kt @@ -2,6 +2,8 @@ package com.berlin.data.mongodb.config import com.mongodb.ConnectionString import com.mongodb.MongoClientSettings +import com.mongodb.ServerApi +import com.mongodb.ServerApiVersion import com.mongodb.kotlin.client.coroutine.MongoClient import com.mongodb.kotlin.client.coroutine.MongoDatabase import org.bson.codecs.configuration.CodecRegistries @@ -9,8 +11,8 @@ import org.bson.codecs.pojo.PojoCodecProvider import com.mongodb.kotlin.client.coroutine.MongoCollection class MongoConfig( - private val connectionString: String = "mongodb+srv://diyarHussein:7p53.t@GQ4F#@2c@planmate.gzyncow.mongodb.net/?retryWrites=true&w=majority&appName=PlanMate", - private val databaseName: String = "PlanMate" + private val connectionString: String = System.getenv("MONGO_URI"), + private val databaseName: String = "TaskManager", ) { fun createMongoClient(): MongoClient { diff --git a/src/main/kotlin/data/mongodb/datasource/MongoDBauditLogDataSource.kt b/src/main/kotlin/data/mongodb/datasource/MongoDBAuditLogDataSource.kt similarity index 71% rename from src/main/kotlin/data/mongodb/datasource/MongoDBauditLogDataSource.kt rename to src/main/kotlin/data/mongodb/datasource/MongoDBAuditLogDataSource.kt index f290ea8..719dcb6 100644 --- a/src/main/kotlin/data/mongodb/datasource/MongoDBauditLogDataSource.kt +++ b/src/main/kotlin/data/mongodb/datasource/MongoDBAuditLogDataSource.kt @@ -1,34 +1,34 @@ package com.berlin.data.mongodb.datasource import com.berlin.data.BaseDataSource +import com.berlin.data.dto.AuditLogDto import com.berlin.data.mongodb.config.MongoConfig -import com.berlin.domain.model.AuditLog import com.mongodb.client.model.Filters import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.toList import kotlinx.coroutines.runBlocking -class MongoDBauditLogDataSource( +class MongoDBAuditLogDataSource( private val mongoConfig: MongoConfig -) : BaseDataSource { +) : BaseDataSource { private val client = mongoConfig.createMongoClient() private val database = mongoConfig.getDatabase(client) - private val collection = mongoConfig.getCollection(database, "audit_logs") + private val collection = mongoConfig.getCollection(database, "audit_logs") - override fun getAll(): List { + override fun getAll(): List { return runBlocking { collection.find().toList() } } - override fun getById(id: String): AuditLog? { + override fun getById(id: String): AuditLogDto? { return runBlocking { collection.find(Filters.eq("_id", id)).firstOrNull() } } - override fun update(id: String, entity: AuditLog): Boolean { + override fun update(id: String, entity: AuditLogDto): Boolean { return runBlocking { collection.replaceOne(Filters.eq("_id", id), entity).wasAcknowledged() } @@ -40,13 +40,13 @@ class MongoDBauditLogDataSource( } } - override fun write(entity: AuditLog): Boolean { + override fun write(entity: AuditLogDto): Boolean { return runBlocking { collection.insertOne(entity).wasAcknowledged() } } - override fun writeAll(entities: List): Boolean { + override fun writeAll(entities: List): Boolean { if (entities.isEmpty()) { return false } diff --git a/src/main/kotlin/data/mongodb/datasource/MongoDBUserDataSource.kt b/src/main/kotlin/data/mongodb/datasource/MongoDBUserDataSource.kt index 21c549a..1b90523 100644 --- a/src/main/kotlin/data/mongodb/datasource/MongoDBUserDataSource.kt +++ b/src/main/kotlin/data/mongodb/datasource/MongoDBUserDataSource.kt @@ -1,6 +1,7 @@ package com.berlin.data.mongodb.datasource import com.berlin.data.BaseDataSource +import com.berlin.data.dto.UserDto import com.berlin.data.mongodb.config.MongoConfig import com.berlin.domain.model.user.User import com.mongodb.client.model.Filters @@ -10,25 +11,25 @@ import kotlinx.coroutines.runBlocking class MongoDBUserDataSource( private val mongoConfig: MongoConfig -) : BaseDataSource { +) : BaseDataSource { private val client = mongoConfig.createMongoClient() private val database = mongoConfig.getDatabase(client) - private val collection = mongoConfig.getCollection(database, "users") + private val collection = mongoConfig.getCollection(database, "users") - override fun getAll(): List { + override fun getAll(): List { return runBlocking { collection.find().toList() } } - override fun getById(id: String): User? { + override fun getById(id: String): UserDto? { return runBlocking { collection.find(Filters.eq("_id", id)).firstOrNull() } } - override fun update(id: String, entity: User): Boolean { + override fun update(id: String, entity: UserDto): Boolean { return runBlocking { collection.replaceOne(Filters.eq("_id", id), entity).wasAcknowledged() } @@ -40,13 +41,13 @@ class MongoDBUserDataSource( } } - override fun write(entity: User): Boolean { + override fun write(entity: UserDto): Boolean { return runBlocking { collection.insertOne(entity).wasAcknowledged() } } - override fun writeAll(entities: List): Boolean { + override fun writeAll(entities: List): Boolean { if (entities.isEmpty()) { return false } diff --git a/src/main/kotlin/di/dataModule.kt b/src/main/kotlin/di/dataModule.kt index d0cd5b5..13a56eb 100644 --- a/src/main/kotlin/di/dataModule.kt +++ b/src/main/kotlin/di/dataModule.kt @@ -1,7 +1,6 @@ package com.berlin.di import com.berlin.data.BaseDataSource -import com.berlin.data.csv_data_source.CsvDataSource import com.berlin.data.csv_data_source.schema.* import com.berlin.data.mongodb.datasource.* import com.berlin.data.dto.* @@ -60,38 +59,32 @@ val dataModule = module { single { MongoConfig() } - single>(named("mongoDbTaskDataSource")) { MongoDBTaskDataSource(get()) } - single>(named("mongoDbStateDataSource")) { MongoDBStateDataSource(get()) } - single>(named("mongoDbProjectDataSource")) { MongoDBProjectDataSource(get()) } - single>(named("mongoDbAuditLogDataSource")) { MongoDBauditLogDataSource(get()) } - single>(named("mongoDbUserDataSource")) { MongoDBUserDataSource(get()) } - - single>(named("AuditDataSource")){ CsvDataSource("csv_files", get(named("AuditSchema"))) } - - single> { CsvDataSource("csv_files", get(named("TaskSchema"))) } + single>(named("mongoDbTaskDataSource")) { MongoDBTaskDataSource(get()) } single>(named("mongoDbStateDataSource")) { MongoDBStateDataSource(get()) } single>(named("mongoDbProjectDataSource")) { MongoDBProjectDataSource(get()) } - single>(named("mongoDbAuditLogDataSource")) { MongoDBauditLogDataSource(get()) } - single>(named("mongoDbUserDataSource")) { MongoDBUserDataSource(get()) } + single>(named("mongoDbAuditLogDataSource")) { MongoDBAuditLogDataSource(get()) } + single>(named("mongoDbUserDataSource")) { MongoDBUserDataSource(get()) } - single>(named("AuditDataSource")) { CsvDataSource("csv_files", get(named("AuditSchema"))) } - - single>(named("UserDataSource")) { CsvDataSource("csv_files", get(named("UserSchema"))) } - single>(named("ProjectDataSource")) { - CsvDataSource( - "csv_files", get(named("ProjectSchema")) - ) - } - single>(named("UserDtoDataSource")) { - CsvDataSource("csv_files", get(named("UserSchema"))) - } - single>(named("TaskDataSource")) { CsvDataSource("csv_files", get(named("TaskSchema"))) } - single>(named("StateDataSource")) { - CsvDataSource( - "csv_files", get(named("StateSchema")) - ) - } - single>(named("AuditDataSource")) { CsvDataSource("csv_files", get(named("AuditSchema"))) } +// single>(named("AuditDataSource")){ CsvDataSource("csv_files", get(named("AuditSchema"))) } +// +// single> { CsvDataSource("csv_files", get(named("TaskSchema"))) } +// +// single>(named("UserDataSource")) { CsvDataSource("csv_files", get(named("UserSchema"))) } +// single>(named("ProjectDataSource")) { +// CsvDataSource( +// "csv_files", get(named("ProjectSchema")) +// ) +// } +// single>(named("UserDtoDataSource")) { +// CsvDataSource("csv_files", get(named("UserSchema"))) +// } +// single>(named("TaskDataSource")) { CsvDataSource("csv_files", get(named("TaskSchema"))) } +// single>(named("StateDataSource")) { +// CsvDataSource( +// "csv_files", get(named("StateSchema")) +// ) +// } +// single>(named("AuditDataSource")) { CsvDataSource("csv_files", get(named("AuditSchema"))) } single { TaskMapper() }.bind>() single { ProjectMapper() }.bind>() diff --git a/src/test/kotlin/data/mongodb/datasource/MongoDBAuditLogDataSourceTest.kt b/src/test/kotlin/data/mongodb/datasource/MongoDBAuditLogDataSourceTest.kt index 5ce4592..9340aaa 100644 --- a/src/test/kotlin/data/mongodb/datasource/MongoDBAuditLogDataSourceTest.kt +++ b/src/test/kotlin/data/mongodb/datasource/MongoDBAuditLogDataSourceTest.kt @@ -1,9 +1,8 @@ package com.berlin.data.mongodb.datasource +import com.berlin.data.dto.AuditLogDto import com.berlin.data.mongodb.config.MongoConfig -import com.berlin.domain.model.AuditAction import com.berlin.domain.model.AuditLog -import com.berlin.domain.model.EntityType import com.google.common.truth.Truth.assertThat import io.mockk.coEvery import io.mockk.every @@ -22,32 +21,32 @@ import org.junit.jupiter.api.TestInstance.Lifecycle @TestInstance(Lifecycle.PER_CLASS) class MongoDBAuditLogDataSourceTest { - private lateinit var dataSource: MongoDBauditLogDataSource + private lateinit var dataSource: MongoDBAuditLogDataSource private val mockMongoConfig = mockk() - private val mockCollection = mockk>() + private val mockCollection = mockk>() private val mockMongoClient = mockk() private val mockMongoDatabase = mockk() - private val mockFindPublisher = mockk>() + private val mockFindPublisher = mockk>() - private val mockAuditLog = AuditLog( + private val mockAuditLog = AuditLogDto( id = "log1", timestamp = 1717027200, createdByUserId = "user1", - auditAction = AuditAction.CREATE, + auditAction = AuditLog.AuditAction.CREATE, changesDescription = "Initial creation", - entityType = EntityType.TASK, + entityType = AuditLog.EntityType.TASK, entityId = "task1" ) private val mockAuditLogs = listOf( mockAuditLog, - AuditLog( + AuditLogDto( id = "log2", timestamp = 1717027300, createdByUserId = "user2", - auditAction = AuditAction.UPDATE, + auditAction = AuditLog.AuditAction.UPDATE, changesDescription = "Status changed", - entityType = EntityType.TASK, + entityType = AuditLog.EntityType.TASK, entityId = "task1" ) ) @@ -56,14 +55,14 @@ class MongoDBAuditLogDataSourceTest { fun setUp() { every { mockMongoConfig.createMongoClient() } returns mockMongoClient every { mockMongoConfig.getDatabase(mockMongoClient) } returns mockMongoDatabase - every { mockMongoConfig.getCollection(mockMongoDatabase, "audit_logs") } returns mockCollection + every { mockMongoConfig.getCollection(mockMongoDatabase, "audit_logs") } returns mockCollection coEvery { mockFindPublisher.collect(any()) } coAnswers { - val collector = arg>(0) + val collector = arg>(0) collector.emit(mockAuditLog) } - dataSource = MongoDBauditLogDataSource(mockMongoConfig) + dataSource = MongoDBAuditLogDataSource(mockMongoConfig) } @Test @@ -71,7 +70,7 @@ class MongoDBAuditLogDataSourceTest { // Given coEvery { mockCollection.find() } returns mockFindPublisher coEvery { mockFindPublisher.collect(any()) } coAnswers { - val collector = arg>(0) + val collector = arg>(0) mockAuditLogs.forEach { collector.emit(it) } } @@ -87,7 +86,7 @@ class MongoDBAuditLogDataSourceTest { // Given coEvery { mockCollection.find(any()) } returns mockFindPublisher coEvery { mockFindPublisher.collect(any()) } coAnswers { - val collector = arg>(0) + val collector = arg>(0) collector.emit(mockAuditLog) } @@ -120,7 +119,7 @@ class MongoDBAuditLogDataSourceTest { coEvery { mockCollection.replaceOne( any(), - any(), + any(), any() ) } returns mockUpdateResult @@ -137,7 +136,7 @@ class MongoDBAuditLogDataSourceTest { // Given val mockUpdateResult = mockk() every { mockUpdateResult.wasAcknowledged() } returns false - coEvery { mockCollection.replaceOne(any(), any(), any()) } returns mockUpdateResult + coEvery { mockCollection.replaceOne(any(), any(), any()) } returns mockUpdateResult // When val result = dataSource.update("log1", mockAuditLog) @@ -179,7 +178,7 @@ class MongoDBAuditLogDataSourceTest { // Given val mockInsertOneResult = mockk() every { mockInsertOneResult.wasAcknowledged() } returns true - coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult + coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult // When val result = dataSource.write(mockAuditLog) @@ -193,7 +192,7 @@ class MongoDBAuditLogDataSourceTest { // Given val mockInsertOneResult = mockk() every { mockInsertOneResult.wasAcknowledged() } returns false - coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult + coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult // When val result = dataSource.write(mockAuditLog) @@ -207,7 +206,7 @@ class MongoDBAuditLogDataSourceTest { // Given val mockInsertManyResult = mockk() every { mockInsertManyResult.wasAcknowledged() } returns true - coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult + coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult // When val result = dataSource.writeAll(mockAuditLogs) @@ -221,7 +220,7 @@ class MongoDBAuditLogDataSourceTest { // Given val mockInsertManyResult = mockk() every { mockInsertManyResult.wasAcknowledged() } returns false - coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult + coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult // When val result = dataSource.writeAll(mockAuditLogs) diff --git a/src/test/kotlin/data/mongodb/datasource/MongoDBProjectDataSourceTest.kt b/src/test/kotlin/data/mongodb/datasource/MongoDBProjectDataSourceTest.kt index 87c32bd..ed96f3f 100644 --- a/src/test/kotlin/data/mongodb/datasource/MongoDBProjectDataSourceTest.kt +++ b/src/test/kotlin/data/mongodb/datasource/MongoDBProjectDataSourceTest.kt @@ -29,7 +29,7 @@ class MongoDBProjectDataSourceTest { private val mockProject = Project( id = "project1", - name = "Task Manager", + title = "Task Manager", description = "Manage tasks efficiently", statesId = listOf("state1", "state2"), tasksId = listOf("task1", "task2") @@ -39,7 +39,7 @@ class MongoDBProjectDataSourceTest { mockProject, Project( id = "project2", - name = "Marketing Campaign", + title = "Marketing Campaign", description = null, statesId = emptyList(), tasksId = null diff --git a/src/test/kotlin/data/mongodb/datasource/MongoDBUserDataSourceTest.kt b/src/test/kotlin/data/mongodb/datasource/MongoDBUserDataSourceTest.kt index af13c00..8a516a1 100644 --- a/src/test/kotlin/data/mongodb/datasource/MongoDBUserDataSourceTest.kt +++ b/src/test/kotlin/data/mongodb/datasource/MongoDBUserDataSourceTest.kt @@ -1,8 +1,8 @@ package com.berlin.data.mongodb.datasource +import com.berlin.data.dto.UserDto import com.berlin.data.mongodb.config.MongoConfig -import com.berlin.domain.model.User -import com.berlin.domain.model.UserRole +import com.berlin.domain.model.user.User import com.google.common.truth.Truth.assertThat import io.mockk.coEvery import io.mockk.every @@ -23,25 +23,25 @@ class MongoDBUserDataSourceTest { private lateinit var dataSource: MongoDBUserDataSource private val mockMongoConfig = mockk() - private val mockCollection = mockk>() + private val mockCollection = mockk>() private val mockMongoClient = mockk() private val mockMongoDatabase = mockk() - private val mockFindPublisher = mockk>() + private val mockFindPublisher = mockk>() - private val mockUser = User( + private val mockUser = UserDto( id = "user1", userName = "admin", password = "secure123", - role = UserRole.ADMIN + role = User.UserRole.ADMIN ) private val mockUsers = listOf( mockUser, - User( + UserDto( id = "user2", userName = "mate", password = "pass456", - role = UserRole.MATE + role = User.UserRole.MATE ) ) @@ -49,10 +49,10 @@ class MongoDBUserDataSourceTest { fun setUp() { every { mockMongoConfig.createMongoClient() } returns mockMongoClient every { mockMongoConfig.getDatabase(mockMongoClient) } returns mockMongoDatabase - every { mockMongoConfig.getCollection(mockMongoDatabase, "users") } returns mockCollection + every { mockMongoConfig.getCollection(mockMongoDatabase, "users") } returns mockCollection coEvery { mockFindPublisher.collect(any()) } coAnswers { - val collector = arg>(0) + val collector = arg>(0) collector.emit(mockUser) } @@ -64,7 +64,7 @@ class MongoDBUserDataSourceTest { // Given coEvery { mockCollection.find() } returns mockFindPublisher coEvery { mockFindPublisher.collect(any()) } coAnswers { - val collector = arg>(0) + val collector = arg>(0) mockUsers.forEach { collector.emit(it) } } @@ -80,7 +80,7 @@ class MongoDBUserDataSourceTest { // Given coEvery { mockCollection.find(any()) } returns mockFindPublisher coEvery { mockFindPublisher.collect(any()) } coAnswers { - val collector = arg>(0) + val collector = arg>(0) collector.emit(mockUser) } @@ -113,7 +113,7 @@ class MongoDBUserDataSourceTest { coEvery { mockCollection.replaceOne( any(), - any(), + any(), any() ) } returns mockUpdateResult @@ -130,7 +130,7 @@ class MongoDBUserDataSourceTest { // Given val mockUpdateResult = mockk() every { mockUpdateResult.wasAcknowledged() } returns false - coEvery { mockCollection.replaceOne(any(), any(), any()) } returns mockUpdateResult + coEvery { mockCollection.replaceOne(any(), any(), any()) } returns mockUpdateResult // When val result = dataSource.update("user1", mockUser) @@ -172,7 +172,7 @@ class MongoDBUserDataSourceTest { // Given val mockInsertOneResult = mockk() every { mockInsertOneResult.wasAcknowledged() } returns true - coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult + coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult // When val result = dataSource.write(mockUser) @@ -186,7 +186,7 @@ class MongoDBUserDataSourceTest { // Given val mockInsertOneResult = mockk() every { mockInsertOneResult.wasAcknowledged() } returns false - coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult + coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult // When val result = dataSource.write(mockUser) @@ -200,7 +200,7 @@ class MongoDBUserDataSourceTest { // Given val mockInsertManyResult = mockk() every { mockInsertManyResult.wasAcknowledged() } returns true - coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult + coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult // When val result = dataSource.writeAll(mockUsers) @@ -214,7 +214,7 @@ class MongoDBUserDataSourceTest { // Given val mockInsertManyResult = mockk() every { mockInsertManyResult.wasAcknowledged() } returns false - coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult + coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult // When val result = dataSource.writeAll(mockUsers) From 04304e6aac38c0d5667f26b4d2bccdf32e907c5a Mon Sep 17 00:00:00 2001 From: Diyar Date: Thu, 15 May 2025 22:42:53 +0300 Subject: [PATCH 16/17] replace domain modal with dto at data package --- .../kotlin/data/mongodb/config/MongoConfig.kt | 2 - .../datasource/MongoDBProjectDataSource.kt | 15 ++-- .../datasource/MongoDBStateDataSource.kt | 15 ++-- .../datasource/MongoDBTaskDataSource.kt | 15 ++-- .../datasource/MongoDBUserDataSource.kt | 1 - src/main/kotlin/di/appModule.kt | 2 +- src/main/kotlin/di/dataModule.kt | 79 +++++-------------- src/main/kotlin/di/repositoryModule.kt | 13 +-- .../MongoDBProjectDataSourceTest.kt | 29 +++---- .../datasource/MongoDBStateDataSourceTest.kt | 30 +++---- .../datasource/MongoDBTaskDataSourceTest.kt | 25 +++--- 11 files changed, 94 insertions(+), 132 deletions(-) diff --git a/src/main/kotlin/data/mongodb/config/MongoConfig.kt b/src/main/kotlin/data/mongodb/config/MongoConfig.kt index b169a22..429082b 100644 --- a/src/main/kotlin/data/mongodb/config/MongoConfig.kt +++ b/src/main/kotlin/data/mongodb/config/MongoConfig.kt @@ -2,8 +2,6 @@ package com.berlin.data.mongodb.config import com.mongodb.ConnectionString import com.mongodb.MongoClientSettings -import com.mongodb.ServerApi -import com.mongodb.ServerApiVersion import com.mongodb.kotlin.client.coroutine.MongoClient import com.mongodb.kotlin.client.coroutine.MongoDatabase import org.bson.codecs.configuration.CodecRegistries diff --git a/src/main/kotlin/data/mongodb/datasource/MongoDBProjectDataSource.kt b/src/main/kotlin/data/mongodb/datasource/MongoDBProjectDataSource.kt index 4322804..97e04e4 100644 --- a/src/main/kotlin/data/mongodb/datasource/MongoDBProjectDataSource.kt +++ b/src/main/kotlin/data/mongodb/datasource/MongoDBProjectDataSource.kt @@ -1,6 +1,7 @@ package com.berlin.data.mongodb.datasource import com.berlin.data.BaseDataSource +import com.berlin.data.dto.ProjectDto import com.berlin.data.mongodb.config.MongoConfig import com.berlin.domain.model.Project import com.mongodb.client.model.Filters @@ -10,25 +11,25 @@ import kotlinx.coroutines.runBlocking class MongoDBProjectDataSource( private val mongoConfig: MongoConfig -) : BaseDataSource { +) : BaseDataSource { private val client = mongoConfig.createMongoClient() private val database = mongoConfig.getDatabase(client) - private val collection = mongoConfig.getCollection(database, "projects") + private val collection = mongoConfig.getCollection(database, "projects") - override fun getAll(): List { + override fun getAll(): List { return runBlocking { collection.find().toList() } } - override fun getById(id: String): Project? { + override fun getById(id: String): ProjectDto? { return runBlocking { collection.find(Filters.eq("_id", id)).firstOrNull() } } - override fun update(id: String, entity: Project): Boolean { + override fun update(id: String, entity: ProjectDto): Boolean { return runBlocking { collection.replaceOne(Filters.eq("_id", id), entity).wasAcknowledged() } @@ -40,13 +41,13 @@ class MongoDBProjectDataSource( } } - override fun write(entity: Project): Boolean { + override fun write(entity: ProjectDto): Boolean { return runBlocking { collection.insertOne(entity).wasAcknowledged() } } - override fun writeAll(entities: List): Boolean { + override fun writeAll(entities: List): Boolean { if (entities.isEmpty()) { return false } diff --git a/src/main/kotlin/data/mongodb/datasource/MongoDBStateDataSource.kt b/src/main/kotlin/data/mongodb/datasource/MongoDBStateDataSource.kt index b173c1f..872d5ba 100644 --- a/src/main/kotlin/data/mongodb/datasource/MongoDBStateDataSource.kt +++ b/src/main/kotlin/data/mongodb/datasource/MongoDBStateDataSource.kt @@ -1,6 +1,7 @@ package com.berlin.data.mongodb.datasource import com.berlin.data.BaseDataSource +import com.berlin.data.dto.TaskStateDto import com.berlin.data.mongodb.config.MongoConfig import com.berlin.domain.model.TaskState import com.mongodb.client.model.Filters @@ -10,25 +11,25 @@ import kotlinx.coroutines.runBlocking class MongoDBStateDataSource( private val mongoConfig: MongoConfig -) : BaseDataSource { +) : BaseDataSource { private val client = mongoConfig.createMongoClient() private val database = mongoConfig.getDatabase(client) - private val collection = mongoConfig.getCollection(database, "states") + private val collection = mongoConfig.getCollection(database, "states") - override fun getAll(): List { + override fun getAll(): List { return runBlocking { collection.find().toList() } } - override fun getById(id: String): TaskState? { + override fun getById(id: String): TaskStateDto? { return runBlocking { collection.find(Filters.eq("_id", id)).firstOrNull() } } - override fun update(id: String, entity: TaskState): Boolean { + override fun update(id: String, entity: TaskStateDto): Boolean { return runBlocking { collection.replaceOne(Filters.eq("_id", id), entity).wasAcknowledged() } @@ -40,13 +41,13 @@ class MongoDBStateDataSource( } } - override fun write(entity: TaskState): Boolean { + override fun write(entity: TaskStateDto): Boolean { return runBlocking { collection.insertOne(entity).wasAcknowledged() } } - override fun writeAll(entities: List): Boolean { + override fun writeAll(entities: List): Boolean { if (entities.isEmpty()) { return false } diff --git a/src/main/kotlin/data/mongodb/datasource/MongoDBTaskDataSource.kt b/src/main/kotlin/data/mongodb/datasource/MongoDBTaskDataSource.kt index 2322cc7..6fb2173 100644 --- a/src/main/kotlin/data/mongodb/datasource/MongoDBTaskDataSource.kt +++ b/src/main/kotlin/data/mongodb/datasource/MongoDBTaskDataSource.kt @@ -1,6 +1,7 @@ package com.berlin.data.mongodb.datasource import com.berlin.data.BaseDataSource +import com.berlin.data.dto.TaskDto import com.berlin.data.mongodb.config.MongoConfig import com.berlin.domain.model.Task import com.mongodb.client.model.Filters @@ -10,25 +11,25 @@ import kotlinx.coroutines.runBlocking class MongoDBTaskDataSource( private val mongoConfig: MongoConfig -) : BaseDataSource { +) : BaseDataSource { private val client = mongoConfig.createMongoClient() private val database = mongoConfig.getDatabase(client) - private val collection = mongoConfig.getCollection(database, "tasks") + private val collection = mongoConfig.getCollection(database, "tasks") - override fun getAll(): List { + override fun getAll(): List { return runBlocking { collection.find().toList() } } - override fun getById(id: String): Task? { + override fun getById(id: String): TaskDto? { return runBlocking { collection.find(Filters.eq("_id", id)).firstOrNull() } } - override fun update(id: String, entity: Task): Boolean { + override fun update(id: String, entity: TaskDto): Boolean { return runBlocking { collection.replaceOne(Filters.eq("_id", id), entity).wasAcknowledged() } @@ -40,13 +41,13 @@ class MongoDBTaskDataSource( } } - override fun write(entity: Task): Boolean { + override fun write(entity: TaskDto): Boolean { return runBlocking { collection.insertOne(entity).wasAcknowledged() } } - override fun writeAll(entities: List): Boolean { + override fun writeAll(entities: List): Boolean { if (entities.isEmpty()) { return false } diff --git a/src/main/kotlin/data/mongodb/datasource/MongoDBUserDataSource.kt b/src/main/kotlin/data/mongodb/datasource/MongoDBUserDataSource.kt index 1b90523..933e43e 100644 --- a/src/main/kotlin/data/mongodb/datasource/MongoDBUserDataSource.kt +++ b/src/main/kotlin/data/mongodb/datasource/MongoDBUserDataSource.kt @@ -3,7 +3,6 @@ package com.berlin.data.mongodb.datasource import com.berlin.data.BaseDataSource import com.berlin.data.dto.UserDto import com.berlin.data.mongodb.config.MongoConfig -import com.berlin.domain.model.user.User import com.mongodb.client.model.Filters import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.toList diff --git a/src/main/kotlin/di/appModule.kt b/src/main/kotlin/di/appModule.kt index 9a4c79e..a58fba1 100644 --- a/src/main/kotlin/di/appModule.kt +++ b/src/main/kotlin/di/appModule.kt @@ -5,5 +5,5 @@ import org.koin.dsl.module val appModule = module { - includes(dataModule, repositoryModule, uiModule, useCaseModule) + includes(dataModule, repositoryModule, useCaseModule, uiModule) } diff --git a/src/main/kotlin/di/dataModule.kt b/src/main/kotlin/di/dataModule.kt index 13a56eb..5d2ff17 100644 --- a/src/main/kotlin/di/dataModule.kt +++ b/src/main/kotlin/di/dataModule.kt @@ -1,7 +1,6 @@ package com.berlin.di import com.berlin.data.BaseDataSource -import com.berlin.data.csv_data_source.schema.* import com.berlin.data.mongodb.datasource.* import com.berlin.data.dto.* import com.berlin.data.mapper.* @@ -21,75 +20,33 @@ import org.koin.dsl.module val dataModule = module { + single { MongoConfig() } + singleOf(::IdGeneratorImplementation) bind IdGenerator::class singleOf(::MD5Hasher) bind HashingString::class - single { AdminUserProvider(get(named("UserDtoDataSource")), get()) } - single { UserCache(get().load()) } - - single>(named("UserSchema")) { - UserSchema( - fileName = "user.csv", header = listOf("User Id", "UserName", "Password", "User Role") - ) - } - single>(named("ProjectSchema")) { - ProjectSchema( - fileName = "project.csv", header = listOf("Project Id", "Project Name", "Description", "States", "Tasks") - ) - } - single>(named("AuditSchema")) { - AuditSchema( - fileName = "audit.csv", header = listOf( - "Audit Id", "Timestamp", "CreatedBy", "Audit Action", "Changes Description", "Entity Type", "Entity Id" - ) - ) - } - single>(named("StateSchema")) { - TaskStateSchema( - fileName = "state.csv", header = listOf("State Id", "Name", "Project Id") - ) - } - single>(named("TaskSchema")) { - TaskSchema( - fileName = "task.csv", header = listOf( - "Task Id", "Project Id", "Title", "Description", "State Id", "Assigned To User Id", "Create By User Id" - ) - ) - } - - single { MongoConfig() } - - single>(named("mongoDbTaskDataSource")) { MongoDBTaskDataSource(get()) } - single>(named("mongoDbStateDataSource")) { MongoDBStateDataSource(get()) } - single>(named("mongoDbProjectDataSource")) { MongoDBProjectDataSource(get()) } - single>(named("mongoDbAuditLogDataSource")) { MongoDBAuditLogDataSource(get()) } - single>(named("mongoDbUserDataSource")) { MongoDBUserDataSource(get()) } + single>(named(DatasourceQualifier.TASK_DATASOURCE)) { MongoDBTaskDataSource(get()) } + single>(named(DatasourceQualifier.TASK_STATE_DATASOURCE)) { MongoDBStateDataSource(get()) } + single>(named(DatasourceQualifier.PROJECT_DATASOURCE)) { MongoDBProjectDataSource(get()) } + single>(named(DatasourceQualifier.AUDIT_LOG_DATASOURCE)) { MongoDBAuditLogDataSource(get()) } + single>(named(DatasourceQualifier.USER_DATASOURCE)) { MongoDBUserDataSource(get()) } -// single>(named("AuditDataSource")){ CsvDataSource("csv_files", get(named("AuditSchema"))) } -// -// single> { CsvDataSource("csv_files", get(named("TaskSchema"))) } -// -// single>(named("UserDataSource")) { CsvDataSource("csv_files", get(named("UserSchema"))) } -// single>(named("ProjectDataSource")) { -// CsvDataSource( -// "csv_files", get(named("ProjectSchema")) -// ) -// } -// single>(named("UserDtoDataSource")) { -// CsvDataSource("csv_files", get(named("UserSchema"))) -// } -// single>(named("TaskDataSource")) { CsvDataSource("csv_files", get(named("TaskSchema"))) } -// single>(named("StateDataSource")) { -// CsvDataSource( -// "csv_files", get(named("StateSchema")) -// ) -// } -// single>(named("AuditDataSource")) { CsvDataSource("csv_files", get(named("AuditSchema"))) } + single { AdminUserProvider(get(named(DatasourceQualifier.USER_DATASOURCE)), get()) } + single { UserCache(get().load()) } single { TaskMapper() }.bind>() single { ProjectMapper() }.bind>() single { TaskStateMapper() }.bind>() single { UserMapper(get()) }.bind>() single { AuditLogMapper() }.bind>() + } +object DatasourceQualifier { + const val TASK_DATASOURCE = "mongoDbTaskDataSource" + const val TASK_STATE_DATASOURCE = "mongoDbStateDataSource" + const val PROJECT_DATASOURCE = "mongoDbProjectDataSource" + const val AUDIT_LOG_DATASOURCE = "mongoDbAuditLogDataSource" + const val USER_DATASOURCE = "mongoDbUserDataSource" + +} \ No newline at end of file diff --git a/src/main/kotlin/di/repositoryModule.kt b/src/main/kotlin/di/repositoryModule.kt index 6c3f64c..55f1833 100644 --- a/src/main/kotlin/di/repositoryModule.kt +++ b/src/main/kotlin/di/repositoryModule.kt @@ -14,31 +14,34 @@ val repositoryModule = module { single { ProjectRepositoryImpl( - get(named("ProjectDataSource")), get() + get(named(DatasourceQualifier.PROJECT_DATASOURCE)), get() ) } single { TaskRepositoryImpl( - get(named("TaskDataSource")), get() + get(named(DatasourceQualifier.TASK_DATASOURCE)), get() ) } single { AuditRepositoryImpl( - get(named("AuditDataSource")), get() + get(named(DatasourceQualifier.AUDIT_LOG_DATASOURCE)), get() ) } single { TaskStateRepositoryImpl( - get(named("StateDataSource")), get(), get(), get() + get(named(DatasourceQualifier.TASK_STATE_DATASOURCE)), + get(named(DatasourceQualifier.TASK_DATASOURCE)), + get(), + get() ) } single { AuthenticationRepositoryImpl( - get(), get(named("UserDataSource")), get() + get(), get(named(DatasourceQualifier.USER_DATASOURCE)), get() ) } } diff --git a/src/test/kotlin/data/mongodb/datasource/MongoDBProjectDataSourceTest.kt b/src/test/kotlin/data/mongodb/datasource/MongoDBProjectDataSourceTest.kt index ed96f3f..1d92876 100644 --- a/src/test/kotlin/data/mongodb/datasource/MongoDBProjectDataSourceTest.kt +++ b/src/test/kotlin/data/mongodb/datasource/MongoDBProjectDataSourceTest.kt @@ -1,5 +1,6 @@ package com.berlin.data.mongodb.datasource +import com.berlin.data.dto.ProjectDto import com.berlin.data.mongodb.config.MongoConfig import com.berlin.domain.model.Project import com.google.common.truth.Truth.assertThat @@ -22,12 +23,12 @@ class MongoDBProjectDataSourceTest { private lateinit var dataSource: MongoDBProjectDataSource private val mockMongoConfig = mockk() - private val mockCollection = mockk>() + private val mockCollection = mockk>() private val mockMongoClient = mockk() private val mockMongoDatabase = mockk() - private val mockFindPublisher = mockk>() + private val mockFindPublisher = mockk>() - private val mockProject = Project( + private val mockProject = ProjectDto( id = "project1", title = "Task Manager", description = "Manage tasks efficiently", @@ -37,7 +38,7 @@ class MongoDBProjectDataSourceTest { private val mockProjects = listOf( mockProject, - Project( + ProjectDto( id = "project2", title = "Marketing Campaign", description = null, @@ -50,10 +51,10 @@ class MongoDBProjectDataSourceTest { fun setUp() { every { mockMongoConfig.createMongoClient() } returns mockMongoClient every { mockMongoConfig.getDatabase(mockMongoClient) } returns mockMongoDatabase - every { mockMongoConfig.getCollection(mockMongoDatabase, "projects") } returns mockCollection + every { mockMongoConfig.getCollection(mockMongoDatabase, "projects") } returns mockCollection coEvery { mockFindPublisher.collect(any()) } coAnswers { - val collector = arg>(0) + val collector = arg>(0) collector.emit(mockProject) } @@ -65,7 +66,7 @@ class MongoDBProjectDataSourceTest { // Given coEvery { mockCollection.find() } returns mockFindPublisher coEvery { mockFindPublisher.collect(any()) } coAnswers { - val collector = arg>(0) + val collector = arg>(0) mockProjects.forEach { collector.emit(it) } } @@ -81,7 +82,7 @@ class MongoDBProjectDataSourceTest { // Given coEvery { mockCollection.find(any()) } returns mockFindPublisher coEvery { mockFindPublisher.collect(any()) } coAnswers { - val collector = arg>(0) + val collector = arg>(0) collector.emit(mockProject) } @@ -114,7 +115,7 @@ class MongoDBProjectDataSourceTest { coEvery { mockCollection.replaceOne( any(), - any(), + any(), any() ) } returns mockUpdateResult @@ -131,7 +132,7 @@ class MongoDBProjectDataSourceTest { // Given val mockUpdateResult = mockk() every { mockUpdateResult.wasAcknowledged() } returns false - coEvery { mockCollection.replaceOne(any(), any(), any()) } returns mockUpdateResult + coEvery { mockCollection.replaceOne(any(), any(), any()) } returns mockUpdateResult // When val result = dataSource.update("project1", mockProject) @@ -173,7 +174,7 @@ class MongoDBProjectDataSourceTest { // Given val mockInsertOneResult = mockk() every { mockInsertOneResult.wasAcknowledged() } returns true - coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult + coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult // When val result = dataSource.write(mockProject) @@ -187,7 +188,7 @@ class MongoDBProjectDataSourceTest { // Given val mockInsertOneResult = mockk() every { mockInsertOneResult.wasAcknowledged() } returns false - coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult + coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult // When val result = dataSource.write(mockProject) @@ -201,7 +202,7 @@ class MongoDBProjectDataSourceTest { // Given val mockInsertManyResult = mockk() every { mockInsertManyResult.wasAcknowledged() } returns true - coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult + coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult // When val result = dataSource.writeAll(mockProjects) @@ -215,7 +216,7 @@ class MongoDBProjectDataSourceTest { // Given val mockInsertManyResult = mockk() every { mockInsertManyResult.wasAcknowledged() } returns false - coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult + coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult // When val result = dataSource.writeAll(mockProjects) diff --git a/src/test/kotlin/data/mongodb/datasource/MongoDBStateDataSourceTest.kt b/src/test/kotlin/data/mongodb/datasource/MongoDBStateDataSourceTest.kt index 90b1d63..3049870 100644 --- a/src/test/kotlin/data/mongodb/datasource/MongoDBStateDataSourceTest.kt +++ b/src/test/kotlin/data/mongodb/datasource/MongoDBStateDataSourceTest.kt @@ -1,7 +1,7 @@ package com.berlin.data.mongodb.datasource +import com.berlin.data.dto.TaskStateDto import com.berlin.data.mongodb.config.MongoConfig -import com.berlin.domain.model.TaskState import com.google.common.truth.Truth.assertThat import io.mockk.coEvery import io.mockk.every @@ -22,12 +22,12 @@ class MongoDBStateDataSourceTest { private lateinit var dataSource: MongoDBStateDataSource private val mockMongoConfig = mockk() - private val mockCollection = mockk>() + private val mockCollection = mockk>() private val mockMongoClient = mockk() private val mockMongoDatabase = mockk() - private val mockFindPublisher = mockk>() + private val mockFindPublisher = mockk>() - private val mockState = TaskState( + private val mockState = TaskStateDto( id = "state1", name = "Todo", projectId = "project1" @@ -35,7 +35,7 @@ class MongoDBStateDataSourceTest { private val mockStates = listOf( mockState, - TaskState( + TaskStateDto( id = "state2", name = "In Progress", projectId = "project1" @@ -46,10 +46,10 @@ class MongoDBStateDataSourceTest { fun setUp() { every { mockMongoConfig.createMongoClient() } returns mockMongoClient every { mockMongoConfig.getDatabase(mockMongoClient) } returns mockMongoDatabase - every { mockMongoConfig.getCollection(mockMongoDatabase, "states") } returns mockCollection + every { mockMongoConfig.getCollection(mockMongoDatabase, "states") } returns mockCollection coEvery { mockFindPublisher.collect(any()) } coAnswers { - val collector = arg>(0) + val collector = arg>(0) collector.emit(mockState) } @@ -61,7 +61,7 @@ class MongoDBStateDataSourceTest { // Given coEvery { mockCollection.find() } returns mockFindPublisher coEvery { mockFindPublisher.collect(any()) } coAnswers { - val collector = arg>(0) + val collector = arg>(0) mockStates.forEach { collector.emit(it) } } @@ -77,7 +77,7 @@ class MongoDBStateDataSourceTest { // Given coEvery { mockCollection.find(any()) } returns mockFindPublisher coEvery { mockFindPublisher.collect(any()) } coAnswers { - val collector = arg>(0) + val collector = arg>(0) collector.emit(mockState) } @@ -110,7 +110,7 @@ class MongoDBStateDataSourceTest { coEvery { mockCollection.replaceOne( any(), - any(), + any(), any() ) } returns mockUpdateResult @@ -127,7 +127,7 @@ class MongoDBStateDataSourceTest { // Given val mockUpdateResult = mockk() every { mockUpdateResult.wasAcknowledged() } returns false - coEvery { mockCollection.replaceOne(any(), any(), any()) } returns mockUpdateResult + coEvery { mockCollection.replaceOne(any(), any(), any()) } returns mockUpdateResult // When val result = dataSource.update("state1", mockState) @@ -169,7 +169,7 @@ class MongoDBStateDataSourceTest { // Given val mockInsertOneResult = mockk() every { mockInsertOneResult.wasAcknowledged() } returns true - coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult + coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult // When val result = dataSource.write(mockState) @@ -183,7 +183,7 @@ class MongoDBStateDataSourceTest { // Given val mockInsertOneResult = mockk() every { mockInsertOneResult.wasAcknowledged() } returns false - coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult + coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult // When val result = dataSource.write(mockState) @@ -197,7 +197,7 @@ class MongoDBStateDataSourceTest { // Given val mockInsertManyResult = mockk() every { mockInsertManyResult.wasAcknowledged() } returns true - coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult + coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult // When val result = dataSource.writeAll(mockStates) @@ -211,7 +211,7 @@ class MongoDBStateDataSourceTest { // Given val mockInsertManyResult = mockk() every { mockInsertManyResult.wasAcknowledged() } returns false - coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult + coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult // When val result = dataSource.writeAll(mockStates) diff --git a/src/test/kotlin/data/mongodb/datasource/MongoDBTaskDataSourceTest.kt b/src/test/kotlin/data/mongodb/datasource/MongoDBTaskDataSourceTest.kt index d1c660f..69c469a 100644 --- a/src/test/kotlin/data/mongodb/datasource/MongoDBTaskDataSourceTest.kt +++ b/src/test/kotlin/data/mongodb/datasource/MongoDBTaskDataSourceTest.kt @@ -1,5 +1,6 @@ package com.berlin.data.mongodb.datasource +import com.berlin.data.dto.TaskDto import com.berlin.data.mongodb.config.MongoConfig import com.berlin.domain.model.Task import com.google.common.truth.Truth.assertThat @@ -22,12 +23,12 @@ class MongoDBTaskDataSourceTest { private lateinit var dataSource: MongoDBTaskDataSource private val mockMongoConfig = mockk() - private val mockCollection = mockk>() + private val mockCollection = mockk>() private val mockMongoClient = mockk() private val mockMongoDatabase = mockk() - private val mockFindPublisher = mockk>() + private val mockFindPublisher = mockk>() - private val mockTask = Task( + private val mockTask = TaskDto( id = "task1", projectId = "project1", title = "Test Task", @@ -39,7 +40,7 @@ class MongoDBTaskDataSourceTest { private val mockTasks = listOf( mockTask, - Task( + TaskDto( id = "task2", projectId = "project1", title = "Another Task", @@ -54,10 +55,10 @@ class MongoDBTaskDataSourceTest { fun setUp() { every { mockMongoConfig.createMongoClient() } returns mockMongoClient every { mockMongoConfig.getDatabase(mockMongoClient) } returns mockMongoDatabase - every { mockMongoConfig.getCollection(mockMongoDatabase, "tasks") } returns mockCollection + every { mockMongoConfig.getCollection(mockMongoDatabase, "tasks") } returns mockCollection coEvery { mockFindPublisher.collect(any()) } coAnswers { - val collector = arg>(0) + val collector = arg>(0) collector.emit(mockTask) } @@ -69,7 +70,7 @@ class MongoDBTaskDataSourceTest { // Given coEvery { mockCollection.find() } returns mockFindPublisher coEvery { mockFindPublisher.collect(any()) } coAnswers { - val collector = arg>(0) + val collector = arg>(0) mockTasks.forEach { collector.emit(it) } } @@ -85,7 +86,7 @@ class MongoDBTaskDataSourceTest { // Given coEvery { mockCollection.find(any()) } returns mockFindPublisher coEvery { mockFindPublisher.collect(any()) } coAnswers { - val collector = arg>(0) + val collector = arg>(0) collector.emit(mockTask) } @@ -177,7 +178,7 @@ class MongoDBTaskDataSourceTest { // Given val mockInsertOneResult = mockk() every { mockInsertOneResult.wasAcknowledged() } returns true - coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult + coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult // When val result = dataSource.write(mockTask) @@ -191,7 +192,7 @@ class MongoDBTaskDataSourceTest { // Given val mockInsertOneResult = mockk() every { mockInsertOneResult.wasAcknowledged() } returns false - coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult + coEvery { mockCollection.insertOne(any(), any()) } returns mockInsertOneResult // When val result = dataSource.write(mockTask) @@ -205,7 +206,7 @@ class MongoDBTaskDataSourceTest { // Given val mockInsertManyResult = mockk() every { mockInsertManyResult.wasAcknowledged() } returns true - coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult + coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult // When val result = dataSource.writeAll(mockTasks) @@ -219,7 +220,7 @@ class MongoDBTaskDataSourceTest { // Given val mockInsertManyResult = mockk() every { mockInsertManyResult.wasAcknowledged() } returns false - coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult + coEvery { mockCollection.insertMany(any>(), any()) } returns mockInsertManyResult // When val result = dataSource.writeAll(mockTasks) From 2baa2bbe1f900ba0787eeef7ec3f849dd0312c19 Mon Sep 17 00:00:00 2001 From: Marwan Qashwa Date: Sat, 17 May 2025 00:36:27 +0300 Subject: [PATCH 17/17] solve koin edit user dto user name --- src/main/kotlin/data/dto/UserDto.kt | 2 +- src/main/kotlin/di/dataModule.kt | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/data/dto/UserDto.kt b/src/main/kotlin/data/dto/UserDto.kt index 9410e14..5908d1b 100644 --- a/src/main/kotlin/data/dto/UserDto.kt +++ b/src/main/kotlin/data/dto/UserDto.kt @@ -6,7 +6,7 @@ import org.bson.codecs.pojo.annotations.BsonProperty data class UserDto( @BsonId val id: String, - @BsonProperty("user_name") val userName: String, + @BsonProperty("username") val userName: String, @BsonProperty("password") val password: String, @BsonProperty("role") val role: User.UserRole ) \ No newline at end of file diff --git a/src/main/kotlin/di/dataModule.kt b/src/main/kotlin/di/dataModule.kt index 5d2ff17..f6ae7d7 100644 --- a/src/main/kotlin/di/dataModule.kt +++ b/src/main/kotlin/di/dataModule.kt @@ -20,6 +20,7 @@ import org.koin.dsl.module val dataModule = module { + single { MongoConfig() } singleOf(::IdGeneratorImplementation) bind IdGenerator::class @@ -37,7 +38,7 @@ val dataModule = module { single { TaskMapper() }.bind>() single { ProjectMapper() }.bind>() single { TaskStateMapper() }.bind>() - single { UserMapper(get()) }.bind>() + single { UserMapper(get(named(DatasourceQualifier.USER_DATASOURCE)))}.bind>() single { AuditLogMapper() }.bind>() }