Skip to content

Commit

Permalink
[refactor/remove-rxjava] RxJava -> Kotlin Coroutines로 로직 리팩토링 (#338)
Browse files Browse the repository at this point in the history
* [remove-rxjava] User 쪽 rxjava 사용처 없애기

* [remove-rxjava] NoticePagingSource에서 rxjava 사용처 없애기

* [remove-rxjava] EditSubscription쪽 코루틴 적용

* [remove-rxjava] Notice쪽 rxjava 제거

* [remove-rxjava] Push 쪽 코루틴 적용

* [remove-rxjava] 필요없는 코드 삭제(data:push)

* [remove-rxjava] Delete RxJava Completely

* Update Test

* fix: 테스트 fail 이슈 수정

---------

Co-authored-by: Wooyoung Myung <[email protected]>
  • Loading branch information
l2hyunwoo and mwy3055 committed Sep 27, 2024
1 parent 8de300c commit 894f3ce
Show file tree
Hide file tree
Showing 57 changed files with 462 additions and 759 deletions.
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@
- Navigation w/ Compose

## Async
- Kotlin Coroutines (main)
- RxJava (sub)
- Kotlin Coroutines

## Network Requests
- Retrofit2
Expand Down
5 changes: 0 additions & 5 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,6 @@
-keep class com.ku_stacks.ku_ring.local.room.** { *; }
# domain classes
-keep class com.ku_stacks.ku_ring.domain.** { *; }
# rxjava classes
-keep class io.reactivex.rxjava3.core.Flowable
-keep class io.reactivex.rxjava3.core.Maybe
-keep class io.reactivex.rxjava3.core.Observable
-keep class io.reactivex.rxjava3.core.Single
# Keep generic signature of Call, Response (R8 full mode strips signatures from non-kept items).
-keep interface retrofit2.Call
-keep class retrofit2.Response
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ class KotlinPlugin : Plugin<Project> {
implementation(libs.library("kotlinx-coroutines-core"))
implementation(libs.library("kotlinx-coroutines-android"))
implementation(libs.library("kotlinx-coroutines-reactive"))
implementation(libs.library("kotlinx-coroutines-rxjava3"))

implementation(libs.library("kotlinx-serialization"))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ class RetrofitPlugin: Plugin<Project> {
implementationPlatform(libs.library("retrofit-bom"))
implementation(libs.library("retrofit"))
implementation(libs.library("retrofit-converter-gson"))
implementation(libs.library("retrofit-adapter-rxjava3"))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ class RoomPlugin : Plugin<Project> {
dependencies {
implementation(libs.library("androidx-room-ktx"))
implementation(libs.library("androidx-room-runtime"))
implementation(libs.library("androidx-room-rxjava3"))
ksp(libs.library("androidx-room-compiler"))
testImplementation(libs.library("androidx-room-testing"))
}
Expand Down
1 change: 0 additions & 1 deletion core/testUtil/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,5 @@ android {

dependencies {
implementation(libs.androidx.lifecycle.livedata)
implementation(libs.bundles.rxjava)
implementation(libs.bundles.unit.test)
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import androidx.work.WorkerParameters
import com.ku_stacks.ku_ring.user.repository.UserRepository
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import timber.log.Timber

@HiltWorker
class RegisterUserWork @AssistedInject constructor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@ import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.ku_stacks.ku_ring.local.entity.BlackUserEntity
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Single
import kotlinx.coroutines.flow.Flow

@Dao
interface BlackUserDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
fun blockUser(user: BlackUserEntity): Completable
suspend fun blockUser(user: BlackUserEntity)

@Query("SELECT * FROM BlackUserEntity")
fun getBlackList(): Single<List<BlackUserEntity>>
fun getBlackList(): Flow<List<BlackUserEntity>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,21 @@ import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.ku_stacks.ku_ring.local.entity.NoticeEntity
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.coroutines.flow.Flow

@Dao
interface NoticeDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertNoticeAsOld(notice: NoticeEntity): Completable
suspend fun insertNoticeAsOld(notice: NoticeEntity)

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertNotice(notice: NoticeEntity)

@Query("SELECT * FROM NoticeEntity ORDER BY isImportant")
fun getOldNoticeList(): Single<List<NoticeEntity>>
fun getOldNoticeList(): Flow<List<NoticeEntity>>

@Query("SELECT articleId FROM NoticeEntity WHERE isRead = :value ORDER BY isImportant")
fun getReadNoticeList(value: Boolean): Flowable<List<String>>
fun getReadNoticeList(value: Boolean): Flow<List<String>>

@Query("SELECT * FROM NoticeEntity WHERE isSaved = :isSaved ORDER BY isImportant")
fun getNoticesBySaved(isSaved: Boolean): Flow<List<NoticeEntity>>
Expand All @@ -33,10 +29,10 @@ interface NoticeDao {
fun getSavedNoticeList(isSaved: Boolean): List<NoticeEntity>

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun updateNotice(notice: NoticeEntity): Completable
suspend fun updateNotice(notice: NoticeEntity)

@Query("UPDATE NoticeEntity SET isRead = 1 WHERE articleId = :articleId AND category = :category")
fun updateNoticeAsRead(articleId: String, category: String): Completable
suspend fun updateNoticeAsRead(articleId: String, category: String)

@Query("UPDATE NoticeEntity SET isSaved = :isSaved WHERE articleId = :articleId AND category = :category")
suspend fun updateNoticeSaveState(articleId: String, category: String, isSaved: Boolean)
Expand All @@ -48,10 +44,10 @@ interface NoticeDao {
suspend fun clearSavedNotices()

@Query("SELECT COUNT(*) FROM NoticeEntity WHERE isRead = :value and articleId = :id")
fun getCountOfReadNotice(value: Boolean, id: String): Single<Int>
suspend fun getCountOfReadNotice(value: Boolean, id: String): Int

fun isReadNotice(id: String): Boolean {
return getCountOfReadNotice(true, id).subscribeOn(Schedulers.io()).blockingGet() > 0
suspend fun isReadNotice(id: String): Boolean {
return getCountOfReadNotice(true, id) > 0
}

// 학과별 공지 쿼리
Expand All @@ -69,5 +65,5 @@ interface NoticeDao {

//not using now
@Query("DELETE FROM NoticeEntity")
fun deleteAllNoticeRecord(): Completable
suspend fun deleteAllNoticeRecord()
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
package com.ku_stacks.ku_ring.local.room

import androidx.room.*
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.ku_stacks.ku_ring.local.entity.PushEntity
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Flowable
import kotlinx.coroutines.flow.Flow

@Dao
interface PushDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertNotification(pushEntity: PushEntity)

@Query("UPDATE PushEntity SET isNew = :value WHERE articleId = :articleId and isNew = not :value")
fun updateNotificationAsOld(articleId: String, value: Boolean): Completable
suspend fun updateNotificationAsOld(articleId: String, value: Boolean)

@Query("SELECT * FROM PushEntity ORDER BY postedDate DESC, receivedDate DESC")
fun getNotificationList(): Flowable<List<PushEntity>>
fun getNotificationList(): Flow<List<PushEntity>>

@Query("SELECT COUNT(articleId) FROM PushEntity WHERE isNew = :value")
fun getNotificationCount(value: Boolean): Flowable<Int>
fun getNotificationCount(value: Boolean): Flow<Int>

@Query("DELETE FROM PushEntity WHERE articleId = :articleId")
fun deleteNotification(articleId: String): Completable
suspend fun deleteNotification(articleId: String)

//not using now
@Query("DELETE FROM PushEntity")
fun deleteAllNotification(): Completable
suspend fun deleteAllNotification()
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,81 +34,81 @@ class NoticeDaoTest : LocalDbAbstract() {
}

@Test
fun `insertNoticeAsOld and getOldNotice Test`() {
fun `insertNoticeAsOld and getOldNotice Test`() = runTest {
// given
val noticeMock = LocalTestUtil.fakeNoticeEntity()
noticeDao.insertNoticeAsOld(noticeMock).blockingSubscribe()
noticeDao.insertNoticeAsOld(noticeMock)

// when
val noticeFromDB = noticeDao.getOldNoticeList().blockingGet()[0]
val noticeFromDB = noticeDao.getOldNoticeList().first().first()

// then : 생성하고 insert 한 mock 와 불러온 데이터가 일치
assertThat(noticeMock, `is`(noticeFromDB))
}

@Test
fun `updateNoticeAsOld and getOldNoticeList Test`() {
fun `updateNoticeAsOld and getOldNoticeList Test`() = runTest {
// given
val noticeMock = LocalTestUtil.fakeNoticeEntity()
noticeDao.insertNoticeAsOld(noticeMock).blockingSubscribe()
noticeDao.insertNoticeAsOld(noticeMock)

// when
val readNoticeMock = readNoticeMock()
noticeDao.updateNotice(readNoticeMock).blockingSubscribe()
noticeDao.updateNotice(readNoticeMock)

// then : insert 후에 update 해도 데이터 수는 1개, 불러온 데이터가 mock 와 일치
val noticeFromDB = noticeDao.getOldNoticeList().blockingGet()
val noticeFromDB = noticeDao.getOldNoticeList().first()
assertThat(noticeFromDB.size, `is`(1))
assertThat(noticeFromDB[0].toString(), `is`(readNoticeMock.toString()))
}

@Test
fun `updateNotice and getCountOfReadNoticeTest`() {
fun `updateNotice and getCountOfReadNoticeTest`() = runTest {
// given
val noticeMock = LocalTestUtil.fakeNoticeEntity()
noticeDao.insertNoticeAsOld(noticeMock).blockingSubscribe()
noticeDao.insertNoticeAsOld(noticeMock)

// when
val readNoticeMock = readNoticeMock()
noticeDao.updateNotice(readNoticeMock).blockingSubscribe()
noticeDao.updateNotice(readNoticeMock)

// then : insert 후에 isRead 를 true 로 update 하면 읽은 공지 데이터가 1개
val countForReadNotice =
noticeDao.getCountOfReadNotice(true, noticeMock.articleId).blockingGet()
noticeDao.getCountOfReadNotice(true, noticeMock.articleId)
assertThat(countForReadNotice, `is`(1))
}

@Test
fun `updateNotice and isReadNotice Test`() {
fun `updateNotice and isReadNotice Test`() = runTest {
// given
val noticeMock = LocalTestUtil.fakeNoticeEntity()
noticeDao.insertNoticeAsOld(noticeMock).blockingSubscribe()
noticeDao.insertNoticeAsOld(noticeMock)

// when
val readNoticeMock = readNoticeMock()
noticeDao.updateNotice(readNoticeMock).blockingSubscribe()
noticeDao.updateNotice(readNoticeMock)

// then : isRead 를 true 로 update 한 공지는 불러왔을 때 isRead 값이 true
assertThat(noticeDao.isReadNotice(noticeMock.articleId), `is`(true))
}

@Test
fun `updateNotice and getReadNoticeList Test`() {
fun `updateNotice and getReadNoticeList Test`() = runTest {
// given
val noticeMock = LocalTestUtil.fakeNoticeEntity()
noticeDao.insertNoticeAsOld(noticeMock).blockingSubscribe()
noticeDao.insertNoticeAsOld(noticeMock)

// when
val sizeOfNotReadNotice = noticeDao.getReadNoticeList(true).blockingFirst().size
val sizeOfNotReadNotice = noticeDao.getReadNoticeList(true).first().size
// then : 공지를 읽기 전엔 isRead 가 true 인 데이터 0개
assertThat(sizeOfNotReadNotice, `is`(0))

// given
val readNoticeMock = readNoticeMock()
noticeDao.updateNotice(readNoticeMock).blockingSubscribe()
noticeDao.updateNotice(readNoticeMock)

// when
val sizeOfReadNotice = noticeDao.getReadNoticeList(true).blockingFirst().size
val sizeOfReadNotice = noticeDao.getReadNoticeList(true).first().size
// then : 공지를 읽은 후엔 isRead 가 true 인 데이터 1개
assertThat(sizeOfReadNotice, `is`(1))
}
Expand All @@ -117,22 +117,22 @@ class NoticeDaoTest : LocalDbAbstract() {
fun `updateNoticeSaveState and getSavedNotices Test`() = runTest {
// given
val notice = LocalTestUtil.fakeNoticeEntity()
noticeDao.insertNoticeAsOld(notice).blockingSubscribe()
noticeDao.insertNoticeAsOld(notice)

// when
noticeDao.updateNoticeSaveState(notice.articleId, notice.category, true)

// then
val savedNotice = notice.copy(isSaved = true)
val noticeFromDB = noticeDao.getNoticesBySaved(true).first()[0]
val noticeFromDB = noticeDao.getNoticesBySaved(true).first().first()
assertThat(noticeFromDB, `is`(savedNotice))
}

@Test
fun `updateNoticeAsReadOnStorage and getSavedNotices Test`() = runTest {
// given
val notice = LocalTestUtil.fakeDepartmentNoticeEntity()
noticeDao.insertNoticeAsOld(notice).blockingSubscribe()
noticeDao.insertNoticeAsOld(notice)

// when
noticeDao.updateNoticeSaveState(notice.articleId, notice.category, true)
Expand All @@ -154,7 +154,7 @@ class NoticeDaoTest : LocalDbAbstract() {
noticeDao.updateNoticeAsRead(
articleId = departmentNotice.articleId,
category = departmentNotice.category
).blockingAwait()
)

// then
val departmentNoticePage = noticeDao.getDepartmentNotices(departmentNotice.department)
Expand Down
Loading

0 comments on commit 894f3ce

Please sign in to comment.