Skip to content
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

πŸš€ 4단계 - μž₯λ°”κ΅¬λ‹ˆ(μˆ˜λŸ‰) #70

Open
wants to merge 85 commits into
base: s9hn
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
7e0ffa5
build: coil μ˜μ‘΄μ„± μΆ”κ°€
s9hn Aug 17, 2024
65f3ff7
feat: 기초 μŠ€νƒ€μΌ κ°€μ΄λ“œ κ΅¬ν˜„
s9hn Aug 17, 2024
c007f36
docs: λ¦¬λ“œλ―Έ μΆ”κ°€
s9hn Aug 17, 2024
07a86d6
feat: μž₯λ°”κ΅¬λ‹ˆ λ·° 탑바 UI κ΅¬ν˜„
s9hn Aug 17, 2024
2f21374
feat: μž₯λ°”κ΅¬λ‹ˆ μ•„μ΄ν…œ μ»΄ν¬λ„ŒνŠΈ κ΅¬ν˜„
s9hn Aug 17, 2024
ea6b678
feat: μž₯λ°”κ΅¬λ‹ˆ μ•„μ΄ν…œ 리슀트 μ»΄ν¬λ„ŒνŠΈ κ΅¬ν˜„
s9hn Aug 17, 2024
878d1f3
feat: μž₯λ°”κ΅¬λ‹ˆ ν™”λ©΄ κ΅¬ν˜„
s9hn Aug 17, 2024
7c2ef86
test: μž₯λ°”κ΅¬λ‹ˆ μ•„μ΄ν…œ 리슀트 UI ν…ŒμŠ€νŠΈ κ΅¬ν˜„
s9hn Aug 17, 2024
f41d177
refactor: lint 정리
s9hn Aug 17, 2024
32311eb
refactor: lint 정리
s9hn Aug 17, 2024
d804962
Merge branch 'step1' of https://github.com/s9hn/android-shopping-cart…
s9hn Aug 17, 2024
ccca82f
docs: κΈ°λŠ₯ λͺ…μ„Έ μˆ˜μ •
s9hn Aug 19, 2024
290bce7
build: λ„€λΉ„κ²Œμ΄μ…˜ μ˜μ‘΄μ„± μΆ”κ°€
s9hn Aug 19, 2024
f23b826
refactor: CenterAlignedTopAppBar둜 Composable μ»΄ν¬λ„ŒνŠΈ λ¦¬νŒ©ν„°λ§
s9hn Aug 19, 2024
fa78176
feat: navController, navHost κ΅¬ν˜„
s9hn Aug 19, 2024
70faa27
refactor: shoppingList 클릭이벀트 ν˜Έμ΄μŠ€νŒ…
s9hn Aug 19, 2024
f57d840
feat: 각 슀크린 λ„€λΉ„κ²Œμ΄μ…˜ ν•¨μˆ˜ κ΅¬ν˜„
s9hn Aug 19, 2024
ecf9b6b
refactor: μ‡Όν•‘λͺ©λ‘ν™”λ©΄ navGraph등둝
s9hn Aug 19, 2024
c64c3b3
build: λ„€λΉ„κ²Œμ΄μ…˜ ν…ŒμŠ€νŠΈ μ˜μ‘΄μ„± μΆ”κ°€
s9hn Aug 19, 2024
91284ef
test: ν…ŒμŠ€νŠΈ 컴파일 μ—λŸ¬ μˆ˜μ •
s9hn Aug 19, 2024
a07b9ba
refactor: sematics content Description μœ„μΉ˜ μˆ˜μ •
s9hn Aug 19, 2024
12b8c38
test: μž₯λ°”κ΅¬λ‹ˆ λ·° 이동 & μƒν’ˆ 상세보기 λ·° 이동 ν…ŒμŠ€νŠΈ κ΅¬ν˜„
s9hn Aug 19, 2024
bac6964
feat: μƒν’ˆ 상세보기 λ·° κ΅¬ν˜„
s9hn Aug 19, 2024
8beb557
refactor: asyncImage μ»΄ν¬λ„ŒνŠΈν™” 및 적용
s9hn Aug 19, 2024
8939020
refactor: Divider μ»΄ν¬λ„ŒνŠΈν™” 및 적용
s9hn Aug 19, 2024
5c8b5e6
refactor: ShoppingDetailProductAddButton μ»΄ν¬λ„ŒνŠΈν™” 및 적용
s9hn Aug 19, 2024
468180e
refactor: ShoppingDetailProductPrice, ShoppingDetailPriceText μ»΄ν¬λ„ŒνŠΈν™” 및 적용
s9hn Aug 19, 2024
b7cb31f
refactor: ShoppingDetailProductTitle μ»΄ν¬λ„ŒνŠΈν™” 및 적용
s9hn Aug 19, 2024
10500df
feat: 상세보기 λ·° 클릭 이벀트 λ„€λΉ„κ²Œμ΄μ…˜ 등둝
s9hn Aug 19, 2024
cbd7640
refactor: Lint정리 및 named call μΆ”κ°€
s9hn Aug 19, 2024
51d4e60
refactor: μ‡Όν•‘μž₯λ°”κ΅¬λ‹ˆ λ·° argumemt 제거
s9hn Aug 19, 2024
9a872ef
docs: κΈ°λŠ₯ λͺ…μ„Έ μ—…λ°μ΄νŠΈ
s9hn Aug 19, 2024
680fb72
test: μƒν’ˆ 상세보기 λ·° 이동 uiν…ŒμŠ€νŠΈ κ΅¬ν˜„
s9hn Aug 19, 2024
19256d2
feat: μž₯λ°”κ΅¬λ‹ˆ λ·° κ΅¬ν˜„
s9hn Aug 19, 2024
4970501
test: μž₯λ°”κ΅¬λ‹ˆ λ·° UI ν…ŒμŠ€νŠΈ κ΅¬ν˜„
s9hn Aug 19, 2024
e572f50
build: resolve merge-conflict
s9hn Aug 19, 2024
3a50d2c
docs: κΈ°λŠ₯ κ΅¬ν˜„ 사항 μ—…λ°μ΄νŠΈ
s9hn Aug 20, 2024
0700b31
feat: Cart λ°μ΄ν„°λ² μ΄μŠ€ 및 λͺ¨λΈ κ΅¬ν˜„
s9hn Aug 20, 2024
1759fac
refactor: Product 파일 뢄리
s9hn Aug 20, 2024
dd36132
feat: μˆ˜λŸ‰ 쑰절 ShoppingCountBar κ΅¬ν˜„
s9hn Aug 20, 2024
73487e6
feat: μˆ˜λŸ‰ 합계 ShoppingCartItemSumText κ΅¬ν˜„
s9hn Aug 20, 2024
c0290b0
feat: μž₯λ°”κ΅¬λ‹ˆ μ•„μ΄ν…œ ShoppingCartItemBody λΆ€λΆ„ κ΅¬ν˜„
s9hn Aug 20, 2024
9ea84af
feat: μž₯λ°”κ΅¬λ‹ˆ μ•„μ΄ν…œ ShoppingCartItemHeader λΆ€λΆ„ κ΅¬ν˜„
s9hn Aug 20, 2024
c3a7636
feat: μž₯λ°”κ΅¬λ‹ˆ ShoppingCartItem μ•„μ΄ν…œ κ΅¬ν˜„
s9hn Aug 20, 2024
b30be9c
feat: μž₯λ°”κ΅¬λ‹ˆ ShoppingCartLazyColumn 리슀트 κ΅¬ν˜„
s9hn Aug 20, 2024
14a2c05
refactor: μž„ν¬νŠΈ 정리
s9hn Aug 20, 2024
c21d971
refactor: ShoppingButton 뢄리 및 곡용 μ»΄ν¬λ„ŒνŠΈν™”
s9hn Aug 20, 2024
6c2afae
feat: ShoppingCartScreen κ΅¬ν˜„ 및 적용
s9hn Aug 20, 2024
92bfcae
refactor: μ½”λ“œ 정리
s9hn Aug 20, 2024
773222f
refactor: ShoppingDetailScreen μž₯λ°”κ΅¬λ‹ˆ μΆ”κ°€ 둜직 μˆ˜μ •
s9hn Aug 20, 2024
f452a6f
refactor: ShoppingCartItemBody μž₯λ°”κ΅¬λ‹ˆ μˆ˜λŸ‰μ‘°μ ˆ 둜직 μˆ˜μ •
s9hn Aug 20, 2024
d981bc6
refactor: ShoppingCartItemBody μž₯λ°”κ΅¬λ‹ˆ μˆ˜λŸ‰μ‘°μ ˆ 둜직 μˆ˜μ •
s9hn Aug 20, 2024
763c4e2
refactor: ShoppingCartItemHeader 클릭 λ§€κ°œλ³€μˆ˜ 넀이밍 μˆ˜μ •
s9hn Aug 20, 2024
773d20a
refactor: μ•„μ΄ν…œ 클릭 λžŒλ‹€ ν˜Έμ΄μŠ€νŒ… 적용
s9hn Aug 20, 2024
051b1e7
refactor: Cart μ—…λ°μ΄νŠΈ 및 UI에 전달
s9hn Aug 20, 2024
dd7c9bf
refactor: ShoppingProductImage width, height 제거
s9hn Aug 21, 2024
693cae7
refactor: width, height -> size둜 μˆ˜μ •
s9hn Aug 21, 2024
e265431
refactor: navigation Route object 넀이밍 μˆ˜μ •
s9hn Aug 21, 2024
c7e8b09
refactor: ShoppingCartScreen -> ShoppingCartRoute둜 뢄리 및 state μ „λ‹¬λ‘œμ§ μˆ˜μ •
s9hn Aug 21, 2024
fdcd3df
refactor: ShoppingDetailScreen -> ShoppingDetailRoute 뢄리 및 state μ „λ‹¬λ‘œμ§ μˆ˜μ •
s9hn Aug 21, 2024
04f3949
refactor: ShoppingListScreen -> ShoppingListRoute 뢄리 및 state μ „λ‹¬λ‘œμ§ μˆ˜μ •
s9hn Aug 21, 2024
476a5a9
refactor: ν…ŒμŠ€νŠΈ νŒ¨ν‚€μ§€ ꡬ쑰 λ³€κ²½
s9hn Aug 21, 2024
e371982
refactor: ShoppingListScreenNavigationTest 넀이밍 μˆ˜μ •
s9hn Aug 21, 2024
14a22bc
refactor: ShoppingDetailNavigationScreenTest 넀이밍 μˆ˜μ •
s9hn Aug 21, 2024
2f5be0d
refactor: ν…ŒμŠ€νŠΈμΌ€μ΄μŠ€ 넀이밍 μˆ˜μ •
s9hn Aug 21, 2024
c3ce6c1
refactor: findProductById μˆ˜μ • 및 적용
s9hn Aug 21, 2024
f29ee0e
refactor: ShoppingCartItem description μΆ”κ°€
s9hn Aug 21, 2024
11bf0f4
refactor: onSubtractClick λ©”μ„œλ“œ μˆ˜μ •
s9hn Aug 21, 2024
ef5bb9e
test: ShoppingCartScreenTest κ΅¬ν˜„
s9hn Aug 21, 2024
bcb707f
refactor: description μˆ˜μ •
s9hn Aug 21, 2024
becc96c
build: resolve merge conflict
s9hn Aug 21, 2024
2bb360a
docs: κΈ°λŠ₯ λͺ…μ„Έ μ—…λ°μ΄νŠΈ
s9hn Sep 1, 2024
d2ec793
feat: μž₯λ°”κ΅¬λ‹ˆ 리슀트 + λ²„νŠΌ κ΅¬ν˜„
s9hn Sep 2, 2024
f941dde
refactor: + λ²„νŠΌ λ””μžμΈ μˆ˜μ •
s9hn Sep 2, 2024
f693298
refactor: Cart λ©”μ„œλ“œ μˆ˜μ •
s9hn Sep 2, 2024
2e800b7
feat: μ‡Όν•‘ λͺ©λ‘ λ·°μ—μ„œ μˆ˜λŸ‰ 쑰절 κΈ°λŠ₯ κ΅¬ν˜„
s9hn Sep 2, 2024
1d04021
refactor: ν…ŒμŠ€νŠΈ μƒμ„±μž μˆ˜μ •
s9hn Sep 2, 2024
cb9f721
test: ν˜„μž¬ μž₯λ°”κ΅¬λ‹ˆμ— μΆ”κ°€λœ μ•„μ΄ν…œ κ°―μˆ˜κ°€ μƒν’ˆ λͺ©λ‘λ·°μ— λ…ΈμΆœλœλ‹€.
s9hn Sep 2, 2024
f87e788
test: μƒν’ˆ μˆ˜λŸ‰μ„ μ‘°μ ˆν•  수 μžˆλ‹€.
s9hn Sep 2, 2024
a18ff4c
refactor: lazyColumn 자체 contentPadding μ‚¬μš©
s9hn Sep 2, 2024
8939e91
refactor: 가격 ν¬λ§€νŒ… μˆ˜μ •
s9hn Sep 2, 2024
47dd987
refactor: μ‚¬μš©λ˜μ§€ μ•ŠλŠ” μˆ˜μ •μž 제거
s9hn Sep 2, 2024
b171732
refactor: 프리뷰 및 modifier μˆ˜μ •
s9hn Sep 2, 2024
8377de7
refactor: 가격 format μˆ˜μ •
s9hn Sep 2, 2024
b8f9d8b
build: resolve merge-conflict
s9hn Sep 2, 2024
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
5 changes: 5 additions & 0 deletions README.md
Copy link
Member

