Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/workflows/ci_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,19 @@ jobs:
echo "naver.client.id=$NAVER_CLIENT_ID" >> local.properties
echo "naver.client.secret=$NAVER_CLIENT_SECRET" >> local.properties

# Unit Test 실행
- name: Run Unit Tests
run: ./gradlew testDebugUnitTest

# 테스트 결과 저장
- name: Upload Test Results
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results
path: app/build/reports/tests/testDebugUnitTest
retention-days: 7

- name: Build Debug APK
run: ./gradlew assembleDebug # 디버그 APK 빌드 명령어 실행

Expand Down
19 changes: 14 additions & 5 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,20 @@ dependencies {
implementation(libs.lottie.compose)
// preferences datastore
implementation(libs.datastore.preferences)
// coroutines
implementation(libs.coroutines.core)
implementation(libs.coroutines.android)

// Unit Test
testImplementation(libs.kotest.runner)
testImplementation(libs.kotest.assertion)
testImplementation(libs.mockk)
testImplementation(libs.kotlinx.coroutines.test)

testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)
}

// Kotest 사용을 위한 JUnit5 설정
tasks.withType<Test> {
useJUnitPlatform()
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.min.dnapp.data.repository

import android.net.http.HttpEngine
import android.util.Log
import com.min.dnapp.data.remote.LocalSearchResponse
import com.min.dnapp.data.remote.LocalSearchService
import com.min.dnapp.domain.model.LocalPlace
Expand All @@ -21,7 +19,7 @@ class LocalSearchRepositoryImpl @Inject constructor(
) : LocalSearchRepository {
override fun searchPlaces(query: String): Flow<Resource<List<LocalPlace>>> = flow {
// 로딩 상태 방출
emit(Resource.Loading())
emit(Resource.Loading)

try {
val response: LocalSearchResponse = api.search(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class FindViewModel @Inject constructor(
// 공유된 기록 목록 가져오기
try {
val sharedRecords = getSharedRecordUseCase()
Log.d("record", "loaFindData - sharedRecords: $sharedRecords")
// Log.d("record", "loaFindData - sharedRecords: $sharedRecords")
val successState = FindUiState.Success(
records = sharedRecords
)
Expand All @@ -40,7 +40,7 @@ class FindViewModel @Inject constructor(
_uiState.value = FindUiState.Success(
records = emptyList()
)
Log.e("record", "기록 목록 조회 실패", e)
// Log.e("record", "기록 목록 조회 실패", e)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class HomeViewModel @Inject constructor(
val successState: HomeUiState.Success
try {
val user = getUserDataUseCase(uid)
Log.d("home", "loadHomeData - user: $user")
// Log.d("home", "loadHomeData - user: $user")

successState = mapUserToHomeUiState(user)

Expand All @@ -58,7 +58,7 @@ class HomeViewModel @Inject constructor(
// 여행기록 정보 로드 및 상태 업데이트
try {
val userRecords = getUserRecordUseCase()
Log.d("home", "loadHomeData - userRecords: $userRecords")
// Log.d("home", "loadHomeData - userRecords: $userRecords")
val finalSuccessState = successState.copy(
records = userRecords
)
Expand All @@ -67,7 +67,7 @@ class HomeViewModel @Inject constructor(
_uiState.value = successState.copy(
records = emptyList()
)
Log.e("home", "기록 정보 로드 실패", e)
// Log.e("home", "기록 정보 로드 실패", e)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ class RecordWriteViewModel @Inject constructor(
private val _completeSaveRecord = Channel<Unit>()
val completeSaveRecordFlow = _completeSaveRecord.receiveAsFlow()

private val _snackbarMessage = MutableSharedFlow<SnackbarMessage>()
// 최근에 발행된 메시지 1개 저장
private val _snackbarMessage = MutableSharedFlow<SnackbarMessage>(replay = 1)
val snackbarMessage = _snackbarMessage.asSharedFlow()

// 이전 검색 작업을 취소하기 위한 Job
Expand All @@ -57,15 +58,15 @@ class RecordWriteViewModel @Inject constructor(
*/
fun updateTitle(newText: String) {
_uiState.value = _uiState.value.copy(recordTitle = newText)
Log.d("write", "updateTitle - newText : $newText")
// Log.d("write", "updateTitle - newText : $newText")
}

/**
* 내용 - textField의 입력 값 업데이트
*/
fun updateContent(newText: String) {
_uiState.value = _uiState.value.copy(recordContent = newText)
Log.d("write", "updateContent - newText : $newText")
// Log.d("write", "updateContent - newText : $newText")
}

/**
Expand All @@ -83,15 +84,15 @@ class RecordWriteViewModel @Inject constructor(
*/
fun updateEmotion(emotionType: EmotionType) {
_uiState.value = _uiState.value.copy(selectedEmotion = emotionType)
Log.d("write", "selectEmotion - emotionType : $emotionType")
// Log.d("write", "selectEmotion - emotionType : $emotionType")
}

/**
* 선택된 날씨 업데이트
*/
fun updateWeather(weatherType: WeatherType) {
_uiState.value = _uiState.value.copy(selectedWeather = weatherType)
Log.d("write", "selectWeather - weatherType : $weatherType")
// Log.d("write", "selectWeather - weatherType : $weatherType")
}

/**
Expand All @@ -104,7 +105,7 @@ class RecordWriteViewModel @Inject constructor(
if (newQuery.isBlank()) {
// 진행중인 검색 작업 취소
searchJob?.cancel()
Log.d("naver", "updateQuery - newQuery blank")
// Log.d("naver", "updateQuery - newQuery blank")
}
}

Expand All @@ -116,7 +117,7 @@ class RecordWriteViewModel @Inject constructor(

// 검색어가 빈 경우
if (currentQuery.isBlank()) {
Log.d("naver", "searchPlace - newQuery blank")
// Log.d("naver", "searchPlace - newQuery blank")
return
}

Expand All @@ -131,28 +132,28 @@ class RecordWriteViewModel @Inject constructor(
// 로딩 시작
_uiState.value = _uiState.value.copy(searchState = _uiState.value.searchState.copy(
isLoading = true,
places = result.data ?: emptyList(),
places = emptyList(),
error = null
))
Log.d("naver", "search for $currentQuery : Loading...")
// Log.d("naver", "search for $currentQuery : Loading...")
}
is Resource.Success -> {
// 성공
_uiState.value = _uiState.value.copy(searchState = _uiState.value.searchState.copy(
isLoading = false,
places = result.data ?: emptyList(),
places = result.data,
error = null
))
Log.d("naver", "search success : ${result.data?.size} 개")
// Log.d("naver", "search success : ${result.data?.size} 개")
}
is Resource.Error -> {
// 에러
_uiState.value = _uiState.value.copy(searchState = _uiState.value.searchState.copy(
isLoading = false,
places = result.data ?: emptyList(),
error = result.message ?: "알 수 없는 에러 발생"
places = emptyList(),
error = result.message
))
Log.e("naver", "search error : ${result.message}")
// Log.e("naver", "search error : ${result.message}")
}
}
}
Expand All @@ -173,7 +174,7 @@ class RecordWriteViewModel @Inject constructor(
places = emptyList(),
error = null
))
Log.d("naver", "result cleared")
// Log.d("naver", "result cleared")
}

/**
Expand All @@ -188,15 +189,15 @@ class RecordWriteViewModel @Inject constructor(
*/
fun updateOverseas(newText: String) {
_uiState.value = _uiState.value.copy(overseasPlace = newText)
Log.d("write", "updateOverseas - newText : $newText")
// Log.d("write", "updateOverseas - newText : $newText")
}

/**
* 공유여부 설정 상태 업데이트
*/
fun updateShare(newChecked: Boolean) {
_uiState.value = _uiState.value.copy(isShareChecked = newChecked)
Log.d("write", "updateShare - newChecked : $newChecked")
// Log.d("write", "updateShare - newChecked : $newChecked")
}

/**
Expand All @@ -218,7 +219,7 @@ class RecordWriteViewModel @Inject constructor(
*/
fun onPhotoSelected(uri: Uri?) {
_uiState.value = _uiState.value.copy(selectedImageUri = uri)
Log.d("write", "onPhotoSelected - uri : $uri")
// Log.d("write", "onPhotoSelected - uri : $uri")
}

/**
Expand Down Expand Up @@ -249,7 +250,7 @@ class RecordWriteViewModel @Inject constructor(
_completeSaveRecord.send(Unit)
}.onFailure { exception ->
// 저장 실패
Log.e("write", "saveRecord - exception : $exception")
// Log.e("write", "saveRecord - exception : $exception")
}

_uiState.update { it.copy(isSaving = false) }
Expand Down
10 changes: 5 additions & 5 deletions app/src/main/java/com/min/dnapp/util/Resource.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.min.dnapp.util

sealed class Resource<T>(val data: T? = null, val message: String? = null) {
class Success<T>(data: T) : Resource<T>(data)
class Error<T>(message: String, data: T? = null) : Resource<T>(data, message)
class Loading<T>(data: T? = null) : Resource<T>(data)
}
sealed class Resource<out T> {
data class Success<out T>(val data: T) : Resource<T>()
data class Error(val message: String) : Resource<Nothing>()
data object Loading : Resource<Nothing>()
}
17 changes: 0 additions & 17 deletions app/src/test/java/com/min/dnapp/ExampleUnitTest.kt

This file was deleted.

Loading