Skip to content

[쇼핑 주문 3, 4단계] 공백 미션 제출합니다. #121

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 69 commits into from
Jun 10, 2025
Merged
Show file tree
Hide file tree
Changes from 57 commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
01d94bc
docs: 3,4단계 기능 명세 추가
junseo511 Jun 2, 2025
321781d
refactor: Data 패키지 코루틴 적용
junseo511 Jun 3, 2025
a1934bc
refactor: Domain 패키지 코루틴 적용
junseo511 Jun 3, 2025
f0d5393
refactor: UI 패키지 코루틴 적용
junseo511 Jun 3, 2025
cfaa6d0
refactor: RepositoryModule import 가독성 개선
junseo511 Jun 3, 2025
11a2139
refactor: 사용자 정보 조회 로직 이동
junseo511 Jun 3, 2025
88c6daa
feat: 주문 완료 문구 출력
junseo511 Jun 3, 2025
a20a756
refactor: 불필요한 runCatching 제거
junseo511 Jun 3, 2025
6fd744e
refactor: 상품 목록 변수명 구체화
junseo511 Jun 3, 2025
7d04bdd
refactor: 불필요한 줄바꿈 정리
junseo511 Jun 3, 2025
461f61d
feat: 쿠폰 목록 조회 서버 연결
junseo511 Jun 3, 2025
cb6eb3d
feat: 쿠폰 목록을 제외한 결제 UI 구현
junseo511 Jun 4, 2025
56ccd2a
fix: API 명세에 맞는 쿠폰 정보로 수정
junseo511 Jun 4, 2025
ca11a16
feat: 쿠폰 목록 UI 구현
junseo511 Jun 4, 2025
549fe17
docs: 구현된 사항에 따른 리드미 업데이트
junseo511 Jun 4, 2025
f722bc6
refactor: 네트워크 오류 로그 추가
junseo511 Jun 4, 2025
93a5e60
refactor: 쿠폰 스크롤 영역 제한
junseo511 Jun 4, 2025
3f109af
feat: 결제 화면 이동 구현
junseo511 Jun 5, 2025
3c014ef
refactor: 뷰홀더 내부 클릭 리스너 주입 위치 변경
junseo511 Jun 5, 2025
1b45551
refactor: 상품 선택 로직 역할 재분배
junseo511 Jun 5, 2025
076d16c
refactor: 상품 주문 장바구니 ID 조회 로직 개선
junseo511 Jun 5, 2025
2cf4942
feat: 추상화된 상품 쿠폰 구현
junseo511 Jun 5, 2025
d68a7b3
feat: 가격 정보 출력 구현
junseo511 Jun 5, 2025
0f054e4
feat: 각 쿠폰 로직 구현
junseo511 Jun 5, 2025
2d5477a
feat: 상품 주문 구현
junseo511 Jun 5, 2025
f934066
refactor: 장바구니 화면 UI 핸들링 통합
junseo511 Jun 6, 2025
e61c077
refactor: 상품 목록 화면 UI 핸들링 통합
junseo511 Jun 6, 2025
6d6bd5a
refactor: 결제 화면 UI 핸들링 통합
junseo511 Jun 6, 2025
ec96f89
refactor: 상품 상세 화면 UI 핸들링 통합
junseo511 Jun 6, 2025
3c32906
refactor: 가독성을 위한 줄바꿈 제거
junseo511 Jun 6, 2025
9813c99
refactor: 상수화된 변수 활용
junseo511 Jun 6, 2025
d032bd5
refactor: UI 상태 동기화 및 백그라운드 작업 이전
junseo511 Jun 6, 2025
091dfea
feat: 만료된 쿠폰 필터링 기능 추가
junseo511 Jun 6, 2025
6e00386
docs: 구현된 사항에 따른 리드미 업데이트
junseo511 Jun 6, 2025
597f66c
refactor: HistoryDaoTest 코루틴 적용
junseo511 Jun 6, 2025
cd81d48
test: CouponsTest 추가
junseo511 Jun 6, 2025
3b853c5
test: PageTest 추가
junseo511 Jun 6, 2025
8b99ed3
test: PriceTest 추가
junseo511 Jun 6, 2025
0a1ef45
test: ProductTest 추가
junseo511 Jun 6, 2025
5753097
test: ProductsTest 추가
junseo511 Jun 6, 2025
c065dea
refactor: 유효하지 않은 테스트 삭제
junseo511 Jun 6, 2025
5cdf22a
feat: 단건 상품 조회 API 적용
junseo511 Jun 6, 2025
2d01081
feat: 쿠폰 사용 가능 여부에 따른 필터링 적용
junseo511 Jun 6, 2025
60f2750
test: ProductDetailViewModelTest 추가
junseo511 Jun 6, 2025
fa9f5b7
test: CatalogViewModelTest 추가
junseo511 Jun 6, 2025
0eb4fd9
test: CartViewModelTest 추가
junseo511 Jun 6, 2025
a93e498
test: PaymentViewModelTest 추가
junseo511 Jun 6, 2025
efc90fa
refactor: 불필요한 클래스 선언 제거
junseo511 Jun 6, 2025
ee5aead
fix: 배송비가 중복 할인되는 오류 해결
junseo511 Jun 6, 2025
284a0c3
fix: UI가 즉각적으로 반영되지 않는 오류 해결
junseo511 Jun 6, 2025
6e5c4a0
fix: 장바구니가 다음 화면으로 이동해도 종료되지 않는 오류 해결
junseo511 Jun 6, 2025
1f097c2
refactor: DI 패키지 내부 객체명 변경
junseo511 Jun 6, 2025
30d53a7
refactor: 중복되는 페이징 객체 외부로 분리
junseo511 Jun 6, 2025
2496442
refactor: 각 Activity에 parentActivityName 속성 지정
junseo511 Jun 6, 2025
1657bc6
refactor: 쿠폰 조회 메서드 파라미터 이동
junseo511 Jun 6, 2025
c5a7519
refactor: 불필요한 람다식 제거
junseo511 Jun 6, 2025
9616287
fix: 쿠폰이 제대로 로딩되지 않는 오류 해결
junseo511 Jun 6, 2025
6d9e455
refactor: 쿠폰 타입 변환 로직 이동
junseo511 Jun 7, 2025
44f15b7
fix: 쿠폰 테스트 오류 해결
junseo511 Jun 7, 2025
b173040
docs: 리드미에 해당 미션별 키워드 추가
junseo511 Jun 7, 2025
99bc4f2
test: FixedDiscountCouponTest 추가
junseo511 Jun 7, 2025
3063b27
test: FreeShippingCouponTest 추가
junseo511 Jun 7, 2025
2f35dbe
test: PercentageDiscountCouponTest 추가
junseo511 Jun 7, 2025
ebdf561
test: QuantityBonusCouponTest 추가
junseo511 Jun 7, 2025
a3fe4ac
refactor: 테스트명 구체적으로 명시
junseo511 Jun 7, 2025
ac19953
refactor: uiState -> uiModel 네이밍 변경
junseo511 Jun 9, 2025
3561772
refactor: advanceUntilIdle 함수 추가를 통한 코루틴 실행 보장
junseo511 Jun 9, 2025
5ddd01f
refactor: Repository 상의 withContext 사용 제거
junseo511 Jun 9, 2025
cac48bb
refactor: CoroutineExceptionHandler 적용
junseo511 Jun 10, 2025
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
59 changes: 59 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,55 @@
- 서버 통신을 위한 JSON 직렬화 라이브러리를 선택하고 PR에 선택 이유를 남긴다.
- 기능 요구 사항에 대한 테스트를 작성해야 한다.