Choose a reason for hiding this comment

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

Q. IconButton λ‚΄λΆ€λ₯Ό λ³΄μ•˜λŠ”λ° Box둜 ν•œλ²ˆ λž˜ν•‘λ˜μ–΄μžˆκ³ , κ²°κ΅­ Box에 Clickable λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•˜κ³  μžˆλŠ”λ° Icon보닀 μ„ ν˜Έν•˜μ‹œλŠ” μ΄μœ κ°€ μžˆμœΌμ‹ κ°€μš”? CompositionLocalProviderλ₯Ό ν†΅ν•œ μ–΄λ–€ 클릭 이벀트 μ΅œμ ν™”κ°€ λ˜μ–΄μžˆλ‚˜μš”?

κ°€μž₯ 큰 효과라고 ν•œλ‹€λ©΄ Material λ””μžμΈ κ°€μ΄λ“œμ—μ„œ μ΄μ•ΌκΈ°ν•˜λŠ” λͺ…μ‹œμ μΈ 역할을 κ°€μž₯ μ‰½κ²Œ κ΅¬ν˜„ν•˜λ„λ‘ λ„μ™€μ£ΌλŠ” 것이라고 ν•  수 μžˆκ² λ„€μš”.
https://m3.material.io/components/icon-buttons

예λ₯Ό λ“€μ–΄ Divider도 λ‚΄λΆ€μ—μ„œ Boxλ₯Ό κ΅¬ν˜„ν•˜κ³  μžˆλŠ”λ°μš”, Boxλ₯Ό Modifier둜 μ‘°μž‘ν•˜λŠ” 것과 λ‹€λ₯΄μ§€ μ•Šλ‹€κ³  생각할 수 μžˆμ§€λ§Œ
λͺ…μ‹œμ μœΌλ‘œ λ ˆμ΄μ•„μ›ƒμ„ λ‚˜λˆ„λŠ” 데에 ν™œμš©ν•˜λŠ” μ»΄ν¬λ„ŒνŠΈλ₯Ό ν™œμš©ν•˜λŠ” 것을 더 μ„ ν˜Έν•©λ‹ˆλ‹€.

