Initial commit: HotDeal Alarm Android App
Features: - Multi-site hot deal scraping (Ppomppu, Clien, Ruriweb, Coolenjoy) - Site filter with color-coded badges - Board display names (e.g., ppomppu8 -> 알리뽐뿌) - Anti-bot protection with request delays and User-Agent rotation - Keyword matching and notifications - Material Design 3 UI
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
package com.hotdeal.alarm
|
||||
|
||||
import androidx.compose.ui.test.*
|
||||
import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import com.hotdeal.alarm.domain.model.HotDeal
|
||||
import com.hotdeal.alarm.domain.model.SiteType
|
||||
import com.hotdeal.alarm.presentation.components.DealItem
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
/**
|
||||
* DealItem 컴포넌트 UI 테스트
|
||||
*/
|
||||
class DealItemTest {
|
||||
|
||||
@get:Rule
|
||||
val composeTestRule = createComposeRule()
|
||||
|
||||
@Test
|
||||
fun `DealItem should display title correctly`() {
|
||||
// Given
|
||||
val deal = HotDeal(
|
||||
id = "test_123",
|
||||
siteName = "ppomppu",
|
||||
boardName = "ppomppu",
|
||||
title = "갤럭시 S24 울트라 핫딜",
|
||||
url = "https://test.com",
|
||||
createdAt = System.currentTimeMillis()
|
||||
)
|
||||
|
||||
// When
|
||||
composeTestRule.setContent {
|
||||
DealItem(deal = deal, onClick = {})
|
||||
}
|
||||
|
||||
// Then
|
||||
composeTestRule.onNodeWithText("갤럭시 S24 울트라 핫딜").assertExists()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `DealItem should display site name`() {
|
||||
// Given
|
||||
val deal = HotDeal(
|
||||
id = "test_123",
|
||||
siteName = "ppomppu",
|
||||
boardName = "ppomppu",
|
||||
title = "Test Deal",
|
||||
url = "https://test.com",
|
||||
createdAt = System.currentTimeMillis()
|
||||
)
|
||||
|
||||
// When
|
||||
composeTestRule.setContent {
|
||||
DealItem(deal = deal, onClick = {})
|
||||
}
|
||||
|
||||
// Then
|
||||
composeTestRule.onNodeWithText("뽐뿌").assertExists()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `DealItem should be clickable`() {
|
||||
// Given
|
||||
var clicked = false
|
||||
val deal = HotDeal(
|
||||
id = "test_123",
|
||||
siteName = "ppomppu",
|
||||
boardName = "ppomppu",
|
||||
title = "Test Deal",
|
||||
url = "https://test.com",
|
||||
createdAt = System.currentTimeMillis()
|
||||
)
|
||||
|
||||
// When
|
||||
composeTestRule.setContent {
|
||||
DealItem(deal = deal, onClick = { clicked = true })
|
||||
}
|
||||
|
||||
// Then
|
||||
composeTestRule.onNodeWithText("Test Deal").performClick()
|
||||
assert(clicked)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `DealItem should show keyword match indicator when isKeywordMatch is true`() {
|
||||
// Given
|
||||
val deal = HotDeal(
|
||||
id = "test_123",
|
||||
siteName = "ppomppu",
|
||||
boardName = "ppomppu",
|
||||
title = "Test Deal",
|
||||
url = "https://test.com",
|
||||
createdAt = System.currentTimeMillis(),
|
||||
isKeywordMatch = true
|
||||
)
|
||||
|
||||
// When
|
||||
composeTestRule.setContent {
|
||||
DealItem(deal = deal, onClick = {})
|
||||
}
|
||||
|
||||
// Then - 키워드 매칭 아이콘이 표시되어야 함
|
||||
composeTestRule.onNodeWithContentDescription("키워드 매칭").assertExists()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package com.hotdeal.alarm
|
||||
|
||||
import androidx.compose.ui.test.*
|
||||
import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import com.hotdeal.alarm.domain.model.Keyword
|
||||
import com.hotdeal.alarm.domain.model.MatchMode
|
||||
import com.hotdeal.alarm.presentation.settings.KeywordItem
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
/**
|
||||
* KeywordItem 컴포넌트 UI 테스트
|
||||
*/
|
||||
class KeywordItemTest {
|
||||
|
||||
@get:Rule
|
||||
val composeTestRule = createComposeRule()
|
||||
|
||||
@Test
|
||||
fun `KeywordItem should display keyword text`() {
|
||||
// Given
|
||||
val keyword = Keyword(
|
||||
id = 1L,
|
||||
keyword = "갤럭시",
|
||||
isEnabled = true
|
||||
)
|
||||
|
||||
// When
|
||||
composeTestRule.setContent {
|
||||
KeywordItem(
|
||||
keyword = keyword,
|
||||
onToggle = {},
|
||||
onDelete = {}
|
||||
)
|
||||
}
|
||||
|
||||
// Then
|
||||
composeTestRule.onNodeWithText("갤럭시").assertExists()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `KeywordItem should have toggle switch`() {
|
||||
// Given
|
||||
val keyword = Keyword(
|
||||
id = 1L,
|
||||
keyword = "test",
|
||||
isEnabled = true
|
||||
)
|
||||
|
||||
// When
|
||||
composeTestRule.setContent {
|
||||
KeywordItem(
|
||||
keyword = keyword,
|
||||
onToggle = {},
|
||||
onDelete = {}
|
||||
)
|
||||
}
|
||||
|
||||
// Then
|
||||
composeTestRule.onNodeWithText("test").assertExists()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `KeywordItem should have delete button`() {
|
||||
// Given
|
||||
val keyword = Keyword(
|
||||
id = 1L,
|
||||
keyword = "test",
|
||||
isEnabled = true
|
||||
)
|
||||
|
||||
// When
|
||||
composeTestRule.setContent {
|
||||
KeywordItem(
|
||||
keyword = keyword,
|
||||
onToggle = {},
|
||||
onDelete = {}
|
||||
)
|
||||
}
|
||||
|
||||
// Then
|
||||
composeTestRule.onNodeWithContentDescription("삭제").assertExists()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `KeywordItem toggle should call onToggle`() {
|
||||
// Given
|
||||
var toggled = false
|
||||
val keyword = Keyword(
|
||||
id = 1L,
|
||||
keyword = "test",
|
||||
isEnabled = true
|
||||
)
|
||||
|
||||
// When
|
||||
composeTestRule.setContent {
|
||||
KeywordItem(
|
||||
keyword = keyword,
|
||||
onToggle = { toggled = true },
|
||||
onDelete = {}
|
||||
)
|
||||
}
|
||||
|
||||
// Then - Switch를 찾아서 클릭
|
||||
composeTestRule.onNode(isToggleable()).performClick()
|
||||
assert(toggled)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package com.hotdeal.alarm
|
||||
|
||||
import androidx.compose.ui.test.*
|
||||
import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import com.hotdeal.alarm.presentation.components.PermissionDialog
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
/**
|
||||
* PermissionDialog UI 테스트
|
||||
*/
|
||||
class PermissionDialogTest {
|
||||
|
||||
@get:Rule
|
||||
val composeTestRule = createComposeRule()
|
||||
|
||||
@Test
|
||||
fun `PermissionDialog should display title`() {
|
||||
// Given
|
||||
val title = "알림 권한 필요"
|
||||
|
||||
// When
|
||||
composeTestRule.setContent {
|
||||
PermissionDialog(
|
||||
title = title,
|
||||
message = "Test message",
|
||||
onDismiss = {},
|
||||
onOpenSettings = {}
|
||||
)
|
||||
}
|
||||
|
||||
// Then
|
||||
composeTestRule.onNodeWithText(title).assertExists()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `PermissionDialog should display message`() {
|
||||
// Given
|
||||
val message = "핫딜 알림을 받으려면 알림 권한이 필요합니다."
|
||||
|
||||
// When
|
||||
composeTestRule.setContent {
|
||||
PermissionDialog(
|
||||
title = "Test",
|
||||
message = message,
|
||||
onDismiss = {},
|
||||
onOpenSettings = {}
|
||||
)
|
||||
}
|
||||
|
||||
// Then
|
||||
composeTestRule.onNodeWithText(message).assertExists()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `PermissionDialog should have settings button`() {
|
||||
// When
|
||||
composeTestRule.setContent {
|
||||
PermissionDialog(
|
||||
title = "Test",
|
||||
message = "Test message",
|
||||
onDismiss = {},
|
||||
onOpenSettings = {}
|
||||
)
|
||||
}
|
||||
|
||||
// Then
|
||||
composeTestRule.onNodeWithText("설정 열기").assertExists()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `PermissionDialog should have cancel button`() {
|
||||
// When
|
||||
composeTestRule.setContent {
|
||||
PermissionDialog(
|
||||
title = "Test",
|
||||
message = "Test message",
|
||||
onDismiss = {},
|
||||
onOpenSettings = {}
|
||||
)
|
||||
}
|
||||
|
||||
// Then
|
||||
composeTestRule.onNodeWithText("취소").assertExists()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `PermissionDialog should call onOpenSettings when settings button clicked`() {
|
||||
// Given
|
||||
var settingsClicked = false
|
||||
|
||||
// When
|
||||
composeTestRule.setContent {
|
||||
PermissionDialog(
|
||||
title = "Test",
|
||||
message = "Test message",
|
||||
onDismiss = {},
|
||||
onOpenSettings = { settingsClicked = true }
|
||||
)
|
||||
}
|
||||
|
||||
// Then
|
||||
composeTestRule.onNodeWithText("설정 열기").performClick()
|
||||
assert(settingsClicked)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `PermissionDialog should call onDismiss when cancel button clicked`() {
|
||||
// Given
|
||||
var dismissed = false
|
||||
|
||||
// When
|
||||
composeTestRule.setContent {
|
||||
PermissionDialog(
|
||||
title = "Test",
|
||||
message = "Test message",
|
||||
onDismiss = { dismissed = true },
|
||||
onOpenSettings = {}
|
||||
)
|
||||
}
|
||||
|
||||
// Then
|
||||
composeTestRule.onNodeWithText("취소").performClick()
|
||||
assert(dismissed)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user