Skip to content

Commit 9311980

Browse files
Merge pull request #5 from MoscowSquad/feature/suggest-clothes-test
Feature/suggest clothes test
2 parents c9335dc + 9c81178 commit 9311980

File tree

4 files changed

+225
-3
lines changed

4 files changed

+225
-3
lines changed

build.gradle.kts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ dependencies {
1717
implementation("io.arrow-kt:arrow-core:2.0.1")
1818
implementation("io.arrow-kt:arrow-fx-coroutines:2.0.1")
1919
implementation("io.insert-koin:koin-core:4.0.2")
20+
implementation("com.github.doyaaaaaken:kotlin-csv-jvm:1.9.0")
2021
testImplementation("org.jetbrains.kotlin:kotlin-test")
2122
testImplementation("org.junit.jupiter:junit-jupiter-api:5.12.0-M1")
2223
testImplementation("io.mockk:mockk:1.13.16")
@@ -35,9 +36,10 @@ dependencies {
3536
implementation("io.ktor:ktor-client-cio:$ktor_version")
3637
implementation("io.ktor:ktor-client-content-negotiation:$ktor_version")
3738
implementation("io.ktor:ktor-serialization-kotlinx-json:$ktor_version")
39+
implementation(kotlin("stdlib-jdk8"))
3840

3941

40-
}
42+
}
4143