A divider is a thin line that groups content in lists and layouts.

Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
- [x] μž₯λ°”κ΅¬λ‹ˆ μ•„μ΄ν…œ μ»΄ν¬λ„ŒνŠΈ κ΅¬ν˜„
- [x] μž₯λ°”κ΅¬λ‹ˆ μ•„μ΄μ½˜μ„ ν΄λ¦­ν•˜λ©΄ μž₯λ°”κ΅¬λ‹ˆ 뷰둜 μ΄λ™ν•œλ‹€.
- [x] μƒν’ˆ 1개λ₯Ό ν΄λ¦­ν•˜λ©΄ ν•΄λ‹Ή μƒν’ˆ 상세보기 뷰둜 μ΄λ™ν•œλ‹€.
- [x] μƒν’ˆ μˆ˜λŸ‰μ„ μ‘°μ ˆν•  수 μžˆλ‹€.
- [x] 0개인 μ•„μ΄ν…œμ˜ '+' μ•„μ΄μ½˜μ„ λˆ„λ₯΄λ©΄ μž₯λ°”κ΅¬λ‹ˆμ— μƒν’ˆμ΄ μΆ”κ°€λ˜λ©° λ™μ‹œμ— κ°―μˆ˜κ°€ λ…ΈμΆœλœλ‹€.
- [x] 1개인 μ•„μ΄ν…œμ˜ '-' μ•„μ΄μ½˜μ„ λˆ„λ₯΄λ©΄ μž₯λ°”κ΅¬λ‹ˆμ— μƒν’ˆμ΄ 제거됨과 μˆ˜λŸ‰ λ²„νŠΌ λ…ΈμΆœμ΄ 사라진닀.
- [x] ν˜„μž¬ μž₯λ°”κ΅¬λ‹ˆμ— μΆ”κ°€λœ μ•„μ΄ν…œ κ°―μˆ˜κ°€ μƒν’ˆ λͺ©λ‘λ·°μ— λ…ΈμΆœλœλ‹€.