## 🧱 기능 요구 사항 (3,4단계)

### 📕 기획 명세
Comment on lines +26 to +28
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기획명세에 대한 정의와 README 작성 너무 좋네요~
추가적으로 한가지팁을 드려보자면, 단계별 나왔던 키워드를 살짝 남겨둔다면 추후에 해당 내용을 보았을 때 아~ 이때 이런 키워드가 나왔었지 이렇게 좀 더 기억에 남을 수도 있겠군요💪

Copy link
Author

@junseo511 junseo511 Jun 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기획명세에 대한 정의와 README 작성 너무 좋네요~ 추가적으로 한가지팁을 드려보자면, 단계별 나왔던 키워드를 살짝 남겨둔다면 추후에 해당 내용을 보았을 때 아~ 이때 이런 키워드가 나왔었지 이렇게 좀 더 기억에 남을 수도 있겠군요💪

한 번 열심히 리마인드 해보겠습니다~~~ 👍
b173040


- Coroutines을 적용하여 비동기 요청을 리팩터링한다.
- 단, Flow를 사용하진 않는다.
- 장바구니에 담긴 상품을 최종 주문할 수 있다.
- 배송비는 기본 3,000원이다.
- 결제 화면에서 적용 가능한 쿠폰을 조회하고 적용할 수 있다.
- 쿠폰은 1개만 적용 가능하다.
- 결제 수단은 구현하지 않는다.
- 결제하기 버튼을 누르면 바로 최종 주문이 완료된다.
- 최종 주문이 완료되면 상품 목록으로 이동과 함께 주문 완료 토스트 메시지를 노출한다.

