From c46bd0c894ef34c44d1a7294fc9fec2aaa16f7dc Mon Sep 17 00:00:00 2001 From: Alexey Zagaichuk Date: Mon, 28 Nov 2022 12:17:45 +0400 Subject: [PATCH 01/18] Update gradle wrapper from version 7.3.3 to 7.6 --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2e6e5897b..f42e62f37 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From cf890b5cce48b39ba33821fa4dbead6ff6129fd3 Mon Sep 17 00:00:00 2001 From: Alexey Zagaichuk Date: Mon, 28 Nov 2022 12:31:15 +0400 Subject: [PATCH 02/18] Update kotlin from version 1.5.32 to 1.7.21 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 4ac912172..f3c6eab8b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,7 +7,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { java signing - kotlin("jvm") version "1.5.32" + kotlin("jvm") version "1.7.21" id("com.adarshr.test-logger") version "2.1.1" id("io.codearte.nexus-staging") version "0.22.0" id("nebula.release") version "17.1.0" From dc452a3c3e28ded28387c06acd88ecc7ee2ae535 Mon Sep 17 00:00:00 2001 From: Alexey Zagaichuk Date: Mon, 28 Nov 2022 12:39:59 +0400 Subject: [PATCH 03/18] Update com.google.code.gson:gson from version 2.8.6 to 2.10 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index f3c6eab8b..849cd9464 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -24,7 +24,7 @@ dependencies { implementation(kotlin("stdlib-jdk8")) implementation(kotlin("reflect")) - api("com.google.code.gson:gson:2.8.6") + api("com.google.code.gson:gson:2.10") api("org.apache.httpcomponents:httpclient:4.5.13") testImplementation("org.junit.jupiter:junit-jupiter:5.7.0") From 4aed45f58683c3c161b689424debe2119c4935f1 Mon Sep 17 00:00:00 2001 From: Alexey Zagaichuk Date: Mon, 28 Nov 2022 12:41:45 +0400 Subject: [PATCH 04/18] Update org.junit.jupiter:junit-jupiter from version 5.7.0 to 5.9.1 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 849cd9464..3692efa6d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -27,7 +27,7 @@ dependencies { api("com.google.code.gson:gson:2.10") api("org.apache.httpcomponents:httpclient:4.5.13") - testImplementation("org.junit.jupiter:junit-jupiter:5.7.0") + testImplementation("org.junit.jupiter:junit-jupiter:5.9.1") testImplementation("org.reflections:reflections:0.9.11") testImplementation("uk.co.jemos.podam:podam:7.2.6.RELEASE") From abcdc086837f5777e5c036a78ea665fda5e78bc6 Mon Sep 17 00:00:00 2001 From: Alexey Zagaichuk Date: Mon, 28 Nov 2022 12:42:56 +0400 Subject: [PATCH 05/18] Update org.reflections:reflections from version 0.9.11 to 0.10.2 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 3692efa6d..8a4fa00c7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -28,7 +28,7 @@ dependencies { api("org.apache.httpcomponents:httpclient:4.5.13") testImplementation("org.junit.jupiter:junit-jupiter:5.9.1") - testImplementation("org.reflections:reflections:0.9.11") + testImplementation("org.reflections:reflections:0.10.2") testImplementation("uk.co.jemos.podam:podam:7.2.6.RELEASE") detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.17.1") From c21e9d41854d882d92c58c0664e409192c57b8b4 Mon Sep 17 00:00:00 2001 From: Alexey Zagaichuk Date: Mon, 28 Nov 2022 12:43:18 +0400 Subject: [PATCH 06/18] Update uk.co.jemos.podam:podam from version 7.2.6.RELEASE to 7.2.11.RELEASE --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 8a4fa00c7..3697e8b98 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -29,7 +29,7 @@ dependencies { testImplementation("org.junit.jupiter:junit-jupiter:5.9.1") testImplementation("org.reflections:reflections:0.10.2") - testImplementation("uk.co.jemos.podam:podam:7.2.6.RELEASE") + testImplementation("uk.co.jemos.podam:podam:7.2.11.RELEASE") detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.17.1") } From 2b1509c01db8919690ab883f55e7908338c54cb3 Mon Sep 17 00:00:00 2001 From: Alexey Zagaichuk Date: Mon, 28 Nov 2022 12:44:28 +0400 Subject: [PATCH 07/18] Update io.gitlab.arturbosch.detekt gradle plugin from version 1.17.1 to 1.22.0 --- build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 3697e8b98..cb0fee2df 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,7 +12,7 @@ plugins { id("io.codearte.nexus-staging") version "0.22.0" id("nebula.release") version "17.1.0" id("maven-publish") - id("io.gitlab.arturbosch.detekt") version "1.17.1" + id("io.gitlab.arturbosch.detekt") version "1.22.0" id("org.gradle.test-retry") version "1.4.1" } @@ -31,7 +31,7 @@ dependencies { testImplementation("org.reflections:reflections:0.10.2") testImplementation("uk.co.jemos.podam:podam:7.2.11.RELEASE") - detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.17.1") + detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.22.0") } configure { From 399fa3080eed62388bb124dcbc1397fd0f346fd7 Mon Sep 17 00:00:00 2001 From: Alexey Zagaichuk Date: Mon, 28 Nov 2022 12:45:26 +0400 Subject: [PATCH 08/18] Update com.adarshr.test-logger gradle plugin from version 2.1.1 to 3.2.0 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index cb0fee2df..ca1e913b3 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ plugins { java signing kotlin("jvm") version "1.7.21" - id("com.adarshr.test-logger") version "2.1.1" + id("com.adarshr.test-logger") version "3.2.0" id("io.codearte.nexus-staging") version "0.22.0" id("nebula.release") version "17.1.0" id("maven-publish") From 84e344b6f289c6457db5f2ccce28a0f509d2b03d Mon Sep 17 00:00:00 2001 From: Alexey Zagaichuk Date: Mon, 28 Nov 2022 12:46:16 +0400 Subject: [PATCH 09/18] Update io.codearte.nexus-staging gradle plugin from version 0.22.0 to 3.2.0 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index ca1e913b3..898711f3e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,7 +9,7 @@ plugins { signing kotlin("jvm") version "1.7.21" id("com.adarshr.test-logger") version "3.2.0" - id("io.codearte.nexus-staging") version "0.22.0" + id("io.codearte.nexus-staging") version "0.30.0" id("nebula.release") version "17.1.0" id("maven-publish") id("io.gitlab.arturbosch.detekt") version "1.22.0" From e8d8909e838a20689b6d40a8994116b96f9c8af4 Mon Sep 17 00:00:00 2001 From: Alexey Zagaichuk Date: Mon, 28 Nov 2022 12:52:07 +0400 Subject: [PATCH 10/18] Update actions/checkout GitHub Action from version 2 to 3 --- .github/workflows/pull-request.yml | 2 +- .github/workflows/push-to-master.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 705e59599..0e1200267 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -10,7 +10,7 @@ jobs: steps: - name: Checkout full repository history - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 diff --git a/.github/workflows/push-to-master.yml b/.github/workflows/push-to-master.yml index d065fb13f..9cd90e449 100644 --- a/.github/workflows/push-to-master.yml +++ b/.github/workflows/push-to-master.yml @@ -13,7 +13,7 @@ jobs: steps: - name: Checkout full repository history - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 From becb216214d2b406dbd512a57a33e6893bf3a097 Mon Sep 17 00:00:00 2001 From: Alexey Zagaichuk Date: Mon, 28 Nov 2022 12:54:43 +0400 Subject: [PATCH 11/18] Update actions/setup-java GitHub Action from version 2 to 3 --- .github/workflows/pull-request.yml | 2 +- .github/workflows/push-to-master.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 0e1200267..6102faed3 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -15,7 +15,7 @@ jobs: fetch-depth: 0 - name: Set up JDK 17 - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: java-version: '17' distribution: 'adopt' diff --git a/.github/workflows/push-to-master.yml b/.github/workflows/push-to-master.yml index 9cd90e449..0511134af 100644 --- a/.github/workflows/push-to-master.yml +++ b/.github/workflows/push-to-master.yml @@ -18,7 +18,7 @@ jobs: fetch-depth: 0 - name: Set up JDK 17 - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: java-version: '17' distribution: 'adopt' From a4745bdb8147097b5d682010aa451eef03b4c904 Mon Sep 17 00:00:00 2001 From: Alexey Zagaichuk Date: Mon, 28 Nov 2022 12:58:17 +0400 Subject: [PATCH 12/18] Update actions/upload-artifact GitHub Action from version 2 to 3 --- .github/workflows/pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 6102faed3..b50b8f35e 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -44,7 +44,7 @@ jobs: GITHUB_HEAD_REF: ${{ github.head_ref }} - name: Upload artifacts with checks results - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 if: failure() with: name: check-results From f4792e1155bfac9fc776206babc7140835486c55 Mon Sep 17 00:00:00 2001 From: Alexey Zagaichuk Date: Mon, 28 Nov 2022 12:59:38 +0400 Subject: [PATCH 13/18] Update github/codeql-action/upload-sarif GitHub Action from version 1 to 2 --- .github/workflows/pull-request.yml | 2 +- .github/workflows/push-to-master.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index b50b8f35e..56882c08c 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -53,7 +53,7 @@ jobs: ${{ github.workspace }}/build/reports/detekt/detekt.html - name: Upload static analysis results - uses: github/codeql-action/upload-sarif@v1 + uses: github/codeql-action/upload-sarif@v2 if: always() with: sarif_file: ${{ github.workspace }}/build/reports/detekt/detekt.sarif diff --git a/.github/workflows/push-to-master.yml b/.github/workflows/push-to-master.yml index 0511134af..805b717dc 100644 --- a/.github/workflows/push-to-master.yml +++ b/.github/workflows/push-to-master.yml @@ -44,7 +44,7 @@ jobs: GRGIT_PASS: ${{ secrets.GRGIT_PASS }} - name: Upload static analysis results - uses: github/codeql-action/upload-sarif@v1 + uses: github/codeql-action/upload-sarif@v2 if: always() with: sarif_file: ${{ github.workspace }}/build/reports/detekt/detekt.sarif From 857adfb87323abb6bbe50b31cdae9dab6d1c056a Mon Sep 17 00:00:00 2001 From: Alexey Zagaichuk Date: Mon, 28 Nov 2022 13:32:25 +0400 Subject: [PATCH 14/18] Fix new detekt inspection violations appeared after the update version of detekt plugin --- config/detekt.yml | 14 +++-- .../com/ecwid/apiclient/v3/ApiClient.kt | 14 +++-- .../com/ecwid/apiclient/v3/ApiClientHelper.kt | 12 +++- .../dto/batch/request/CreateBatchRequest.kt | 4 +- .../v3/dto/category/result/FetchedCategory.kt | 2 +- .../v3/dto/custom/CustomAppRequest.kt | 21 ------- .../request/GetProductFiltersRequest.kt | 60 +++++++++++++------ .../request/UpdatedExtrafieldConfig.kt | 4 +- .../profile/result/FetchedExtrafieldConfig.kt | 4 +- .../v3/impl/ProductVariationsApiClientImpl.kt | 2 - .../GsonProductFiltersDeserializer.kt | 6 +- .../v3/DTOsEmptinessCheckerUnitTest.kt | 1 - .../v3/FetchedUpdatedDTOsCheckerUnitTest.kt | 10 ---- .../ecwid/apiclient/v3/entity/BatchApiTest.kt | 4 +- .../ecwid/apiclient/v3/entity/CartsTest.kt | 1 - .../ecwid/apiclient/v3/entity/CouponsTest.kt | 1 - .../apiclient/v3/entity/CustomerGroupsTest.kt | 4 +- .../apiclient/v3/entity/ProductTypesTest.kt | 2 +- .../ecwid/apiclient/v3/entity/ProductsTest.kt | 6 +- .../v3/rule/NullablePropertyRules.kt | 9 +-- .../FetchedCategoryRules.kt | 4 +- .../FetchedOrderRules.kt | 4 +- .../FetchedVariationRules.kt | 2 +- 23 files changed, 97 insertions(+), 94 deletions(-) diff --git a/config/detekt.yml b/config/detekt.yml index 649016b2d..0d6f673cd 100644 --- a/config/detekt.yml +++ b/config/detekt.yml @@ -1,17 +1,17 @@ complexity: - ComplexMethod: + CyclomaticComplexMethod: threshold: 40 LargeClass: - excludes: ['**/test/**'] + excludes: [ '**/test/**' ] LongMethod: threshold: 100 - excludes: ['**/test/**'] + excludes: [ '**/test/**' ] LongParameterList: functionThreshold: 10 constructorThreshold: 15 - excludes: ['**/com/ecwid/apiclient/v3/ApiClient.kt'] + excludes: [ '**/com/ecwid/apiclient/v3/ApiClient.kt' ] NestedBlockDepth: - excludes: ['**/test/**'] + excludes: [ '**/test/**' ] TooManyFunctions: thresholdInFiles: 50 thresholdInClasses: 50 @@ -29,7 +29,7 @@ style: ReturnCount: max: 5 UnnecessaryAbstractClass: - excludes: ['**/test/**'] + excludes: [ '**/test/**' ] WildcardImport: active: false @@ -37,6 +37,8 @@ style: formatting: MaximumLineLength: maxLineLength: 180 + EnumEntryNameCase: + active: false # We need to fix all enums before enabling this inspection # Initially enabled NoBlankLineBeforeRbrace: active: false diff --git a/src/main/kotlin/com/ecwid/apiclient/v3/ApiClient.kt b/src/main/kotlin/com/ecwid/apiclient/v3/ApiClient.kt index cf535e806..9b7d209d3 100644 --- a/src/main/kotlin/com/ecwid/apiclient/v3/ApiClient.kt +++ b/src/main/kotlin/com/ecwid/apiclient/v3/ApiClient.kt @@ -116,12 +116,14 @@ interface StoreProfileApiClient { fun getStoreProfile(request: StoreProfileRequest): FetchedStoreProfile fun updateStoreProfile(request: StoreProfileUpdateRequest): StoreProfileUpdateResult fun getLatestStats(request: LatestStatsRequest): FetchedLatestStats - fun getShippingOptions(request: ShippingOptionsRequest): ShippingOptionsResult -// fun addShippingOption() -// fun updateShippingOption() - fun getPaymentOptions(request: PaymentOptionsRequest): PaymentOptionsResult -// fun addPaymentOption() -// fun updatePaymentOption() + fun getShippingOptions(request: ShippingOptionsRequest): ShippingOptionsResult + + // fun addShippingOption() + // fun updateShippingOption() + fun getPaymentOptions(request: PaymentOptionsRequest): PaymentOptionsResult + + // fun addPaymentOption() + // fun updatePaymentOption() fun uploadStoreLogo(request: StoreLogoUploadRequest): StoreLogoUploadResult fun removeStoreLogo(request: StoreLogoRemoveRequest): StoreLogoRemoveResult fun uploadInvoiceLogo(request: InvoiceLogoUploadRequest): InvoiceLogoUploadResult diff --git a/src/main/kotlin/com/ecwid/apiclient/v3/ApiClientHelper.kt b/src/main/kotlin/com/ecwid/apiclient/v3/ApiClientHelper.kt index 9111f938f..a337ff7ce 100644 --- a/src/main/kotlin/com/ecwid/apiclient/v3/ApiClientHelper.kt +++ b/src/main/kotlin/com/ecwid/apiclient/v3/ApiClientHelper.kt @@ -129,13 +129,16 @@ class ApiClientHelper private constructor( ) } } + is HttpResponse.Error -> { try { val responseBody = responseBytes.asString() logErrorResponseIfNeeded(requestId, requestTime, httpResponse.statusCode, responseBody) val ecwidError = if (responseBody.isNotBlank()) { jsonTransformer.deserialize(responseBody, EcwidApiError::class.java) - } else null + } else { + null + } throw EcwidApiException( statusCode = httpResponse.statusCode, reasonPhrase = httpResponse.reasonPhrase, @@ -151,6 +154,7 @@ class ApiClientHelper private constructor( ) } } + is HttpResponse.TransportError -> { logTransportErrorResponseIfNeeded( requestId, @@ -196,16 +200,19 @@ class ApiClientHelper private constructor( uri = createApiEndpointUri(pathSegments), params = params.withCredentialsParams(credentials) ) + HttpMethod.POST -> HttpRequest.HttpPostRequest( uri = createApiEndpointUri(pathSegments), params = params.withCredentialsParams(credentials), transportHttpBody = httpBody.prepare(jsonTransformer) ) + HttpMethod.PUT -> HttpRequest.HttpPutRequest( uri = createApiEndpointUri(pathSegments), params = params.withCredentialsParams(credentials), transportHttpBody = httpBody.prepare(jsonTransformer) ) + HttpMethod.DELETE -> HttpRequest.HttpDeleteRequest( uri = createApiEndpointUri(pathSegments), params = params.withCredentialsParams(credentials) @@ -393,12 +400,15 @@ internal fun HttpBody.prepare(jsonTransformer: JsonTransformer): TransportHttpBo val bodyAsBytes = jsonTransformer.serialize(obj, objExt).toByteArray() TransportHttpBody.ByteArrayBody(bodyAsBytes, MIME_TYPE_APPLICATION_JSON) } + is HttpBody.ByteArrayBody -> { TransportHttpBody.ByteArrayBody(bytes, mimeType) } + is HttpBody.InputStreamBody -> { TransportHttpBody.InputStreamBody(stream, mimeType) } + is HttpBody.LocalFileBody -> { TransportHttpBody.LocalFileBody(file, mimeType) } diff --git a/src/main/kotlin/com/ecwid/apiclient/v3/dto/batch/request/CreateBatchRequest.kt b/src/main/kotlin/com/ecwid/apiclient/v3/dto/batch/request/CreateBatchRequest.kt index 6c48d84cc..cdc593c3a 100644 --- a/src/main/kotlin/com/ecwid/apiclient/v3/dto/batch/request/CreateBatchRequest.kt +++ b/src/main/kotlin/com/ecwid/apiclient/v3/dto/batch/request/CreateBatchRequest.kt @@ -72,13 +72,15 @@ private data class SingleBatchRequest( is HttpBody.EmptyBody -> { null } + is HttpBody.JsonBody -> { requestInfo.httpBody.obj } + is HttpBody.ByteArrayBody, is HttpBody.InputStreamBody, is HttpBody.LocalFileBody -> { - throw IllegalStateException("Request type ${requestInfo.httpBody.javaClass.simpleName} is not allowed in batch requests") + error("Request type ${requestInfo.httpBody.javaClass.simpleName} is not allowed in batch requests") } } ) diff --git a/src/main/kotlin/com/ecwid/apiclient/v3/dto/category/result/FetchedCategory.kt b/src/main/kotlin/com/ecwid/apiclient/v3/dto/category/result/FetchedCategory.kt index 4ad102121..6a9f29192 100644 --- a/src/main/kotlin/com/ecwid/apiclient/v3/dto/category/result/FetchedCategory.kt +++ b/src/main/kotlin/com/ecwid/apiclient/v3/dto/category/result/FetchedCategory.kt @@ -20,7 +20,7 @@ data class FetchedCategory( val hdThumbnailUrl: String? = null, val thumbnailUrl: String? = null, - val imageUrl: String? = null, // TODO Cannot test due to bug https://track.ecwid.com/youtrack/issue/ECWID-53222 + val imageUrl: String? = null, // TODO Cannot test due to bug https://track.ecwid.com/youtrack/issue/ECWID-53222 val originalImageUrl: String? = null, val originalImage: PictureInfo? = null, val url: String? = null, diff --git a/src/main/kotlin/com/ecwid/apiclient/v3/dto/custom/CustomAppRequest.kt b/src/main/kotlin/com/ecwid/apiclient/v3/dto/custom/CustomAppRequest.kt index 3ef46b46b..321eb727f 100644 --- a/src/main/kotlin/com/ecwid/apiclient/v3/dto/custom/CustomAppRequest.kt +++ b/src/main/kotlin/com/ecwid/apiclient/v3/dto/custom/CustomAppRequest.kt @@ -290,25 +290,4 @@ data class CustomAppRequest( val height: Double? = null ) - fun forLogging(): CustomAppRequest { - return this.copy(merchantAppSettings = merchantAppSettings?.let { - MerchantAppSettings(it.map { (key, value) -> key to formatSettingValue(key, value) }.toMap()) - }) - } - - private fun formatSettingValue(key: String, value: String): String { - if (key == STORAGE_PUBLIC_CONFIG_KEY) { - return value - } - if (value.length <= 2) { - return SECRET_KEYS_PLACEHOLDER - } - return value.first() + SECRET_KEYS_PLACEHOLDER + value.last() - } - - companion object { - private const val STORAGE_PUBLIC_CONFIG_KEY = "public" - private const val SECRET_KEYS_PLACEHOLDER = "XXX" - } - } diff --git a/src/main/kotlin/com/ecwid/apiclient/v3/dto/product/request/GetProductFiltersRequest.kt b/src/main/kotlin/com/ecwid/apiclient/v3/dto/product/request/GetProductFiltersRequest.kt index cf61d3b79..ea5219c81 100644 --- a/src/main/kotlin/com/ecwid/apiclient/v3/dto/product/request/GetProductFiltersRequest.kt +++ b/src/main/kotlin/com/ecwid/apiclient/v3/dto/product/request/GetProductFiltersRequest.kt @@ -1,6 +1,7 @@ package com.ecwid.apiclient.v3.dto.product.request import com.ecwid.apiclient.v3.dto.ApiRequest +import com.ecwid.apiclient.v3.dto.product.request.GetProductFiltersRequest.* import com.ecwid.apiclient.v3.impl.RequestInfo import java.util.* import java.util.concurrent.TimeUnit @@ -110,28 +111,24 @@ data class GetProductFiltersRequest( private fun toParams(): Map { val request = this return mutableMapOf().apply { - put("filterFields", request.filterFields.joinToString(separator = ",") { filterFieldType -> - filterFieldType.getFilterFieldName() - }) + put("filterFields", request.filterFields.toFilterFields()) request.filterFacetLimits?.let { filterFacetLimits -> - val filterFacetLimitValue = filterFacetLimits - .toList() - .joinToString(separator = ",") { (filterFieldType, filterFacetLimit) -> - "${filterFieldType.getFilterFieldName()}:${filterFacetLimit.getFilterFacetLimitValue()}" - } - put("filterFacetLimit", filterFacetLimitValue) + put("filterFacetLimit", filterFacetLimits.toFilterFacetLimitValue()) } request.filterParentCategoryId?.let { filterParentCategoryId -> put("filterParentCategoryId", filterParentCategoryId.getFilterParentCategoryIdValue()) } - request.keyword?.let { keyword -> put("keyword", keyword) } - request.priceFrom?.let { priceFrom -> put("priceFrom", "$priceFrom") } - request.priceTo?.let { priceTo -> put("priceTo", "$priceTo") } + request.keyword?.let { keyword -> + put("keyword", keyword) + } + request.priceFrom?.let { priceFrom -> + put("priceFrom", "$priceFrom") + } + request.priceTo?.let { priceTo -> + put("priceTo", "$priceTo") + } request.categories?.let { categories -> - val categoriesValue = categories.joinToString(separator = ",") { categoryId -> - categoryId.getFilterParentCategoryIdValue() - } - put("categories", categoriesValue) + put("categories", categories.toCategoriesValue()) } request.includeProductsFromSubcategories?.let { includeProductsFromSubcategories -> put("includeProductsFromSubcategories", "$includeProductsFromSubcategories") @@ -161,9 +158,34 @@ data class GetProductFiltersRequest( put(attributeField.getFilterFieldName(), attributeValues.joinToString(separator = ",")) } } - request.inventory?.let { inventory -> put("inventory", if (inventory) "instock" else "outofstock") } - request.onSale?.let { onSale -> put("onsale", if (onSale) "onsale" else "notonsale") } - request.lang?.let { lang -> put("lang", lang) } + request.inventory?.let { inventory -> + put("inventory", if (inventory) "instock" else "outofstock") + } + request.onSale?.let { onSale -> + put("onsale", if (onSale) "onsale" else "notonsale") + } + request.lang?.let { lang -> + put("lang", lang) + } }.toMap() } + +} + +private fun List.toFilterFields(): String { + return joinToString(separator = ",", transform = FilterFieldType::getFilterFieldName) +} + +private fun Map.toFilterFacetLimitValue(): String { + return toList() + .joinToString(separator = ",") { (filterFieldType, filterFacetLimit) -> + "${filterFieldType.getFilterFieldName()}:${filterFacetLimit.getFilterFacetLimitValue()}" + } +} + +private fun List.toCategoriesValue(): String { + val categoriesValue = joinToString(separator = ",") { categoryId -> + categoryId.getFilterParentCategoryIdValue() + } + return categoriesValue } diff --git a/src/main/kotlin/com/ecwid/apiclient/v3/dto/profile/request/UpdatedExtrafieldConfig.kt b/src/main/kotlin/com/ecwid/apiclient/v3/dto/profile/request/UpdatedExtrafieldConfig.kt index 501309e5d..16d43cc46 100644 --- a/src/main/kotlin/com/ecwid/apiclient/v3/dto/profile/request/UpdatedExtrafieldConfig.kt +++ b/src/main/kotlin/com/ecwid/apiclient/v3/dto/profile/request/UpdatedExtrafieldConfig.kt @@ -3,10 +3,10 @@ package com.ecwid.apiclient.v3.dto.profile.request import com.ecwid.apiclient.v3.dto.common.ApiUpdatedDTO import com.ecwid.apiclient.v3.dto.common.ApiUpdatedDTO.ModifyKind import com.ecwid.apiclient.v3.dto.common.LocalizedValueMap +import com.ecwid.apiclient.v3.dto.profile.enums.CheckoutDisplaySection import com.ecwid.apiclient.v3.dto.profile.enums.ExtrafieldType -import com.ecwid.apiclient.v3.dto.profile.enums.SurchargeType import com.ecwid.apiclient.v3.dto.profile.enums.OrderDetailsDisplaySection -import com.ecwid.apiclient.v3.dto.profile.enums.CheckoutDisplaySection +import com.ecwid.apiclient.v3.dto.profile.enums.SurchargeType import com.ecwid.apiclient.v3.dto.profile.result.FetchedExtrafieldConfig data class UpdatedExtrafieldConfig( diff --git a/src/main/kotlin/com/ecwid/apiclient/v3/dto/profile/result/FetchedExtrafieldConfig.kt b/src/main/kotlin/com/ecwid/apiclient/v3/dto/profile/result/FetchedExtrafieldConfig.kt index 8cc35a2ba..d80480e5c 100644 --- a/src/main/kotlin/com/ecwid/apiclient/v3/dto/profile/result/FetchedExtrafieldConfig.kt +++ b/src/main/kotlin/com/ecwid/apiclient/v3/dto/profile/result/FetchedExtrafieldConfig.kt @@ -3,10 +3,10 @@ package com.ecwid.apiclient.v3.dto.profile.result import com.ecwid.apiclient.v3.dto.common.ApiFetchedDTO import com.ecwid.apiclient.v3.dto.common.ApiFetchedDTO.ModifyKind import com.ecwid.apiclient.v3.dto.common.LocalizedValueMap +import com.ecwid.apiclient.v3.dto.profile.enums.CheckoutDisplaySection import com.ecwid.apiclient.v3.dto.profile.enums.ExtrafieldType -import com.ecwid.apiclient.v3.dto.profile.enums.SurchargeType import com.ecwid.apiclient.v3.dto.profile.enums.OrderDetailsDisplaySection -import com.ecwid.apiclient.v3.dto.profile.enums.CheckoutDisplaySection +import com.ecwid.apiclient.v3.dto.profile.enums.SurchargeType import com.ecwid.apiclient.v3.dto.profile.request.UpdatedExtrafieldConfig data class FetchedExtrafieldConfig( diff --git a/src/main/kotlin/com/ecwid/apiclient/v3/impl/ProductVariationsApiClientImpl.kt b/src/main/kotlin/com/ecwid/apiclient/v3/impl/ProductVariationsApiClientImpl.kt index fb5c8bd36..a16182ccb 100644 --- a/src/main/kotlin/com/ecwid/apiclient/v3/impl/ProductVariationsApiClientImpl.kt +++ b/src/main/kotlin/com/ecwid/apiclient/v3/impl/ProductVariationsApiClientImpl.kt @@ -2,8 +2,6 @@ package com.ecwid.apiclient.v3.impl import com.ecwid.apiclient.v3.ApiClientHelper import com.ecwid.apiclient.v3.ProductVariationsApiClient -import com.ecwid.apiclient.v3.dto.variation.request.ProductVariationImageAsyncUploadRequest -import com.ecwid.apiclient.v3.dto.variation.result.ProductVariationImageAsyncUploadResult import com.ecwid.apiclient.v3.dto.variation.request.* import com.ecwid.apiclient.v3.dto.variation.result.* diff --git a/src/main/kotlin/com/ecwid/apiclient/v3/jsontransformer/gson/typeadapters/GsonProductFiltersDeserializer.kt b/src/main/kotlin/com/ecwid/apiclient/v3/jsontransformer/gson/typeadapters/GsonProductFiltersDeserializer.kt index 1370c5084..b2334a510 100644 --- a/src/main/kotlin/com/ecwid/apiclient/v3/jsontransformer/gson/typeadapters/GsonProductFiltersDeserializer.kt +++ b/src/main/kotlin/com/ecwid/apiclient/v3/jsontransformer/gson/typeadapters/GsonProductFiltersDeserializer.kt @@ -13,7 +13,6 @@ class GsonProductFiltersDeserializer : JsonDeserializer { typeOfT: Type, context: JsonDeserializationContext ): ProductFilters { - var priceFilter: PriceFilter? = null var inventoryFilterValues: InventoryFilterValues? = null var onSaleFilterValues: OnSaleFilterValues? = null @@ -27,15 +26,19 @@ class GsonProductFiltersDeserializer : JsonDeserializer { key == "price" -> { priceFilter = context.deserialize(jsonElement, PriceFilter::class.java) } + key == "inventory" -> { inventoryFilterValues = context.deserialize(jsonElement, InventoryFilterValues::class.java) } + key == "onsale" -> { onSaleFilterValues = context.deserialize(jsonElement, OnSaleFilterValues::class.java) } + key == "categories" -> { categoriesFilterValues = context.deserialize(jsonElement, CategoriesFilterValues::class.java) } + key.startsWith("option_") -> { val optionName = key.replaceFirst("option_", "") val optionFilterValues: OptionFilterValues = @@ -45,6 +48,7 @@ class GsonProductFiltersDeserializer : JsonDeserializer { newOptionsFilterMapValues[Option(optionName)] = optionFilterValues optionsFilterMapValues = newOptionsFilterMapValues } + key.startsWith("attribute_") -> { val attributeName = key.replaceFirst("attribute_", "") val attributeFilterValue: AttributeFilterValues = diff --git a/src/test/kotlin/com/ecwid/apiclient/v3/DTOsEmptinessCheckerUnitTest.kt b/src/test/kotlin/com/ecwid/apiclient/v3/DTOsEmptinessCheckerUnitTest.kt index 6350eae49..581ebf1f1 100644 --- a/src/test/kotlin/com/ecwid/apiclient/v3/DTOsEmptinessCheckerUnitTest.kt +++ b/src/test/kotlin/com/ecwid/apiclient/v3/DTOsEmptinessCheckerUnitTest.kt @@ -11,7 +11,6 @@ class DTOsEmptinessCheckerUnitTest { @Test fun `test DTOs check for emptiness and default fields value works well`() { - data class BooleanDTO( val booleanField1: Boolean, val booleanField2: Boolean, diff --git a/src/test/kotlin/com/ecwid/apiclient/v3/FetchedUpdatedDTOsCheckerUnitTest.kt b/src/test/kotlin/com/ecwid/apiclient/v3/FetchedUpdatedDTOsCheckerUnitTest.kt index 8faa64ccd..9448425dd 100644 --- a/src/test/kotlin/com/ecwid/apiclient/v3/FetchedUpdatedDTOsCheckerUnitTest.kt +++ b/src/test/kotlin/com/ecwid/apiclient/v3/FetchedUpdatedDTOsCheckerUnitTest.kt @@ -11,7 +11,6 @@ class FetchedUpdatedDTOsCheckerUnitTest { @Test fun `test field found in Fetched DTO but not found in Updated DTO`() { - data class FetchedDTO( val field1: Int, val field2: String @@ -38,7 +37,6 @@ class FetchedUpdatedDTOsCheckerUnitTest { @Test fun `test field in Fetched sub DTO but not found in Updated sub DTO`() { - data class FetchedSubDTO( val subField1: Double, val subField2: String @@ -75,7 +73,6 @@ class FetchedUpdatedDTOsCheckerUnitTest { @Test fun `test incompatible field types`() { - data class FetchedDTO( val field1: Int, val field2: String, @@ -117,7 +114,6 @@ class FetchedUpdatedDTOsCheckerUnitTest { @Test fun `test field is list in Fetched DTO but is not in Updated DTO`() { - data class FetchedDTO( val field1: Int, val field2: List @@ -149,7 +145,6 @@ class FetchedUpdatedDTOsCheckerUnitTest { @Test fun `test field is map in Fetched DTO but is not in Updated DTO`() { - data class FetchedDTO( val field1: Int, val field2: Map @@ -181,7 +176,6 @@ class FetchedUpdatedDTOsCheckerUnitTest { @Test fun `test incompatible list generic type for field in Fetched and Updated DTOs`() { - class FetchedListWrapper : ArrayList() data class FetchedDTO( @@ -223,7 +217,6 @@ class FetchedUpdatedDTOsCheckerUnitTest { @Test fun `test incompatible map generic types for field in Fetched and Updated DTOs`() { - class FetchedMapWrapper : HashMap() data class FetchedDTO( @@ -286,7 +279,6 @@ class FetchedUpdatedDTOsCheckerUnitTest { @Test fun `test non primitive fields types must not be shared between Fetched and Updated DTOs`() { - data class FetchedDTO( val field1: Int, val field2: SharedDTO, @@ -316,7 +308,6 @@ class FetchedUpdatedDTOsCheckerUnitTest { @Test fun `test ignored fields`() { - data class FetchedDTO( val field1: Int, val field2: String @@ -338,7 +329,6 @@ class FetchedUpdatedDTOsCheckerUnitTest { @Test fun `test success`() { - class FetchedListWrapper : ArrayList() class FetchedMapWrapper : HashMap() diff --git a/src/test/kotlin/com/ecwid/apiclient/v3/entity/BatchApiTest.kt b/src/test/kotlin/com/ecwid/apiclient/v3/entity/BatchApiTest.kt index 7c92265ec..68cf5ee29 100644 --- a/src/test/kotlin/com/ecwid/apiclient/v3/entity/BatchApiTest.kt +++ b/src/test/kotlin/com/ecwid/apiclient/v3/entity/BatchApiTest.kt @@ -56,10 +56,10 @@ class BatchApiTest : BaseEntityTest() { val productCreateResult = createResponses.first().toTypedResponse(ProductCreateResult::class.java) ) { - is TypedBatchResponse.Ok -> { Assertions.assertTrue(productCreateResult.value.id > 0) } + is TypedBatchResponse.ApiError -> Assertions.fail("Api error is unexpected") is TypedBatchResponse.ParseError -> Assertions.fail("Parse error is unexpected") is TypedBatchResponse.NotExecuted -> Assertions.fail("Not executed error is not expected") @@ -88,10 +88,10 @@ class BatchApiTest : BaseEntityTest() { val productsSearchResult = searchResponses.first().toTypedResponse(ProductsSearchResult::class.java) ) { - is TypedBatchResponse.Ok -> { Assertions.assertTrue(productsSearchResult.value.count > 0) } + is TypedBatchResponse.ApiError -> Assertions.fail("Api error is unexpected") is TypedBatchResponse.ParseError -> Assertions.fail("Parse error is unexpected") is TypedBatchResponse.NotExecuted -> Assertions.fail("Not executed error is not expected") diff --git a/src/test/kotlin/com/ecwid/apiclient/v3/entity/CartsTest.kt b/src/test/kotlin/com/ecwid/apiclient/v3/entity/CartsTest.kt index 3ed0b4239..1859d539c 100644 --- a/src/test/kotlin/com/ecwid/apiclient/v3/entity/CartsTest.kt +++ b/src/test/kotlin/com/ecwid/apiclient/v3/entity/CartsTest.kt @@ -331,7 +331,6 @@ class CartsTest : BaseEntityTest() { @Test @Disabled("Will be fixed in ECWID-75364") fun testSearchCarts() { - // Create two carts val totalPrice = randomPrice() val cartForSearch1 = generateCartForTestingSearch(totalPrice, false) diff --git a/src/test/kotlin/com/ecwid/apiclient/v3/entity/CouponsTest.kt b/src/test/kotlin/com/ecwid/apiclient/v3/entity/CouponsTest.kt index dd9773689..336be1b9f 100644 --- a/src/test/kotlin/com/ecwid/apiclient/v3/entity/CouponsTest.kt +++ b/src/test/kotlin/com/ecwid/apiclient/v3/entity/CouponsTest.kt @@ -34,7 +34,6 @@ class CouponsTest : BaseEntityTest() { @Test fun testCouponLifecycle() { - // Create two products val productCreateResult1 = createTestProduct() val productCreateResult2 = createTestProduct() diff --git a/src/test/kotlin/com/ecwid/apiclient/v3/entity/CustomerGroupsTest.kt b/src/test/kotlin/com/ecwid/apiclient/v3/entity/CustomerGroupsTest.kt index d1c72d4ab..f19426e18 100644 --- a/src/test/kotlin/com/ecwid/apiclient/v3/entity/CustomerGroupsTest.kt +++ b/src/test/kotlin/com/ecwid/apiclient/v3/entity/CustomerGroupsTest.kt @@ -70,13 +70,13 @@ class CustomerGroupsTest : BaseEntityTest() { assertTrue(customerGroupCreateResult.id > 0) } - // Trying to request first page + // Trying to request first page val customerGroupsSearchRequest1 = CustomerGroupsSearchRequest(offset = 0, limit = 2) val customerGroupsSearchResult1 = apiClient.searchCustomerGroups(customerGroupsSearchRequest1) assertEquals(2 + 1, customerGroupsSearchResult1.count) // “General” group exists is on every page assertEquals(3, customerGroupsSearchResult1.total) - // Trying to request second and the last page + // Trying to request second and the last page val customerGroupsSearchRequest2 = CustomerGroupsSearchRequest(offset = 2, limit = 2) val customerGroupsSearchResult2 = apiClient.searchCustomerGroups(customerGroupsSearchRequest2) assertEquals(1 + 1, customerGroupsSearchResult2.count) // “General” group exists is on every page diff --git a/src/test/kotlin/com/ecwid/apiclient/v3/entity/ProductTypesTest.kt b/src/test/kotlin/com/ecwid/apiclient/v3/entity/ProductTypesTest.kt index 9e7523650..7a8467995 100644 --- a/src/test/kotlin/com/ecwid/apiclient/v3/entity/ProductTypesTest.kt +++ b/src/test/kotlin/com/ecwid/apiclient/v3/entity/ProductTypesTest.kt @@ -154,7 +154,7 @@ class ProductTypesTest : BaseEntityTest() { assertTrue(productTypeCreateResult.id > 0) } - // Trying to request all product types + // Trying to request all product types val customerGroupsSearchResult = apiClient.getAllProductTypes(ProductTypesGetAllRequest()) assertEquals(3 + 1, customerGroupsSearchResult.size) // “General” product type always exists in every store } diff --git a/src/test/kotlin/com/ecwid/apiclient/v3/entity/ProductsTest.kt b/src/test/kotlin/com/ecwid/apiclient/v3/entity/ProductsTest.kt index ae65617f8..3cf91b432 100644 --- a/src/test/kotlin/com/ecwid/apiclient/v3/entity/ProductsTest.kt +++ b/src/test/kotlin/com/ecwid/apiclient/v3/entity/ProductsTest.kt @@ -1,15 +1,11 @@ package com.ecwid.apiclient.v3.entity import com.ecwid.apiclient.v3.converter.toUpdated -import com.ecwid.apiclient.v3.dto.common.NullableUpdatedValue import com.ecwid.apiclient.v3.dto.category.request.CategoriesSearchRequest import com.ecwid.apiclient.v3.dto.category.request.CategoriesSearchRequest.ParentCategory import com.ecwid.apiclient.v3.dto.category.request.CategoryCreateRequest import com.ecwid.apiclient.v3.dto.category.request.UpdatedCategory -import com.ecwid.apiclient.v3.dto.common.AsyncPictureData -import com.ecwid.apiclient.v3.dto.common.LocalizedValueMap -import com.ecwid.apiclient.v3.dto.common.ProductCondition -import com.ecwid.apiclient.v3.dto.common.UploadFileData +import com.ecwid.apiclient.v3.dto.common.* import com.ecwid.apiclient.v3.dto.product.enums.ShippingSettingsType import com.ecwid.apiclient.v3.dto.product.request.* import com.ecwid.apiclient.v3.dto.product.request.GetProductFiltersRequest.* diff --git a/src/test/kotlin/com/ecwid/apiclient/v3/rule/NullablePropertyRules.kt b/src/test/kotlin/com/ecwid/apiclient/v3/rule/NullablePropertyRules.kt index f9efb03b1..5a7acbc4c 100644 --- a/src/test/kotlin/com/ecwid/apiclient/v3/rule/NullablePropertyRules.kt +++ b/src/test/kotlin/com/ecwid/apiclient/v3/rule/NullablePropertyRules.kt @@ -6,17 +6,18 @@ import com.ecwid.apiclient.v3.dto.cart.result.CartUpdateResult import com.ecwid.apiclient.v3.dto.cart.result.ConvertCartToOrderResult import com.ecwid.apiclient.v3.dto.order.result.DeletedOrder import com.ecwid.apiclient.v3.dto.payment.PaymentAppRequest -import com.ecwid.apiclient.v3.dto.product.request.* +import com.ecwid.apiclient.v3.dto.product.request.ProductInventoryUpdateRequest +import com.ecwid.apiclient.v3.dto.product.request.ProductUpdateRequest +import com.ecwid.apiclient.v3.dto.product.result.FetchedProduct import com.ecwid.apiclient.v3.dto.product.result.GetProductFiltersResult import com.ecwid.apiclient.v3.dto.product.result.ProductInventoryUpdateResult import com.ecwid.apiclient.v3.dto.profile.request.StoreProfileRequest +import com.ecwid.apiclient.v3.dto.profile.result.FetchedLatestStats +import com.ecwid.apiclient.v3.dto.storage.result.FetchedStorageData import com.ecwid.apiclient.v3.dto.variation.request.ProductVariationsRequest import com.ecwid.apiclient.v3.rule.NullablePropertyRule.AllowNullable import com.ecwid.apiclient.v3.rule.NullablePropertyRule.IgnoreNullable import com.ecwid.apiclient.v3.rule.nullablepropertyrules.* -import com.ecwid.apiclient.v3.dto.product.result.FetchedProduct -import com.ecwid.apiclient.v3.dto.profile.result.FetchedLatestStats -import com.ecwid.apiclient.v3.dto.storage.result.FetchedStorageData import kotlin.reflect.KProperty1 val otherNullablePropertyRules: List> = listOf( diff --git a/src/test/kotlin/com/ecwid/apiclient/v3/rule/nullablepropertyrules/FetchedCategoryRules.kt b/src/test/kotlin/com/ecwid/apiclient/v3/rule/nullablepropertyrules/FetchedCategoryRules.kt index 5174ea05f..ef026a120 100644 --- a/src/test/kotlin/com/ecwid/apiclient/v3/rule/nullablepropertyrules/FetchedCategoryRules.kt +++ b/src/test/kotlin/com/ecwid/apiclient/v3/rule/nullablepropertyrules/FetchedCategoryRules.kt @@ -2,11 +2,11 @@ package com.ecwid.apiclient.v3.rule.nullablepropertyrules import com.ecwid.apiclient.v3.dto.category.result.FetchedCategory import com.ecwid.apiclient.v3.rule.NullablePropertyRule -import com.ecwid.apiclient.v3.rule.NullablePropertyRule.IgnoreNullable import com.ecwid.apiclient.v3.rule.NullablePropertyRule.AllowNullable +import com.ecwid.apiclient.v3.rule.NullablePropertyRule.IgnoreNullable val fetchedCategoryNullablePropertyRules: List> = listOf( - IgnoreNullable(FetchedCategory::description), + IgnoreNullable(FetchedCategory::description), IgnoreNullable(FetchedCategory::descriptionTranslated), IgnoreNullable(FetchedCategory::enabledProductCount), IgnoreNullable(FetchedCategory::hdThumbnailUrl), diff --git a/src/test/kotlin/com/ecwid/apiclient/v3/rule/nullablepropertyrules/FetchedOrderRules.kt b/src/test/kotlin/com/ecwid/apiclient/v3/rule/nullablepropertyrules/FetchedOrderRules.kt index 14773271f..d8518ac22 100644 --- a/src/test/kotlin/com/ecwid/apiclient/v3/rule/nullablepropertyrules/FetchedOrderRules.kt +++ b/src/test/kotlin/com/ecwid/apiclient/v3/rule/nullablepropertyrules/FetchedOrderRules.kt @@ -2,8 +2,8 @@ package com.ecwid.apiclient.v3.rule.nullablepropertyrules import com.ecwid.apiclient.v3.dto.order.result.FetchedOrder import com.ecwid.apiclient.v3.rule.NullablePropertyRule -import com.ecwid.apiclient.v3.rule.NullablePropertyRule.IgnoreNullable import com.ecwid.apiclient.v3.rule.NullablePropertyRule.AllowNullable +import com.ecwid.apiclient.v3.rule.NullablePropertyRule.IgnoreNullable val fetchedOrderNullablePropertyRules: List> = listOf( AllowNullable(FetchedOrder.BaseOrderItemTax::name), @@ -284,7 +284,7 @@ val fetchedOrderNullablePropertyRules: List> = listOf AllowNullable(FetchedOrder.TaxInvoice::type), AllowNullable(FetchedOrder::invoices), AllowNullable(FetchedOrder::predictedPackage), - AllowNullable(FetchedOrder::externalOrderData), + AllowNullable(FetchedOrder::externalOrderData), AllowNullable(FetchedOrder.ExternalOrderData::externalOrderId), AllowNullable(FetchedOrder.ExternalOrderData::externalFulfillment), AllowNullable(FetchedOrder.ExternalOrderData::refererId), diff --git a/src/test/kotlin/com/ecwid/apiclient/v3/rule/nullablepropertyrules/FetchedVariationRules.kt b/src/test/kotlin/com/ecwid/apiclient/v3/rule/nullablepropertyrules/FetchedVariationRules.kt index 7030a6518..00eb34fa4 100644 --- a/src/test/kotlin/com/ecwid/apiclient/v3/rule/nullablepropertyrules/FetchedVariationRules.kt +++ b/src/test/kotlin/com/ecwid/apiclient/v3/rule/nullablepropertyrules/FetchedVariationRules.kt @@ -2,8 +2,8 @@ package com.ecwid.apiclient.v3.rule.nullablepropertyrules import com.ecwid.apiclient.v3.dto.variation.result.FetchedVariation import com.ecwid.apiclient.v3.rule.NullablePropertyRule -import com.ecwid.apiclient.v3.rule.NullablePropertyRule.IgnoreNullable import com.ecwid.apiclient.v3.rule.NullablePropertyRule.AllowNullable +import com.ecwid.apiclient.v3.rule.NullablePropertyRule.IgnoreNullable val fetchedVariationTypeNullablePropertyRules: List> = listOf( IgnoreNullable(FetchedVariation::attributes), From 59a3b62715a46a25bdd5c62f190842430cb26911 Mon Sep 17 00:00:00 2001 From: Alexey Zagaichuk Date: Mon, 28 Nov 2022 15:36:45 +0400 Subject: [PATCH 15/18] Adapt tests to update version of org.reflections:reflections dependency --- .../ecwid/apiclient/v3/DtoContractUnitTest.kt | 117 +++++++++++------- .../v3/util/DTORandomDataProviderStrategy.kt | 29 ++--- 2 files changed, 84 insertions(+), 62 deletions(-) diff --git a/src/test/kotlin/com/ecwid/apiclient/v3/DtoContractUnitTest.kt b/src/test/kotlin/com/ecwid/apiclient/v3/DtoContractUnitTest.kt index 585ecc30e..9317273f7 100644 --- a/src/test/kotlin/com/ecwid/apiclient/v3/DtoContractUnitTest.kt +++ b/src/test/kotlin/com/ecwid/apiclient/v3/DtoContractUnitTest.kt @@ -18,9 +18,8 @@ import org.junit.jupiter.api.Order import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestMethodOrder import org.reflections.Reflections -import org.reflections.scanners.MethodParameterScanner -import org.reflections.scanners.SubTypesScanner -import org.reflections.util.ClasspathHelper +import org.reflections.scanners.Scanners +import org.reflections.scanners.Scanners.SubTypes import org.reflections.util.ConfigurationBuilder import org.reflections.util.FilterBuilder import uk.co.jemos.podam.api.PodamFactoryImpl @@ -36,21 +35,53 @@ import kotlin.reflect.jvm.javaGetter @TestMethodOrder(OrderAnnotation::class) class DtoContractUnitTest { - private val convertersReflections = + private val convertersReflections = lazy { Reflections( ConfigurationBuilder() - .filterInputsBy(FilterBuilder().includePackage("com.ecwid.apiclient.v3.converter")) - .setUrls(ClasspathHelper.forPackage("")) - .setScanners(MethodParameterScanner()) + .forPackage("com.ecwid.apiclient.v3.converter") + .filterInputsBy( + FilterBuilder() + .includePattern("com\\.ecwid\\.apiclient\\.v3\\.converter\\..*") + ) + .setScanners(Scanners.MethodsReturn) + ) + } + + private val apiRequestClassesReflections = lazy { + Reflections( + ConfigurationBuilder() + .forPackage(ApiRequest::class.java.packageName) + .filterInputsBy( + FilterBuilder() + .includePattern(ApiRequest::class.java.packageName + "\\..*") + ) + .setScanners(SubTypes.filterResultsBy { true }) ) + } + + private val getDtoClassesToCheck = lazy { + apiRequestClassesReflections + .value + .getSubTypesOf(Object::class.java) + .filterNot { clazz -> clazz.isInterface || clazz.isAnonymousClass } + .filterNot { clazz -> + try { + clazz.kotlin.isCompanion + } catch (ignore: UnsupportedOperationException) { + // Filtering file facades classes (*Kt classes) and synthetic classes (i.e. when-mappings classes) + true + } + } + .sortedBy { clazz -> clazz.canonicalName } + } @Test @Order(0) fun `test all DTOs marked as data classes`() { - val dtoClasses = getDtoClassesToCheck() - assertFalse(dtoClasses.isEmpty()) + val dtoClassesToCheck = getDtoClassesToCheck.value + assertFalse(dtoClassesToCheck.isEmpty()) - val problemDtoClasses = dtoClasses.filter { dtoClass -> + val problemDtoClasses = dtoClassesToCheck.filter { dtoClass -> !dtoClass.kotlin.isData && isDtoShouldBeMarkedAsDataClass(dtoClass) } assertTrue(problemDtoClasses.isEmpty()) { @@ -61,11 +92,11 @@ class DtoContractUnitTest { @Test @Order(1) fun `test all data classes DTOs has default constructor`() { - val dtoDataClasses = getDtoClassesToCheck() + val dtoClassesToCheck = getDtoClassesToCheck.value .filter { dtoClass -> dtoClass.kotlin.isData } - assertFalse(dtoDataClasses.isEmpty()) + assertFalse(dtoClassesToCheck.isEmpty()) - val problemDtoClasses = dtoDataClasses.filter { dtoDataClass -> + val problemDtoClasses = dtoClassesToCheck.filter { dtoDataClass -> val constructors = dtoDataClass.constructors val hasZeroArgConstructor = constructors.any { constructor -> constructor.parameters.isEmpty() } !hasZeroArgConstructor && isDtoShouldHaveZeroArgConstructor(constructors) @@ -80,11 +111,11 @@ class DtoContractUnitTest { @Test @Order(2) fun `test all data classes DTOs has only val parameters in their primary constructors`() { - val dtoDataClasses = getDtoClassesToCheck() + val dtoClassesToCheck = getDtoClassesToCheck.value .filter { dtoClass -> dtoClass.kotlin.isData } - assertFalse(dtoDataClasses.isEmpty()) + assertFalse(dtoClassesToCheck.isEmpty()) - val problemDtoClasses = dtoDataClasses.filter { dtoDataClass -> + val problemDtoClasses = dtoClassesToCheck.filter { dtoDataClass -> isPrimaryConstructorHasMutableProperties(dtoDataClass) } assertTrue(problemDtoClasses.isEmpty()) { @@ -104,12 +135,12 @@ class DtoContractUnitTest { ApiResultDTO::class.java ) - val dtoDataClasses = getDtoClassesToCheck() + val dtoClassesToCheck = getDtoClassesToCheck.value .filterNot { dtoClass -> dtoClass.isEnum } .filterNot { dtoClass -> dtoClass.packageName.startsWith("com.ecwid.apiclient.v3.dto.common") } - assertFalse(dtoDataClasses.isEmpty()) + assertFalse(dtoClassesToCheck.isEmpty()) - val problemDtoClasses = dtoDataClasses + val problemDtoClasses = dtoClassesToCheck .filterNot { dtoClass -> dtoClass.isClassifiedDTOOrEnclosingClass(*dtoMarkerInterfaces) } assertTrue(problemDtoClasses.isEmpty()) { val interfacesStr = dtoMarkerInterfaces.joinToString(separator = ", ") { int -> int.simpleName } @@ -121,7 +152,7 @@ class DtoContractUnitTest { @Test @Order(4) fun `test all DTOs marked as 'preferably having non-nullable fields' have only non-nullable fields or fields added to exclusion list`() { - val dtoDataClasses = getDtoClassesToCheck() + val dtoClassesToCheck = getDtoClassesToCheck.value .filter { dtoClass -> dtoClass.isClassifiedDTOOrEnclosingClass( ApiFetchedDTO::class.java, @@ -130,14 +161,14 @@ class DtoContractUnitTest { ) } .filterNot { dtoClass -> dtoClass.kotlin.visibility == KVisibility.PRIVATE } - assertFalse(dtoDataClasses.isEmpty()) + assertFalse(dtoClassesToCheck.isEmpty()) val allowedOrIgnoredNullableProperties = nullablePropertyRules .filter { rule -> rule is AllowNullable || rule is IgnoreNullable } .map { rule -> rule.property } .toSet() - val nullableProperties = dtoDataClasses + val nullableProperties = dtoClassesToCheck .flatMap { dtoDataClass -> getPrimaryConstructorProperties(dtoDataClass) .filter { property -> property.returnType.isMarkedNullable } @@ -170,20 +201,20 @@ class DtoContractUnitTest { @Test @Order(6) fun `test all DTOs marked as 'preferably having nullable fields' have only nullable fields or fields added to exclusion list`() { - val dtoDataClasses = getDtoClassesToCheck() + val dtoClassesToCheck = getDtoClassesToCheck.value .filter { dtoClass -> dtoClass.isClassifiedDTOOrEnclosingClass( ApiUpdatedDTO::class.java ) } - assertFalse(dtoDataClasses.isEmpty()) + assertFalse(dtoClassesToCheck.isEmpty()) val allowedOrIgnoredNonnullProperties = nonnullPropertyRules .filter { rule -> rule is AllowNonnull || rule is IgnoreNonnull } .map { rule -> rule.property } .toSet() - val nonnullProperties = dtoDataClasses + val nonnullProperties = dtoClassesToCheck .flatMap { dtoDataClass -> getPrimaryConstructorProperties(dtoDataClass) .filterNot { property -> property.returnType.isMarkedNullable } @@ -216,7 +247,9 @@ class DtoContractUnitTest { @Test @Order(8) fun `test fetched and updated DTOs correctly linked to each other`() { - val dtoClassesToCheck = getDtoClassesToCheck() + val dtoClassesToCheck = getDtoClassesToCheck.value + assertFalse(dtoClassesToCheck.isEmpty()) + val fetchedDTOClassesToModifyKindMap = getFetchedDTOClassesToModifyKindMap(dtoClassesToCheck) val updatedDTOClassesToModifyKindMap = getUpdatedDTOClassesToModifyKindMap(dtoClassesToCheck) @@ -226,6 +259,7 @@ class DtoContractUnitTest { ApiFetchedDTO.ModifyKind.ReadOnly -> { // No UpdatedDTO to check } + is ApiFetchedDTO.ModifyKind.ReadWrite -> { val updatedDTOClass = kind.updatedDTOClass val updatedDtoModifyKind = updatedDTOClassesToModifyKindMap[updatedDTOClass] @@ -236,6 +270,7 @@ class DtoContractUnitTest { "Classes ${dtoClass.qualifiedName} and ${updatedDTOClass.qualifiedName} does not links to each other" ) } + null -> { fail("Impossible situation") } @@ -254,9 +289,11 @@ class DtoContractUnitTest { ApiFetchedDTO.ModifyKind.ReadOnly -> { fail("Updatable class ${dtoClass.qualifiedName} links to class ${fetchedDTOClass.qualifiedName} which is marked as read-only ") } + is ApiFetchedDTO.ModifyKind.ReadWrite -> { // Backlink was checked before } + null -> { fail("Impossible situation") } @@ -269,7 +306,8 @@ class DtoContractUnitTest { @Test @Order(9) fun `test fetched and updated DTOs fields list and their types are synchronized`() { - val dtoClassesToCheck = getDtoClassesToCheck() + val dtoClassesToCheck = getDtoClassesToCheck.value + assertFalse(dtoClassesToCheck.isEmpty()) val fetchedUpdatedDTOs = dtoClassesToCheck .filter { dtoClass -> @@ -315,7 +353,9 @@ class DtoContractUnitTest { val dataStrategy = DTORandomDataProviderStrategy() val factory = PodamFactoryImpl(dataStrategy) - val dtoClassesToCheck = getDtoClassesToCheck() + val dtoClassesToCheck = getDtoClassesToCheck.value + assertFalse(dtoClassesToCheck.isEmpty()) + val fetchedDTOClassesToModifyKindMap = getFetchedDTOClassesToModifyKindMap(dtoClassesToCheck) val problemMessages = mutableListOf() @@ -326,13 +366,14 @@ class DtoContractUnitTest { // No UpdatedDTO to check null } + is ApiFetchedDTO.ModifyKind.ReadWrite -> { @Suppress("UNCHECKED_CAST") val fetchedDtoKClass = fetchedDtoClass as KClass val updatedDTOClass = kind.updatedDTOClass val toUpdatedMethod: Method? = - findToUpdatedMethod(convertersReflections, fetchedDtoKClass, updatedDTOClass) + findToUpdatedMethod(convertersReflections.value, fetchedDtoKClass, updatedDTOClass) if (toUpdatedMethod == null) { problemMessages += "Extension function with signature `${fetchedDtoKClass.java.canonicalName}.toUpdated(): ${updatedDTOClass.java.canonicalName}` is not implemented" null @@ -399,9 +440,11 @@ private fun FieldProblem.buildMessage(): String { FieldProblemKind.FIELD_NOT_FOUND -> { "All updatable fields from Fetched DTO must have corresponding field in Updated DTO." } + FieldProblemKind.TYPE_MUST_NOT_BE_REUSED -> { "Fields with the same name in Fetched and Updated DTOs must not share the same DTO (except for primitives and enums)" } + FieldProblemKind.FIELD_IS_NOT_MAP, FieldProblemKind.FIELD_IS_NOT_LIST, FieldProblemKind.PRIMITIVE_FIELDS_INCOMPATIBLE_TYPE -> { @@ -415,6 +458,7 @@ private fun FieldProblem.buildMessage(): String { "If this field is read-only in Ecwid API you CAN add it as `ReadOnly()` exclusion to file `NonUpdatablePropertyRules.kt`.\n" + "You MUST NOT add exclusion with type Ignored() which is used only for old fields until they are fixed." } + FieldProblemKind.FIELD_IS_NOT_MAP, FieldProblemKind.FIELD_IS_NOT_LIST, FieldProblemKind.PRIMITIVE_FIELDS_INCOMPATIBLE_TYPE, @@ -475,10 +519,12 @@ private fun isDtoShouldBeMarkedAsDataClass(dtoClass: Class<*>): Boolean { // Sealed classes must not be instantiated by themself but their inheritors must be marked as data classes false } + kclass.objectInstance != null -> { // Singleton classes has no explicit constructor arguments so it cannot be marked as data class false } + else -> { // Classes that has only one zero-arg constructor cannot be marked as data class val constructors = dtoClass.constructors @@ -541,19 +587,6 @@ private fun getUpdatedDTOClassesToModifyKindMap(dtoClassesToCheck: List } } -internal fun getDtoClassesToCheck() = Reflections(ApiRequest::class.java.packageName, SubTypesScanner(false)) - .getSubTypesOf(Object::class.java) - .filterNot { clazz -> clazz.isInterface || clazz.isAnonymousClass } - .filterNot { clazz -> - try { - clazz.kotlin.isCompanion - } catch (ignore: UnsupportedOperationException) { - // Filtering file facades classes (*Kt classes) and synthetic classes (i.e. when-mappings classes) - true - } - } - .sortedBy { clazz -> clazz.canonicalName } - private fun findToUpdatedMethod( reflections: Reflections, fetchedDtoClass: KClass, diff --git a/src/test/kotlin/com/ecwid/apiclient/v3/util/DTORandomDataProviderStrategy.kt b/src/test/kotlin/com/ecwid/apiclient/v3/util/DTORandomDataProviderStrategy.kt index ae4ec6ff1..73db797c8 100644 --- a/src/test/kotlin/com/ecwid/apiclient/v3/util/DTORandomDataProviderStrategy.kt +++ b/src/test/kotlin/com/ecwid/apiclient/v3/util/DTORandomDataProviderStrategy.kt @@ -1,9 +1,7 @@ package com.ecwid.apiclient.v3.util -import com.google.common.base.Predicate -import com.google.common.base.Predicates -import org.reflections.ReflectionUtils import org.reflections.Reflections +import org.reflections.util.ReflectionUtilsPredicates.withClassModifier import uk.co.jemos.podam.api.AbstractRandomDataProviderStrategy import uk.co.jemos.podam.api.DataProviderStrategy import uk.co.jemos.podam.common.PodamConstants @@ -71,13 +69,14 @@ internal class DTORandomDataProviderStrategy : AbstractRandomDataProviderStrateg @Suppress("UNCHECKED_CAST") private fun fillConcreteSubclasses(abstractClass: Class) { - this.subclasses.addAll( - ReflectionUtils.getAll( - reflections.getSubTypesOf(abstractClass as Class), - Predicates.not(IS_ABSTRACT), - Predicates.not(IS_SUBCLASS_OF_ENUM) - ) - ) + val subclasses = reflections.getSubTypesOf(abstractClass as Class) + .filter { clazz -> + val isAbstract = withClassModifier(Modifier.ABSTRACT).test(clazz) + val isInterface = withClassModifier(Modifier.INTERFACE).test(clazz) + val isSubclassOfEnum = clazz?.superclass?.isEnum == true + !isAbstract && !isInterface && !isSubclassOfEnum + } + this.subclasses.addAll(subclasses) } private fun sortClassesByName(classes: MutableList>) { @@ -87,17 +86,7 @@ internal class DTORandomDataProviderStrategy : AbstractRandomDataProviderStrateg } companion object { - private val reflections = Reflections("com.ecwid.apiclient.v3") - - private val IS_ABSTRACT = Predicates.or( - ReflectionUtils.withClassModifier(Modifier.ABSTRACT), - ReflectionUtils.withClassModifier(Modifier.INTERFACE) - ) - - private val IS_SUBCLASS_OF_ENUM = Predicate> { clazz -> - clazz?.superclass?.isEnum == true - } } } } From 8b8c8c6ab459f14589101dfff5fe72a0996d0b05 Mon Sep 17 00:00:00 2001 From: Alexey Zagaichuk Date: Mon, 28 Nov 2022 17:58:19 +0400 Subject: [PATCH 16/18] Fix typos in method names --- .github/workflows/pull-request.yml | 2 +- .github/workflows/push-to-master.yml | 2 +- build.gradle.kts | 17 +++++++++++------ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 56882c08c..f6bc8e1df 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -32,7 +32,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Build, run tests and upload dev snapshot to Maven Central with Gradle - run: ./gradlew devSnapshot printDevSnapshotReleaseNode + run: ./gradlew devSnapshot printDevSnapshotReleaseNote env: STORE_ID: ${{ secrets.STORE_ID }} API_TOKEN: ${{ secrets.API_TOKEN }} diff --git a/.github/workflows/push-to-master.yml b/.github/workflows/push-to-master.yml index 805b717dc..e1ca06753 100644 --- a/.github/workflows/push-to-master.yml +++ b/.github/workflows/push-to-master.yml @@ -34,7 +34,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Build, upload release version to Maven Central and create git release tag with Gradle - run: ./gradlew detekt final closeAndReleaseRepository printFinalReleaseNode + run: ./gradlew detekt final closeAndReleaseRepository printFinalReleaseNote env: GPG_SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }} GPG_SIGNING_PASSWORD: ${{ secrets.GPG_SIGNING_PASSWORD }} diff --git a/build.gradle.kts b/build.gradle.kts index 898711f3e..c8b5a4eb5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -95,9 +95,9 @@ tasks.withType { } } -tasks.register("printFinalReleaseNode") { +tasks.register(Tasks.PRINT_FINAL_RELEASE_NOTE_TASK_NAME) { doLast { - printFinalReleaseNode( + printFinalReleaseNote( groupId = PublicationSettings.GROUP_ID, artifactId = PublicationSettings.ARTIFACT_ID, sanitizedVersion = project.sanitizeVersion() @@ -105,9 +105,9 @@ tasks.register("printFinalReleaseNode") { } } -tasks.register("printDevSnapshotReleaseNode") { +tasks.register(Tasks.PRINT_DEV_SNAPSHOT_RELEASE_NOTE_TASK_NAME) { doLast { - printDevSnapshotReleaseNode( + printDevSnapshotReleaseNote( groupId = PublicationSettings.GROUP_ID, artifactId = PublicationSettings.ARTIFACT_ID, sanitizedVersion = project.sanitizeVersion() @@ -227,7 +227,7 @@ fun Project.sanitizeVersion(): String { fun Project.isSnapshotVersion() = version.toString().contains("-dev.") -fun printFinalReleaseNode(groupId: String, artifactId: String, sanitizedVersion: String) { +fun printFinalReleaseNote(groupId: String, artifactId: String, sanitizedVersion: String) { println() println("========================================================") println() @@ -249,7 +249,7 @@ fun printFinalReleaseNode(groupId: String, artifactId: String, sanitizedVersion: println() } -fun printDevSnapshotReleaseNode(groupId: String, artifactId: String, sanitizedVersion: String) { +fun printDevSnapshotReleaseNote(groupId: String, artifactId: String, sanitizedVersion: String) { println() println("========================================================") println() @@ -330,3 +330,8 @@ object Consts { const val SLOW_TESTS_LOGGING_THRESHOLD_MS = 30_000L const val MAX_TEST_RETRIES_COUNT = 3 } + +object Tasks { + const val PRINT_FINAL_RELEASE_NOTE_TASK_NAME = "printFinalReleaseNote" + const val PRINT_DEV_SNAPSHOT_RELEASE_NOTE_TASK_NAME = "printDevSnapshotReleaseNote" +} From 6244bcb660ccf48d51949264b6507bd76eaa9d8b Mon Sep 17 00:00:00 2001 From: Alexey Zagaichuk Date: Mon, 28 Nov 2022 18:04:36 +0400 Subject: [PATCH 17/18] Added an explicit dependsOn declarations to execute tasks in the correct order --- build.gradle.kts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index c8b5a4eb5..16f120325 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -87,6 +87,7 @@ tasks.withType { doFirst { settingsProvider.validateGPGSecrets() } + dependsOn(tasks.getByName("build")) } tasks.withType { @@ -103,6 +104,7 @@ tasks.register(Tasks.PRINT_FINAL_RELEASE_NOTE_TASK_NAME) { sanitizedVersion = project.sanitizeVersion() ) } + dependsOn(tasks.getByName("final")) } tasks.register(Tasks.PRINT_DEV_SNAPSHOT_RELEASE_NOTE_TASK_NAME) { @@ -113,6 +115,7 @@ tasks.register(Tasks.PRINT_DEV_SNAPSHOT_RELEASE_NOTE_TASK_NAME) { sanitizedVersion = project.sanitizeVersion() ) } + dependsOn(tasks.getByName("devSnapshot")) } detekt { From 464f9607cc071a67a05348915b2598926117ebe1 Mon Sep 17 00:00:00 2001 From: Alexey Zagaichuk Date: Mon, 28 Nov 2022 18:33:12 +0400 Subject: [PATCH 18/18] Add toolchains.xml to .gitignore file which created by actions/setup-java@v3 github action --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 6bd5bd4c4..3d74bdd2d 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ src/test/resources/test.properties # Files created by github actions before workflow job run # Task `gradle release` requires that git reposoitary to be clean -settings.xml \ No newline at end of file +settings.xml +toolchains.xml