- μƒν’ˆ 상세 λ·°
- [x] μƒν’ˆ 정보λ₯Ό λ³Ό 수 μžˆλ‹€.
Expand All @@ -36,3 +40,4 @@
- [x] μˆ˜λŸ‰λ§ŒνΌμ˜ 담은 μƒν’ˆ 총계λ₯Ό λ³Ό 수 μžˆλ‹€.
- [x] μž₯λ°”κ΅¬λ‹ˆμ— λ‹΄κΈ΄ λͺ¨λ“  μƒν’ˆμ˜ 총계λ₯Ό λ³Ό 수 μžˆλ‹€.


Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ class ShoppingCartScreenTest {

// then:
composeTestRule.onNodeWithContentDescription("ShoppingButton")
.assertTextEquals("μ£Όλ¬Έν•˜κΈ°(1100)원")
.assertTextEquals("μ£Όλ¬Έν•˜κΈ°(1,100)원")
}

@Test
Expand Down Expand Up @@ -256,7 +256,7 @@ class ShoppingCartScreenTest {

// then:
composeTestRule.onNodeWithContentDescription("ShoppingButton")
.assertTextEquals("μ£Όλ¬Έν•˜κΈ°(1200)원")
.assertTextEquals("μ£Όλ¬Έν•˜κΈ°(1,200)원")
}