### 📗 API 명세

- 최종 주문이 완료되면 장바구니에서 주문된 상품이 초기화되는 것이 정상이다.
- 쿠폰을 사용해도 사라지지 않는 것이 정상이다.

### 📘 이벤트 명세

- 다음과 같은 4가지 유형의 쿠폰을 사용할 수 있어야 한다. (쿠폰은 데이터는 API 문서에서 확인할 수 있다) 각 쿠폰의 특성을 잘 이해하고, 해당 쿠폰을 적용했을 때의 할인 효과를 정확히 계산할 수 있도록 구현한다.

1. 5,000원 할인 쿠폰
- 쿠폰 코드: FIXED5000
- 할인 금액: 5,000원
- 최소 주문 금액: 100,000원
- 만료일: 2024년 11월 30일

2. 2개 구매 시 1개 무료 쿠폰
- 쿠폰 코드: BOGO
- 구매 수량: 2
- 무료 제공 수량: 1
- 만료일: 2024년 5월 30일
- BOGO 쿠폰은 장바구니에 동일한 제품을 3개를 담은 상태에서 사용하면, 1개 분량의 금액을 할인한다.
- 3개씩 담은 제품이 여러개인 경우, 1개당 금액이 가장 비싼 제품에 적용한다.

3. 5만원 이상 구매 시 무료 배송 쿠폰
- 쿠폰 코드: FREESHIPPING
- 최소 주문 금액: 50,000원
- 만료일: 2024년 8월 31일
- 배송비 무료 쿠폰은 도서 및 산간 지역인 경우에도 무료 배송이 가능하다.

4. 미라클모닝 30% 할인 쿠폰
- 쿠폰 코드: MIRACLESALE
- 할인율: 30%
- 사용 가능 시간: 오전 4시부터 7시까지
- 만료일: 2024년 7월 31일

## 🛠️ 구현할 기능 (1,2단계)

- [x] 상품 로딩 전 스켈레톤 UI를 구현한다.
Expand All @@ -31,3 +80,13 @@
- [x] 추천 상품은 10개까지 노출한다.
- [x] 장바구니에 이미 추가된 상품은 추천 상품에 보이지 않는다.
- [x] 상품을 주문할 수 있다.

## 🛠️ 구현할 기능 (3,4단계)

- [x] 모든 API 및 DAO 함수에 suspend를 적용한다.
- [x] 배송비를 3,000원 추가한다.
- [x] 결제 화면에서 쿠폰을 조회한다.
- [x] 결제 화면에서 쿠폰을 적용한다.
- [x] 쿠폰은 1개만 적용 가능하다.
- [x] 결제하기 버튼을 누르면 주문이 완료된다.
- [x] 주문이 완료되면 주문 완료 토스트 메시지를 보여준다.
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,19 @@ import android.content.Context
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.jupiter.api.extension.ExtendWith
import woowacourse.shopping.DUMMY_HISTORY_PRODUCT_1
import woowacourse.shopping.DUMMY_HISTORY_PRODUCT_2
import woowacourse.shopping.data.database.ShoppingDatabase
import woowacourse.shopping.util.CoroutinesTestExtension

