Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 3 additions & 2 deletions src/main/kotlin/com/ecwid/apiclient/v3/ApiClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ import com.ecwid.apiclient.v3.dto.customergroup.request.*
import com.ecwid.apiclient.v3.dto.customergroup.result.*
import com.ecwid.apiclient.v3.dto.instantsite.redirects.request.*
import com.ecwid.apiclient.v3.dto.instantsite.redirects.result.*
import com.ecwid.apiclient.v3.dto.order.request.*
import com.ecwid.apiclient.v3.dto.order.result.*
import com.ecwid.apiclient.v3.dto.productreview.request.*
import com.ecwid.apiclient.v3.dto.productreview.result.*
import com.ecwid.apiclient.v3.dto.producttype.request.*
Expand Down Expand Up @@ -55,6 +53,7 @@ import kotlin.reflect.KClass
open class ApiClient private constructor(
protected val apiClientHelper: ApiClientHelper,
storeProfileApiClient: StoreProfileApiClient,
brandsApiClient: BrandsApiClient,
productsApiClient: ProductsApiClient,
categoriesApiClient: CategoriesApiClient,
ordersApiClient: OrdersApiClient,
Expand All @@ -76,6 +75,7 @@ open class ApiClient private constructor(
storeExtrafieldsApiClient: StoreExtrafieldsApiClientImpl,
) :
StoreProfileApiClient by storeProfileApiClient,
BrandsApiClient by brandsApiClient,
ProductsApiClient by productsApiClient,
CategoriesApiClient by categoriesApiClient,
OrdersApiClient by ordersApiClient,
Expand All @@ -99,6 +99,7 @@ open class ApiClient private constructor(
constructor(apiClientHelper: ApiClientHelper) : this(
apiClientHelper = apiClientHelper,
storeProfileApiClient = StoreProfileApiClientImpl(apiClientHelper),
brandsApiClient = BrandsApiClientImpl(apiClientHelper),
productsApiClient = ProductsApiClientImpl(apiClientHelper),
categoriesApiClient = CategoriesApiClientImpl(apiClientHelper),
ordersApiClient = OrdersApiClientImpl(apiClientHelper),
Expand Down
21 changes: 21 additions & 0 deletions src/main/kotlin/com/ecwid/apiclient/v3/BrandsApiClient.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.ecwid.apiclient.v3

import com.ecwid.apiclient.v3.dto.brand.request.BrandsSearchRequest
import com.ecwid.apiclient.v3.dto.brand.result.BrandsSearchResult
import com.ecwid.apiclient.v3.dto.common.PartialResult
import kotlin.reflect.KClass

// Brands
// https://api-docs.ecwid.com/reference/product-brands
interface BrandsApiClient {
fun searchBrands(request: BrandsSearchRequest): BrandsSearchResult
fun <Result> searchBrands(request: BrandsSearchRequest, resultClass: KClass<Result>): Result
where Result : PartialResult<BrandsSearchResult>
}

@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
inline fun <reified Result : PartialResult<BrandsSearchResult>> BrandsApiClient.searchBrands(
request: BrandsSearchRequest
): Result {
return searchBrands(request, resultClass = Result::class)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.ecwid.apiclient.v3.dto.brand.request

import com.ecwid.apiclient.v3.dto.ApiRequest
import com.ecwid.apiclient.v3.dto.common.PagingRequest
import com.ecwid.apiclient.v3.impl.RequestInfo
import com.ecwid.apiclient.v3.responsefields.ResponseFields

sealed class BrandsSearchRequest : ApiRequest {

data class ByFilters(
val limit: Int = 100,
override val offset: Int = 0,
val lang: String? = null,
val hiddenBrands: Boolean? = null,
val baseUrl: String? = null,
val cleanUrls: Boolean? = null,
val sortBy: SortOrder? = null,
val responseFields: ResponseFields = ResponseFields.All,
) : BrandsSearchRequest(), PagingRequest<ByFilters> {
override fun toRequestInfo() = RequestInfo.createGetRequest(
pathSegments = listOf(
"brands",
),
params = toParams(),
responseFields = responseFields,
)

private fun toParams(): Map<String, String> {
val request = this
return mutableMapOf<String, String>().apply {
put("limit", request.limit.toString())
put("offset", request.offset.toString())
request.lang?.let { put("lang", it) }
request.hiddenBrands?.let { put("hiddenBrands", it.toString()) }
request.baseUrl?.let { put("baseUrl", it) }
request.cleanUrls?.let { put("cleanUrls", it.toString()) }
request.sortBy?.let { put("sortBy", it.name) }
}.toMap()
}

override fun copyWithOffset(offset: Int) = copy(offset = offset)
}

@Suppress("unused")
enum class SortOrder {
PRODUCT_COUNT_DESC,
NAME_ASC,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.ecwid.apiclient.v3.dto.brand.result

import com.ecwid.apiclient.v3.dto.common.ApiResultDTO

data class BrandsSearchResult(
val items: List<FetchedBrand> = listOf(),
val count: Int = 0,
val total: Int = 0,
val limit: Int = 0,
val offset: Int = 0
) : ApiResultDTO
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.ecwid.apiclient.v3.dto.brand.result

import com.ecwid.apiclient.v3.dto.common.ApiFetchedDTO
import com.ecwid.apiclient.v3.dto.common.ApiResultDTO

data class FetchedBrand(
val name: String = "",
val nameTranslated: Map<String, String>? = null,
val productsFilteredByBrandUrl: String? = null,
) : ApiFetchedDTO, ApiResultDTO {
override fun getModifyKind() = ApiFetchedDTO.ModifyKind.ReadOnly
}
26 changes: 26 additions & 0 deletions src/main/kotlin/com/ecwid/apiclient/v3/impl/BrandsApiClientImpl.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.ecwid.apiclient.v3.impl

import com.ecwid.apiclient.v3.ApiClientHelper
import com.ecwid.apiclient.v3.BrandsApiClient
import com.ecwid.apiclient.v3.dto.brand.request.BrandsSearchRequest
import com.ecwid.apiclient.v3.dto.brand.result.BrandsSearchResult
import com.ecwid.apiclient.v3.dto.common.PartialResult
import kotlin.reflect.KClass

internal class BrandsApiClientImpl(
private val apiClientHelper: ApiClientHelper,
) : BrandsApiClient {

override fun searchBrands(request: BrandsSearchRequest) =
apiClientHelper.makeObjectResultRequest<BrandsSearchResult>(request)

override fun <Result : PartialResult<BrandsSearchResult>> searchBrands(
request: BrandsSearchRequest,
resultClass: KClass<Result>
): Result {
return apiClientHelper.makeObjectPartialResultRequest(
request = request,
resultClass = resultClass,
)
}
}
96 changes: 96 additions & 0 deletions src/test/kotlin/com/ecwid/apiclient/v3/entity/BrandsTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package com.ecwid.apiclient.v3.entity

import com.ecwid.apiclient.v3.dto.brand.request.BrandsSearchRequest
import com.ecwid.apiclient.v3.dto.product.request.ProductCreateRequest
import com.ecwid.apiclient.v3.dto.product.request.ProductsSearchRequest.ByFilters
import com.ecwid.apiclient.v3.dto.product.request.UpdatedProduct
import com.ecwid.apiclient.v3.dto.product.request.UpdatedProduct.*
import com.ecwid.apiclient.v3.util.randomAlphanumeric
import com.ecwid.apiclient.v3.util.randomPrice
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.BeforeEach
import kotlin.test.Test
import kotlin.test.assertEquals

class BrandsTest : BaseEntityTest() {

@BeforeEach
override fun beforeEach() {
super.beforeEach()

initStoreProfile()
removeAllProducts()
}

@Test
fun getBrands() {
val brandedProductsCreateResult = createProductsWithBrands()

// Waiting till product became available for searching
brandedProductsCreateResult.skus.forEach { sku ->
waitForIndexedProducts(
productsSearchRequest = ByFilters(sku = sku),
desiredProductCount = 1
)
}

val result = apiClient.searchBrands(BrandsSearchRequest.ByFilters())
assertEquals(
brandedProductsCreateResult.brandNames,
result.items.map { it.name }
)
}

private fun createProductsWithBrands(productsCount: Int = 5): BrandedProductsCreateResult {
val brands = mutableListOf<String>()
val skus = mutableListOf<String>()

for (i in 1..productsCount) {
val randomBrand = randomAlphanumeric(8)
val randomSku = randomAlphanumeric(10)
val price = randomPrice()

val productCreateRequest = ProductCreateRequest(
newProduct = UpdatedProduct(
name = "Product $i ${randomAlphanumeric(8)}",
sku = randomSku,
price = price,
compareToPrice = 2 * price,
enabled = true,
quantity = 10,
attributes = listOf(
AttributeValue.createBrandAttributeValue(randomBrand),
),
options = listOf(
ProductOption.createSelectOption(
name = "Color",
choices = listOf(
ProductOptionChoice("Black"),
ProductOptionChoice("White"),
ProductOptionChoice("Yellow"),
ProductOptionChoice("Red")
),
defaultChoice = 0,
required = true
)
)
)
)
val productCreateResult = apiClient.createProduct(productCreateRequest)
assertTrue(productCreateResult.id > 0)

skus.add(randomSku)
brands.add(randomBrand)
}

return BrandedProductsCreateResult(
brandNames = brands,
skus = skus,
)
}

data class BrandedProductsCreateResult(
val brandNames: List<String>,
val skus: List<String>,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ val nullablePropertyRules: List<NullablePropertyRule<*, *>> = listOf(
productReviewMassUpdateRequestNullablePropertyRules,
productReviewSearchRequestNullablePropertyRules,
fetchedCustomersConfigNullablePropertyRules,
brandsSearchRequestNullablePropertyRules,
fetchedBrandNullablePropertyRules,
).flatten()

sealed class NullablePropertyRule<T, R>(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.ecwid.apiclient.v3.rule.nullablepropertyrules

import com.ecwid.apiclient.v3.dto.brand.request.BrandsSearchRequest
import com.ecwid.apiclient.v3.rule.NullablePropertyRule
import com.ecwid.apiclient.v3.rule.NullablePropertyRule.AllowNullable

val brandsSearchRequestNullablePropertyRules: List<NullablePropertyRule<*, *>> = listOf(
AllowNullable(BrandsSearchRequest.ByFilters::lang),
AllowNullable(BrandsSearchRequest.ByFilters::hiddenBrands),
AllowNullable(BrandsSearchRequest.ByFilters::baseUrl),
AllowNullable(BrandsSearchRequest.ByFilters::cleanUrls),
AllowNullable(BrandsSearchRequest.ByFilters::sortBy),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.ecwid.apiclient.v3.rule.nullablepropertyrules

import com.ecwid.apiclient.v3.dto.brand.result.FetchedBrand
import com.ecwid.apiclient.v3.rule.NullablePropertyRule
import com.ecwid.apiclient.v3.rule.NullablePropertyRule.AllowNullable

val fetchedBrandNullablePropertyRules: List<NullablePropertyRule<*, *>> = listOf(
AllowNullable(FetchedBrand::nameTranslated),
AllowNullable(FetchedBrand::productsFilteredByBrandUrl),
)
4 changes: 2 additions & 2 deletions src/test/kotlin/com/ecwid/apiclient/v3/util/OrderUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ fun generateTestOrder(): UpdatedOrder {
shippingMethodName = "Method " + randomAlphanumeric(8),
shippingRate = randomPrice(),
estimatedTransitTime = "Estimates " + randomAlphanumeric(8),
isPickup = false,
isPickup = true,
pickupInstruction = "Instruction " + randomAlphanumeric(64),
fulfillmentType = FulfillmentType.SHIPPING
fulfillmentType = FulfillmentType.PICKUP
),
taxesOnShipping = listOf(),
handlingFee = UpdatedOrder.HandlingFee(
Expand Down
Loading