@Test
Expand Down Expand Up @@ -305,7 +305,7 @@ class ShoppingCartScreenTest {

// then:
composeTestRule.onNodeWithContentDescription("ShoppingButton")
.assertTextEquals("μ£Όλ¬Έν•˜κΈ°(1000)원")
.assertTextEquals("μ£Όλ¬Έν•˜κΈ°(1,000)원")
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
package nextstep.shoppingcart.shoppinglist.shoppinglist

import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertIsNotDisplayed
import androidx.compose.ui.test.assertTextEquals
import androidx.compose.ui.test.isDisplayed
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import nextstep.shoppingcart.ui.shoppinglist.ShoppingListScreen
import nextstep.shoppingcart.ui.shoppinglist.model.Product
import org.junit.Rule
import org.junit.Test

class ShoppingListScreenTest {
Copy link
Member

Choose a reason for hiding this comment

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

의미 μžˆλŠ” μ‹œλ‚˜λ¦¬μ˜€λ₯Ό 정말 잘 λ„μΆœν•΄μ£Όμ…¨λ„€μš” πŸ‘
이제 ν…ŒμŠ€νŠΈλŠ” 더 ν”Όλ“œλ°± μ•ˆ λ“œλ €λ„ λ˜κ² μ–΄μš”~


@get:Rule
val composeTestRule = createComposeRule()

@Test
fun μƒν’ˆμ˜_λ‹΄κΈ°_λ²„νŠΌμ„_λˆ„λ₯΄λ©΄_μˆ˜λŸ‰μ‘°μ ˆ_λ²„νŠΌμ΄_λ…ΈμΆœλœλ‹€() {
// given:
var products by mutableStateOf(
listOf(
Product(
id = 0L,
name = "ν…ŒμŠ€νŠΈ1",
imageUrl = "",
price = 110L,
containedCount = 0,
)
)
)

composeTestRule.apply {
setContent {
ShoppingListScreen(
products = products,
onShoppingCartClick = {},
onItemClick = {},
onPutClick = { selectedProductId ->
products = products.map { product ->
if (selectedProductId == product.id) product.copy(
containedCount = product.containedCount + 1
) else product
}
},
onAddClick = {},
onSubtractClick = {},
)
}
}

// when:
composeTestRule.onNodeWithContentDescription("shoppingProductAddButtonDescription")
.performClick()

// then:
composeTestRule.onNodeWithContentDescription("shoppingCountBarDescription")
.assertIsDisplayed()
}

@Test
fun λ‹΄κΈ΄_μƒν’ˆμ˜_μˆ˜λŸ‰μ΄_1개_미만일_경우_μˆ˜λŸ‰μ‘°μ ˆ_λ²„νŠΌμ΄_사라지고_λ‹΄κΈ°λ²„νŠΌμ΄_λ…ΈμΆœλœλ‹€() {
// given:
var products by mutableStateOf(
listOf(
Product(
id = 0L,
name = "ν…ŒμŠ€νŠΈ1",
imageUrl = "",
price = 110L,
containedCount = 1,
)
)
)

composeTestRule.apply {
setContent {
ShoppingListScreen(
products = products,
onShoppingCartClick = {},
onItemClick = {},
onPutClick = {},
onAddClick = {},
onSubtractClick = { selectedProductId ->
products = products.map { product ->
if (selectedProductId == product.id) product.copy(
containedCount = product.containedCount - 1
) else product
}
},
)
}
}

// when:
composeTestRule.onNodeWithContentDescription("ShoppingCountBarSubtractIcon").performClick()

// then:
composeTestRule.onNodeWithContentDescription("ShoppingProductAddButton")
.assertIsDisplayed()
composeTestRule.onNodeWithContentDescription("shoppingCountBarDescription")
.assertIsNotDisplayed()
}

@Test
fun λ‹΄κΈ΄_μƒν’ˆμ˜_μˆ˜λŸ‰μ΄_2개일_경우_μΆ”κ°€λ‹΄κΈ°_λ²„νŠΌμ„_λˆ„λ₯΄λ©΄_3κ°œκ°€_λœλ‹€() {
// given:
var products by mutableStateOf(
listOf(
Product(
id = 0L,
name = "ν…ŒμŠ€νŠΈ1",
imageUrl = "",
price = 110L,
containedCount = 2,
)
)
)

composeTestRule.apply {
setContent {
ShoppingListScreen(
products = products,
onShoppingCartClick = {},
onItemClick = {},
onPutClick = {},
onAddClick = { selectedProductId ->
products = products.map { product ->
if (selectedProductId == product.id) product.copy(
containedCount = product.containedCount + 1
) else product
}
},
onSubtractClick = {},
)
}
}

// when:
composeTestRule.onNodeWithContentDescription("ShoppingCountBarAddIcon").performClick()

// then:
composeTestRule.onNodeWithText("3").isDisplayed()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ class ShoppingListLazyVerticalGridTest {
),
),
onItemClick = {},
onPutClick = {},
onAddClick = {},
onSubtractClick = {},
)
}
}
Expand Down Expand Up @@ -73,6 +76,9 @@ class ShoppingListLazyVerticalGridTest {
)
),
onItemClick = {},
onPutClick = {},
onAddClick = {},
onSubtractClick = {},
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package nextstep.shoppingcart.shoppinglist.shoppinglist.component