4244
tasks.test {
4345
useJUnitPlatform()

settings.gradle.kts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
pluginManagement {
2+
plugins {
3+
kotlin("jvm") version "2.1.0"
4+
}
5+
}
16
plugins {
27
id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0"
38
}
Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,51 @@
11
package domain.use_cases
22

3-
import domain.models.CurrentWeather
3+
import WeatherRepository
44

55
class SuggestClothesBasedOnWeatherUseCase(
6-
private val weather: CurrentWeather
6+
private val weatherRepository: WeatherRepository
77
) {
8+
suspend fun getSuggestClothesByWeather(latitude: Double, longitude: Double): List<String>{
9+
val weather = weatherRepository.getCurrentWeather(latitude, longitude)
10+
val suggestions = mutableListOf<String>()
11+
val temperature = weather.temperature2m.toFloat()
12+
val windSpeed = weather.windSpeed10m.toFloat()
13+
val cloudCover = weather.cloudCover.toInt()
14+
val isDay = weather.isDay == 1
15+
val weatherCode = weather.weatherCode.toInt()
16+
val rain = weather.rain.toFloat()
17+
val snowfall = weather.snowfall.toFloat()
18+
19+
// Temperature-based suggestions
20+
when {
21+
temperature > 30 -> {
22+
suggestions.addAll(listOf("very light clothes", "tank tops", "shorts"))
23+
}
24+
temperature in 25f..30f -> {
25+
suggestions.addAll(listOf("light T-shirt", "shorts", "breathable wear"))
26+
}
27+
temperature < 0 -> {
28+
suggestions.addAll(listOf("heavy winter coat", "gloves", "scarf"))
29+
}
30+
}
31+
32+
// Wind-based suggestions
33+
when {
34+
windSpeed > 15 -> suggestions.add("windbreaker")
35+
windSpeed in 8f..15f -> suggestions.add("light jacket")
36+
}
37+
38+
// Precipitation-based suggestions
39+
when {
40+
rain > 0 -> suggestions.addAll(listOf("waterproof jacket", "umbrella"))
41+
snowfall > 0 -> suggestions.addAll(listOf("snow boots", "insulated gloves"))
42+
}
43+
44+
// Nighttime suggestion
45+
if (!isDay && temperature < 18) {
46+
suggestions.add("reflective clothing")
47+
}
48+
49+
return suggestions.distinct()
50+
}
851
}
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
package domain.use_cases
2+
3+
import WeatherRepository
4+
import com.google.common.truth.Truth
5+
import domain.models.CurrentWeather
6+
import org.junit.jupiter.api.Test
7+
import com.google.common.truth.Truth.assertThat
8+
import io.mockk.coEvery
9+
import io.mockk.mockk
10+
import kotlinx.coroutines.test.runTest
11+
import org.junit.jupiter.api.BeforeEach
12+
13+
class SuggestClothesBasedOnWeatherUseCaseTest {
14+
private lateinit var repository: WeatherRepository
15+
private lateinit var useCase: SuggestClothesBasedOnWeatherUseCase
16+
17+
@BeforeEach
18+
fun setUp() {
19+
repository = mockk(relaxed = true)
20+
useCase = SuggestClothesBasedOnWeatherUseCase(repository)
21+
}
22+
23+
@Test
24+
fun `getSuggestClothesByWeather() should suggest very light clothes when temperature is greater than 30 C`() = runTest {
25+
// Given
26+
val weather = createWeather(temperature2m = 32.0)
27+
28+
coEvery { repository.getCurrentWeather(any(), any()) } returns weather
29+
30+
// When
31+
val suggestions = useCase.getSuggestClothesByWeather(52.52,13.419998)
32+
33+
// Then
34+
assertThat(suggestions).containsAtLeast(
35+
"very light clothes",
36+
"tank tops",
37+
"shorts"
38+
)
39+
}
40+
41+
@Test
42+
fun `getSuggestClothesByWeather() should suggest light T-shirt when temperature between 25-30 C`() = runTest{
43+
// Given
44+
val weather = createWeather(temperature2m = 27.0)
45+
46+
coEvery { repository.getCurrentWeather(any(), any()) } returns weather
47+
48+
// When
49+
val suggestions = useCase.getSuggestClothesByWeather(52.52,13.419998)
50+
51+
// Then
52+
assertThat(suggestions).containsAtLeast(
53+
"light T-shirt",
54+
"shorts",
55+
"breathable wear"
56+
)
57+
}
58+
59+
@Test
60+
fun `getSuggestClothesByWeather() should suggest jacket when temperature is less than 0 C`() = runTest {
61+
// Given
62+
val weather = createWeather(temperature2m = -5.0)
63+
64+
coEvery { repository.getCurrentWeather(any(), any()) } returns weather
65+
66+
// When
67+
val suggestions = useCase.getSuggestClothesByWeather(52.52,13.419998)
68+
69+
// Then
70+
assertThat(suggestions).containsAtLeast(
71+
"heavy winter coat",
72+
"gloves",
73+
"scarf"
74+
)
75+
}
76+
77+
@Test
78+
fun `getSuggestClothesByWeather() should suggest windbreaker when wind speed is greater than 15 kmh`() = runTest {
79+
// Given
80+
val weather = createWeather(windSpeed10m = 17.0)
81+
coEvery { repository.getCurrentWeather(any(), any()) } returns weather
82+
83+
// When
84+
val suggestions = useCase.getSuggestClothesByWeather(52.52,13.419998)
85+
86+
// Then
87+
assertThat(suggestions).contains("windbreaker")
88+
}
89+
90+
@Test
91+
fun `getSuggestClothesByWeather() should suggest light jacket when wind speed 8-15 kmh`() = runTest {
92+
// Given
93+
val weather = createWeather(windSpeed10m = 10.0)
94+
coEvery { repository.getCurrentWeather(any(), any()) } returns weather
95+
96+
// When
97+
val suggestions = useCase.getSuggestClothesByWeather(52.52,13.419998)
98+
99+
// Then
100+
assertThat(suggestions).contains("light jacket")
101+
}
102+
103+
@Test
104+
fun `getSuggestClothesByWeather() should suggest waterproof jacket or umbrella when rain is greater than 0 mm`() = runTest {
105+
// Given
106+
val weather = createWeather(rain = 2.00)
107+
108+
coEvery { repository.getCurrentWeather(any(), any()) } returns weather
109+
110+
// When
111+
val suggestions = useCase.getSuggestClothesByWeather(52.52,13.419998)
112+
113+
// Then
114+
assertThat(suggestions).containsAtLeast("waterproof jacket", "umbrella")
115+
}
116+
117+
@Test
118+
fun `getSuggestClothesByWeather() should suggest snow boots or insulated gloves when snowfall is greater than 0 cm`() = runTest {
119+
// Given
120+
val weather = createWeather(snowfall = 3.00)
121+
122+
coEvery { repository.getCurrentWeather(any(), any()) } returns weather
123+
124+
// When
125+
val suggestions = useCase.getSuggestClothesByWeather(52.52,13.419998)
126+
127+
// Then
128+
assertThat(suggestions).containsAtLeast("snow boots", "insulated gloves")
129+
}
130+
131+
@Test
132+
fun `getSuggestClothesByWeather() should suggest reflective clothing layers at night and temperature is less than 18`() = runTest {
133+
// Given
134+
val weather = createWeather(isDay = 0, temperature2m = 15.0)
135+
136+
coEvery { repository.getCurrentWeather(any(), any()) } returns weather
137+
138+
// When
139+
val suggestions = useCase.getSuggestClothesByWeather(52.52,13.419998)
140+
141+
// Then
142+
assertThat(suggestions).contains("reflective clothing")
143+
}
144+
145+
fun createWeather(
146+
temperature2m: Double = 32.0,
147+
windSpeed10m: Double = 5.0,
148+
cloudCover: Double = 20.0,
149+
isDay: Int = 1,
150+
relativeHumidity2m: Double = 50.0,
151+
apparentTemperature: Double = 33.0,
152+
rain: Double = 0.0,
153+
snowfall: Double = 0.0,
154+
weatherCode: Double = 1.0,
155+
time: String = "2025-05-07T13:45",
156+
interval: Double = 900.0
157+
): CurrentWeather {
158+
return CurrentWeather(
159+
temperature2m = temperature2m,
160+
windSpeed10m = windSpeed10m,
161+
cloudCover = cloudCover,
162+
isDay = isDay,
163+
relativeHumidity2m = relativeHumidity2m,
164+
apparentTemperature = apparentTemperature,
165+
rain = rain,
166+
snowfall = snowfall,
167+
weatherCode = weatherCode,
168+
time = time,
169+
interval = interval
170+
)
171+
}
172+
}

0 commit comments

Comments
 (0)