@ExperimentalCoroutinesApi
@ExtendWith(CoroutinesTestExtension::class)
@Suppress("ktlint:standard:function-naming")
class HistoryDaoTest {
private lateinit var database: ShoppingDatabase
Expand All @@ -28,108 +34,114 @@ class HistoryDaoTest {
}

@Test
fun 검색_기록을_저장하고_조회한다() {
// given
val historyProduct = DUMMY_HISTORY_PRODUCT_1
dao.insertHistory(historyProduct)

// when
val result = dao.getHistoryProducts()

// then
assertThat(result).hasSize(1)
assertThat(result[0].productId).isEqualTo(DUMMY_HISTORY_PRODUCT_1.productId)
}
fun 검색_기록을_저장하고_조회한다() =
runTest {
// given
Comment on lines -42 to +39
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

runTest를 활용한 코루틴 테스트 아주 좋네요~
runTest 로 하게 된다면, 일발적으로는 어떤 디스패처를 통해서 테스트를 하게 되는 것일까요?!
(이 부분과 직접적으로 연관된 내용을 아닐 것 같지만, 한번 알아둔다면 도움이 될 것 같아서 남겨두었습니다😊
사실 연관이 있는 부분은 Ui테스트 부분이겠군요)

이전에 마이그레이션 하다가 withContext 또는 CoroutineScope.launch(Dispatcher.Main)등 직접 메인 디스패처로 정의를 하는 로직이 있은 곳에서는 현재처럼 runTest 내의 모든 suspend 함수를 넣었을 때, 재대로 테스트가 동작을 통과를 못하는 경우가 있었어서, 기억이 났습니다~

Copy link
Author

@junseo511 junseo511 Jun 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

runTest를 활용한 코루틴 테스트 아주 좋네요~ runTest 로 하게 된다면, 일발적으로는 어떤 디스패처를 통해서 테스트를 하게 되는 것일까요?! (이 부분과 직접적으로 연관된 내용을 아닐 것 같지만, 한번 알아둔다면 도움이 될 것 같아서 남겨두었습니다😊 사실 연관이 있는 부분은 Ui테스트 부분이겠군요)

공식문서는 다음과 같이 명시하고 있습니다.

The test is run on a single thread, unless other CoroutineDispatcher are used for child coroutines.

테스트만을 위한 싱글 스레드에서 작업을 진행하나보네요!
내부 코드도 살펴보면

public fun runTest(
    context: CoroutineContext = EmptyCoroutineContext,
    timeout: Duration = DEFAULT_TIMEOUT.getOrThrow(),
    testBody: suspend TestScope.() -> Unit
): TestResult {
    check(context[RunningInRunTest] == null) {
        "Calls to `runTest` can't be nested. Please read the docs on `TestResult` for details."
    }
    return TestScope(context + RunningInRunTest).runTest(timeout, testBody)
}

위와 같이 context도 EmptyCoroutineContext 로 진행이 되고 있습니다
함수가 테스트만을 위한 공간을 만들어주는걸까요 🤔

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

함수가 테스트만을 위한 공간을 만들어주는걸까요 🤔

혹시 이 내용이 어떤 내용인지 좀 더 설명이 가능할까요~?
사실 이 질문은 advanceUntilIdle()등의 메서드가 있어서, 이걸 한번 알아두고자 시작했던 질문이었습니다

Copy link
Author

@junseo511 junseo511 Jun 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

혹시 이 내용이 어떤 내용인지 좀 더 설명이 가능할까요~? 사실 이 질문은 advanceUntilIdle()등의 메서드가 있어서, 이걸 한번 알아두고자 시작했던 질문이었습니다

해당 내용을 위한 공식문서가 따로 있었네요!!
테스트 과정에서 말씀하신 함수 활용을 통해 코루틴 실행을 보장할 수 있겠어요 👍
바로 진행해보도록 하겠습니다 :)
3561772

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

하나를 말씀드리면, 열에 대한 내용을 알아오시는군요👍

val historyProduct = DUMMY_HISTORY_PRODUCT_1
dao.insertHistory(historyProduct)

// when
val result = dao.getHistoryProducts()

// then
assertThat(result).hasSize(1)
assertThat(result[0].productId).isEqualTo(DUMMY_HISTORY_PRODUCT_1.productId)
}