import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertIsNotDisplayed
import androidx.compose.ui.test.assertTextEquals
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithContentDescription
import nextstep.shoppingcart.ui.shoppinglist.component.ShoppingProductHeader
import nextstep.shoppingcart.ui.shoppinglist.model.Product
import org.junit.Rule
import org.junit.Test

class ShoppingProductHeaderTest {
Copy link
Member

Choose a reason for hiding this comment

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

이 ν…ŒμŠ€νŠΈ μ‹œλ‚˜λ¦¬μ˜€μ— λŒ€ν•΄ μ»΄ν¬λ„ŒνŠΈμ˜ Previewλ‘œλ„ λ…ΈμΆœν•΄λ³΄λ©΄ μ–΄λ–¨κΉŒμš”? PreviewParameterλ₯Ό ν™œμš©ν•΄λ³Ό 수 μžˆμ„ 것 κ°™μ•„μš”!


@get:Rule
val composeTestRule = createComposeRule()

@Test
fun `0번_μƒν’ˆμ΄_μž₯λ°”κ΅¬λ‹ˆμ—_1개_이상_λ‹΄κ²¨μžˆλ‹€λ©΄_κ°―μˆ˜κ°€_λ…ΈμΆœλœλ‹€`() {
// given:
composeTestRule.apply {
setContent {
ShoppingProductHeader(
Copy link
Member

Choose a reason for hiding this comment

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

HeaderλΌλŠ” 이름은 보톡 νŽ˜μ΄μ§€ 상단에 μžˆλŠ” 전체적인 머릿글을 일컬을 λ•Œ μ‚¬μš©ν•˜κ³€ ν•˜λŠ”λ°μš”, 더 μ μ ˆν•œ 이름이 μžˆμ„κΉŒμš”?

product = Product(
id = 0L,
name = "μš”κ΅¬λ₯΄νŠΈ",
imageUrl = "",
price = 500000000L,
containedCount = 2,
),
onPutClick = {},
onAddClick = {},
onSubtractClick = {},
)
}
}

// when:
// then:
composeTestRule.onNodeWithContentDescription("ShoppingProductAddButton")
.assertIsNotDisplayed()
composeTestRule.onNodeWithContentDescription("ShoppingCountBarTotalCount")
.assertTextEquals("2")
}

@Test
fun `0번_μƒν’ˆμ΄_μž₯λ°”κ΅¬λ‹ˆμ—_0개_λ‹΄κ²¨μžˆλ‹€λ©΄_갯수_μΆ”κ°€_λ²„νŠΌμ΄_λ…ΈμΆœλœλ‹€`() {
// given:
composeTestRule.apply {
setContent {
ShoppingProductHeader(
product = Product(
id = 0L,
name = "μš”κ΅¬λ₯΄νŠΈ",
imageUrl = "",
price = 500000000L,
containedCount = 0,
),
onPutClick = {},
onAddClick = {},
onSubtractClick = {},
)
}
}

// when:
// then:
composeTestRule.onNodeWithContentDescription("ShoppingProductAddButton")
.assertIsDisplayed()
composeTestRule.onNodeWithContentDescription("shoppingCountBarDescription")
.assertIsNotDisplayed()
}
}
4 changes: 2 additions & 2 deletions app/src/main/java/nextstep/shoppingcart/data/Cart.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ object Cart {
return items
}

