sales and news request and test

This commit is contained in:
user5 2025-05-27 12:19:10 +03:00
parent c0de6f6606
commit 7f699d5478
8 changed files with 134 additions and 28 deletions

View File

@ -1,8 +1,9 @@
package com.example.api.core.data.core package com.example.api.core.data.core
import com.example.api.core.data.dto.AuthUserResponseDto import com.example.api.core.data.dto.AuthUserResponseDto
import com.example.api.core.data.dto.RegisterUserDto
import com.example.api.core.data.dto.ProjectsDto import com.example.api.core.data.dto.ProjectsDto
import com.example.api.core.data.dto.RegisterUserDto
import com.example.api.core.data.dto.SalesAndNewsDto
import com.example.api.core.data.dto.SignInUserDto import com.example.api.core.data.dto.SignInUserDto
import com.example.api.core.data.dto.UserResponseDto import com.example.api.core.data.dto.UserResponseDto
import retrofit2.http.Body import retrofit2.http.Body
@ -25,6 +26,6 @@ internal interface ApiService {
@GET("collections/project/records") @GET("collections/project/records")
suspend fun projects(): ProjectsDto suspend fun projects(): ProjectsDto
// @GET("collections/products/records") @GET("collections/news/records")
// suspend fun products(): suspend fun salesAndNews(): SalesAndNewsDto
} }

View File

@ -0,0 +1,12 @@
package com.example.api.core.data.dto
import kotlinx.serialization.Serializable
@Serializable
internal data class SalesAndNewsDto(
val items: List<SalesAndNewsItemDto>,
val page: Int,
val perPage: Int,
val totalItems: Int,
val totalPages: Int
)

View File

@ -0,0 +1,13 @@
package com.example.api.core.data.dto
import kotlinx.serialization.Serializable
@Serializable
internal data class SalesAndNewsItemDto(
val collectionId: String,
val collectionName: String,
val created: String,
val id: String,
val newsImage: String,
val updated: String
)

View File

@ -169,6 +169,49 @@ class ServiceTest {
assertEquals("/collections/project/records", request.path) assertEquals("/collections/project/records", request.path)
} }
@Test
fun test_sales_and_news() = runBlocking {
val response = """
{
"items": [
{
"collectionId": "pbc_2599178718",
"collectionName": "News",
"created": "2025-05-26 14:21:46.284Z",
"id": "yxe08bp4woz996w",
"newsImage": "banner_u9uqsy4sf9.png",
"updated": "2025-05-26 15:29:41.083Z"
},
{
"collectionId": "pbc_2599178718",
"collectionName": "News",
"created": "2025-05-26 15:29:50.831Z",
"id": "lqg3hpgn46efgmz",
"newsImage": "banner_2_10pjar2fq7.png",
"updated": "2025-05-26 15:29:50.831Z"
}
],
"page": 1,
"perPage": 30,
"totalItems": 2,
"totalPages": 1
}
""".trimIndent()
mockWebServer.enqueue(MockResponse().setResponseCode(200).setBody(response))
val responseResult = service.salesAndNews()
val request = mockWebServer.takeRequest()
assertEquals(2, responseResult.items.size)
assertEquals("News", responseResult.items.first().collectionName)
assertEquals("lqg3hpgn46efgmz", responseResult.items[1].id)
assertEquals("GET", request.method)
assertEquals("/collections/news/records", request.path)
}
@After @After
fun teardown() { fun teardown() {
mockWebServer.shutdown() mockWebServer.shutdown()

View File

@ -0,0 +1,25 @@
package com.example.api
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
/**
* Автор: Манякин Дмитрий (user5)
* Дата создания: 27.05.2025
* */
abstract class BaseViewModel : ViewModel() {
protected fun<T> handle(action: suspend () -> T, ui: (T) -> Unit) {
viewModelScope.launch(Dispatchers.IO) {
val result = action.invoke()
withContext(Dispatchers.Main) {
ui.invoke(result)
}
}
}
}

View File

@ -1,18 +1,13 @@
package com.example.api package com.example.api
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.api.core.domain.ApiRepository import com.example.api.core.domain.ApiRepository
import com.example.api.core.domain.AuthUserResponse import com.example.api.core.domain.AuthUserResponse
import com.example.api.core.domain.RegisterUser
import com.example.api.core.domain.Projects import com.example.api.core.domain.Projects
import com.example.api.core.domain.RegisterUser
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import javax.inject.Inject import javax.inject.Inject
/** /**
@ -23,41 +18,39 @@ import javax.inject.Inject
@HiltViewModel @HiltViewModel
class MainViewModel @Inject constructor( class MainViewModel @Inject constructor(
private val apiRepository: ApiRepository private val apiRepository: ApiRepository
) : ViewModel() { ) : BaseViewModel() {
private val _authUiState = private val _authUiState =
MutableStateFlow<FetchResultUiState<AuthUserResponse>>(FetchResultUiState.Initial()) MutableStateFlow<FetchResultUiState<AuthUserResponse>>(FetchResultUiState.Initial())
val authUiState: StateFlow<FetchResultUiState<AuthUserResponse>> val authUiState: StateFlow<FetchResultUiState<AuthUserResponse>>
get() = _authUiState.asStateFlow() get() = _authUiState.asStateFlow()
private val _ProjectsUiState = private val _projectsUiState =
MutableStateFlow<FetchResultUiState<Projects>>(FetchResultUiState.Initial()) MutableStateFlow<FetchResultUiState<Projects>>(FetchResultUiState.Initial())
val projectsUiState: StateFlow<FetchResultUiState<Projects>> val projectsUiState: StateFlow<FetchResultUiState<Projects>>
get() = _ProjectsUiState.asStateFlow() get() = _projectsUiState.asStateFlow()
fun auth(email: String, password: String) { fun auth(email: String, password: String) {
viewModelScope.launch(Dispatchers.IO) { handle(
val result = apiRepository.auth( action = {
RegisterUser( apiRepository.auth(
email = email, RegisterUser(
password = password, email = email,
passwordConfirm = password password = password,
passwordConfirm = password
)
) )
)
withContext(Dispatchers.Main) {
_authUiState.value = result.map(FetchResultMapper())
} }
) {
_authUiState.value = it.map(FetchResultMapper())
} }
} }
fun salesAndProjects() { fun salesAndProjects() {
viewModelScope.launch(Dispatchers.IO) { handle(
val result = apiRepository.projects() action = { apiRepository.projects() }
) {
withContext(Dispatchers.Main) { _projectsUiState.value = it.map(FetchResultMapper())
_ProjectsUiState.value = result.map(FetchResultMapper())
}
} }
} }
} }

View File

@ -0,0 +1,9 @@
package com.example.api
data class SalesAndNews(
val items: List<SalesAndNewsItem>,
val page: Int,
val perPage: Int,
val totalItems: Int,
val totalPages: Int
)

View File

@ -0,0 +1,10 @@
package com.example.api
data class SalesAndNewsItem(
val collectionId: String,
val collectionName: String,
val created: String,
val id: String,
val newsImage: String,
val updated: String
)