@Test
fun 검색_기록을_최신순으로_조회한다() {
// given
dao.insertHistory(DUMMY_HISTORY_PRODUCT_1.copy(timestamp = 1))
dao.insertHistory(DUMMY_HISTORY_PRODUCT_2.copy(timestamp = 0))

// when
val result = dao.getHistoryProducts()

// then
assertThat(
result.map { it.productId },
).containsExactly(DUMMY_HISTORY_PRODUCT_1.productId, DUMMY_HISTORY_PRODUCT_2.productId).inOrder()
}
fun 검색_기록을_최신순으로_조회한다() =
runTest {
// given
dao.insertHistory(DUMMY_HISTORY_PRODUCT_1.copy(timestamp = 1))
dao.insertHistory(DUMMY_HISTORY_PRODUCT_2.copy(timestamp = 0))

// when
val result = dao.getHistoryProducts()

// then
assertThat(
result.map { it.productId },
).containsExactly(DUMMY_HISTORY_PRODUCT_1.productId, DUMMY_HISTORY_PRODUCT_2.productId).inOrder()
}

@Test
fun 검색_기록이_제한을_초과하면_오래된_기록부터_삭제된다() {
// given
repeat(5) { index ->
dao.insertHistory(
DUMMY_HISTORY_PRODUCT_1.copy(
productId = index.toLong(),
timestamp = index.toLong(),
),
fun 검색_기록이_제한을_초과하면_오래된_기록부터_삭제된다() =
runTest {
// given
repeat(5) { index ->
dao.insertHistory(
DUMMY_HISTORY_PRODUCT_1.copy(
productId = index.toLong(),
timestamp = index.toLong(),
),
)
}

// when
dao.insertHistoryWithLimit(
history = DUMMY_HISTORY_PRODUCT_2,
limit = 5,
)
}

// when
dao.insertHistoryWithLimit(
history = DUMMY_HISTORY_PRODUCT_2,
limit = 5,
)

// then
val result = dao.getHistoryProducts()
assertThat(result).hasSize(5)
assertThat(result.any { it.productId == 0L }).isFalse()
assertThat(result.first().productId).isEqualTo(DUMMY_HISTORY_PRODUCT_2.productId)
}
// then
val result = dao.getHistoryProducts()
assertThat(result).hasSize(5)
assertThat(result.any { it.productId == 0L }).isFalse()
assertThat(result.first().productId).isEqualTo(DUMMY_HISTORY_PRODUCT_2.productId)
}

@Test
fun 최근_검색_기록을_조회한다() {
// given
dao.insertHistory(DUMMY_HISTORY_PRODUCT_1.copy(timestamp = 0))
dao.insertHistory(DUMMY_HISTORY_PRODUCT_2.copy(timestamp = 1))
fun 최근_검색_기록을_조회한다() =
runTest {
// given
dao.insertHistory(DUMMY_HISTORY_PRODUCT_1.copy(timestamp = 0))
dao.insertHistory(DUMMY_HISTORY_PRODUCT_2.copy(timestamp = 1))

// when
val result = dao.getRecentHistoryProduct()
// when
val result = dao.getRecentHistoryProduct()

// then
assertThat(result?.productId).isEqualTo(DUMMY_HISTORY_PRODUCT_2.productId)
}
// then
assertThat(result?.productId).isEqualTo(DUMMY_HISTORY_PRODUCT_2.productId)
}

@Test
fun 총_검색_기록_개수를_조회한다() {
// given
dao.insertHistory(DUMMY_HISTORY_PRODUCT_1)
dao.insertHistory(DUMMY_HISTORY_PRODUCT_2)
fun 총_검색_기록_개수를_조회한다() =
runTest {
// given
dao.insertHistory(DUMMY_HISTORY_PRODUCT_1)
dao.insertHistory(DUMMY_HISTORY_PRODUCT_2)

// when
val count = dao.getHistoryCount()
// when
val count = dao.getHistoryCount()

// then
assertThat(count).isEqualTo(2)
}
// then
assertThat(count).isEqualTo(2)
}

@Test
fun 오래된_검색_기록을_원하는_개수만큼_삭제한다() {
// given
val base = System.currentTimeMillis()
repeat(5) { index ->
dao.insertHistory(
DUMMY_HISTORY_PRODUCT_1.copy(
productId = index.toLong(),
timestamp = base + index,
),
)
fun 오래된_검색_기록을_원하는_개수만큼_삭제한다() =
runTest {
// given
val base = System.currentTimeMillis()
repeat(5) { index ->
dao.insertHistory(
DUMMY_HISTORY_PRODUCT_1.copy(
productId = index.toLong(),
timestamp = base + index,
),
)
}

// when
dao.deleteOldestHistories(2)

// then
val result = dao.getHistoryProducts()
assertThat(result).hasSize(3)
assertThat(result.map { it.productId }).doesNotContain(0)
assertThat(result.map { it.productId }).doesNotContain(1)
}

// when
dao.deleteOldestHistories(2)

// then
val result = dao.getHistoryProducts()
assertThat(result).hasSize(3)
assertThat(result.map { it.productId }).doesNotContain(0)
assertThat(result.map { it.productId }).doesNotContain(1)
}

@After
fun tearDown() {
database.close()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
@file:Suppress("ktlint:standard:no-empty-file")

package woowacourse.shopping.study.data.dao

class CartDaoStudyTest
/*
import android.content.Context
import android.os.SystemClock
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package woowacourse.shopping.util

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestDispatcher
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.setMain
import org.junit.jupiter.api.extension.AfterEachCallback
import org.junit.jupiter.api.extension.BeforeEachCallback
import org.junit.jupiter.api.extension.ExtensionContext

@ExperimentalCoroutinesApi
class CoroutinesTestExtension(
private val dispatcher: TestDispatcher = UnconfinedTestDispatcher(),
) : BeforeEachCallback,
AfterEachCallback {
override fun beforeEach(context: ExtensionContext?) {
Dispatchers.setMain(dispatcher)
}

override fun afterEach(context: ExtensionContext?) {
Dispatchers.resetMain()
}
}
Comment on lines +14 to +25
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CoroutineTestExtension의 활용 정말 좋습니다~

11 changes: 8 additions & 3 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
tools:targetApi="31">
<activity
android:name=".ui.cart.CartActivity"
android:exported="false" />
android:exported="false"
android:parentActivityName=".ui.catalog.CatalogActivity" />
<activity
android:name=".ui.catalog.CatalogActivity"
android:exported="true">
Expand All @@ -30,7 +31,11 @@
</activity>
<activity
android:name=".ui.productdetail.ProductDetailActivity"
android:exported="false" />
android:exported="false"
android:parentActivityName=".ui.catalog.CatalogActivity" />
<activity
android:name=".ui.payment.PaymentActivity"
android:exported="false"
android:parentActivityName=".ui.catalog.CatalogActivity" />
Comment on lines +36 to +39
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parentActivityName에 대한 설정을 해주셨네요👍

</application>

</manifest>
8 changes: 4 additions & 4 deletions app/src/main/java/woowacourse/shopping/ShoppingApp.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package woowacourse.shopping

import android.app.Application
import woowacourse.shopping.di.DatabaseModule
import woowacourse.shopping.di.PreferenceModule
import woowacourse.shopping.di.DatabaseInjection
import woowacourse.shopping.di.PreferenceInjection

class ShoppingApp : Application() {
override fun onCreate() {
super.onCreate()
DatabaseModule.init(this)
PreferenceModule.init(this)
DatabaseInjection.init(this)
PreferenceInjection.init(this)
Comment on lines +10 to +11
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오호~ 저번 미션에서의 코멘트의 injection 이라는 네이밍이 마음에 드셨군요😊
반영 너무 좋습니다!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오호~ 저번 미션에서의 코멘트의 injection 이라는 네이밍이 마음에 드셨군요😊 반영 너무 좋습니다!

앞으로는 Injection 을 애용할 것 같아요 🤣

}
}
Loading