fun findProductById(productId: Long) =
items.find { it.product.id == productId } ?: throw IllegalArgumentException()
fun findCartProductById(cartProductId: Long) =
items.find { it.product.id == cartProductId } ?: throw IllegalArgumentException()
}
6 changes: 6 additions & 0 deletions app/src/main/java/nextstep/shoppingcart/data/Products.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package nextstep.shoppingcart.data

import nextstep.shoppingcart.data.Cart.items
import nextstep.shoppingcart.ui.shoppinglist.model.Product

object Products {
Expand Down Expand Up @@ -56,4 +57,9 @@ object Products {

fun findProductById(productId: Long) =
dummyProducts.find { it.id == productId } ?: throw IllegalArgumentException()

fun List<Product>.updateProducts(): List<Product> = map { product ->
items.find { it.product.id == product.id }
?.let { product.copy(containedCount = it.count) } ?: product
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import nextstep.shoppingcart.R.drawable.ic_add
import nextstep.shoppingcart.R.drawable.ic_subtract
import nextstep.shoppingcart.R.string.shopping_count_bar_add_icon
import nextstep.shoppingcart.R.string.shopping_count_bar_count
import nextstep.shoppingcart.R.string.shopping_count_bar_description
import nextstep.shoppingcart.R.string.shopping_count_bar_subtract_icon
import nextstep.shoppingcart.R.string.shopping_count_bar_total_count
import nextstep.shoppingcart.ui.theme.RobotoRegular
Expand All @@ -43,11 +44,14 @@ fun ShoppingCountBar(
val shoppingCountBarSubtractIcon = stringResource(id = shopping_count_bar_subtract_icon)
val shoppingCountBarAddIcon = stringResource(id = shopping_count_bar_add_icon)
val shoppingCountBarTotalCount = stringResource(id = shopping_count_bar_total_count)
val shoppingCountBar = stringResource(shopping_count_bar_description)

Row(
horizontalArrangement = Arrangement.SpaceEvenly,
verticalAlignment = Alignment.CenterVertically,
modifier = modifier.background(color = Color.White),
modifier = modifier
.background(color = Color.White)
.semantics { contentDescription = shoppingCountBar },
) {
Icon(
painter = painterResource(id = ic_subtract),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import nextstep.shoppingcart.data.Cart.addOne
import nextstep.shoppingcart.data.Cart.findProductById
import nextstep.shoppingcart.data.Cart.findCartProductById
import nextstep.shoppingcart.data.Cart.items
import nextstep.shoppingcart.data.Cart.removeAll
import nextstep.shoppingcart.data.Cart.removeOne
Expand All @@ -25,17 +25,17 @@ fun ShoppingCartRoute(
total = total,
onBackClick = onBackClick,
onRemoveClick = { cartProductId ->
removeAll(findProductById(cartProductId).product)
removeAll(findCartProductById(cartProductId).product)
cartProducts = items
total = totalPrice
},
onAddClick = { cartProductId ->
addOne(findProductById(cartProductId).product)
addOne(findCartProductById(cartProductId).product)
cartProducts = items
total = totalPrice
},
onSubtractClick = { cartProductId ->
removeOne(findProductById(cartProductId).product)
removeOne(findCartProductById(cartProductId).product)
cartProducts = items
total = totalPrice
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ fun ShoppingCartItem(

Column(
modifier = modifier
.fillMaxWidth()
.wrapContentHeight()
.border(
width = 1.dp,
color = Color.Gray,
Expand All @@ -60,7 +58,7 @@ fun ShoppingCartItem(
}
}

@Preview
@Preview(showBackground = true)
@Composable
private fun ShoppingCartItemPreview() {
ShoppingCartItem(
Expand Down
Loading